| |
| modeltype UML2EcoreControl uses 'http://www.eclipse.org/ocl/2012/UML2EcoreControl'; |
| modeltype UML2EcoreMapping 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'; |
| |
| /** |
| * Analyze the references and directives from a UML2EcoreControl to produce an analysis of what needs synthesis. |
| */ |
| transformation UML2EcoreAnalyze(in uml2ecore : UML2EcoreControl, out UML2EcoreMapping); |
| |
| property debugPackage : Boolean = false; |
| property debugProperty : Boolean = false; |
| property showDuplicateUnnavigableOpposites : Boolean = true; |
| |
| helper Set(UML::Property)::display() : String { |
| return self->sortedBy(getPropertyName())->iterate(p; acc : String = '' | acc + ' ' + p.getPropertyName()); |
| } |
| |
| helper Set(UML::Type)::display() : String { |
| return self->sortedBy(getTypeName())->iterate(t; acc : String = '' | acc + ' ' + t.getTypeName()); |
| } |
| |
| helper Set(UML2EcoreControl::CreateProperty)::display() : String { |
| return self->sortedBy(newName)->iterate(p; acc : String = '' | acc + ' ' + p.newName); |
| } |
| |
| helper Set(String)::display() : String { |
| return self->sortedBy(n | n)->iterate(c; acc : String = '' | acc + ' ' + c); |
| } |
| |
| helper UML::NamedElement::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.package.getName() + '::' + type.getName() + '::' + self.getName(); |
| } |
| |
| helper UML::Type::getTypeName() : String { |
| return self.package.getName() + '::' + self.getName(); |
| } |
| |
| /* |
| * Packages |
| */ |
| property rootMappings : Set(UML2EcoreControl::Mappings) = uml2ecore.objectsOfKind(UML2EcoreControl::Mappings); |
| property packageMappings : Set(UML2EcoreControl::PackageMapping) = rootMappings.mappings->selectByKind(UML2EcoreControl::PackageMapping)->asSet(); |
| property explicitCreatePackageMappings : Set(UML2EcoreControl::CreatePackage) = rootMappings.mappings->selectByKind(UML2EcoreControl::CreatePackage)->asSet(); |
| property explicitDeletePackagesMappings : Set(UML2EcoreControl::DeletePackages) = rootMappings.mappings->selectByKind(UML2EcoreControl::DeletePackages)->asSet(); |
| |
| property packageMappings_oldPackages : Set(UML::Package) = packageMappings.oldPackages->asSet(); |
| property packageMappings_nestingPackages : Set(UML::Package) = packageMappings_oldPackages->closure(nestingPackage)->union(packageMappings_oldPackages); |
| property allPackages : Set(UML::Package) = packageMappings_nestingPackages->closure(nestedPackage)->union(packageMappings_nestingPackages); |
| |
| property explicitCreatePackages : Set(UML::Package) = explicitCreatePackageMappings.oldPackages->asSet(); |
| property explicitDeletePackages : Set(UML::Package) = explicitDeletePackagesMappings.oldPackages->asSet(); |
| property implicitCopyPackages : Set(UML::Package) = allPackages - explicitDeletePackages - explicitCreatePackages; |
| |
| main() { |
| -- log(' allAssociationsSize', allAssociations->size()); |
| -- log(' allAssociations', allAssociations->sortedBy(name)->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| -- log(' allUnnavigableOppositesSize', allUnnavigableOpposites->size()); |
| -- log(' allUnnavigableOppositesSize2', allUnnavigableOpposites->excluding(null)->size()); |
| -- log(' allUnnavigableOpposites', let opps : Sequence(UML::Property) = allUnnavigableOpposites->asSequence() in Sequence{1..allUnnavigableOpposites->size()} |
| -- ->iterate(i; acc : String = '' | let o = opps->at(i) in acc + ' ' + if o.name <> null then o.name else 'null' endif)); |
| -- log(' allUnnavigableOpposites', allUnnavigableOpposites->sortedBy(if name <> null then name else 'null' endif)->iterate(n; acc : String = '' | acc + ' ' + if n.name <> null then n.name else 'null' endif)); |
| if (showDuplicateUnnavigableOpposites) log(' duplicateUnnavigableOpposites', duplicateUnnavigableOpposites->sortedBy(getPropertyName())->iterate(n; acc : String = '' | acc + '\n\t' + n.getPropertyName() + ' -> ' + n.getOtherEnd().getPropertyName())); |
| -- log(' allUnnavigableForwardsSize', allUnnavigableForwards->size()); |
| -- log(' allUnnavigableForwards', allUnnavigableForwards->sortedBy(name)->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| var packageRenames : Set(UML2EcoreMapping::CreatePackage) := explicitCreatePackageMappings->map createRenamePackage()->asSet(); |
| var packageCopies : Set(UML2EcoreMapping::CreatePackage) := implicitCopyPackages->map createCopyPackage()->asSet(); |
| var packageDeletes : Set(UML2EcoreMapping::DeletePackage) := explicitDeletePackages->map createDeletePackage()->asSet(); |
| object UML2EcoreMapping::Mappings { |
| mappings += packageDeletes->sortedBy(oldName); |
| mappings += packageRenames->union(packageCopies)->sortedBy(newName); |
| }; |
| } |
| |
| /** |
| * Create a CreatePackage for a renamed package and CreateType/DeleteType etc for children. |
| */ |
| mapping UML2EcoreControl::CreatePackage::createRenamePackage() : UML2EcoreMapping::CreatePackage |
| { |
| if (debugPackage) log('createRenamePackage', self.label); |
| var myOldTypes : Set(UML::Type) := self.oldPackages.ownedType->reject(oclIsKindOf(UML::Association))->asSet(); |
| var myCreateTypes : Set(UML2EcoreControl::CreateType) := self.createTypes; |
| var myOldTypeNames : Set(String) := myOldTypes.name->asSet(); |
| -- log(' packageMappings_oldPackages', packageMappings_oldPackages->sortedBy(name)->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| -- log(' packageMappings_nestingPackages', packageMappings_nestingPackages->sortedBy(name)->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| -- log(' allPackages', allPackages->sortedBy(name)->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| -- log(' myOldTypeNames', myOldTypeNames->sortedBy(n | n)->iterate(n; acc : String = '' | acc + ' ' + n)); |
| var myUsedTypeNames : Set(String) := myCreateTypes.oldTypes.name->asSet() - allDeleteTypeNames; |
| -- log(' myUsedTypeNames', myUsedTypeNames->sortedBy(n | n)->iterate(n; acc : String = '' | acc + ' ' + n)); |
| var myCopyTypeNames : Set(String) := myOldTypeNames - allDeleteTypeNames - myUsedTypeNames; |
| -- log(' myCopyTypeNames', myCopyTypeNames->sortedBy(n | n)->iterate(n; acc : String = '' | acc + ' ' + n)); |
| -- var myDeleteTypeNames : Set(String) := myOldTypeNames - myUsedTypeNames - myCopyTypeNames; |
| -- log(' myDeleteTypeNames', myDeleteTypeNames->sortedBy(n | n)->iterate(n; acc : String = '' | acc + ' ' + n)); |
| -- var myUsedTypes : Set(UML::Type) := allTypes->select(myUsedTypeNames->includes(name)); |
| var myCopyTypes : Set(UML::Type) := getAllTypes(myCopyTypeNames); |
| -- var myDeleteTypes : Set(UML::Type) := allTypes->select(myDeleteTypeNames->includes(name)); |
| var deleteTypes : Set(UML2EcoreMapping::DeleteType) := explicitDeleteTypesMappings.oldTypes->map createDeleteType()->asSet(); |
| var createTypes : Set(UML2EcoreMapping::CreateType) := myCreateTypes->map createRenameType()->asSet(); |
| var copyTypes : Set(UML2EcoreMapping::CreateType) := myCopyTypeNames->map createCreateType()->asSet(); |
| result.newName := self.newName; |
| result.nsPrefix := self.nsPrefix; |
| result.nsURI := self.nsURI; |
| result.isASmetamodel := self.isASmetamodel; |
| result.oldPackages := self.oldPackages; |
| result.typeMappings += deleteTypes->sortedBy(oldName); |
| result.typeMappings += createTypes->union(copyTypes)->sortedBy(newName); |
| } |
| |
| /** |
| * Create a CreatePackage for a copied package and CreateType/DeleteType etc for children. |
| */ |
| mapping UML::Package::createCopyPackage() : UML2EcoreMapping::CreatePackage |
| { |
| if (debugPackage) log('createCreatePackage', self); |
| var renameTypeMappings : Set(UML2EcoreControl::CreateType) := Set{}; --self.typeMappings->selectByKind(UML2Ecore::CreateType)->asSet(); |
| var renameTypes : Set(UML::Type) := renameTypeMappings.oldTypes->asSet(); |
| var myTypes : Set(UML::Type) := self.ownedType->reject(oclIsKindOf(UML::Association))->asSet(); |
| var myCopyTypes : Set(UML::Type) := myTypes - allDeleteTypes - renameTypes; |
| var myRenameTypes : Set(UML::Type) := myTypes - allDeleteTypes - myCopyTypes; |
| var myTypeDeletes : Set(UML::Type) := myTypes - myRenameTypes - myCopyTypes; |
| |
| var typeRenamings : Set(UML2EcoreMapping::CreateType) := renameTypeMappings->map createRenameType()->asSet(); |
| var typeCopies : Set(UML2EcoreMapping::CreateType) := myCopyTypes->map createCreateType()->asSet(); |
| var typeDeletes : OrderedSet(UML2EcoreMapping::TypeMapping) := explicitDeleteTypesMappings.oldTypes->map createDeleteType()->asSet()->sortedBy(oldName); |
| result.newName := self.name; |
| result.oldPackages := self->asSet(); |
| result.typeMappings := typeDeletes->union(typeRenamings->union(typeCopies)->sortedBy(newName)); |
| } |
| |
| /** |
| * Create a DeletePackage for an unwanted package and DeleteType etc for not explicitly wanted children. |
| */ |
| mapping UML::Package::createDeletePackage() : UML2EcoreMapping::DeletePackage |
| { |
| if (debugPackage) log('createDeletePackage', self.name); |
| result.oldName := self.name; |
| result.oldPackages := self->asSet(); |
| var unwantedTypes : Set(UML::Type) := self.ownedType->reject(oclIsKindOf(UML::Association));-->reject(allCreateTypeNames->includes(name)); |
| result.deleteTypes := unwantedTypes->map createDeleteType()->asSet()->sortedBy(oldName); |
| } |
| |
| /* |
| * Types |
| */ |
| property explicitDeleteTypesMappings : Set(UML2EcoreControl::DeleteTypes) = uml2ecore.objectsOfKind(UML2EcoreControl::DeleteTypes); |
| property explicitCreateTypesMappings : Set(UML2EcoreControl::CreateType) = uml2ecore.objectsOfKind(UML2EcoreControl::CreateType); |
| property explicitDeleteInheritances : Set(UML2EcoreControl::DeleteInheritances) = uml2ecore.objectsOfKind(UML2EcoreControl::DeleteInheritances); |
| |
| property explicitCreateTypes : Set(UML::Type) = explicitCreateTypesMappings.oldTypes->asSet(); |
| property explicitDeleteTypes : Set(UML::Type) = (explicitDeletePackages.ownedType->asSet() - explicitCreateTypes)->union(explicitDeleteTypesMappings.oldTypes->asSet()); |
| |
| property allDeleteTypeNames : Set(String) = explicitDeleteTypesMappings.oldTypes.name->asSet(); |
| property allCreateTypeNames : Set(String) = explicitCreateTypesMappings.oldTypes.name->asSet(); |
| |
| --property deletePropertyNames : Set(String) = deletePropertiesMappings.oldProperties.name->asSet(); |
| --property createPropertyNames : Set(String) = createPropertyMappings.oldProperties.name->asSet(); |
| property allAssociations : Set(UML::Association) = |
| (allPackages-explicitDeletePackages).ownedType->selectByKind(UML::Association)->asSet(); |
| property allUnnavigableOpposites : Set(UML::Property) = |
| allAssociations.ownedEnd->asSet()->select(name <> null); |
| /** |
| * Identify opposites that would give duplicate name c onflicts if realized. |
| */ |
| -- NB opposite seems to be null BUG 439915 |
| property duplicateUnnavigableOpposites : Set(UML::Property) = |
| -- sort allUnnavigableOpposites so that duplicates are adjacent |
| let allSortedUnnavigableOpposites : OrderedSet(UML::Property) = |
| allUnnavigableOpposites->sortedBy(getOtherEnd().type.getName() + "::" + getName()) |
| -- select the second index of each allUnnavigableOpposites duplicate |
| in let _duplicateUnnavigableIndexes : Sequence(Integer) = |
| Sequence{2..allSortedUnnavigableOpposites->size()} |
| ->select(i | let p1 = allSortedUnnavigableOpposites->at(i-1), p2 = allSortedUnnavigableOpposites->at(i) |
| in (p1.getOtherEnd().type = p2.getOtherEnd().type) and (p1.getName() = p2.getName())) |
| in _duplicateUnnavigableIndexes->collect(i | Sequence{allSortedUnnavigableOpposites->at(i-1), allSortedUnnavigableOpposites->at(i)})->asSet(); |
| property realizableUnnavigableOpposites : Set(UML::Property) = allUnnavigableOpposites - duplicateUnnavigableOpposites; |
| property realizableUnnavigableForwards : Set(UML::Property) = realizableUnnavigableOpposites.getOtherEnd()->asSet(); |
| |
| property allUnnavigableForwards : Set(UML::Property) = realizableUnnavigableForwards; -- ->reject(isComposite); |
| --property allUnnavigableForwards2 : Set(UML::Property) = allAssociations.memberEnd->asSet() - allAssociations.ownedEnd->asSet(); |
| property allTypes : Set(UML::Type) = (allPackages-explicitDeletePackages).ownedType->asSet() - allAssociations; |
| property allStructuredClassifiers : Set(UML::StructuredClassifier) = allTypes->selectByKind(UML::StructuredClassifier)->asSet(); |
| property allClasses : Set(UML::Class) = allTypes->selectByKind(UML::Class)->asSet(); |
| property allDeleteTypes : Set(UML::Type) = allTypes->select(allDeleteTypeNames->includes(name)); |
| |
| helper getAllTypes(types : Set(UML::Type)) : Set(UML::Type) { |
| -- log(' types', types->sortedBy(name)->iterate(t; acc : String = '' | acc + ' ' + t._package.name + '::' + t.name)); |
| 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)); |
| } |
| |
| mapping UML2EcoreControl::CreateType::createRenameType() : UML2EcoreMapping::CreateType |
| { |
| -- log('createRenameType', self.newName); |
| var myTypes : Set(UML::Type) := getAllTypes(self.oldTypes->asSet()) - explicitDeleteTypes; |
| -- log(' myTypes', myTypes->sortedBy(name)->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| result.newName := self.newName; |
| result.newInstanceTypeName := self.newInstanceTypeName; |
| result.orderedSuperTypes := self.orderedSuperTypes; |
| result.oldTypes := myTypes; |
| result.operationMappings := selectOperations(myTypes); |
| result.propertyMappings := selectProperties(myTypes); |
| } |
| |
| mapping String::createCreateType() : UML2EcoreMapping::CreateType |
| { |
| -- log('createCreateType', self); |
| var myTypes : Set(UML::Type) := allTypes->select(name = self) - explicitDeleteTypes; |
| result.newName := self; |
| result.oldTypes := myTypes; |
| result.excludeTypes := selectDeleteTypes(myTypes); |
| result.excludeProperties := selectDeleteProperties(myTypes); |
| result.includeProperties := selectIncludeProperties(myTypes); |
| result.operationMappings := selectOperations(myTypes); |
| result.propertyMappings := selectProperties(myTypes); |
| } |
| |
| mapping UML::Type::createCreateType() : UML2EcoreMapping::CreateType |
| { |
| -- log('createCreateType', self.name); |
| var myTypes : Set(UML::Type) := getAllTypes(self->asSet()) - explicitDeleteTypes; |
| result.newName := self.name; |
| result.oldTypes := myTypes; |
| result.excludeTypes := selectDeleteTypes(myTypes); |
| result.excludeProperties := selectDeleteProperties(myTypes); |
| result.includeProperties := selectIncludeProperties(myTypes); |
| result.operationMappings := selectOperations(myTypes); |
| result.propertyMappings := selectProperties(myTypes); |
| } |
| /*mapping UML::StructuredClassifier::createCreateType() : UML2EcoreMapping::CreateType |
| inherits UML::Type::createCreateType |
| { |
| log('createCreateStructuredClassifier', self.name); |
| var myProperties : Set(UML::Property) := self.ownedAttribute; --->reject(createTypeNames->includes(name)); |
| result.propertyMappings := myProperties->map createCreateProperty()->asSet()->sortedBy(newName); |
| } */ |
| |
| mapping UML::Type::createDeleteType() : UML2EcoreMapping::DeleteType |
| { |
| -- log('createDeleteType', self.name); |
| var myTypes : Set(UML::Type) := getAllTypes(self->asSet()) - explicitCreateTypes; |
| result.oldName := self.name; |
| result.oldTypes := myTypes; |
| result.operationMappings := selectOperations(myTypes); |
| result.propertyMappings := selectProperties(myTypes); |
| } |
| /*mapping UML::StructuredClassifier::createDeleteType() : UML2EcoreMapping::DeleteType |
| inherits UML::Type::createDeleteType |
| { |
| -- log('createDeleteStructuredClassifier', self.name); |
| var myProperties : Set(UML::Property) := self.ownedAttribute; --->reject(createTypeNames->includes(name)); |
| result.propertyMappings := myProperties->map createCreateProperty()->asSet()->sortedBy(oldName); |
| } */ |
| |
| |
| /* |
| * Operations |
| */ |
| property deleteOperationsMappings : Set(UML2EcoreControl::DeleteOperations) = uml2ecore.objectsOfKind(UML2EcoreControl::DeleteOperations); |
| property createOperationMappings : Set(UML2EcoreControl::CreateOperation) = uml2ecore.objectsOfKind(UML2EcoreControl::CreateOperation); |
| property allOperations : Set(UML::Operation) = allClasses.ownedOperation->asSet(); |
| |
| mapping String::createCreateOperation(oldOperations2 : Set(UML::Operation)) : UML2EcoreMapping::CreateOperation |
| { |
| -- log(' createOperationMappings', createOperationMappings->sortedBy(newName)->iterate(n; acc : String = '' | acc + ' ' + n.newName)); |
| -- log(' namedOperations', createOperationMappings.oldOperations->flatten()->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| -- log(' oldOperations2', oldOperations2->sortedBy(name)->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| -- log(' createCreateOperation', self); |
| var sameNamedOperations : Set(UML::Operation) := oldOperations2->select(name = self); |
| -- log(' sameNamedOperations', sameNamedOperations->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| var createOperations : Set(UML2EcoreControl::CreateOperation) := createOperationMappings->select(oldOperations->intersection(sameNamedOperations)->notEmpty()); |
| -- log(' createOperations', createOperations->sortedBy(newName)->iterate(n; acc : String = '' | acc + ' ' + n.newName)); |
| result.newName := if createOperations->notEmpty() then createOperations->any(true).newName else self endif; |
| result.oldOperations := sameNamedOperations; |
| } |
| |
| mapping UML::Operation::createDeleteOperation() : UML2EcoreMapping::DeleteOperation |
| { |
| --- log('createDeleteOperation', self.name); |
| result.oldName := self.name; |
| result.oldOperations := self->asSet(); |
| } |
| |
| query selectOperations(types : Set(UML::Type)) : OrderedSet(UML2EcoreMapping::OperationMapping) = |
| let classes : Set(UML::Class) = types->selectByKind(UML::Class)->asSet(), |
| interfaces : Set(UML::Interface) = types->selectByKind(UML::Interface)->asSet(), |
| operations : Set(UML::Operation) = classes.ownedOperation->asSet()->union(interfaces.ownedOperation->asSet()), |
| unwantedOperations : Set(UML::Operation) = Set{}, --operations->select(isDerivedUnion), |
| wantedOperations : Set(UML::Operation) = operations - unwantedOperations - deleteOperationsMappings.oldOperations->asSet(), |
| wantedOperationNames : Set(String) = wantedOperations.name->asSet(), |
| creates : Sequence(UML2EcoreMapping::OperationMapping) = wantedOperationNames->map createCreateOperation(wantedOperations)->asSequence()->sortedBy(newName), |
| deletes : Sequence(UML2EcoreMapping::OperationMapping) = unwantedOperations->map createDeleteOperation()->asSequence()->sortedBy(oldName) |
| in creates->iterate(c : UML2EcoreMapping::OperationMapping; acc : Sequence(UML2EcoreMapping::OperationMapping) = deletes | acc->including(c))->asOrderedSet(); |
| |
| |
| /* |
| * Properties |
| */ |
| property explicitDeletePropertiesMappings : Set(UML2EcoreControl::DeleteProperties) = uml2ecore.objectsOfKind(UML2EcoreControl::DeleteProperties); |
| property explicitCreatePropertyMappings : Set(UML2EcoreControl::CreateProperty) = uml2ecore.objectsOfKind(UML2EcoreControl::CreateProperty); |
| property allProperties : Set(UML::Property) = allStructuredClassifiers.ownedAttribute->asSet(); |
| property explicitDeleteProperties : Set(UML::Property) = explicitDeletePropertiesMappings.oldProperties->asSet(); |
| |
| mapping String::createCreateProperty(wantedProperties : Set(UML::Property)) : UML2EcoreMapping::CreateProperty |
| { |
| -- log(' createPropertyMappings', createPropertyMappings->sortedBy(newName)->iterate(n; acc : String = '' | acc + ' ' + n.newName)); |
| -- log(' namedProperties', createPropertyMappings.oldProperties->flatten()->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| -- log(' oldProperties2', oldProperties2->sortedBy(name)->iterate(n; acc : String = '' | acc + ' ' + n.name)); |
| if (debugProperty) log(' createCreateProperty', self); |
| var sameNamedProperties : Set(UML::Property) := wantedProperties->select(name = self); |
| if (debugProperty) log(' sameNamedProperties', sameNamedProperties->display()); |
| var explicitCreateProperties : Set(UML2EcoreControl::CreateProperty) := explicitCreatePropertyMappings->select(oldProperties->intersection(sameNamedProperties)->notEmpty()); |
| -- log(' explicitCreateProperties', explicitCreateProperties->display()); |
| assert fatal (explicitCreateProperties->size() <= 1) with log("Duplicate CreateProperty ", explicitCreateProperties->display()); |
| result.newName := if explicitCreateProperties->notEmpty() then explicitCreateProperties->any(true).newName else self endif; |
| result.newIsDerived := let newIsDerived : Bag(Boolean) = explicitCreateProperties->collect(newIsDerived)->excluding(null) in if newIsDerived->notEmpty() then newIsDerived->exists(n | n) else null endif; |
| result.newIsResolveProxies := let newIsResolveProxies : Bag(Boolean) = explicitCreateProperties->collect(newIsResolveProxies)->excluding(null) in if newIsResolveProxies->notEmpty() then newIsResolveProxies->exists(n | n) else null endif; |
| result.newIsTransient := let newIsTransient : Bag(Boolean) = explicitCreateProperties->collect(newIsTransient)->excluding(null) in if newIsTransient->notEmpty() then newIsTransient->exists(n | n) else null endif; |
| result.newIsUnsettable := let newIsUnsettable : Bag(Boolean) = explicitCreateProperties->collect(newIsUnsettable)->excluding(null) in if newIsUnsettable->notEmpty() then newIsUnsettable->exists(n | n) else null endif; |
| result.newIsVolatile := let newIsVolatile : Bag(Boolean) = explicitCreateProperties->collect(newIsVolatile)->excluding(null) in if newIsVolatile->notEmpty() then newIsVolatile->exists(n | n) else null endif; |
| result.newLowerBound := let newLowerBound : Bag(Integer) = explicitCreateProperties->collect(newLowerBound)->excluding(null) in if newLowerBound->notEmpty() then newLowerBound->max() else null endif; |
| result.oldProperties := sameNamedProperties; |
| var oppositeProperties1 : Set(UML::Property) := sameNamedProperties.getOtherEnd()->excluding(null)->asSet(); |
| if (debugProperty) log(' oppositeProperties1', oppositeProperties1->display()); |
| var oppositeProperties2 : Set(UML::Property) := oppositeProperties1 - explicitDeleteProperties; |
| if (debugProperty) log(' oppositeProperties2', oppositeProperties2->display()); |
| assert warning (oppositeProperties2->size() <= 1) with log("Duplicate Opposite Property " + oppositeProperties2->display()); |
| result.opposite := oppositeProperties2->any(true); --(s - duplicateUnnavigableOpposites)->any(true); |
| } |
| |
| mapping UML::Property::createDeleteProperty() : UML2EcoreMapping::DeleteProperty |
| { |
| if (debugProperty) log('createDeleteProperty', self.name); |
| result.oldName := self.name; |
| result.oldProperties := self->asSet(); |
| } |
| |
| mapping UML2EcoreControl::CreateProperty::createRenameProperty() : UML2EcoreMapping::CreateProperty |
| { |
| if (debugProperty) log(' createRenameProperty', self.newName); |
| result.newName := self.newName; |
| var oldProperties : Set(UML::Property) := self.oldProperties; |
| if (debugProperty) log(' oldProperties', oldProperties->display()); |
| result.oldProperties := oldProperties; |
| if (debugProperty) log(' newIsDerived', self.newIsDerived); |
| result.newIsDerived := self.newIsDerived; |
| if (debugProperty) log(' newIsResolveProxies', self.newIsResolveProxies); |
| result.newIsResolveProxies := self.newIsResolveProxies; |
| if (debugProperty) log(' newIsTransient', self.newIsTransient); |
| result.newIsTransient := self.newIsTransient; |
| if (debugProperty) log(' newIsUnsettable', self.newIsUnsettable); |
| result.newIsUnsettable := self.newIsUnsettable; |
| if (debugProperty) log(' newIsVolatile', self.newIsVolatile); |
| result.newIsVolatile := self.newIsVolatile; |
| if (debugProperty) log(' newLowerBound', self.newLowerBound); |
| result.newLowerBound := self.newLowerBound; |
| var oppositeProperties1 : Set(UML::Property) := oldProperties.getOtherEnd()->excluding(null)->asSet(); |
| if (debugProperty) log(' oppositeProperties1', oppositeProperties1->display()); |
| var oppositeProperties2 : Set(UML::Property) := oppositeProperties1 - explicitDeleteProperties; |
| if (debugProperty) log(' oppositeProperties2', oppositeProperties2->display()); |
| assert warning (oppositeProperties2->size() <= 1) with log("Duplicate Opposite Property " + oppositeProperties2->display()); |
| result.opposite := oppositeProperties2->any(true); --(s - duplicateUnnavigableOpposites)->any(true); |
| } |
| |
| /** |
| * Select the properties for the merge of types and return as a set of CreateProperty for keeps and DeleteProperty for removes. |
| */ |
| query selectProperties(types : Set(UML::Type)) : OrderedSet(UML2EcoreMapping::PropertyMapping) { |
| if (debugProperty) log(' selectProperties', types->display()); |
| var classifiers : Set(UML::StructuredClassifier) = types->selectByKind(UML::StructuredClassifier)->asSet(); |
| var directProperties : Set(UML::Property) = classifiers.ownedAttribute->asSet(); |
| var indirectProperties : Set(UML::Property) = allUnnavigableForwards->select(types->includes(type))->collect(association.ownedEnd)->asSet(); |
| var properties : Set(UML::Property) = directProperties->union(indirectProperties); |
| var unwantedProperties : Set(UML::Property) = properties->select(isDerivedUnion); |
| var deletedProperties : Set(UML::Property) = explicitDeletePropertiesMappings.oldProperties->asSet(); |
| var wantedProperties : Set(UML::Property) = properties - unwantedProperties - deletedProperties; |
| if (debugProperty) log(' wantedProperties', wantedProperties->display()); |
| |
| var renameProperties : Set(UML2EcoreControl::CreateProperty) := explicitCreatePropertyMappings->select(oldProperties->intersection(wantedProperties)->notEmpty()); |
| var renamedProperties : Set(UML::Property) := renameProperties.oldProperties->asSet(); |
| var moveProperties : Set(UML2EcoreControl::CreateProperty) := explicitCreatePropertyMappings->select(types->includes(newOwningType)); |
| var movedProperties : Set(UML::Property) := moveProperties.oldProperties->asSet(); |
| var oldPropertyNames : Set(String) := renamedProperties.name->asSet(); |
| var newPropertyNames : Set(String) := renameProperties.newName->asSet()->union(moveProperties.newName->asSet()); |
| |
| var wantedPropertyNames : Set(String) = (wantedProperties.name->asSet() - oldPropertyNames); -- ->union(newPropertyNames); |
| |
| |
| |
| var creates : Sequence(UML2EcoreMapping::PropertyMapping) = wantedPropertyNames->map createCreateProperty(wantedProperties)->asSequence()->sortedBy(newName); |
| var renames : Sequence(UML2EcoreMapping::CreateProperty) = renameProperties->union(moveProperties)->map createRenameProperty()->asSequence()->sortedBy(newName); |
| var deletes : Sequence(UML2EcoreMapping::PropertyMapping) = unwantedProperties->map createDeleteProperty()->asSequence()->sortedBy(oldName); |
| var createsAndRenames : Sequence(UML2EcoreMapping::PropertyMapping) = creates->iterate(c : UML2EcoreMapping::PropertyMapping; acc : Sequence(UML2EcoreMapping::PropertyMapping) = renames | acc->including(c)); |
| return createsAndRenames->iterate(c : UML2EcoreMapping::PropertyMapping; acc : Sequence(UML2EcoreMapping::PropertyMapping) = deletes | acc->including(c))->asOrderedSet(); |
| } |
| |
| /** |
| * Select the properties for the merge of types and return as a set of CreateProperty for keeps and DeleteProperty for removes. |
| */ |
| query selectDeleteTypes(types : Set(UML::Type)) : Set(UML::Type) { |
| var selectedDeleteInheritances : Set(UML2EcoreControl::DeleteInheritances) = explicitDeleteInheritances->select(oldTypes->intersection(types)->notEmpty())->asSet(); |
| var unwantedTypes : Set(UML::Type) = selectedDeleteInheritances.excludeTypes->asSet(); |
| var unwantedTypesAndProperties : Set(UML::Type) = selectedDeleteInheritances.excludeTypesAndProperties->asSet(); |
| var unwantedAllTypesAndProperties : Set(UML::Type) = getAllTypes(selectedDeleteInheritances.excludeAllTypesAndProperties->asSet()); |
| return unwantedTypes->union(unwantedTypesAndProperties)->union(unwantedAllTypesAndProperties); |
| } |
| query selectDeleteProperties(types : Set(UML::Type)) : Set(UML::Property) { |
| var selectedDeleteInheritances : Set(UML2EcoreControl::DeleteInheritances) = explicitDeleteInheritances->select(oldTypes->intersection(types)->notEmpty())->asSet(); |
| var unwantedTypesAndProperties : Set(UML::Type) = selectedDeleteInheritances.excludeTypesAndProperties->asSet(); |
| var unwantedAllTypesAndProperties : Set(UML::Type) = getAllTypes(selectedDeleteInheritances.excludeAllTypesAndProperties->asSet()); |
| var unwantedTypeProperties : Set(UML::Property) = unwantedTypesAndProperties->union(unwantedAllTypesAndProperties)->selectByKind(UML::Class).ownedAttribute->asSet(); |
| var unwantedProperties : Set(UML::Property) = selectedDeleteInheritances.excludeProperties->asSet(); |
| var wantedProperties : Set(UML::Property) = selectedDeleteInheritances.includeProperties->asSet(); |
| return unwantedProperties->union(unwantedTypeProperties) - wantedProperties; |
| } |
| query selectIncludeProperties(types : Set(UML::Type)) : Set(UML::Property) { |
| var selectedDeleteInheritances : Set(UML2EcoreControl::DeleteInheritances) = explicitDeleteInheritances->select(oldTypes->intersection(types)->notEmpty())->asSet(); |
| var wantedProperties : Set(UML::Property) = selectedDeleteInheritances.includeProperties->asSet(); |
| return wantedProperties; |
| } |
| |