blob: 7a6b9251bce9b1c81c060440412c480730a84641 [file] [log] [blame]
/*******************************************************************************
* 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);
}