| /***************************************************************************** |
| * Copyright (c) 2013, 2016 CEA LIST. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation |
| *****************************************************************************/ |
| import org.eclipse.papyrus.interoperability.common.utils.UI; |
| import org.eclipse.papyrus.interoperability.common.utils.NotationTypes; |
| import libraries.EclipseUI; |
| import org.eclipse.papyrus.interoperability.rsa.RTMappings; |
| import org.eclipse.papyrus.interoperability.common.blackboxes.emf.EMFResource; |
| |
| modeltype notation "strict" uses 'http://www.eclipse.org/gmf/runtime/1.0.2/notation'; |
| modeltype umlNotation "strict" uses 'http://www.eclipse.org/papyrus/umlnotation'; |
| modeltype uml "strict" uses 'http://www.eclipse.org/uml2/5.0.0/UML'; |
| modeltype ecore "strict" uses 'http://www.eclipse.org/emf/2002/Ecore'; |
| modeltype sash "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/sashdi'; |
| modeltype config "strict" uses 'http:///RSAToPapyrusParameters.ecore'; |
| |
| /** |
| * Transformation rules for importing an RSA Semantic model into Papyrus (SashModel + cleanup semantics) |
| */ |
| transformation RSAModelToPapyrus(inout semantics : uml, inout graphics : notation, out di : sash, in param : config); |
| |
| |
| main() { |
| assert fatal (not semantics.rootObjects()[uml::Element]->isEmpty()) with log('Cannot find root uml::Element'); |
| |
| //semantics.objectsOfType(Element).map deleteSourceDiagrams(); //TODO programatically to clean up everything (Avoid memory leaks) |
| |
| if param.rootObjects()[Config]->any(true).convertOpaqueExpressionToLiteralString then |
| semantics.objectsOfType(OpaqueExpression).map convertToLiteralString() |
| endif; |
| |
| semantics.objectsOfType(OpaqueExpression).map fixLanguage(); |
| semantics.objectsOfType(Stereotype).map fixBaseProperties(); //Bug 492872: Multiplicity change between UML 2.3 (RSA) and 2.4+ (Papyrus) |
| } |
| |
| //If the OpaqueExpression doesn't have a language, and a single body, replace it with a LiteralString |
| mapping inout OpaqueExpression::convertToLiteralString() : LiteralString when { |
| (self.language->size() = 0 and self.body->size() <= 1) or |
| (self.language->size() = 1 and self.body->size() <= 1 and |
| self.language->at(1).isEmpty() |
| ) |
| } { |
| init { |
| result := self.map toLiteralString() //Blackbox cast: Transform OpaqueExpression to LiteralString (Preserve incoming references and compatible features) |
| } |
| |
| result.value := if self.body->size() = 0 then null else self.body->at(1) endif; |
| |
| self.oclAsType(EObject).forceDelete(true); //Destroy the source OpaqueExpression |
| worked(1); |
| } |
| |
| intermediate class Opaque { |
| language: String; |
| body: String; |
| } |
| |
| mapping inout OpaqueExpression::fixLanguage() when { |
| (self.language->size() > 1 or self.body->size() > 1) and |
| (self.language->exists(isEmpty()) or self.language.size() <> self.body.size()) |
| } { |
| //Replace empty languages by "Undefined" (In Papyrus, "Empty" is interpreted as "OCL", which is the default. This is not the case in RSA, where "Empty" means "Undefined") |
| |
| var maxSize : Integer := self.language->size().max(self.body->size()); |
| |
| var newLanguages : OrderedSet(Opaque) := OrderedSet{}; |
| var i : Integer = 1; |
| |
| while(i <= maxSize) { |
| var lang : String := self.language->at(i); |
| var body : String := self.body->at(i); |
| |
| var newLanguage := object Opaque{}; |
| newLanguage.language := if lang.oclIsInvalid() or lang.isEmpty() then 'Undefined' else lang endif; |
| newLanguage.body := if body.oclIsInvalid() or body.isEmpty() then '' else body endif; |
| |
| newLanguages += newLanguage; |
| |
| i := i+1; |
| }; |
| |
| self.language := newLanguages.language; |
| self.body := newLanguages.body; |
| } |
| |
| |
| //Bug 492872: Multiplicity change between UML 2.3 (RSA) and 2.4+ (Papyrus) |
| mapping inout Stereotype::fixBaseProperties() when { |
| self.baseProperties()->size() > 1 |
| }{ |
| self.baseProperties().map fixMultiplicity(); |
| } |
| |
| mapping inout Property::fixMultiplicity() { |
| if (not self.lowerValue.oclIsUndefined()) and self.lowerValue.oclIsKindOf(LiteralInteger) then |
| self.lowerValue.oclAsType(LiteralInteger).value := 0 |
| else |
| self.lowerValue := object LiteralInteger { |
| value := 0; |
| } |
| endif; |
| |
| if (not self.upperValue.oclIsUndefined()) and self.upperValue.oclIsKindOf(LiteralUnlimitedNatural) then |
| self.upperValue.oclAsType(LiteralUnlimitedNatural).value := 1 |
| elif (not self.upperValue.oclIsUndefined()) and self.upperValue.oclIsKindOf(LiteralInteger) then |
| self.upperValue.oclAsType(LiteralInteger).value := 1 |
| else |
| self.upperValue := object LiteralUnlimitedNatural { |
| value := 1; |
| } |
| endif; |
| } |
| |
| query String::isEmpty() : Boolean { |
| return self.oclIsUndefined() or self = ''; |
| } |
| |
| query Stereotype::baseProperties() : Set(Property){ |
| return self.ownedAttribute->select(p | p.name.startsWith("base_") and p.type.oclIsTypeOf(Class)) //Typed with a UML Metaclass |
| } |
| |