{- |
Module      :  ./QVTR/ParseQvtAsLibDefn.hs
Description :  QVTR .qvt parser
Copyright   :  (c) Daniel Calegari Universidad de la Republica, Uruguay 2013
License     :  GPLv2 or higher, see LICENSE.txt
Maintainer  :  dcalegar@fing.edu.uy
Stability   :  provisional
Portability :  portable
-}

module QVTR.ParseQvtAsLibDefn where

import CSMOF.As
import CSMOF.Parser

import QVTR.As
import QVTR.Parser
import QVTR.Logic_QVTR

import Logic.Grothendieck

import Syntax.AS_Library
import Syntax.AS_Structured
import Common.AS_Annotation
import Common.IRI
import Common.Id
import Common.LibName
import Common.Utils

import Text.XML.Light

import System.IO
import System.FilePath (replaceBaseName, replaceExtension, takeBaseName)

import Text.ParserCombinators.Parsec

parseQvt :: FilePath -> String -> IO LIB_DEFN
parseQvt :: FilePath -> FilePath -> IO LIB_DEFN
parseQvt fp :: FilePath
fp input :: FilePath
input =
  case GenParser Char () Transformation
-> () -> FilePath -> FilePath -> Either ParseError Transformation
forall tok st a.
GenParser tok st a
-> st -> FilePath -> [tok] -> Either ParseError a
runParser GenParser Char () Transformation
forall st. CharParser st Transformation
pTransformation () FilePath
fp FilePath
input of  -- Either ParseError String
      Left erro :: ParseError
erro -> do
                  ParseError -> IO ()
forall a. Show a => a -> IO ()
print ParseError
erro
                  LIB_DEFN -> IO LIB_DEFN
forall (m :: * -> *) a. Monad m => a -> m a
return (LibName -> [Annoted LIB_ITEM] -> Range -> [Annotation] -> LIB_DEFN
Lib_defn (FilePath -> LibName
emptyLibName (FilePath -> FilePath
convertFileToLibStr FilePath
fp)) [] Range
nullRange [])
      Right trans :: Transformation
trans -> let (_, sMet :: FilePath
sMet, _) = Transformation -> (FilePath, FilePath, Metamodel)
sourceMetamodel Transformation
trans
                         (_, tMet :: FilePath
tMet, _) = Transformation -> (FilePath, FilePath, Metamodel)
targetMetamodel Transformation
trans
                     in
                       do
                         Metamodel
sourceMetam <- FilePath -> IO Metamodel
parseXmiMetamodel (FilePath -> FilePath -> FilePath
replaceName FilePath
fp FilePath
sMet)
                         Metamodel
targetMetam <- FilePath -> IO Metamodel
parseXmiMetamodel (FilePath -> FilePath -> FilePath
replaceName FilePath
fp FilePath
tMet)
                         LIB_DEFN -> IO LIB_DEFN
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> Transformation -> LIB_DEFN
convertToLibDefN FilePath
fp (Transformation -> Metamodel -> Metamodel -> Transformation
createTransfWithMeta Transformation
trans Metamodel
sourceMetam Metamodel
targetMetam))


replaceName :: FilePath -> String -> String
replaceName :: FilePath -> FilePath -> FilePath
replaceName fp :: FilePath
fp = FilePath -> FilePath -> FilePath
replaceBaseName (FilePath -> FilePath -> FilePath
replaceExtension FilePath
fp "xmi")


parseXmiMetamodel :: FilePath -> IO Metamodel
parseXmiMetamodel :: FilePath -> IO Metamodel
parseXmiMetamodel fullFileName :: FilePath
fullFileName =
  do
    let fp :: FilePath
fp = FilePath -> FilePath -> FilePath
tryToStripPrefix "file://" FilePath
fullFileName
    Handle
handle <- FilePath -> IOMode -> IO Handle
openFile FilePath
fp IOMode
ReadMode
    FilePath
contents <- Handle -> IO FilePath
hGetContents Handle
handle
    case FilePath -> Maybe Element
forall s. XmlSource s => s -> Maybe Element
parseXMLDoc FilePath
contents of
      Nothing -> Metamodel -> IO Metamodel
