| //import org.eclipse.ocl.examples.build.qvto.BlackBoxLibrary; |
| import BlackBoxLibrary; |
| |
| modeltype UML2Ecore uses 'http://www.eclipse.org/ocl/2012/UML2EcoreMapping'; |
| modeltype UML uses 'http://www.eclipse.org/uml2/5.0.0/UML'; |
| modeltype Ecore uses 'http://www.eclipse.org/emf/2002/Ecore'; |
| |
| /** |
| * Expand the UML2Ecore analysis to create an Ecore output, possibly referring to some built-in Ecore elements. |
| */ |
| transformation UML2EcoreSynthesizer(in analysis : UML2Ecore, in ecore : Ecore, out Ecore); |
| |
| configuration property selectedPackage : String; |
| |
| property debugImport : Boolean = false; |
| property debugProperties : Boolean = false; |
| property debugCreateProperty : Boolean = false; |
| property debugDerived : Boolean = false; |
| property debugResolveProxies : Boolean = false; |
| property debugType : Boolean = false; |
| property debug_EClass_abstract : Boolean = false; |
| property debug_EReference_eOpposite : Boolean = false; |
| property showPropertyOverrides : Boolean = false; |
| |
| property mappings : Set(UML2Ecore::Mapping) = analysis.objectsOfKind(UML2Ecore::Mappings).mappings->asSet(); |
| property createPackages : Set(UML2Ecore::CreatePackage) = mappings->selectByKind(UML2Ecore::CreatePackage)->asSet(); |
| --property createTypes : Set(UML2Ecore::CreateType) = analysis.objectsOfKind(UML2Ecore::CreateType)->asSet(); |
| |
| property packageMappings : Set(UML2Ecore::PackageMapping) = analysis.objectsOfKind(UML2Ecore::PackageMapping); |
| property deletePackageMappings : Set(UML2Ecore::DeletePackage) = analysis.objectsOfKind(UML2Ecore::DeletePackage); |
| property renamePackageMappings : Set(UML2Ecore::CreatePackage) = analysis.objectsOfKind(UML2Ecore::CreatePackage); |
| property deleteTypeMappings : Set(UML2Ecore::DeleteType) = analysis.objectsOfKind(UML2Ecore::DeleteType); |
| property createTypeMappings : Set(UML2Ecore::CreateType) = analysis.objectsOfKind(UML2Ecore::CreateType); |
| |
| property oldPackages : Set(UML::Package) = packageMappings.oldPackages->asSet(); |
| property nestingPackages : Set(UML::Package) = oldPackages->closure(nestingPackage)->union(oldPackages); |
| property allPackages : Set(UML::Package) = nestingPackages->closure(nestedPackage)->union(nestingPackages); |
| property deletePackages : Set(UML::Package) = deletePackageMappings.oldPackages->asSet(); |
| property renamePackages : Set(UML::Package) = renamePackageMappings.oldPackages->asSet(); |
| property copyPackages : Set(UML::Package) = allPackages - deletePackages - renamePackages; |
| |
| property allTypes : Set(UML::Type) = allPackages.ownedType->asSet()->select(name <> null); |
| property allClasses : Set(UML::Class) = allPackages.ownedType->selectByKind(UML::Class)->asSet(); |
| |
| property deletePackageTypes : Set(UML::Type) = deletePackages.ownedType->asSet(); |
| property deleteTypes : Set(UML::Type) = deleteTypeMappings.oldTypes->union(deleteTypeMappings.oldTypes)->asSet(); |
| property deleteTypeNames : Set(String) = deleteTypes.name->asSet(); |
| property deleteClasses : Set(UML::Class) = deleteTypeMappings.oldTypes->selectByKind(UML::Class)->asSet(); |
| |
| property umlType2createType : Dict(UML::Type, UML2Ecore::CreateType) = Dict{}; |
| property umlType2deleteType : Dict(UML::Type, UML2Ecore::DeleteType) = Dict{}; |
| |
| property umlType2depth : Dict(UML::Type, Integer) = Dict{}; |
| property createProperty2depth : Dict(UML2Ecore::CreateProperty, Integer) = Dict{}; |
| |
| helper Set(UML::NamedElement)::display() : String { |
| return self->sortedBy(name)->iterate(c; acc : String = '' | if acc = '' then '' else acc + ' ' endif + c.name); |
| } |
| |
| helper Set(UML::Type)::display() : String { |
| return self->sortedBy(name)->iterate(c; acc : String = '' | if acc = '' then '' else acc + ' ' endif + c.display()); |
| } |
| |
| helper Set(UML::Property)::display() : String { |
| return self->sortedBy(name)->iterate(c; acc : String = '' | if acc = '' then '' else acc + ' ' endif + c.getPropertyName()); |
| } |
| |
| helper Set(UML2EcoreMapping::CreateProperty)::display() : String { |
| return self->sortedBy(newName)->iterate(c; acc : String = '' | if acc = '' then '' else acc + ' ' endif + c.newName + '[' + c.oldProperties->display() + ']'); |
| } |
| |
| helper Set(UML2EcoreMapping::CreateType)::display() : String { |
| return self->sortedBy(newName)->iterate(c; acc : String = '' | if acc = '' then '' else acc + ' ' endif + c.newName); |
| } |
| |
| helper Set(UML2EcoreMapping::DeleteProperty)::display() : String { |
| return self->sortedBy(oldName)->iterate(c; acc : String = '' | if acc = '' then '' else acc + ' ' endif + c.oldName); |
| } |
| |
| helper Set(UML2EcoreMapping::DeleteType)::display() : String { |
| return self->sortedBy(oldName)->iterate(c; acc : String = '' | if acc = '' then '' else acc + ' ' endif + c.oldName); |
| } |
| |
| helper Set(String)::display() : String { |
| return self->sortedBy(n | n)->iterate(c; acc : String = '' | if acc = '' then '' else acc + ' ' endif + c); |
| } |
| |
| helper Set(Ecore::EPackage)::display() : String { |
| return self->sortedBy(name)->iterate(c; acc : String = '' | acc + ' ' + c.getName()); |
| } |
| |
| helper Set(Ecore::EStructuralFeature)::display() : String { |
| return self->sortedBy(name)->iterate(c; acc : String = '' | acc + ' ' + c.getPropertyName()); |
| } |
| |
| helper Ecore::EClassifier::display() : String { |
| return self.ePackage.getName() + '::' + self.getName(); |
| } |
| |
| helper Ecore::EStructuralFeature::display() : String { |
| return self.eContainingClass.display() + '::' + self.getName(); |
| } |
| |
| helper UML::Property::display() : String { |
| return self.getOwningType().display() + '::' + self.getName(); |
| } |
| |
| helper UML::Type::display() : String { |
| return self.package.getName() + '::' + self.getName(); |
| } |
| |
| helper UML::NamedElement::getName() : String { |
| return if self.name <> null then self.name else 'null' endif; |
| } |
| |
| helper Ecore::ENamedElement::getName() : String { |
| return if self.name <> null then self.name else 'null' endif; |
| } |
| |
| helper UML::Property::getOwningType() : Type { |
| return if self._'class' <> null then self._'class' else self.getOtherEnd().type endif; |
| } |
| |
| helper UML::Property::getPropertyName() : String { |
| var type : Type := self.getOwningType(); |
| return type.display() + '::' + self.getName(); |
| } |
| |
| helper Ecore::EStructuralFeature::getPropertyName() : String { |
| var type : Ecore::EClassifier := self.eContainingClass; |
| return type.display() + '::' + self.getName(); |
| } |
| |
| main() { |
| -- |
| -- Pass 0: Analyze the input model and select the required elements |
| -- |
| -- log('packageMappings', packageMappings); |
| log('selectedPackage', selectedPackage); |
| -- log('oldPackages', oldPackages->display()); |
| -- log('deletePackages', deletePackages->display()); |
| -- log('renamePackages', renamePackages.name->asSet()->sortedBy(n | n)); |
| -- log('copyPackages', copyPackages.name->asSet()->sortedBy(n | n)); |
| -- log('nestingPackages', nestingPackages.name->asSet()->sortedBy(n | n)); |
| -- log('allPackages', allPackages->display()); |
| -- log('allTypes', allTypes->display()); |
| -- log('deleteTypes', deleteTypes.name->asSet()); |
| -- log('createPackages', createPackages.newName->asSet()); |
| -- log('createTypeMappings', createTypeMappings.newName->asSet()); |
| createTypeMappings->forEach(createType) { |
| createType.oldTypes->forEach(oldType) { |
| umlType2createType->put(oldType, createType); |
| }; |
| }; |
| deleteTypeMappings->forEach(deleteType) { |
| deleteType.oldTypes->forEach(oldType) { |
| umlType2deleteType->put(oldType, deleteType); |
| }; |
| }; |
| -- log('oldType2createType', oldType2createType); |
| -- |
| -- Pass 1: Create the output containment hierarchy |
| -- |
| createPackages->map createPackage(); |
| -- |
| -- Pass 2: Resolve references within the output containment hierarchy |
| -- |
| umlType2eClass->values()->sortedBy(name)->map resolveEClass(); |
| umlProperty2eReference->values()->sortedBy(name)->map resolveEReference(); |
| -- umlPackage2ePackage->values()->sortedBy(name)->map resolveImport(); |
| -- object Comment { body := 'association keys size = ' + out2in->keys()->select(oclIsKindOf(Association))->size().toString(); }; |
| } |
| |
| /** |
| * Pass 1 convert the containment tree. |
| */ |
| mapping UML2Ecore::CreatePackage::createPackage() : Ecore::EPackage |
| { |
| self.oldPackages->forEach(p) { umlPackage2ePackage->put(p, result); }; |
| var createTypes : Set(UML2Ecore::CreateType) := self.typeMappings->selectByKind(UML2Ecore::CreateType)->asSet(); |
| -- self.convertNamedElement(result); |
| result.name := self.newName; |
| result.nsURI := self.nsURI; |
| result.nsPrefix := self.nsPrefix; |
| result.eClassifiers += createTypes->select(let t = oldTypes->any(true) in t.oclIsKindOf(UML::DataType) and not t.oclIsKindOf(UML::Enumeration))->sortedBy(newName)->createType(self); |
| result.eClassifiers += createTypes->select(oldTypes->any(true).oclIsKindOf(UML::Enumeration))->sortedBy(newName)->createType(self); |
| -- result.eClassifiers += createTypes->select(oldTypes->any(true).oclIsKindOf(UML::Interface))->sortedBy(newName)->createType(self); |
| result.eClassifiers += createTypes->select(oldTypes->any(true).oclIsKindOf(UML::Class) or oldTypes->any(true).oclIsKindOf(UML::Interface))->sortedBy(newName)->createType(self); |
| -- result.eAnnotations += object Ecore::EAnnotation { |
| -- source := 'http://www.eclipse.org/ocl/2012/UML2EcoreMapping'; |
| -- _references := self.oldPackages->sortedBy(name).oclAsType(ecore::EObject); |
| -- }; |
| if (self.isASmetamodel) { |
| result.eAnnotations += object Ecore::EAnnotation { |
| source := 'http://www.eclipse.org/OCL/ASMetamodel'; |
| }; |
| }; |
| } |
| |
| helper UML2Ecore::CreateType::createType(createPackage : UML2Ecore::CreatePackage) : Ecore::EClassifier |
| { |
| return self.oldTypes->at(1).map createType(self); |
| -- result.eAnnotations += object Ecore::EAnnotation { |
| -- source := 'http://www.eclipse.org/ocl/2012/UML2EcoreMapping'; |
| -- _references := self.oldTypes->sortedBy(name).oclAsType(ecore::EObject); |
| -- } |
| } |
| mapping UML::Type::createType(createType : UML2Ecore::CreateType) : Ecore::EClassifier |
| disjuncts UML::Enumeration::createEnumeration, UML::DataType::createDataType,UML::Classifier::createClass; |
| abstract mapping UML::Type::createAbstractType(createType : UML2Ecore::CreateType) : Ecore::EClassifier |
| { |
| -- log(' createAbstractType', self.name); |
| result.name := createType.newName; |
| result.map installComments(createType.oldTypes.ownedComment->sortedBy(body)); |
| createType.oldTypes->forEach(t) { |
| -- log(' <= ', t.name); |
| umlType2eClassifier->put(t, result); |
| }; |
| eClassifier2createType->put(result, createType); |
| } |
| mapping UML::Classifier::createClass(createType : UML2Ecore::CreateType) : Ecore::EClass |
| inherits UML::Type::createAbstractType |
| { |
| if (debug_EClass_abstract) log(' createClass', result.name); |
| createType.oldTypes->forEach(t) { umlType2eClass->put(t, result); }; |
| if (createType.newInstanceTypeName <> null) { |
| result.instanceTypeName := createType.newInstanceTypeName; |
| } |
| else { |
| result.map installInstanceClassName(createType.oldTypes, 'Ecore::EClass'); |
| }; |
| var oldClasses : Set(UML::Class) := createType.oldTypes->selectByKind(UML::Class)->asSet(); |
| -- log(' oldClasses', oldClasses->display()); |
| var oldSameNamedClasses : Set(UML::Class) := oldClasses->select(c | c.name = createType.newName); |
| -- log(' oldSameNamedClasses', oldSameNamedClasses->display()); |
| var oldAbstractClasses : Set(UML::Class) := oldSameNamedClasses->select(isAbstract); |
| var oldNonAbstractClasses : Set(UML::Class) := oldSameNamedClasses->reject(isAbstract); |
| assert error (oldAbstractClasses->isEmpty() or oldNonAbstractClasses->isEmpty()) with log('Inconsistently abstract ' + self.name + ' ' + oldAbstractClasses->size().toString() + '/' + oldNonAbstractClasses->size().toString(), oldClasses->any(true)); |
| if (debug_EClass_abstract) log(' oldSameNamedClasses', oldSameNamedClasses->display()); |
| if (debug_EClass_abstract) log(' oldAbstractClasses', oldAbstractClasses->display()); |
| if (debug_EClass_abstract) log(' oldNonAbstractClasses', oldNonAbstractClasses->display()); |
| result._'abstract' := oldAbstractClasses->notEmpty() or self.oclIsKindOf(UML::Interface); |
| result.interface := self.oclIsKindOf(UML::Interface); |
| var templateSignatures : Set(TemplateSignature) = oldClasses.ownedTemplateSignature->asSet(); |
| if (templateSignatures->notEmpty()) { |
| var sortedTemplateSignatures : OrderedSet(TemplateSignature) = templateSignatures->excluding(null)->sortedBy(parameter->size()); |
| if (sortedTemplateSignatures->notEmpty()) { |
| var templateSignature : TemplateSignature = sortedTemplateSignatures->last(); |
| result.eTypeParameters += templateSignature.parameter->map createTemplateParameter(); |
| } |
| } |
| } |
| /*mapping UML::Interface::createInterface(createType : UML2Ecore::CreateType) : Ecore::EClass |
| inherits UML::Type::createAbstractType |
| { |
| -- log(' createInterface', self.name); |
| createType.oldTypes->forEach(t) { umlType2eClass->put(t, result); }; |
| if (createType.newInstanceTypeName <> null) { |
| result.instanceTypeName := createType.newInstanceTypeName; |
| } |
| else { |
| result.map installInstanceClassName(createType.oldTypes, 'Ecore::EClass'); |
| }; |
| result._'abstract' := true; |
| result.interface := true; |
| } */ |
| |
| mapping UML::DataType::createDataType(createType : UML2Ecore::CreateType) : Ecore::EDataType |
| inherits UML::Type::createAbstractType |
| { |
| if (createType.newInstanceTypeName <> null) { |
| result.instanceTypeName := createType.newInstanceTypeName; |
| } |
| else { |
| result.map installInstanceClassName(createType.oldTypes, 'Ecore::EDataType'); |
| }; |
| } |
| mapping UML::Enumeration::createEnumeration(createType : UML2Ecore::CreateType) : Ecore::EEnum |
| inherits UML::Type::createAbstractType |
| { |
| var literals : OrderedSet(UML::EnumerationLiteral) := self.ownedLiteral; |
| result.eLiterals := literals->map createEnumerationLiteral(literals); |
| } |
| |
| mapping UML::EnumerationLiteral::createEnumerationLiteral(literals : OrderedSet(UML::EnumerationLiteral)) : Ecore::EEnumLiteral |
| { |
| var idx : Integer := self.enumeration.ownedLiteral->indexOf(self)-1; |
| -- log(' convertEnumerationLiteral', self.name + self.enumeration.ownedLiteral->iterate(l; acc : String = ':' | acc + ' ' + l.name) + ' / ' + idx.toString()); |
| umlEnumerationLiteral2eEnumLiteral->put(self, result); |
| result.name := self.name; |
| result.map installComments(self.ownedComment->asSequence()->sortedBy(body)); |
| result.value := idx; |
| } |
| |
| mapping UML2EcoreMapping::CreateOperation::createOperation(type : Ecore::EClassifier, oldOperations : Set(UML::Operation), newType : Ecore::EClassifier) : Ecore::EOperation |
| { |
| oldOperations->forEach(p) { umlOperation2eOperation->put(p, result); }; |
| eOperation2createOperation->put(result, self); |
| var oldOperation : Operation := oldOperations->any(true); |
| -- log(' createOperation', self.newName); |
| result.name := self.newName; |
| result.map installComments(oldOperations.ownedComment->sortedBy(body)); |
| result.lowerBound := oldOperation.lower; |
| result.upperBound := oldOperation.upper; |
| result.unique := oldOperation.isUnique; |
| result._'ordered' := if (0 <= oldOperation.upper) and (oldOperation.upper <= 1) then true else oldOperation.isOrdered endif; |
| -- log(' createOperation', Sequence{oldType, newType}); |
| result.eType := newType; |
| result.eParameters := oldOperation.ownedParameter->select(direction <> UML::ParameterDirectionKind::_'return')->map createParameter(); |
| -- log(' defaultValues', defaultValues->iterate(l; acc : String = ':' | acc + ' ' + l.toString())); |
| } |
| |
| mapping UML::Parameter::createParameter() : Ecore::EParameter |
| { |
| -- log(' createParameter', self.newName); |
| result.name := self.name; |
| result.map installComments(self.ownedComment->asSequence()->sortedBy(body)); |
| result.lowerBound := self.lower; |
| result.upperBound := self.upper; |
| result.unique := self.isUnique; |
| result._'ordered' := if (0 <= self.upper) and (self.upper <= 1) then true else self.isOrdered endif; |
| result.eType := umlType2eClassifier->get(self.type).resolveForXtext(); |
| } |
| |
| mapping UML2EcoreMapping::CreateProperty::createProperty(type : Ecore::EClassifier, oldProperties : Set(UML::Property), newType : Ecore::EClassifier) : Ecore::EStructuralFeature |
| disjuncts UML2EcoreMapping::CreateProperty::createAttribute, UML2EcoreMapping::CreateProperty::createReference; |
| mapping UML2EcoreMapping::CreateProperty::createAttribute(type : Ecore::EClassifier, oldProperties : Set(UML::Property), newType : Ecore::EClassifier) : Ecore::EAttribute |
| when { newType.oclIsKindOf(Ecore::EDataType) } |
| { |
| if (debugCreateProperty or debugDerived) log(' createAttribute', type.display() + "::" + self.newName + " " + oldProperties->display()); |
| self.createStructuralFeature(result, oldProperties, newType); |
| var isDerived : Boolean := if self.newIsDerived <> null then self.newIsDerived else oldProperties->exists(isDerived) endif; |
| if (debugDerived) log(' derived', self.newIsDerived.toString() + "=>" + isDerived.toString()); |
| var isTransient : Boolean := if self.newIsTransient <> null then self.newIsTransient else isDerived endif; |
| if (debugDerived) log(' transient', self.newIsTransient.toString() + "=>" + isTransient.toString()); |
| var isUnsettable : Boolean := if self.newIsUnsettable <> null then self.newIsUnsettable else false endif; |
| if (debugDerived) log(' unsettable', self.newIsUnsettable.toString() + "=>" + isUnsettable.toString()); |
| var isVolatile : Boolean := if self.newIsVolatile <> null then self.newIsVolatile else isDerived endif; |
| if (debugDerived) log(' volatile', self.newIsVolatile.toString() + "=>" + isVolatile.toString()); |
| result._'derived' := isDerived; |
| result.map installTransient(oldProperties, 'Ecore::EAttribute', isTransient); |
| result.map installUnsettable(oldProperties, 'Ecore::EAttribute', isUnsettable); |
| result.map installVolatile(oldProperties, 'Ecore::EAttribute', isVolatile); |
| } |
| mapping UML2EcoreMapping::CreateProperty::createReference(type : Ecore::EClassifier, oldProperties : Set(UML::Property), newType : Ecore::EClassifier) : Ecore::EReference |
| when { not newType.oclIsKindOf(Ecore::EDataType) } |
| { |
| if (debugCreateProperty or debugDerived) log(' createReference', type.display() + "::" + self.newName + " " + oldProperties->display()); |
| oldProperties->forEach(p) { umlProperty2eReference->put(p, result); }; |
| eReference2createProperty->put(result, self); |
| var oldProperty : Property := oldProperties->any(true); |
| self.createStructuralFeature(result, oldProperties, newType); |
| result.containment := oldProperty.aggregation = UML::AggregationKind::composite; |
| var isDerived : Boolean := if self.newIsDerived <> null then self.newIsDerived else oldProperties->exists(isDerived) endif;-- and oldProperties->forAll(let opposite = getOtherEnd() in opposite = null or opposite.isDerived); |
| if (debugDerived) log(' derived', self.newIsDerived.toString() + "=>" + isDerived.toString()); |
| var isTransient : Boolean := if self.newIsTransient <> null then self.newIsTransient else isDerived endif; --and oldProperties->forAll(let opposite = getOtherEnd() in opposite = null or opposite.isDerived) endif; |
| if (debugDerived) log(' transient', self.newIsTransient.toString() + "=>" + isTransient.toString()); |
| var isUnsettable : Boolean := if self.newIsUnsettable <> null then self.newIsUnsettable else false endif; |
| if (debugDerived) log(' unsettable', self.newIsUnsettable.toString() + "=>" + isUnsettable.toString()); |
| var isVolatile : Boolean := if self.newIsVolatile <> null then self.newIsVolatile else isDerived endif; |
| if (debugDerived) log(' volatile', self.newIsVolatile.toString() + "=>" + isVolatile.toString()); |
| result._'derived' := isDerived; |
| result.map installTransient(oldProperties, 'Ecore::EReference', isTransient); |
| result.map installUnsettable(oldProperties, 'Ecore::EReference', isUnsettable); |
| result.map installVolatile(oldProperties, 'Ecore::EReference', isVolatile); |
| var isResolveProxies : Boolean := if self.newIsResolveProxies <> null then self.newIsResolveProxies else not (result._derived or result.transient or result.volatile) endif; |
| if (debugDerived) log(' resolveProxies', self.newIsResolveProxies.toString() + "=>" + isResolveProxies.toString()); |
| result.map installResolveProxies(oldProperties, 'Ecore::EReference', isResolveProxies); |
| if (debug_EReference_eOpposite) log('eReference2createProperty:put ', oldProperties->display() + " => " + result.display()); |
| } |
| |
| helper UML2EcoreMapping::CreateProperty::createStructuralFeature(inout output : Ecore::EStructuralFeature, oldProperties : Set(UML::Property), newType : Ecore::EClassifier) |
| { |
| -- log(' createStructuralFeature', oldProperties->display()); |
| var oldProperty : Property := oldProperties->any(true); |
| var defaultValues : Set(UML::ValueSpecification) := oldProperties.defaultValue->excluding(null)->asSet(); |
| output.name := self.newName; |
| output.map installComments(oldProperties.ownedComment->sortedBy(body)); |
| output.lowerBound := if self.newLowerBound <> null then self.newLowerBound else oldProperties.lower->excluding(null)->max() endif; |
| if (debugDerived) log(' lowerBound', if self.newLowerBound <>null then self.newLowerBound.toString() else 'null' endif + "=>" + output.lowerBound.toString()); |
| var finiteUppers := oldProperties.upper->excluding(null)->select(n | n >= 0); |
| output.upperBound := if finiteUppers->notEmpty() then finiteUppers->min() else -1 endif; |
| if (debugDerived) log(' upperBound', 'null' + "=>" + output.upperBound.toString()); |
| output.unique := oldProperty->exists(isUnique); |
| output._'ordered' := if (0 <= output.upperBound) and (output.upperBound <= 1) then true else oldProperty->exists(isOrdered) endif; |
| output.changeable := oldProperties->forAll(not isReadOnly); |
| -- var isDerived : Boolean := oldProperties->exists(isDerived); |
| -- output._'derived' := isDerived; |
| -- output.volatile := isDerived; |
| -- output.unsettable := false; --oldProperty.lower < 1; |
| -- output.unsettable := false; --(oldProperty.lower = 1) and (oldProperty.upper = 1) and defaultValues->isEmpty() and output.oclIsKindOf(EAttribute); -- BooleanLiteralExp.booleanSymbol |
| -- log(' createStructuralFeature', Sequence{oldType, newType}); |
| output.eType := newType.resolveForXtext(); |
| -- log(' defaultValues', defaultValues->iterate(l; acc : String = ':' | acc + ' ' + l.toString())); |
| var oldDefaultValueSpec : UML::ValueSpecification := if defaultValues->notEmpty() then defaultValues->any(true) else null endif; |
| var oldDefaultValue : String := if oldDefaultValueSpec <> null then oldDefaultValueSpec.getDefaultValue() else output.eType.getDefaultValue() endif; |
| -- var newDefaultValue : OclAny := if oldDefaultValue.oclIsKindOf(UML::EnumerationLiteral) and (umlEnumerationLiteral2eEnumLiteral->get(oldDefaultValue.oclAsType(UML::EnumerationLiteral)) <> null) then umlEnumerationLiteral2eEnumLiteral->get(oldDefaultValue.oclAsType(UML::EnumerationLiteral)) else oldDefaultValue endif; |
| output.defaultValueLiteral := oldDefaultValue; |
| return; |
| } |
| |
| mapping UML::TemplateParameter::createTemplateParameter() : Ecore::ETypeParameter |
| { |
| -- log(' createTemplateParameter', self.name); |
| result.name := self.parameteredElement.oclAsType(NamedElement).name; |
| } |
| |
| helper UML::ValueSpecification::getDefaultValue() : String |
| { |
| return self.toString(); |
| } |
| helper UML::InstanceValue::getDefaultValue() : String |
| { |
| return self.instance.name; |
| } |
| helper UML::LiteralBoolean::getDefaultValue() : String |
| { |
| return self.value.toString(); |
| } |
| helper UML::LiteralInteger::getDefaultValue() : String |
| { |
| return self.value.toString(); |
| } |
| helper UML::LiteralReal::getDefaultValue() : String |
| { |
| return self.value.toString(); |
| } |
| helper UML::LiteralString::getDefaultValue() : String |
| { |
| return self.value; |
| } |
| helper UML::LiteralUnlimitedNatural::getDefaultValue() : String |
| { |
| return if self.value = -1 then '*' else self.value.toString() endif; |
| } |
| |
| helper Ecore::EClassifier::getDefaultValue() : String |
| { |
| if ('Boolean' = self.name) return null; |
| if ('Integer' = self.name) return null; |
| if ('String' = self.name) return null; |
| return null; |
| } |
| |
| mapping inout Ecore::ENamedElement::installComments(in comments : Sequence(UML::Comment)) |
| { |
| var eComment : Ecore::EAnnotation := if comments->notEmpty() then object Ecore::EAnnotation { |
| source := 'http://www.eclipse.org/emf/2002/GenModel'; |
| details += object Ecore::EStringToStringMapEntry { |
| key := 'documentation'; |
| value := comments->iterate(c; acc : String = '' | if acc = '' then '' else acc + '\n\n' endif + c.body.trim()) |
| }; |
| } else null endif; |
| self.eAnnotations += if eComment <> null then Set{eComment} else Set{} endif; |
| } |
| |
| mapping inout Ecore::EClassifier::installInstanceClassName(in types : Set(UML::Type), stereotypeName : String) |
| { |
| var stereotypedTypes : Set(UML::Type) := types->select(getAppliedStereotype(stereotypeName) <> null)->asSet(); |
| var stereotypedType : UML::Type := if stereotypedTypes->notEmpty() then stereotypedTypes->any(true) else null endif; |
| -- var stereotypes : Set(UML::Stereotype) := createType.oldTypes.oclAsType(UML::DataType).getAppliedStereotype('Ecore::EDataType')->asSet(); |
| -- log('stereotypedType', stereotypedType); |
| var instanceClassName : String := if stereotypedType <> null then stereotypedType.getValue(stereotypedType.getAppliedStereotype(stereotypeName), 'instanceClassName').oclAsType(String) else null endif; |
| -- log('instanceClassName', instanceClassName); |
| self.instanceClassName := instanceClassName; |
| -- result.defaultValue := instanceClassName; |
| } |
| |
| mapping inout Ecore::EReference::installResolveProxies(in properties : Set(UML::Property), stereotypeName : String, defaultValue : Boolean) |
| { |
| var stereotypedProperties : Set(UML::Property) := properties->select(getAppliedStereotype(stereotypeName) <> null)->asSet(); |
| var stereotypedProperty : UML::Property := if stereotypedProperties->notEmpty() then stereotypedProperties->any(true) else null endif; |
| if (debugResolveProxies) log('installResolveProxies', properties->display()); |
| -- var stereotypes : Set(UML::Stereotype) := createType.oldTypes.oclAsType(UML::DataType).getAppliedStereotype('Ecore::EDataType')->asSet(); |
| -- log('stereotypedType', stereotypedType); |
| var resolveProxies : Boolean := if stereotypedProperty <> null then stereotypedProperty.getValue(stereotypedProperty.getAppliedStereotype(stereotypeName), 'isResolveProxies').oclAsType(Boolean) else defaultValue endif; |
| if (debugResolveProxies) log('installResolveProxies', resolveProxies); |
| -- log('instanceClassName', instanceClassName); |
| self.resolveProxies := resolveProxies; |
| -- result.defaultValue := instanceClassName; |
| } |
| |
| mapping inout Ecore::EStructuralFeature::installTransient(in properties : Set(UML::Property), stereotypeName : String, defaultValue : Boolean) |
| { |
| var stereotypedProperties : Set(UML::Property) := properties->select(getAppliedStereotype(stereotypeName) <> null)->asSet(); |
| var stereotypedProperty : UML::Property := if stereotypedProperties->notEmpty() then stereotypedProperties->any(true) else null endif; |
| -- var stereotypes : Set(UML::Stereotype) := createType.oldTypes.oclAsType(UML::DataType).getAppliedStereotype('Ecore::EDataType')->asSet(); |
| -- log('stereotypedType', stereotypedType); |
| var transient : Boolean := if stereotypedProperty <> null then stereotypedProperty.getValue(stereotypedProperty.getAppliedStereotype(stereotypeName), 'isTransient').oclAsType(Boolean) else defaultValue endif; |
| -- log('instanceClassName', instanceClassName); |
| self.transient := transient ; |
| -- result.defaultValue := instanceClassName; |
| } |
| |
| mapping inout Ecore::EStructuralFeature::installUnsettable(in properties : Set(UML::Property), stereotypeName : String, defaultValue : Boolean) |
| { |
| var stereotypedProperties : Set(UML::Property) := properties->select(getAppliedStereotype(stereotypeName) <> null)->asSet(); |
| var stereotypedProperty : UML::Property := if stereotypedProperties->notEmpty() then stereotypedProperties->any(true) else null endif; |
| -- var stereotypes : Set(UML::Stereotype) := createType.oldTypes.oclAsType(UML::DataType).getAppliedStereotype('Ecore::EDataType')->asSet(); |
| -- log('stereotypedType', stereotypedType); |
| var unsettable : Boolean := if stereotypedProperty <> null then stereotypedProperty.getValue(stereotypedProperty.getAppliedStereotype(stereotypeName), 'isUnsettable').oclAsType(Boolean) else defaultValue endif; |
| -- log('instanceClassName', instanceClassName); |
| self.unsettable := unsettable ; |
| -- result.defaultValue := instanceClassName; |
| } |
| |
| mapping inout Ecore::EStructuralFeature::installVolatile(in properties : Set(UML::Property), stereotypeName : String, defaultValue : Boolean) |
| { |
| var stereotypedProperties : Set(UML::Property) := properties->select(getAppliedStereotype(stereotypeName) <> null)->asSet(); |
| var stereotypedProperty : UML::Property := if stereotypedProperties->notEmpty() then stereotypedProperties->any(true) else null endif; |
| -- var stereotypes : Set(UML::Stereotype) := createType.oldTypes.oclAsType(UML::DataType).getAppliedStereotype('Ecore::EDataType')->asSet(); |
| -- log('stereotypedType', stereotypedType); |
| var volatile : Boolean := if stereotypedProperty <> null then stereotypedProperty.getValue(stereotypedProperty.getAppliedStereotype(stereotypeName), 'isVolatile').oclAsType(Boolean) else defaultValue endif; |
| -- log('instanceClassName', instanceClassName); |
| self.volatile := volatile ; |
| -- result.defaultValue := instanceClassName; |
| } |
| |
| /** |
| * Pass 1 results for use in pass 2. |
| */ |
| property umlType2eClassifier : Dict(UML::Type, Ecore::EClassifier) = Dict{}; |
| property umlType2eClass : Dict(UML::Type, Ecore::EClass) = Dict{}; |
| property umlEnumerationLiteral2eEnumLiteral : Dict(UML::EnumerationLiteral, Ecore::EEnumLiteral) = Dict{}; |
| property umlPackage2ePackage : Dict(UML::Package, Ecore::EPackage) = Dict{}; |
| property umlOperation2eOperation : Dict(UML::Operation, Ecore::EOperation) = Dict{}; |
| property umlProperty2eReference : Dict(UML::Property, Ecore::EReference) = Dict{}; |
| |
| property eClassifier2createType : Dict(Ecore::EClassifier, UML2Ecore::CreateType) = Dict{}; |
| --property ePackage2createPackage : Dict(Ecore::EPackage, UML2Ecore::CreatePackage) = Dict{}; |
| property eOperation2createOperation : Dict(Ecore::EOperation, UML2Ecore::CreateOperation) = Dict{}; |
| property eReference2createProperty : Dict(Ecore::EReference, UML2Ecore::CreateProperty) = Dict{}; |
| |
| /** |
| * Pass 2 install all references. |
| */ |
| mapping inout Ecore::EClass::resolveEClass() |
| { |
| if (debugType or debugProperties) log('resolveEClass', self.name); |
| var createType : UML2Ecore::CreateType := eClassifier2createType->get(self); |
| if (debugType) log(' preallOldTypes', createType.oldTypes->display()); |
| var allOldTypes : Set(UML::Type) := getAllTypes(createType.oldTypes); |
| if (debugType) log(' allOldTypes', allOldTypes->display()); |
| if (debugType) log(' allOldTypes2', getAllTypes2(createType.oldTypes)->display()); |
| var oldProperSuperClassClosure : Set(UML::Type) := |
| getProperSuperTypes(allOldTypes); |
| if (debugType) log(' oldProperSuperClassClosure', oldProperSuperClassClosure->display()); |
| var excludeTypes : Set(UML::Type) := |
| createType.excludeTypes; |
| var excludeTypeNames : Set(String) := |
| createType.excludeTypes.name->asSet(); |
| if (debugType) log(' excludeTypeNames', excludeTypeNames->display()); |
| var newSuperClassClosure : Set(UML::Type) := |
| oldProperSuperClassClosure->reject(deleteTypeNames->includes(name))->reject(excludeTypeNames->includes(name))-createType.oldTypes; |
| var newProperSuperClassClosure : Set(UML::Type) := |
| getAllTypes(newSuperClassClosure); |
| if (debugType) log(' newProperSuperClassClosure', newProperSuperClassClosure->display()); |
| var newSuperSuperClassClosure2 : Set(UML::Type) := |
| getProperSuperTypes(newProperSuperClassClosure); |
| if (debugType) log(' newSuperSuperClassClosure', newSuperSuperClassClosure2->display()); |
| if (debugType) log(' orderedSuperTypes', createType.orderedSuperTypes->display()); |
| var requiredSuperClasses : OrderedSet(UML::Type) := (newProperSuperClassClosure - newSuperSuperClassClosure2)->asSet()->sortedBy(sc | if sc.oclIsKindOf(UML::Class) then sc.name else '_'+sc.name endif); |
| if (debugType) log(' requiredSuperClasses', requiredSuperClasses->display()); |
| var orderedSuperClasses : OrderedSet(UML::Type) := |
| requiredSuperClasses->iterate(s; acc : OrderedSet(UML::Type) = createType.orderedSuperTypes | if acc->includes(s) then acc else acc->append(s) endif); |
| if (debugType) log(' orderedSuperClasses', orderedSuperClasses->display()); |
| self.eSuperTypes := orderedSuperClasses->collect(sc | umlType2eClass->get(sc))->asOrderedSet(); |
| var oldInheritedClasses : Set(UML::Type) := createType.oldTypes->union(oldProperSuperClassClosure); |
| if (debugType) log(' oldInheritedClasses', oldInheritedClasses->display()); |
| var newInheritedClasses : Set(UML::Type) := requiredSuperClasses->union(getProperSuperTypes(requiredSuperClasses)); |
| if (debugType) log(' newInheritedClasses', newInheritedClasses->display()); |
| var localClasses : Set(UML::Type) := oldInheritedClasses - newInheritedClasses; |
| if (debugType) log(' localClasses', localClasses->display()); |
| var localCreateTypes : Set(UML2EcoreMapping::CreateType) := |
| localClasses->collect(t | umlType2createType->get(t))->excluding(null)->asSet()->reject(excludeTypeNames->includes(name)); |
| if (debugType) log(' localCreateTypes', localCreateTypes.oldTypes->asSet()->display()); |
| var localDeleteTypes : Set(UML2EcoreMapping::DeleteType) := |
| localClasses->collect(t | umlType2deleteType->get(t))->excluding(null)->asSet(); |
| if (debugType) log(' localDeleteTypes', localDeleteTypes.oldTypes->asSet()->display()); |
| var inheritedCreateTypes : Set(UML2EcoreMapping::CreateType) := |
| newProperSuperClassClosure->collect(t | umlType2createType->get(t))->excluding(null)->asSet(); |
| if (debugType) log(' inheritedCreateTypes', inheritedCreateTypes.oldTypes->asSet()->display()); |
| var inheritedDeleteTypes : Set(UML2EcoreMapping::DeleteType) := |
| oldProperSuperClassClosure->collect(t | umlType2deleteType->get(t))->excluding(null)->asSet() - localDeleteTypes; |
| if (debugType) log(' inheritedDeleteTypes', inheritedDeleteTypes.oldTypes->asSet()->display()); |
| |
| var propertyCreates : Set(UML2EcoreMapping::CreateProperty) := |
| localCreateTypes.propertyMappings->selectByKind(UML2EcoreMapping::CreateProperty)->asSet(); |
| if (debugProperties) log(' propertyCreates', propertyCreates.oldProperties->asSet()->display()); |
| var inheritedPropertyCreates1 : Set(UML2EcoreMapping::CreateProperty) := |
| inheritedCreateTypes.propertyMappings->selectByKind(UML2EcoreMapping::CreateProperty)->asSet(); |
| var inheritedPropertyCreates2 : Set(UML2EcoreMapping::CreateProperty) := |
| inheritedDeleteTypes.propertyMappings->selectByKind(UML2EcoreMapping::CreateProperty)->asSet(); |
| var inheritedPropertyCreates : Set(UML2EcoreMapping::CreateProperty) := |
| inheritedPropertyCreates1->union(inheritedPropertyCreates2); |
| if (debugProperties) log(' inheritedPropertyCreates', inheritedPropertyCreates.oldProperties->asSet()->display()); |
| var inheritedPropertyMerges : Set(UML2EcoreMapping::CreateProperty) := |
| localDeleteTypes.propertyMappings->selectByKind(UML2EcoreMapping::CreateProperty)->asSet(); |
| if (debugProperties) log(' inheritedPropertyMerges', inheritedPropertyMerges.oldProperties->asSet()->display()); |
| var inheritedPropertyDeletes : Set(UML2EcoreMapping::DeleteProperty) := |
| inheritedDeleteTypes.propertyMappings->selectByKind(UML2EcoreMapping::DeleteProperty)->asSet(); |
| if (debugProperties) log(' inheritedPropertyDeletes', inheritedPropertyDeletes.oldProperties->asSet()->display()); |
| var propertyCreateNames : Set(String) := |
| propertyCreates.newName->asSet(); |
| if (debugProperties) log(' propertyCreateNames', propertyCreateNames->display()); |
| var excludedProperties : Set(UML::Property) := |
| createType.excludeProperties; |
| if (debugProperties) log(' excludedProperties', excludedProperties->display()); |
| -- var excludedPropertyNames : Set(String) := |
| -- excludeTypes->selectByKind(UML::Class).ownedAttribute.name->asSet(); |
| -- if (debugProperties) log(' excludedPropertyNames', excludedPropertyNames->display()); |
| var inheritedPropertyCreateNames : Set(String) := |
| inheritedPropertyCreates.newName->asSet(); |
| if (debugProperties) log(' inheritedPropertyCreateNames', inheritedPropertyCreateNames->display()); |
| var inheritedPropertyMergeNames : Set(String) := |
| inheritedPropertyMerges.newName->asSet(); |
| if (debugProperties) log(' inheritedPropertyMergeNames', inheritedPropertyMergeNames->display()); |
| var localPropertyCreateNames : Set(String) := |
| propertyCreateNames->union(inheritedPropertyMergeNames) - inheritedPropertyCreateNames; |
| if (debugProperties) log(' localPropertyCreateNames', localPropertyCreateNames->display()); |
| var localPropertyCreates : Set(UML2EcoreMapping::CreateProperty) := |
| propertyCreates->union(inheritedPropertyMerges)->select(localPropertyCreateNames->includes(newName)); |
| if (debugProperties) log(' localPropertyCreates', localPropertyCreates->display()); |
| localPropertyCreateNames->sortedBy(n | n)->forEach(createName) { |
| var thePropertyCreates : Set(UML2EcoreMapping::CreateProperty) := localPropertyCreates->select(newName = createName); |
| var thePropertyCreate : UML2EcoreMapping::CreateProperty := thePropertyCreates->sortedBy(pc | depth(pc))->last(); |
| if (thePropertyCreates->size() > 1) { |
| thePropertyCreate := thePropertyCreates->sortedBy(pc | depth(pc))->last(); |
| if (showPropertyOverrides) log(thePropertyCreate->display() + ' overrides ' + thePropertyCreates->excluding(thePropertyCreate)->display()); |
| if (debugProperties or debugCreateProperty) log(' thePropertyCreates', thePropertyCreate->display() + ' overrides ' + thePropertyCreates->excluding(thePropertyCreate)->display()); |
| } |
| else { |
| thePropertyCreate := thePropertyCreates->any(true); |
| if (debugProperties or debugCreateProperty) log(' thePropertyCreate', thePropertyCreate->display()); |
| }; |
| -- var theTypes : Set(UML::Class) := thePropertyCreates.oldProperties.getOwningType()->selectByKind(UML::Class)->asSet(); |
| -- var theType : UML::Class := theTypes->sortedBy(t | depth(t))->last(); |
| -- if (debugCreateProperty) log(' theTypes', theType.display() + ", " + theTypes->display()); |
| -- var pc : UML2EcoreMapping::CreateProperty := thePropertyCreates->any(true); |
| var oldProperties : Set(UML::Property) := thePropertyCreates.oldProperties->asSet() - excludedProperties; |
| var oldType : UML::Type := selectType(oldProperties.type->asSet()); |
| var newType : Ecore::EClassifier := umlType2eClassifier->get(oldType); |
| if (newType <> null) then { |
| self.eStructuralFeatures += thePropertyCreate.map createProperty(self, oldProperties, newType); |
| } else { |
| log(' thePropertyCreate', thePropertyCreate->display()); |
| log(' oldType', oldType->display()); |
| /*if (debugProperties)*/ log(' obsolete referenced type', oldType.display() + ' for ' + thePropertyCreate->display()); |
| } endif; |
| }; |
| |
| var operationCreates : Set(UML2EcoreMapping::CreateOperation) := localCreateTypes.operationMappings->selectByKind(UML2EcoreMapping::CreateOperation)->asSet(); |
| -- log(' operationCreates', operationCreates->sortedBy(newName)->iterate(c; acc : String = '' | acc + ' ' + c.newName)); |
| var inheritedOperationCreates : Set(UML2EcoreMapping::CreateOperation) := inheritedCreateTypes.operationMappings->selectByKind(UML2EcoreMapping::CreateOperation)->asSet(); |
| -- log(' inheritedOperationCreates', inheritedOperationCreates->sortedBy(newName)->iterate(c; acc : String = '' | acc + ' ' + c.newName)); |
| var operationCreateNames : Set(String) := operationCreates.newName->asSet(); |
| -- log(' operationCreateNames', operationCreateNames->sortedBy(n | n)->iterate(c; acc : String = '' | acc + ' ' + c)); |
| var inheritedOperationCreateNames : Set(String) := inheritedOperationCreates.newName->asSet(); |
| -- log(' inheritedOperationCreateNames', inheritedOperationCreateNames->sortedBy(n | n)->iterate(c; acc : String = '' | acc + ' ' + c)); |
| var localOperationCreateNames : Set(String) := operationCreateNames; // - inheritedOperationCreateNames; |
| -- log(' localOperationCreateNames', localOperationCreateNames->sortedBy(n | n)->iterate(c; acc : String = '' | acc + ' ' + c)); |
| var localOperationCreates : Set(UML2EcoreMapping::CreateOperation) := operationCreates->select(localOperationCreateNames->includes(newName)); |
| -- log(' localOperationCreates', localOperationCreates->sortedBy(newName)->iterate(c; acc : String = '' | acc + ' ' + c.newName)); |
| localOperationCreates->sortedBy(newName)->forEach(pc) { |
| var oldOperation : Operation := pc.oldOperations->any(true); |
| var oldType : UML::Type := selectType(pc.oldOperations.type->asSet()); |
| var newType : Ecore::EClassifier := umlType2eClassifier->get(oldType); |
| if (newType <> null) then { |
| var oldParameters := pc.oldOperations.ownedParameter->select(direction <> UML::ParameterDirectionKind::_'return'); |
| var oldParameterTypes := oldParameters.type->asSet(); |
| var newParameterTypes := oldParameterTypes->collect(ot | umlType2eClassifier->get(ot)); |
| if (newParameterTypes->excludes(null)) then { |
| self.eOperations += pc.map createOperation(self, pc.oldOperations, newType); |
| } endif; |
| } endif; |
| }; |
| |
| } |
| |
| /*mapping inout Ecore::EPackage::resolveImport() |
| { |
| if (debugImport) log('resolveImport', self.name); |
| var eClasses := self.eClassifiers->selectByKind(Ecore::EClass); |
| if (debugImport) log(' eClasses', eClasses->display()); |
| var eOperations := eClasses.eOperations; |
| var eReferencedTypes := eOperations.eType->asSet()->union(eOperations.eParameters.eType->asSet())->union(eClasses.eStructuralFeatures.eType->asSet())->union(eClasses.eSuperTypes->asSet()); |
| if (debugImport) log(' eReferencedTypes', eReferencedTypes->display()); |
| var eReferencedPackages := eReferencedTypes.ePackage->asSet()->excluding(self); |
| if (debugImport) log(' eReferencedPackages', eReferencedPackages->display()); |
| if (eReferencedPackages->notEmpty()) { |
| self.eAnnotations += object Ecore::EAnnotation { |
| source := 'http://www.eclipse.org/OCL/Import'; |
| details := eReferencedPackages->sortedBy(name)->map resolveImportDetail(); |
| }; |
| } |
| } |
| |
| mapping Ecore::EPackage::resolveImportDetail() : Ecore::EStringToStringMapEntry { |
| key := self.name; |
| value := getURI(self.oclAsType(Ecore::EObject)); -- we don't know the final location ...' |
| // value := self.nsURI; |
| } */ |
| |
| mapping inout Ecore::EReference::resolveEReference() |
| { |
| if (debug_EReference_eOpposite) log('resolveEReference', self->display()); |
| var createProperty : UML2EcoreMapping::CreateProperty := eReference2createProperty->get(self); |
| var oldProperties : Set(UML::Property) := createProperty.oldProperties; |
| var oppositeProperty : UML::Property := createProperty.opposite; |
| if (debug_EReference_eOpposite) log(' oldProperties', oldProperties->display() + ' # ' + oppositeProperty->display()); |
| -- var oppositeProperties : Set(UML::Property) := oldProperties.getOtherEnd()->excluding(null)->asSet(); |
| -- if (debug_EReference_eOpposite) log(' oppositeProperties', oppositeProperties->display()); |
| -- var oppositeReferences : Set(Ecore::EReference) := oppositeProperties->collect(c | umlProperty2eReference->get(c))->excluding(null)->asSet(); |
| var oppositeReference : Ecore::EReference := if oppositeProperty <> null then umlProperty2eReference->get(oppositeProperty) else null endif; |
| if (debug_EReference_eOpposite) log(' oppositeReferences', oppositeReference->display()); |
| -- self.eOpposite := if oppositeReferences->notEmpty() and not self._'derived' and oppositeReferences->forAll(not _'derived') then oppositeReferences->any(true) else null endif; |
| self.eOpposite := oppositeReference; --if oppositeReferences->notEmpty() then oppositeReferences->any(true) else null endif; |
| -- var isDerived : Boolean := oldProperties->forAll(isDerived) and (oppositeReference = null); |
| -- self._'derived' := isDerived; |
| -- self.map installTransient(oldProperties, 'Ecore::EReference', self._'derived'); |
| -- self.map installResolveProxies(oldProperties, 'Ecore::EReference', not self._'derived'); |
| -- self.map installVolatile(oldProperties, 'Ecore::EReference', self._'derived'); |
| } |
| |
| helper getAllClasses(classes : Set(UML::Class)) : Set(UML::Class) { |
| return getAllTypes(classes)->selectByKind(UML::Class)->asSet(); |
| } |
| |
| helper getAllClassesOrInterfaces(classifiers : Set(UML::Type)) : Set(UML::Classifier) { |
| var allClassifiers := getAllTypes(classifiers); |
| var allClasses : Set(UML::Classifier) := allClassifiers->selectByKind(UML::Class)->asSet(); |
| var allInterfaces : Set(UML::Classifier) := allClassifiers->selectByKind(UML::Interface)->asSet(); |
| return allClasses->union(allInterfaces); |
| } |
| |
| helper getAllInterfaces(interfaces : Set(UML::Interface)) : Set(UML::Interface) { |
| return getAllTypes(interfaces)->selectByKind(UML::Interface)->asSet(); |
| } |
| |
| helper getAllTypes(types : Set(UML::Type)) : Set(UML::Type) { |
| return getAllTypes(types.name->asSet()) - deletePackageTypes; |
| } |
| |
| helper getAllTypes2(types : Set(UML::Type)) : Set(UML::Type) { |
| return getAllTypes(types.name->asSet()); |
| } |
| |
| helper getAllTypes(names : Set(String)) : Set(UML::Type) { |
| -- log(' types', types->sortedBy(name)->iterate(t; acc : String = '' | acc + ' ' + t._package.name + '::' + t.name)); |
| return allTypes->select(names->includes(name)); |
| } |
| |
| helper getProperSuperTypes(types : Set(UML::Type)) : Set(UML::Type) { |
| -- log(' types', types->sortedBy(name)->iterate(t; acc : String = '' | acc + ' ' + t._package.name + '::' + t.name)); |
| var selfClassesOrInterfaces : Set(UML::Classifier) := getAllClassesOrInterfaces(types); |
| var properSuperClassClosure1 : Set(UML::Classifier) := getAllClassesOrInterfaces(selfClassesOrInterfaces->closure(generalization.general)); |
| var properSuperClassClosure2 : Set(UML::Classifier) := getAllClassesOrInterfaces(properSuperClassClosure1->closure(generalization.general))->union(properSuperClassClosure1); |
| var properSuperClassClosure : Set(UML::Classifier) := getAllClassesOrInterfaces(properSuperClassClosure2->closure(generalization.general))->union(properSuperClassClosure2); |
| var interfaceRealizations : Set(UML::InterfaceRealization) := properSuperClassClosure->union(selfClassesOrInterfaces)->selectByKind(UML::Class).interfaceRealization->asSet()->excluding(null); |
| -- log(' interfaceRealizations', interfaceRealizations); |
| var superInterfaces : Set(UML::Interface) := interfaceRealizations.contract->asSet(); |
| -- log(' superInterfaces', superInterfaces.name->asSet()->sortedBy(n | n)->iterate(n; acc : String = '' | acc + ' ' + n)); |
| var names : Set(String) := properSuperClassClosure.name->asSet()->union(superInterfaces.name)->asSet(); |
| return getAllTypes(names); |
| } |
| |
| /** |
| * Xtext requires Ecore EClass references to be to the workspace resource. |
| */ |
| helper Ecore::EClassifier::resolveForXtext() : Ecore::EClassifier { |
| return self; |
| } |
| helper Ecore::EClass::resolveForXtext() : Ecore::EClassifier { |
| -- log('resolveType', self->display()); |
| var ePackage : Ecore::EPackage := self.ePackage; |
| if (ePackage.nsURI = 'http://www.eclipse.org/emf/2002/Ecore') { |
| var eClass := ecore.objectsOfKind(Ecore::EClass)->any(name = self.name); |
| -- log(' resolveType', eClass->display()); |
| return ecore.objectsOfKind(Ecore::EClass)->any(name = self.name); |
| }; |
| return self; |
| } |
| |
| helper selectType(types : Set(UML::Type)) : UML::Type { |
| var classes : Set(UML::Class) = types->selectByKind(UML::Class)->asSet(); |
| if (classes->size() <= 1) return types->any(true); |
| var type : UML::Type = classes->sortedBy(t | depth(t))->last(); |
| -- if (types->size() > 1) { |
| -- log(' ', types->display() + ' => ' + type->display()); |
| -- }; |
| return type; |
| } |
| |
| query depth(type : UML::Class) : Integer { |
| var depth : Integer = umlType2depth->get(type); |
| if (depth <> null) return depth; |
| var allClasses : Set(UML::Class) = allTypes->select(name = type.name)->selectByKind(UML::Class)->asSet(); |
| var allSuperClasses : Set(UML::Class) = allClasses.superClass->asSet(); |
| depth := if allSuperClasses->notEmpty() then allSuperClasses->collect(t | depth(t))->max()+1 else 0 endif; |
| -- log(' ', type->display() + ' => ' + depth.toString()); |
| allClasses->forEach(t) { umlType2depth->put(t, depth); }; |
| return depth; |
| } |
| |
| query depth(createProperty : UML2EcoreMapping::CreateProperty) : Integer { |
| var depth : Integer = createProperty2depth->get(createProperty); |
| if (depth <> null) return depth; |
| var allClasses : Set(UML::Class) = createProperty.oldProperties.getOwningType()->selectByKind(UML::Class)->asSet(); |
| depth := allClasses->collect(t | depth(t))->max(); |
| createProperty2depth->put(createProperty, depth); |
| return depth; |
| } |