blob: 899ee7e6f21f9365f59f6652f6c32dcccb7eb2b1 [file] [log] [blame]
//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;
}