module Language.Clafer.JSONMetaData (
generateJSONnameUIDMap,
generateJSONScopes,
parseJSONScopes,
writeCfrScopeFile,
readCfrScopeFile
)
where
import Control.Lens hiding (element)
import Data.Aeson.Lens
import qualified Data.List as List
import Data.Maybe
import Data.Json.Builder
import Data.String.Conversions
import qualified Data.Text as T
import System.FilePath
import System.Directory
import Language.Clafer.QNameUID
generateJSONnameUIDMap :: QNameMaps -> String
generateJSONnameUIDMap qNameMaps =
prettyPrintJSON $ convertString $ toJsonBS $ foldl generateQNameUIDArrayEntry mempty sortedTriples
where
sortedTriples :: [(FQName, PQName, UID)]
sortedTriples = List.sortBy (\(fqName1, _, _) (fqName2, _, _) -> compare fqName1 fqName2) $ getQNameUIDTriples qNameMaps
generateQNameUIDArrayEntry :: Array -> (FQName, PQName, UID) -> Array
generateQNameUIDArrayEntry array (fqName, lpqName, uid) =
mappend array $ element $ mconcat [
row ("fqName" :: String) fqName,
row ("lpqName" :: String) lpqName,
row ("uid" :: String) uid ]
generateJSONScopes :: QNameMaps -> [(UID, Integer)] -> String
generateJSONScopes qNameMaps scopes =
prettyPrintJSON $ convertString $ toJsonBS $ foldl generateLpqNameScopeArrayEntry mempty sortedLpqNameScopeList
where
lpqNameScopeList = map (\(uid, scope) -> (fromMaybe uid $ getLPQName qNameMaps uid, scope)) scopes
sortedLpqNameScopeList :: [(PQName, Integer)]
sortedLpqNameScopeList = List.sortBy (\(lpqName1, _) (lpqName2, _) -> compare lpqName1 lpqName2) lpqNameScopeList
generateLpqNameScopeArrayEntry :: Array -> (PQName, Integer) -> Array
generateLpqNameScopeArrayEntry array (lpqName, scope) =
mappend array $ element $ mconcat [
row ("lpqName" :: String) lpqName,
row ("scope" :: String) scope ]
prettyPrintJSON :: String -> String
prettyPrintJSON ('[':line) = '[':'\n':(prettyPrintJSON line)
prettyPrintJSON ('{':line) = '{':'\n':(prettyPrintJSON line)
prettyPrintJSON (',':line) = ',':'\n':(prettyPrintJSON line)
prettyPrintJSON (']':line) = '\n':']':(prettyPrintJSON line)
prettyPrintJSON ('}':line) = '\n':'}':(prettyPrintJSON line)
prettyPrintJSON (c:line) = c:(prettyPrintJSON line)
prettyPrintJSON "" = ""
parseJSONScopes :: QNameMaps -> String -> [ (UID, Integer) ]
parseJSONScopes qNameMaps scopesJSON =
foldl (\uidScopes qScope -> (qNameToUIDs qScope) ++ uidScopes) [] decodedScopes
where
decodedScopes :: [ (T.Text, Integer) ]
decodedScopes = scopesJSON ^.. _Array . traverse
. to (\o -> ( o ^?! key "lpqName" . _String
, o ^?! key "scope" . _Integer)
)
qNameToUIDs :: (T.Text, Integer) -> [ (UID, Integer) ]
qNameToUIDs (qName, scope) = if T.null qName
then [ ("", scope) ]
else [ (uid, scope) | uid <- getUIDs qNameMaps $ convertString qName]
writeCfrScopeFile :: [ (UID, Integer) ] -> QNameMaps -> FilePath -> IO ()
writeCfrScopeFile uidScopes qNameMaps modelName = do
let
scopesInJSON = generateJSONScopes qNameMaps uidScopes
writeFile (replaceExtension modelName ".cfr-scope") scopesInJSON
readCfrScopeFile :: QNameMaps -> FilePath -> IO (Maybe [ (UID, Integer) ])
readCfrScopeFile qNameMaps modelName = do
let
cfrScopeFileName = replaceExtension modelName ".cfr-scope"
exists <- doesFileExist cfrScopeFileName
if exists
then do
scopesInJSON <- readFile cfrScopeFileName
return $ Just $ parseJSONScopes qNameMaps scopesInJSON
else return Nothing