forall (m :: * -> *) a. Monad m => a -> m a
return Metamodel :: FilePath -> [NamedElement] -> [Model] -> Metamodel
Metamodel { metamodelName :: FilePath
metamodelName = FilePath -> FilePath
takeBaseName FilePath
fp
                           , element :: [NamedElement]
element = []
                           , model :: [Model]
model = []
                           }
      Just el :: Element
el -> Metamodel -> IO Metamodel
forall (m :: * -> *) a. Monad m => a -> m a
return (Element -> Metamodel
parseCSMOF Element
el)


convertToLibDefN :: FilePath -> Transformation -> LIB_DEFN
convertToLibDefN :: FilePath -> Transformation -> LIB_DEFN
convertToLibDefN filename :: FilePath
filename el :: Transformation
el = LibName -> [Annoted LIB_ITEM] -> Range -> [Annotation] -> LIB_DEFN
Lib_defn
                               (FilePath -> LibName
emptyLibName (FilePath -> LibName) -> FilePath -> LibName
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
convertFileToLibStr FilePath
filename)
                               (QVTR -> Annoted LIB_ITEM
forall lid. Language lid => lid -> Annoted LIB_ITEM
makeLogicItem QVTR
QVTR Annoted LIB_ITEM -> [Annoted LIB_ITEM] -> [Annoted LIB_ITEM]
forall a. a -> [a] -> [a]
: [Transformation -> Annoted LIB_ITEM
convertoItem Transformation
el])
                               Range
nullRange []

convertoItem :: Transformation -> Annoted LIB_ITEM
convertoItem :: Transformation -> Annoted LIB_ITEM
convertoItem el :: Transformation
el = SPEC_NAME -> Annoted SPEC -> Annoted LIB_ITEM
makeSpecItem (SIMPLE_ID -> SPEC_NAME
simpleIdToIRI (SIMPLE_ID -> SPEC_NAME) -> SIMPLE_ID -> SPEC_NAME
forall a b. (a -> b) -> a -> b
$ FilePath -> SIMPLE_ID
mkSimpleId (FilePath -> SIMPLE_ID) -> FilePath -> SIMPLE_ID
forall a b. (a -> b) -> a -> b
$ Transformation -> FilePath
transfName Transformation
el) (Annoted SPEC -> Annoted LIB_ITEM)
-> Annoted SPEC -> Annoted LIB_ITEM
forall a b. (a -> b) -> a -> b
$ Transformation -> Annoted SPEC
createSpec Transformation
el

createSpec :: Transformation -> Annoted SPEC
createSpec :: Transformation -> Annoted SPEC
createSpec el :: Transformation
el = G_basic_spec -> Annoted SPEC
makeSpec (G_basic_spec -> Annoted SPEC) -> G_basic_spec -> Annoted SPEC
forall a b. (a -> b) -> a -> b
$ QVTR -> Transformation -> G_basic_spec
forall lid sublogics basic_spec sentence symb_items symb_map_items
       sign morphism symbol raw_symbol proof_tree.
Logic
  lid
  sublogics
  basic_spec
  sentence
  symb_items
  symb_map_items
  sign
  morphism
  symbol
  raw_symbol
  proof_tree =>
lid -> basic_spec -> G_basic_spec
G_basic_spec QVTR
QVTR Transformation
el


createTransfWithMeta :: Transformation -> Metamodel -> Metamodel -> Transformation
createTransfWithMeta :: Transformation -> Metamodel -> Metamodel -> Transformation
createTransfWithMeta trans :: Transformation
trans souMeta :: Metamodel
souMeta tarMeta :: Metamodel
tarMeta =
  let (sVar :: FilePath
sVar, sMet :: FilePath
sMet, _) = Transformation -> (FilePath, FilePath, Metamodel)
sourceMetamodel Transformation
trans
      (tVar :: FilePath
tVar, tMet :: FilePath
tMet, _) = Transformation -> (FilePath, FilePath, Metamodel)
targetMetamodel Transformation
trans
  in
    FilePath
-> (FilePath, FilePath, Metamodel)
-> (FilePath, FilePath, Metamodel)
-> [Key]
-> [Relation]
-> Transformation
Transformation (Transformation -> FilePath
transfName Transformation
trans) (FilePath
sVar, FilePath
sMet, Metamodel
souMeta) (FilePath
tVar, FilePath
tMet, Metamodel
tarMeta) (Transformation -> [Key]
keys Transformation
trans) (Transformation -> [Relation]
relations Transformation
trans)