From 7e50434905cbb7f5d03636033b698e17a9075e9d Mon Sep 17 00:00:00 2001 From: OszkarSemerath Date: Sat, 13 Jan 2018 19:33:26 +0100 Subject: Initial commit of the configuration language and application --- .../application/execution/MetamodelLoader.xtend | 178 +++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/MetamodelLoader.xtend (limited to 'Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/MetamodelLoader.xtend') diff --git a/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/MetamodelLoader.xtend b/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/MetamodelLoader.xtend new file mode 100644 index 00000000..126dbb7d --- /dev/null +++ b/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/MetamodelLoader.xtend @@ -0,0 +1,178 @@ +package hu.bme.mit.inf.dslreasoner.application.execution + +import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.ClassElement +import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.FeatureElement +import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.MetamodelEntry +import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.MetamodelSpecification +import hu.bme.mit.inf.dslreasoner.ecore2logic.EcoreMetamodelDescriptor +import java.util.ArrayList +import java.util.HashMap +import java.util.LinkedList +import java.util.List +import java.util.Map +import java.util.Set +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.EAttribute +import org.eclipse.emf.ecore.EClass +import org.eclipse.emf.ecore.EDataType +import org.eclipse.emf.ecore.EEnum +import org.eclipse.emf.ecore.EEnumLiteral +import org.eclipse.emf.ecore.ENamedElement +import org.eclipse.emf.ecore.EPackage +import org.eclipse.emf.ecore.EReference +import org.eclipse.emf.ecore.EcorePackage +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl +import org.eclipse.xtend.lib.annotations.Data + +@Data +class Metamodel { + List packages + EcoreMetamodelDescriptor descriptor +} + +class MetamodelLoader { + + def private static init() { + EcorePackage.eINSTANCE.EClass + Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("ecore",new XMIResourceFactoryImpl) + } + + public new() { init } + + def loadMetamodel(List specification, ResourceSet rs, Context context) { + + } + + def loadMetamodel(MetamodelSpecification specification, ResourceSet rs, Context context) { + val Map> entry2Packages = new HashMap + + for(entry : specification.entries) { + val packagesInEntry = entry.path.path.loadPackageFromPath(rs,context) + entry2Packages.put(entry,packagesInEntry) + } + + return entry2Packages + } + + public def pruneMetamodel(Map> specification, ResourceSet rs, Context context) { + val List classes = new LinkedList + val List enums = new LinkedList + val List literals = new LinkedList + val List references = new LinkedList + val List attributes = new LinkedList + + + /** Add all included types */ + for(entry : specification.entrySet) { + val metamodelEntry = entry.key + val packages = entry.value + + /** Excluted types */ + val excludedTypeNames = metamodelEntry.excluding.filter(ClassElement).map[name].toSet + /** Excluded features */ + val excludedFeatureNames = metamodelEntry.excluding.filter(FeatureElement).map[it.container.name -> it.name].toSet + + /** Load the types */ + for(package : packages) { + for(class : package.EClassifiers.filter(EClass)) { + classes.addIfNotExcluded(class,excludedTypeNames) + } + for(enum : package.EClassifiers.filter(EEnum)) { + val added = enums.addIfNotExcluded(enum,excludedTypeNames) + if(added) { + for(literal : enum.ELiterals) { + literals.addIfNotExcluded(literal,enum,excludedFeatureNames) + } + } + } + } + } + + /** Add all included references and attributes*/ + for(entry : specification.entrySet) { + val metamodelEntry = entry.key + val packages = entry.value + + /** Excluded features */ + val excludedFeatureNames = metamodelEntry.excluding.filter(FeatureElement).map[it.container.name -> it.name].toSet + + /** See if type is included */ + for(package : packages) { + for(class : package.EClassifiers.filter(EClass)) { + if(classes.contains(class)) { + for(reference : class.EReferences) { + if(classes.contains(reference.EType)) { + references.addIfNotExcluded(reference,class,excludedFeatureNames) + } + } + for(attribute : class.EAttributes) { + val type = attribute.EType + if(type instanceof EEnum) { + if(enums.contains(type)) { + attributes.addIfNotExcluded(attribute,class,excludedFeatureNames) + } else if(type == EcorePackage.Literals) { + if(enums.contains(type)) { + attributes.addIfNotExcluded(attribute,class,excludedFeatureNames) + } + } + } else if(supportedEDataType(type as EDataType)) { + attributes.addIfNotExcluded(attribute,class,excludedFeatureNames) + } + } + } + } + } + } + } + + private def supportedEDataType(EDataType dataType) { + val extension l = EcorePackage.eINSTANCE + return #[EInt, EBoolean, EString, EDouble, EFloat].contains(dataType) + } + + private def addIfNotExcluded( + List target, + T element, + Set excluded) + { + if(excluded.contains(element.name)) { + target += element + return true + } else { + return false + } + } + private def addIfNotExcluded( + List target, + T1 element, + ENamedElement container, + Set> excluded) + { + val pair = (container.name) -> (element.name) + + if(excluded.contains(pair)) { + target += element + } + } + + private def List loadPackageFromPath(String path, ResourceSet rs, Context context) throws RuntimeException { + var Resource resource; + try{ + resource = rs.getResource(URI.createURI(path),true) + } catch(RuntimeException e) { + context.writeError('''Unable to load EPackage: Error in path "«path»"!''') + return #[] + } + val res = new ArrayList(resource.contents.size) + for(content: resource.contents) { + if(content instanceof EPackage) { + res += content + } else { + context.writeError('''Unable to load EPackage: The content of "«path»" is not an EPackage, but "«content.eClass.name»"!''') + } + } + return res + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2