multifocal-0.0.1: src/UI/CmdLine.hs
-----------------------------------------------------------------------------
-- |
-- Module : UI.CmdLine
-- Copyright : (c) 2011 University of Minho
-- License : BSD3
--
-- Maintainer : hpacheco@di.uminho.pt
-- Stability : experimental
-- Portability : non-portable
--
-- Multifocal:
-- Bidirectional Two-level Transformation of XML Schemas
--
-- Main file for the multifocal tool.
--
-----------------------------------------------------------------------------
module Main where
import Data.Type
import Data.Equal
import Data.Transform.TwoLevel
import UI.GenHaskell
import Language.TLT.Tlt2Strat
import Language.XML.Type2Xsd
import Language.XML.Xsd2Type
import Transform.Rules.Lenses
import Language.XML.HaXmlAliases
import Language.TLT.TltParser
import Transform.Rewriting as R
import UI.Menu
import System.IO
import System.Environment
import System.Console.GetOpt
import System.Exit
import Control.Monad.State as ST
-----------------------------------------------------------------------------
-- * Command line options
-- | Record type to hold all program options.
data Options = Options
{
optInputXsdFile :: Maybe FilePath
, optInput2LTFile :: Maybe FilePath
, optOutputXsdFile :: Maybe FilePath
, optOutputHsFile :: Maybe FilePath
, optOptimize :: Bool
}
-- | Default options.
startOpt :: Options
startOpt = Options
{ optInputXsdFile = Nothing
, optInput2LTFile = Nothing
, optOutputXsdFile = Nothing
, optOutputHsFile = Nothing
, optOptimize = False
}
-- | Description of all available program options.
options :: Opts Options
options =
[ Option "h" ["help"]
(NoArg (\opt -> exitHelp options))
"Show usage info"
, Option "i" ["input"]
(ReqArg (\arg opt -> return opt { optInputXsdFile = Just arg }) "FILE")
"Input XML Schema"
, Option "t" ["2lt"]
(ReqArg (\arg opt -> return opt { optInput2LTFile = Just arg }) "FILE")
"Input 2LT Transformation File"
, Option "o" ["output"]
(ReqArg (\arg opt -> return opt { optOutputXsdFile = Just arg }) "FILE")
"Output XML Schema (default: stdout)"
, Option "c" ["haskell"]
(ReqArg (\arg opt -> do return opt { optOutputHsFile = Just arg }) "FILE")
"Output Haskell program with the corresponding bidirectional transformation."
, Option "e" ["optimize"]
(NoArg (\opt -> do return opt { optOptimize = True }))
"Optimize the resulting bidirectional transformation."
]
main = menu
menu :: IO ()
menu = do
argv <- getArgs
opts <- parseOptions startOpt options argv
i <- run "input XML Schema missing" $ optInputXsdFile opts
-- parse Xml Schema
xml <- readFile i
schema <- run "Error parsing input XML Schema" $ parseXsd i xml
-- parse input XSD into a type
(DynT a,tops) <- run "error translating input XML Schema" $ xsd2toptype schema
--putStrLn $ showDatas a
t <- run "input Multifocal Transformation missing" $ optInput2LTFile opts
-- parse 2LT transformation file
tfile <- readFile t
let tlt = parseTLT tfile
--putStrLn $ show tlt
-- translate the parsed 2LT transformation into Haskell
RuleTRep rule <- run "Error translating 2LT transformation" $ evalStateT (tlt2strat tlt) tops
-- evaluate the 2LT transformation
(View lns b,news) <- run "Failed to apply 2LT transformation" $ transform a rule
-- print output XML Schema
--putStrLn $ showDatas b
outputHandle <- maybe (return stdout) (\f -> openFile f WriteMode) (optOutputXsdFile opts)
doc <- run "Error generating output XML Schema file" $ type2doc b
hPutStrLn outputHandle $ renderXml doc
hClose outputHandle
-- generate output Haskell Lens File
let srcSchema = maybe "" id (optInputXsdFile opts)
tgtSchema = maybe "" id (optOutputXsdFile opts)
rule :: Rule
rule = if optOptimize opts then optimise_all_lns else R.nop
case optOutputHsFile opts of
Nothing -> return ()
Just hs -> generateHaskell' srcSchema tgtSchema [] hs a (View lns b) news rule