| /******************************************************************************* |
| * Copyright (c) 2014 Willink Transformations and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * Contributors: |
| * E.D.Willink - Initial API and implementation |
| *******************************************************************************/ |
| |
| 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'; |
| |
| /** |
| * Merger the imports of a UML2EcoreContrtol model to create a simpler control file. |
| */ |
| transformation UML2EcoreMerger(in uml2ecore : UML2EcoreControl, out UML2EcoreControl); |
| |
| 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(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(); |
| } |
| |
| main() { |
| var rootMapping : Set(UML2EcoreControl::Mappings) = uml2ecore.objectsOfKind(UML2EcoreControl::Mappings); |
| var rootMappings : Set(UML2EcoreControl::Mappings) = rootMapping->closure(imports)->union(rootMapping); |
| var allCreatePackages : OrderedSet(UML2EcoreControl::CreatePackage) = rootMappings.mappings->selectByKind(UML2EcoreControl::CreatePackage)->asOrderedSet(); |
| var allDeleteInheritances : Set(UML2EcoreControl::DeleteInheritances) := rootMappings.mappings->selectByKind(UML2EcoreControl::DeleteInheritances)->asSet(); |
| var packageDeletes : Set(UML::Package) := rootMappings.mappings->selectByKind(UML2EcoreControl::DeletePackages).oldPackages->asSet(); |
| var typeDeletes : Set(UML::Type) := rootMappings.mappings->selectByKind(UML2EcoreControl::DeleteTypes).oldTypes->asSet(); |
| var propertyDeletes : Set(UML::Property) := rootMappings.mappings->selectByKind(UML2EcoreControl::DeleteProperties).oldProperties->asSet(); |
| var operationDeletes : Set(UML::Operation) := rootMappings.mappings->selectByKind(UML2EcoreControl::DeleteOperations).oldOperations->asSet(); |
| object UML2EcoreControl::Mappings { |
| if (allCreatePackages->notEmpty()) { |
| mappings += allCreatePackages.newName->asSet()->createCreatePackage(allCreatePackages); |
| }; |
| if (allDeleteInheritances->notEmpty()) { |
| mappings += allDeleteInheritances.oldTypes->asSet()->createCreateDeleteInheritances(allDeleteInheritances); |
| }; |
| if (packageDeletes->notEmpty()) { |
| mappings += object UML2EcoreControl::DeletePackages { |
| oldPackages := packageDeletes; |
| }; |
| }; |
| if (typeDeletes->notEmpty()) { |
| mappings += object UML2EcoreControl::DeleteTypes { |
| oldTypes := typeDeletes; |
| }; |
| }; |
| if (propertyDeletes->notEmpty()) { |
| mappings += object UML2EcoreControl::DeleteProperties { |
| oldProperties := propertyDeletes; |
| }; |
| }; |
| if (operationDeletes->notEmpty()) { |
| mappings += object UML2EcoreControl::DeleteOperations { |
| oldOperations := operationDeletes; |
| }; |
| }; |
| }; |
| } |
| |
| /** |
| * Create a CreatePackage for a merge by name |
| */ |
| mapping String::createCreatePackage(someCreatePackages : OrderedSet(UML2EcoreControl::CreatePackage)) : UML2EcoreControl::CreatePackage |
| { |
| if (debugPackage) log('createCreatePackage', self); |
| result.newName := self; |
| var myCreatePackages : OrderedSet(UML2EcoreControl::CreatePackage) := someCreatePackages->select(newName = self); |
| var nsPrefixes := myCreatePackages.nsPrefix->asSet()->excluding(null); |
| if (nsPrefixes->size() > 1) log("Ambiguous nsPrefix for ", self); |
| if (nsPrefixes->size() = 1) result.nsPrefix := nsPrefixes->any(true); |
| var nsURIs := myCreatePackages.nsURI->asSet()->excluding(null); |
| if (nsURIs->size() > 1) log("Ambiguous nsURI for ", self); |
| if (nsURIs->size() = 1) result.nsURI := nsURIs->any(true); |
| var isASmetamodels := myCreatePackages.isASmetamodel->asSet()->excluding(null); |
| if (isASmetamodels->size() > 1) log("Ambiguous isASmetamodel for ", self); |
| if (isASmetamodels->size() = 1) result.isASmetamodel := isASmetamodels->any(true); |
| var ecoreFileStems := myCreatePackages.ecoreFileStem->asSet()->excluding(null); |
| if (ecoreFileStems->size() > 1) log("Ambiguous ecoreFileStem for ", self); |
| if (ecoreFileStems->size() = 1) result.ecoreFileStem := ecoreFileStems->any(true); |
| result.oldPackages := myCreatePackages.oldPackages->asSet()->excluding(null); |
| var myCreateTypes : OrderedSet(UML2EcoreControl::CreateType) := myCreatePackages.createTypes->asOrderedSet(); |
| result.createTypes += myCreateTypes.newName->asSet()->createCreateType(myCreateTypes); |
| } |
| |
| /** |
| * Create a CreatePackage for a merge by name |
| */ |
| mapping UML::Type::createCreateDeleteInheritances(someDeleteInheritances : Set(UML2EcoreControl::DeleteInheritances)) : UML2EcoreControl::DeleteInheritances |
| { |
| if (debugPackage) log('createCreateDeleteInheritances', self); |
| var myDeleteInheritances : Set(UML2EcoreControl::DeleteInheritances) := someDeleteInheritances->select(oldTypes->includes(self)); |
| var excludeProperties := myDeleteInheritances.excludeProperties->asSet()->excluding(null); |
| result.excludeProperties := excludeProperties->any(true); |
| var excludeTypes := myDeleteInheritances.excludeTypes->asSet()->excluding(null); |
| result.excludeTypes := excludeTypes->any(true); |
| var excludeTypesAndProperties := myDeleteInheritances.excludeTypesAndProperties->asSet()->excluding(null); |
| result.excludeTypesAndProperties := excludeTypesAndProperties->any(true); |
| var includeProperties := myDeleteInheritances.includeProperties->asSet()->excluding(null); |
| result.includeProperties := includeProperties->any(true); |
| var excludeAllTypesAndProperties := myDeleteInheritances.excludeAllTypesAndProperties->asSet()->excluding(null); |
| result.excludeAllTypesAndProperties := excludeAllTypesAndProperties->any(true); |
| result.oldTypes := self->asSet(); |
| } |
| |
| /** |
| * Create a CreateType for a merge by name |
| */ |
| mapping String::createCreateType(someCreateTypes : OrderedSet(UML2EcoreControl::CreateType)) : UML2EcoreControl::CreateType |
| { |
| if (debugPackage) log('createCreateType', self); |
| result.newName := self; |
| var myCreateTypes : OrderedSet(UML2EcoreControl::CreateType) := someCreateTypes->select(newName = self); |
| var newInstanceTypeNames := myCreateTypes.newInstanceTypeName->asSet()->excluding(null); |
| if (newInstanceTypeNames->size() > 1) log("Ambiguous newInstanceTypeName for ", self); |
| if (newInstanceTypeNames->size() = 1) result.newInstanceTypeName := newInstanceTypeNames->any(true); |
| result.oldTypes := myCreateTypes.oldTypes->asSet()->excluding(null); |
| var myCreateOperations : Set(UML2EcoreControl::CreateOperation) := myCreateTypes.createOperations->asSet(); |
| result.createOperations += myCreateOperations.newName->asSet()->createCreateOperation(myCreateOperations); |
| var myCreateProperties : Set(UML2EcoreControl::CreateProperty) := myCreateTypes.createProperties->asSet(); |
| result.createProperties += myCreateProperties.newName->asSet()->createCreateProperty(myCreateProperties); |
| var myOrderedSuperClasses : OrderedSet(UML::Type) := myCreateTypes.orderedSuperTypes->asOrderedSet(); |
| result.orderedSuperTypes += myOrderedSuperClasses; |
| } |
| |
| /** |
| * Create a CreateOperation for a merge by name |
| */ |
| mapping String::createCreateOperation(someCreateOperations : Set(UML2EcoreControl::CreateOperation)) : UML2EcoreControl::CreateOperation |
| { |
| if (debugPackage) log('createCreateOperation', self); |
| result.newName := self; |
| var myCreateOperations : Set(UML2EcoreControl::CreateOperation) := someCreateOperations->select(newName = self); |
| result.oldOperations := myCreateOperations.oldOperations->asSet()->excluding(null); |
| } |
| |
| /** |
| * Create a CreateProperty for a merge by name |
| */ |
| mapping String::createCreateProperty(someCreateProperties : Set(UML2EcoreControl::CreateProperty)) : UML2EcoreControl::CreateProperty |
| { |
| if (debugPackage) log('createCreateProperty', self); |
| result.newName := self; |
| var myCreateProperties : Set(UML2EcoreControl::CreateProperty) := someCreateProperties->select(newName = self); |
| var newOwningTypes := myCreateProperties.newOwningType->asSet()->excluding(null); |
| if (newOwningTypes->size() > 1) log("Ambiguous newOwningType for ", self); |
| if (newOwningTypes->size() = 1) result.newOwningType := newOwningTypes->any(true); |
| var newIsDeriveds := myCreateProperties.newIsDerived->asSet()->excluding(null); |
| if (newIsDeriveds->size() > 1) log("Ambiguous newIsDerived for ", self); |
| if (newIsDeriveds->size() = 1) result.newIsDerived := newIsDeriveds->any(true); |
| var newIsResolveProxieses := myCreateProperties.newIsResolveProxies->asSet()->excluding(null); |
| if (newIsResolveProxieses->size() > 1) log("Ambiguous newIsResolveProxies for ", self); |
| if (newIsResolveProxieses->size() = 1) result.newIsResolveProxies := newIsResolveProxieses->any(true); |
| var newIsTransients := myCreateProperties.newIsTransient->asSet()->excluding(null); |
| if (newIsTransients->size() > 1) log("Ambiguous newIsTransient for ", self); |
| if (newIsTransients->size() = 1) result.newIsTransient := newIsTransients->any(true); |
| var newIsUnsettables := myCreateProperties.newIsUnsettable->asSet()->excluding(null); |
| if (newIsUnsettables->size() > 1) log("Ambiguous newIsUnsettable for ", self); |
| if (newIsUnsettables->size() = 1) result.newIsUnsettable := newIsUnsettables->any(true); |
| var newIsVolatiles := myCreateProperties.newIsVolatile->asSet()->excluding(null); |
| if (newIsVolatiles->size() > 1) log("Ambiguous newIsVolatile for ", self); |
| if (newIsVolatiles->size() = 1) result.newIsVolatile := newIsVolatiles->any(true); |
| var newLowerBounds := myCreateProperties.newLowerBound->asSet()->excluding(null); |
| if (newLowerBounds->size() > 1) log("Ambiguous newLowerBound for ", self); |
| if (newLowerBounds->size() = 1) result.newLowerBound := newLowerBounds->max(); |
| result.oldProperties := myCreateProperties.oldProperties->asSet()->excluding(null); |
| } |