aboutsummaryrefslogtreecommitdiffstats
path: root/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/MetamodelLoader.xtend
blob: 626329dc8f35738ab93092fa85f68c1baf071364 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package hu.bme.mit.inf.dslreasoner.application.execution

import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.AllPackageEntry
import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.MetamodelElement
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.LinkedHashSet
import java.util.List
import java.util.Set
import org.eclipse.emf.ecore.EAttribute
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.EEnum
import org.eclipse.emf.ecore.EEnumLiteral
import org.eclipse.emf.ecore.EReference
import org.eclipse.emf.ecore.EcorePackage
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
import org.eclipse.xtext.xbase.lib.Functions.Function1

class MetamodelLoader {
	
	def private static init() {
		EcorePackage.eINSTANCE.EClass
		Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("ecore",new XMIResourceFactoryImpl)
	}
	
	public new() { init }
	
	def loadMetamodel(MetamodelSpecification specification) throws IllegalArgumentException {

		val Set<EClass> classes = new LinkedHashSet
		val Set<EEnum> enums = new LinkedHashSet
		val Set<EEnumLiteral> literals = new LinkedHashSet
		val Set<EReference> references = new LinkedHashSet
		val Set<EAttribute> attributes = new LinkedHashSet
		
		/** Add all included types */
		for(entry : specification.entries) {
			classes+=entry.classes
			enums+=entry.enums
			literals+=entry.literals
			references+=entry.references
			attributes+=entry.attributes
		}
		
		return new EcoreMetamodelDescriptor(classes.toList, emptySet, false, enums.toList, literals.toList, references.toList, attributes.toList)
	}
	
	def <T> List<T> extractElements(MetamodelEntry entry, Function1<AllPackageEntry,Iterable<T>> packageEntryExtractor, Function1<MetamodelElement,Iterable<T>> metamodelElementExtractor) {
		if(entry instanceof MetamodelElement) {
			return metamodelElementExtractor.apply(entry).toList
		} else if(entry instanceof AllPackageEntry) {
			val excluded = entry.exclusion.map[metamodelElementExtractor.apply(it)].flatten.toSet
			return packageEntryExtractor.apply(entry).filter[!excluded.contains(it)].toList
		} else throw new IllegalArgumentException('''Unsupported entry type: "«entry.class.simpleName»"!''')
	}
	
	def getClasses(MetamodelEntry entry) {
		return entry.extractElements(
			[package.EClassifiers.filter(EClass)],
			[val classifier = it.classifier
				if(classifier instanceof EClass){ if(it.feature === null) { return #[classifier]} }
				return emptyList
			]
		)
	}
	def getEnums(MetamodelEntry entry) {
		return entry.extractElements(
			[package.EClassifiers.filter(EEnum)],
			[val classifier = it.classifier
				if(classifier instanceof EEnum){ if(it.feature === null) { return #[classifier]} }
				return emptyList
			]
		)
	}
	def getLiterals(MetamodelEntry entry) {
		return entry.extractElements(
			[package.EClassifiers.filter(EEnum).map[ELiterals].flatten],
			[val feature = it.feature
				if(feature instanceof EEnumLiteral){ return #[feature] }
				return emptyList
			]
		)
	}
	def getReferences(MetamodelEntry entry) {
		return entry.extractElements(
			[package.EClassifiers.filter(EClass).map[EReferences].flatten],
			[val feature = it.feature
				if(feature instanceof EReference) { return #[feature] }
				return emptyList
			]
		)
	}
	def getAttributes(MetamodelEntry entry) {
		return entry.extractElements(
			[package.EClassifiers.filter(EClass).map[EAttributes].flatten],
			[val feature = it.feature
				if(feature instanceof EAttribute) {return #[feature]}
				return emptyList
			]
		)
	}
	
//	public def List<EPackage> 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<EPackage>(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
//	}
}