diff options
Diffstat (limited to 'extraplugins')
9 files changed, 783 insertions, 46 deletions
diff --git a/extraplugins/migration/org.eclipse.papyrus.migration.common/src/org/eclipse/papyrus/migration/common/transformation/AbstractImportTransformation.java b/extraplugins/migration/org.eclipse.papyrus.migration.common/src/org/eclipse/papyrus/migration/common/transformation/AbstractImportTransformation.java index e630d01bfe9..56af92d3078 100644 --- a/extraplugins/migration/org.eclipse.papyrus.migration.common/src/org/eclipse/papyrus/migration/common/transformation/AbstractImportTransformation.java +++ b/extraplugins/migration/org.eclipse.papyrus.migration.common/src/org/eclipse/papyrus/migration/common/transformation/AbstractImportTransformation.java @@ -809,4 +809,13 @@ public abstract class AbstractImportTransformation implements IImportTransformat values.remove(elementToDelete); } } + + /** + * + * @return + * the trace of the transformation + */ + protected Trace getTrace() { + return this.trace; + } } diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/META-INF/MANIFEST.MF b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/META-INF/MANIFEST.MF index 8b9434a8a7d..be17879bc15 100755 --- a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/META-INF/MANIFEST.MF +++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/META-INF/MANIFEST.MF @@ -38,7 +38,6 @@ Require-Bundle: org.eclipse.ui, org.eclipse.papyrus.views.properties;bundle-version="3.0.0", org.eclipse.papyrus.migration.common;bundle-version="0.7.0", org.eclipse.papyrus.m2m.qvto;bundle-version="1.4.0", - org.eclipse.papyrus.migration.rhapsody.blackboxes;bundle-version="0.7.0", org.eclipse.m2m.qvt.oml.runtime;bundle-version="3.7.0", org.eclipse.papyrus.sysml;bundle-version="1.2.0", org.eclipse.papyrus.migration.rhapsody.parser;bundle-version="0.7.0", @@ -57,4 +56,5 @@ Export-Package: org.eclipse.papyrus.migration.rhapsody, org.eclipse.papyrus.migration.rhapsody.messages, org.eclipse.papyrus.migration.rhapsody.transformations, org.eclipse.papyrus.migration.rhapsody.transformations.notation, - org.eclipse.papyrus.migration.rhapsody.utils + org.eclipse.papyrus.migration.rhapsody.utils, + org.eclipse.papyrus.migration.rhapsody.xmi diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/importer/utils/RpyUtil.java b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/importer/utils/RpyUtil.java index 8bd84357ea8..0b73e42f1df 100755 --- a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/importer/utils/RpyUtil.java +++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/importer/utils/RpyUtil.java @@ -44,32 +44,39 @@ import org.eclipse.xtext.nodemodel.util.NodeModelUtils; */ public class RpyUtil { - public static final Object RAW_CONTAINER_NAME = "IRPYRawContainer"; - public static final String RAW_CONTAINER_VALUE_FEATURE_NAME = "value"; - - private static final String ID_FEATURE_NAME = "_id"; - private static final String IHANDLE_NAME = "IHandle"; - private static final String ISUBSYSTEM_HANDLE_NAME = "ISubsystemHandle"; - private static final String INOBJECT_HANDLE_NAME ="INObjectHandle"; - private static final String ICLASSIFIER_HANDLE_NAME = "IClassifierHandle"; - - private static final String HANDLE_FILE_NAME_REF = "_filename"; - private static final String ELEMENT_FILE_NAME_REF = "fileName"; - private static final String ELEMENT_PERSIST_AT = "_persistAs"; - private static final String OWNER_HANDLE_FEATURE_NAME = "_ownerHandle"; - private static final String NAME_FEATURE_NAME = "_name"; - private static final String SUBSYSTEM_FEATURE_NAME="_subsystem"; - private static final String ISUBSYSTEM_NODE_NAME = "ISubsystem"; - private static final String CLASS_FEATURE_NAME = "_class"; - private static final String M2_CLASS_FEATURE_NAME = "_m2Class"; + public static final String GUID_STRING = "GUID"; //$NON-NLS-1$ + + public static final String OLDID_STRING = "OLDID"; //$NON-NLS-1$ + + public static final String ID_SEPARATOR = "-"; //$NON-NLS-1$ + + + public static final Object RAW_CONTAINER_NAME = "IRPYRawContainer"; //$NON-NLS-1$ + public static final String RAW_CONTAINER_VALUE_FEATURE_NAME = "value"; //$NON-NLS-1$ + + private static final String ID_FEATURE_NAME = "_id"; //$NON-NLS-1$ + private static final String IHANDLE_NAME = "IHandle"; //$NON-NLS-1$ + private static final String ISUBSYSTEM_HANDLE_NAME = "ISubsystemHandle"; //$NON-NLS-1$ + private static final String INOBJECT_HANDLE_NAME ="INObjectHandle"; //$NON-NLS-1$ + private static final String ICLASSIFIER_HANDLE_NAME = "IClassifierHandle"; //$NON-NLS-1$ + + private static final String HANDLE_FILE_NAME_REF = "_filename"; //$NON-NLS-1$ + private static final String ELEMENT_FILE_NAME_REF = "fileName"; //$NON-NLS-1$ + private static final String ELEMENT_PERSIST_AT = "_persistAs"; //$NON-NLS-1$ + private static final String OWNER_HANDLE_FEATURE_NAME = "_ownerHandle"; //$NON-NLS-1$ + private static final String NAME_FEATURE_NAME = "_name"; //$NON-NLS-1$ + private static final String SUBSYSTEM_FEATURE_NAME="_subsystem"; //$NON-NLS-1$ + private static final String ISUBSYSTEM_NODE_NAME = "ISubsystem"; //$NON-NLS-1$ + private static final String CLASS_FEATURE_NAME = "_class"; //$NON-NLS-1$ + private static final String M2_CLASS_FEATURE_NAME = "_m2Class"; //$NON-NLS-1$ public static List<String> SUPPORTED_EXTENSIONS = new ArrayList<String>(); public static Map<String, String> nodeTypeToExtensionMap = new HashMap<String, String>() ; - private static final String FILE_EXTENSION_PROPERTIES = "fileextension.properties"; - private static final String NULL_STRING = "NULL"; + private static final String FILE_EXTENSION_PROPERTIES = "fileextension.properties"; //$NON-NLS-1$ + private static final String NULL_STRING = "NULL"; //$NON-NLS-1$ - public static final String OWNED_ELEMENT_FEATURE_NAME = "graphElements"; - public static final String UNKNWON_CLASS_NAME = "UnknownType"; + public static final String OWNED_ELEMENT_FEATURE_NAME = "graphElements"; //$NON-NLS-1$ + public static final String UNKNWON_CLASS_NAME = "UnknownType"; //$NON-NLS-1$ static { Properties prop = new Properties(); @@ -81,7 +88,7 @@ public class RpyUtil { for (Map.Entry<Object, Object> entry: prop.entrySet()){ SUPPORTED_EXTENSIONS.add((String) entry.getKey()); String valueString = (String) entry.getValue(); - String[] valueTable = valueString.split(","); + String[] valueTable = valueString.split(","); //$NON-NLS-1$ for (String value : valueTable){ nodeTypeToExtensionMap.put(value, (String) entry.getKey()); } @@ -111,7 +118,7 @@ public class RpyUtil { * @return the feature of null if the path is incorrect */ public static RpyFeatureValue getFeatureValueFromPath(EObject context, String featurePath) { - String[] path = featurePath.split("."); + String[] path = featurePath.split("."); //$NON-NLS-1$ //TODO Implement it if needed @@ -178,17 +185,22 @@ public class RpyUtil { * @return */ public static String getStringValue(SimpleValueList value) { - if (!value.getValueElements().isEmpty()) { - - String ret = ""; + final StringBuilder builder = new StringBuilder(); + if(value.isIsGUID()) { + builder.append(GUID_STRING); + builder.append(ID_SEPARATOR); + } + if(value.isIsOldID()) { + builder.append(OLDID_STRING); + builder.append(ID_SEPARATOR); + } for (RpySimpleValueElement simpleValueElem : value.getValueElements()){ for (String val : simpleValueElem.getValues()){ - ret += val; + builder.append(val); } } - - return ret; + return builder.toString(); } return null; } @@ -223,7 +235,7 @@ public class RpyUtil { String nodeType = node.getName(); String extension = nodeTypeToExtensionMap.get(nodeType); if (extension != null){ - fileName +="."+extension; + fileName +="."+extension; //$NON-NLS-1$ return fileName; }else { Activator.log.error(NLS.bind(Messages.UnknownExtension, new String[]{nodeType, fileName, getNodeIndexInFile(node), node.eResource().getURI().toFileString()}), null); @@ -244,8 +256,8 @@ public class RpyUtil { private static String getPathStringInFeature(RpyNode node, String featurePath) { String stringValue = getNodeFeatureValueAsString(node, featurePath); - if (stringValue != null && stringValue.startsWith("\"")){ - stringValue = stringValue.replaceAll("\"", ""); + if (stringValue != null && stringValue.startsWith("\"")){ //$NON-NLS-1$ + stringValue = stringValue.replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$ } return stringValue; } @@ -277,7 +289,7 @@ public class RpyUtil { */ public static String getNodeIndexInFile(RpyNode node) { ICompositeNode xtextNode = NodeModelUtils.getNode(node); - String index ="-"; + String index ="-"; //$NON-NLS-1$ if (xtextNode != null){ index=Integer.toString(xtextNode.getStartLine()); } @@ -345,7 +357,7 @@ public class RpyUtil { String m2Class = getNodeFeatureValueAsString(handlerNode, M2_CLASS_FEATURE_NAME); if (m2Class != null){ RpyNode ret= RpySyntaxFactory.eINSTANCE.createRpyNode(); - ret.setName(m2Class.replaceAll("\"", "")); + ret.setName(m2Class.replaceAll("\"", "")); //$NON-NLS-1$ //$NON-NLS-2$ for (RpyFeature feature : getNodeFeatures(handlerNode)){ if (ID_FEATURE_NAME.equals(feature.getName()) || NAME_FEATURE_NAME.equals(feature.getName())){ ret.getContents().add(EcoreUtil.copy(feature)); diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/transformations/ImportTransformations.java b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/transformations/ImportTransformations.java index 833ea5bb0bf..efbd44cea10 100644 --- a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/transformations/ImportTransformations.java +++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/transformations/ImportTransformations.java @@ -53,11 +53,9 @@ import org.eclipse.m2m.qvt.oml.util.Trace; import org.eclipse.m2m.qvt.oml.util.WriterLog; import org.eclipse.papyrus.infra.emf.utils.EMFHelper; import org.eclipse.papyrus.infra.tools.util.ListHelper; -import org.eclipse.papyrus.m2m.qvto.TransformationUI; import org.eclipse.papyrus.migration.common.concurrent.ExecutorsPool; import org.eclipse.papyrus.migration.common.concurrent.ResourceAccessHelper; import org.eclipse.papyrus.migration.rhapsody.Activator; -import org.eclipse.papyrus.migration.rhapsody.blackboxes.Rhapsody2PapyrusNotationBlackboxes; import org.eclipse.uml2.uml.resource.UMLResource; import org.eclipse.uml2.uml.util.UMLUtil; @@ -146,7 +144,9 @@ public class ImportTransformations { // Collection<URI> transformations = getSemanticTransformationURI(); for (URI transformationURI : transformations) { - TransformationExecutor.BlackboxRegistry.INSTANCE.registerModules(Rhapsody2PapyrusNotationBlackboxes.class); + +// TransformationExecutor.BlackboxRegistry.INSTANCE.registerModules(Rhapsody2PapyrusNotationBlackboxes.class); + TransformationExecutor executor = new TransformationExecutor(transformationURI); ExecutionDiagnostic resultTransdo = executor.execute(context, extents.toArray(new ModelExtent[0])); result = createStatusFromDiagnostic(resultTransdo); diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/transformations/RhapsodyImportTransformation.java b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/transformations/RhapsodyImportTransformation.java index c746ea42046..9ec4b499c11 100644 --- a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/transformations/RhapsodyImportTransformation.java +++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/transformations/RhapsodyImportTransformation.java @@ -35,6 +35,7 @@ import org.eclipse.gmf.runtime.emf.core.resources.GMFResource; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.Style; import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.m2m.internal.qvt.oml.library.Context; import org.eclipse.m2m.qvt.oml.BasicModelExtent; import org.eclipse.m2m.qvt.oml.ExecutionContextImpl; import org.eclipse.m2m.qvt.oml.ModelExtent; @@ -47,6 +48,7 @@ import org.eclipse.papyrus.migration.common.concurrent.ResourceAccessHelper; import org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation; import org.eclipse.papyrus.migration.common.transformation.IDependencyAnalysisHelper; import org.eclipse.papyrus.migration.rhapsody.Activator; +import org.eclipse.papyrus.migration.rhapsody.xmi.PreserveRhapsodySemanticIDHelper; import org.eclipse.papyrus.uml.internationalization.utils.UMLInternationalizationKeyResolver; import org.eclipse.uml2.uml.resource.UMLResource; @@ -127,7 +129,7 @@ public class RhapsodyImportTransformation extends AbstractImportTransformation { // TODO : warning, this step is not in RSA monitor.subTask("Importing semantic model..."); URI semanticTransformationURI = getSemanticTransformationURI(); - if(null!=semanticTransformationURI){ + if (null != semanticTransformationURI) { result = runTransformation(semanticTransformationURI, extents, monitor); generationStatus.add(result); } @@ -168,7 +170,7 @@ public class RhapsodyImportTransformation extends AbstractImportTransformation { long endExtensionsAfter = System.nanoTime(); this.importExtensionsTime += endExtensionsAfter - startExtensionsAfter; } finally { - context = null; + // context = null; } // @@ -199,6 +201,11 @@ public class RhapsodyImportTransformation extends AbstractImportTransformation { List<EObject> outUMLObjects = getInOutUMLModel().getContents(); umlResource.getContents().addAll(outUMLObjects); + PreserveRhapsodySemanticIDHelper helper = new PreserveRhapsodySemanticIDHelper(new Context(context)); + helper.keepIdForUMLResource((XMIResource) this.umlResource); + + context = null; + GMFResource notationResource = new GMFResource(notationModelURI); // GMF Resource content type? resourceSet.getResources().add(notationResource); List<EObject> outNotationObjects = getInoutNotationModel().getContents(); @@ -407,19 +414,19 @@ public class RhapsodyImportTransformation extends AbstractImportTransformation { protected Collection<URI> getAllTransformationURIs() { final Collection<URI> allTransformations = new ArrayList<URI>(); final URI semanticTransformationURI = getSemanticTransformationURI(); - if(null!=semanticTransformationURI){ + if (null != semanticTransformationURI) { allTransformations.add(semanticTransformationURI); } final Collection<URI> diagramTransformationURI = getDiagramTransformationURIs(); - if(null!=diagramTransformationURI){ + if (null != diagramTransformationURI) { allTransformations.addAll(diagramTransformationURI); } final Collection<URI> profilesTransformationURI = getProfilesTransformationURI(); - if(null!=profilesTransformationURI){ + if (null != profilesTransformationURI) { allTransformations.addAll(profilesTransformationURI); } final Collection<URI> additionalTransformationURIs = getAdditionalTransformationURIs(); - if(null!=additionalTransformationURIs){ + if (null != additionalTransformationURIs) { allTransformations.addAll(additionalTransformationURIs); } return allTransformations; diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/EMF_XMI_ID_Helper.java b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/EMF_XMI_ID_Helper.java new file mode 100755 index 00000000000..db59933ec27 --- /dev/null +++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/EMF_XMI_ID_Helper.java @@ -0,0 +1,92 @@ +/***************************************************************************** + * Copyright (c) 2017 CEA LIST and others. + * + * 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: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.migration.rhapsody.xmi; + +import org.eclipse.emf.ecore.EAnnotation; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl; +import org.eclipse.papyrus.migration.rhapsody.importer.utils.RpyUtil; + +/** + * @author VL222926 + * This helper allows to build XMI_ID for EMF objects + */ +public class EMF_XMI_ID_Helper { + + + /** + * + * @param eobject + * an element + * @return + * the calculated XMI_ID for the given element, value can be <code>null</code> + */ + public static final String calculateIdForEMF(final EObject eobject) { + String result = null; + if (eobject instanceof EAnnotation) { + result = calculateId((EAnnotation) eobject); + } else if (eobject instanceof EStringToStringMapEntryImpl) { + result = calculateId((EStringToStringMapEntryImpl) eobject); + } + return result; + } + + /** + * + * @param eannotation + * an eannotation + * @return + * the ID calculated for it + */ + public static final String calculateId(final EAnnotation eannotation) { + final EObject parent = eannotation.eContainer(); + StringBuilder builder = new StringBuilder(); + if (null != parent) { + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + builder.append(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(eannotation.eClass().getName()); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(eannotation.getSource().hashCode()); + } else { + builder = new StringBuilder(); + } + return builder.toString(); + } + + /** + * + * @param map + * a map + * @return + * the ID calculated for it + */ + public static final String calculateId(final EStringToStringMapEntryImpl map) { + final EObject parent = map.eContainer(); + StringBuilder builder = new StringBuilder(); + if (null != parent) { + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + builder.append(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(map.eClass().getName()); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(map.getKey().hashCode()); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(map.getValue().hashCode()); + } else { + builder = new StringBuilder(); + } + return builder.toString(); + } +} diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/PreserveRhapsodySemanticIDHelper.java b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/PreserveRhapsodySemanticIDHelper.java new file mode 100755 index 00000000000..a4745fa49a9 --- /dev/null +++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/PreserveRhapsodySemanticIDHelper.java @@ -0,0 +1,177 @@ +/***************************************************************************** + * Copyright (c) 2017 CEA LIST and others. + * + * 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: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.migration.rhapsody.xmi; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.xmi.XMIResource; +import org.eclipse.m2m.internal.qvt.oml.library.Context; +import org.eclipse.papyrus.m2m.qvto.TraceHelper; +import org.eclipse.papyrus.migration.rhapsody.importer.utils.RpyUtil; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * @author VL222926 + * + * This class allows to reuse Rhapsody id when possible end and calls helper to generate "standart" XMI_ID when we can't reuse Rhapsody ones. + * + */ +public class PreserveRhapsodySemanticIDHelper { + + /** + * The context of the QVTo transformation + */ + @SuppressWarnings("restriction") + private Context context; + + /** + * the name of the feature representing the Rhapsody ID + */ + private static final String ID_FEATURE_NAME = "id"; //$NON-NLS-1$ + /** + * The helper to use to manipulate QVTo trace + */ + private TraceHelper helper = new TraceHelper(); + + /** + * + * Constructor. + * + * @param context + * the context of the QVTo transformation + */ + public PreserveRhapsodySemanticIDHelper(@SuppressWarnings("restriction") final Context context) { + this.context = context; + } + + public void keepIdForUMLResource(final XMIResource res) { + + // a set owning the known id to avoid duplicate + final Set<String> knownIds = new HashSet<String>(); + + // the object to manage in the second run + final List<EObject> eobjectForSecondRun = new ArrayList<>(); + + // we mainly set the stereotype application in this list + final List<EObject> eobjectForThirdRun = new ArrayList<>(); + + // we iterate on all elements of the UML model + final TreeIterator<EObject> iter = res.getAllContents(); + while (iter.hasNext()) { + final EObject current = iter.next(); + if (isStereotypeApplication(current)) { + eobjectForThirdRun.add(current); + continue; + } + if (requiredToBeManagedInASecondRun(current)) { + eobjectForSecondRun.add(current); + continue; + } + + + // looking for the Rhapsody object in the QVto trace + final Object result = helper.traceFrom(context, current, null); + String rpyId = getRhapsodyId(result); + + if (isValidId(rpyId) && false == knownIds.contains(rpyId)) { + knownIds.add(rpyId); + res.setID(current, rpyId); + } else { + eobjectForSecondRun.add(current); + } + } + + // second run (duplicated and null id in the first run) + for (final EObject current : eobjectForSecondRun) { + final String value = XMI_ID_Helper.calculateXMI_ID(current); + if (isValidId(value) && false == knownIds.contains(value)) { + knownIds.add(value); + res.setID(current, value); + } else { + System.out.println("It is not possible to found an id for " + current.toString()); //$NON-NLS-1$ + } + } + + // third run (stereotype) + for (final EObject current : eobjectForThirdRun) { + final String value = XMI_ID_Helper.calculateXMI_ID(current); + if (isValidId(value) && false == knownIds.contains(value)) { + knownIds.add(value); + res.setID(current, value); + } else { + System.out.println("It is not possible to found an id for " + current.toString()); //$NON-NLS-1$ + } + } + } + + /** + * + * @param eobject + * an eobject + * @return + * <code>true</code> if the object must be manage during the second run + */ + protected boolean requiredToBeManagedInASecondRun(final EObject eobject) { + return eobject instanceof ConnectorEnd; + } + + /** + * + * @param object + * a rhapsody object + * @return + * the id of this object or <code>null</code> if not found + */ + protected String getRhapsodyId(final Object object) { + if (object instanceof EObject) { + final EObject eobject = (EObject) object; + final EStructuralFeature idFeature = eobject.eClass().getEStructuralFeature(ID_FEATURE_NAME); + if (null != idFeature) { + final String value = (String) eobject.eGet(idFeature); + return value; + } + } + return null; + } + + /** + * + * @param eobject + * an eobject + * @return + * <code>true</code> when the element represents a stereotype application + */ + protected boolean isStereotypeApplication(final EObject eobject) { + return null != UMLUtil.getBaseElement(eobject); + } + + /** + * + * @param id + * an id + * @return + * <code>true</code> when the string represents a valid id : so it must contains GUID or OLDID + */ + public static final boolean isValidId(final String id) { + return null != id && (id.contains(RpyUtil.GUID_STRING) || id.contains(RpyUtil.OLDID_STRING)); + } + +} diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/UML_XMI_ID_Helper.java b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/UML_XMI_ID_Helper.java new file mode 100755 index 00000000000..4b9498174d9 --- /dev/null +++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/UML_XMI_ID_Helper.java @@ -0,0 +1,381 @@ +/***************************************************************************** + * Copyright (c) 2017 CEA LIST and others. + * + * 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: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.migration.rhapsody.xmi; + +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrus.migration.rhapsody.importer.utils.RpyUtil; +import org.eclipse.uml2.uml.Association; +import org.eclipse.uml2.uml.Comment; +import org.eclipse.uml2.uml.Connector; +import org.eclipse.uml2.uml.ConnectorEnd; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.InstanceValue; +import org.eclipse.uml2.uml.OpaqueExpression; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.PackageImport; +import org.eclipse.uml2.uml.ProfileApplication; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.TemplateBinding; +import org.eclipse.uml2.uml.TemplateParameterSubstitution; +import org.eclipse.uml2.uml.TemplateableElement; +import org.eclipse.uml2.uml.UMLPackage; +import org.eclipse.uml2.uml.ValueSpecification; +import org.eclipse.uml2.uml.util.UMLUtil; + +/** + * @author VL222926 + * This class allows to generate XMI_ID to use for UML element + */ +public class UML_XMI_ID_Helper { + + private static final String PROPERTY_OF_ASSOCIATION__OTHER_END = "-other-end"; //$NON-NLS-1$ + + private static final String ASSOCIATION = "-association"; //$NON-NLS-1$ + + private static final String CONNECTOR_END = "end"; //$NON-NLS-1$ + + public static final String VALUE_SPECIFICATION__LOWER_VALUE = "multiplicity-lower-value"; //$NON-NLS-1$ + + public static final String VALUE_SPECIFICATION__UPPER_VALUE = "multiplicity-upper-value"; //$NON-NLS-1$ + + public static final String MODEL_ELEMENT_OWNED_COMMENT = "modelElement-ownedComment"; //$NON-NLS-1$ + + public static final String OF = "of"; //$NON-NLS-1$ + + /** + * + * @param element + * an element + * @return + * the calculated XMI_ID for the given element, value can be <code>null</code> + */ + public static final String calculateIdForUML(EObject element) { + String result = null; + if (element instanceof Element) { + // it is a UML Element + result = calculateIdForUML((Element) element); + } else if (element instanceof EObject) { + // we check if it is a Stereotype Application + Element baseElement = UMLUtil.getBaseElement(element); + if (null != baseElement) { + result = calculateIDForStereotypeApplication(element, baseElement); + } else { + result = EMF_XMI_ID_Helper.calculateIdForEMF(element); + } + } + return result; + } + + /** + * + * @param element + * an element + * @return + * the ID calculated for this element + */ + private static final String calculateIdForUML(final Element element) { + String returnedValue = null; + if(element instanceof OpaqueExpression) { + returnedValue = calculateId((OpaqueExpression) element); + }else if(element instanceof InstanceValue) { + returnedValue = calculateId((InstanceValue) element); + }else if(element instanceof Comment) { + returnedValue = calculateId((Comment) element); + }else if (element instanceof Package) { + returnedValue = calculateId((Package) element); + } else if (element instanceof Property) { + returnedValue = calculateId((Property) element); + } else if (element instanceof Association) { + returnedValue = calculateId((Association) element); + } else if (element instanceof TemplateBinding) { + returnedValue = calculateId((TemplateBinding) element); + } else if (element instanceof TemplateParameterSubstitution) { + returnedValue = calculateId((TemplateParameterSubstitution) element); + } else if (element instanceof ConnectorEnd) { + returnedValue = calculateId((ConnectorEnd) element); + } else if (element instanceof ValueSpecification) { + returnedValue = calculateId((ValueSpecification) element); + } else if (element instanceof PackageImport) { + returnedValue = calculateId((PackageImport) element); + } else if (element instanceof ProfileApplication) { + returnedValue = calculateId((ProfileApplication) element); + } else { + // Activator.log.warn(NLS.bind("The element of type {0} has no ID and is not yet managed", element.eClass())); //$NON-NLS-1$ + } + return returnedValue; + } + + /** + * + * @param comment + * a comment + * @return + * the ID calculated for it + */ + public static final String calculateId(Comment comment) { + final Element owner = comment.getOwner(); + final String parentId = XMI_ID_Helper.getXMI_ID(owner); + final StringBuilder builder = new StringBuilder(parentId); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(MODEL_ELEMENT_OWNED_COMMENT); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(getIndexToUseToBuildXMI_ID(owner.getOwnedComments(), comment)); + return builder.toString(); + } + + /** + * + * @param pack + * a package + * @return + * the ID calculated for it + */ + public static final String calculateId(final Package pack) { // use for the package created by the transformation (like this one for user type declaration) + final Element parent = pack.getOwner(); + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + final StringBuilder builder = new StringBuilder(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(pack.eClass().getName()); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(pack.getQualifiedName()); + return builder.toString(); + } + + /** + * + * @param property + * a property + * @return + * the ID calculated for it + */ + public static final String calculateId(final Property property) { + final Association association = property.getAssociation(); + final List<Property> ends = association.getMemberEnds(); + final StringBuilder builder = new StringBuilder(); + for (final Property current : ends) { + if (current != property) { + builder.append(XMI_ID_Helper.getXMI_ID(current)); + builder.append(PROPERTY_OF_ASSOCIATION__OTHER_END); + if (ends.size() > 2) { + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(getIndexToUseToBuildXMI_ID(ends, current)); + } + break; + } + } + + return builder.toString(); + } + + /** + * + * @param association + * an association + * @return + * the ID calculated for it + */ + public static final String calculateId(final Association association) { + final List<Property> ends = association.getMemberEnds(); + final StringBuilder builder = new StringBuilder(); + for (final Property current : ends) { + if (current.eContainer() != association) { + builder.append(XMI_ID_Helper.getXMI_ID(current)); + builder.append(ASSOCIATION); + if (ends.size() > 2) { + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(getIndexToUseToBuildXMI_ID(ends, current)); + } + break; + } + } + return builder.toString(); + } + + /** + * + * @param templateBinding + * a templateBinding + * @return + * the ID calculated for it + */ + public static final String calculateId(final TemplateBinding templateBinding) { + final TemplateableElement parent = (TemplateableElement) templateBinding.getOwner(); + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + final StringBuilder builder = new StringBuilder(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(templateBinding.eClass().getName()); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(getIndexToUseToBuildXMI_ID(parent.getTemplateBindings(), templateBinding)); + return builder.toString(); + } + + /** + * + * @param templateBindingSubsitution + * a templateBindingSubsitution + * @return + * the ID calculated for it + */ + public static final String calculateId(final TemplateParameterSubstitution templateBindingSubsitution) { + final TemplateBinding parent = templateBindingSubsitution.getTemplateBinding(); + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + final StringBuilder builder = new StringBuilder(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(templateBindingSubsitution.eClass().getName()); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(getIndexToUseToBuildXMI_ID(parent.getParameterSubstitutions(), templateBindingSubsitution)); + return builder.toString(); + } + + /** + * + * @param connectorEnd + * a connectorEnd + * @return + * the ID calculated for it + */ + public static final String calculateId(ConnectorEnd connectorEnd) { + final Connector owner = (Connector) connectorEnd.getOwner(); + final String parentId = XMI_ID_Helper.getXMI_ID(owner); + final StringBuilder builder = new StringBuilder(parentId); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(CONNECTOR_END); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(getIndexToUseToBuildXMI_ID(owner.getEnds(), connectorEnd)); + return builder.toString(); + } + + /** + * + * @param list + * a list + * @param anEObject + * an eobejct + * @return + * the index of the object to use to build the XMI_ID + */ + protected static final int getIndexToUseToBuildXMI_ID(final List<? extends EObject> list, final EObject anEObject) { + return list.indexOf(anEObject) + 1; // +1 to match with an import previously existing at our initial partner and to ease model comparison + } + + /** + * + * @param valueSpec + * a valueSpec + * @return + * the ID calculated for it + */ + public static final String calculateId(final ValueSpecification valueSpec) { + StringBuilder builder = new StringBuilder(XMI_ID_Helper.getXMI_ID(valueSpec.eContainer())); + builder.append(RpyUtil.ID_SEPARATOR); + if (valueSpec instanceof ValueSpecification && valueSpec.eContainingFeature() == UMLPackage.eINSTANCE.getMultiplicityElement_LowerValue()) { + builder.append(VALUE_SPECIFICATION__LOWER_VALUE); + } else if (valueSpec instanceof ValueSpecification && valueSpec.eContainingFeature() == UMLPackage.eINSTANCE.getMultiplicityElement_UpperValue()) { + builder.append(VALUE_SPECIFICATION__UPPER_VALUE); + } else { + builder = new StringBuilder(); // no idea ? + } + return builder.toString(); + } + + /** + * + * @param packageImport + * a packageImport + * @return + * the ID calculated for it + */ + public static final String calculateId(final PackageImport packageImport) { + final EObject parent = packageImport.eContainer(); + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + final StringBuilder builder = new StringBuilder(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(packageImport.eClass().getName()); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(((PackageImport) packageImport).getImportedPackage().getQualifiedName()); + return builder.toString(); + } + + /** + * + * @param profileApplication + * a profileApplication + * @return + * the ID calculated for it + */ + public static final String calculateId(final ProfileApplication profileApplication) { + final EObject parent = profileApplication.eContainer(); + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + final StringBuilder builder = new StringBuilder(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(profileApplication.eClass().getName()); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(((ProfileApplication) profileApplication).getAppliedProfile().getQualifiedName()); + return builder.toString(); + } + + + /** + * + * @param eobject + * an eobject representing a stereotype application + * @return + * the calculated XMI_ID for the given element + */ + private static final String calculateIDForStereotypeApplication(final EObject stereotypeApplication, final Element baseElement) { + final StringBuilder builder = new StringBuilder(); + String baseElementId = XMI_ID_Helper.getXMI_ID(baseElement); + String eClassName = stereotypeApplication.eClass().getName(); + builder.append(eClassName); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(OF); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(baseElementId); + return builder.toString(); + } + + /** + * + * @param eobject + * an eobject representing a stereotype application + * @return + * the calculated XMI_ID for the given element + */ + private static final String calculateId(final OpaqueExpression opaqueExpression) { + final EObject parent = opaqueExpression.eContainer(); + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + final StringBuilder builder = new StringBuilder(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(opaqueExpression.eClass().getName()); + return builder.toString(); + } + + /** + * + * @param eobject + * an eobject representing a stereotype application + * @return + * the calculated XMI_ID for the given element + */ + private static final String calculateId(final InstanceValue instanceValue) { + final EObject parent = instanceValue.eContainer(); + final String parentID = XMI_ID_Helper.getXMI_ID(parent); + final StringBuilder builder = new StringBuilder(parentID); + builder.append(RpyUtil.ID_SEPARATOR); + builder.append(instanceValue.eClass().getName()); + return builder.toString(); + } +} diff --git a/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/XMI_ID_Helper.java b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/XMI_ID_Helper.java new file mode 100755 index 00000000000..0028be0b873 --- /dev/null +++ b/extraplugins/migration/rhapsody/org.eclipse.papyrus.migration.rhapsody/src/org/eclipse/papyrus/migration/rhapsody/xmi/XMI_ID_Helper.java @@ -0,0 +1,59 @@ +/***************************************************************************** + * Copyright (c) 2017 CEA LIST and others. + * + * 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: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.migration.rhapsody.xmi; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.xmi.XMIResource; +import org.eclipse.osgi.util.NLS; +import org.eclipse.papyrus.migration.rhapsody.Activator; + +/** + * This class is used to calculate XMI_ID + * + */ +public class XMI_ID_Helper { + + /** + * This method calculate an XMI ID for element. The goal of this method is to generate unique XMI_ID for element which doesn't exist in Rhapsody and there is not + * + * @param element + * an element + * @return + * the XMI_ID to use for the element + */ + public static final String calculateXMI_ID(final EObject element) { + String result = UML_XMI_ID_Helper.calculateIdForUML(element); +// if (result!=null && !result.contains(RpyUtil.GUID_STRING) && !result.contains(RpyUtil.OLDID_STRING)) { +// Activator.log.warn(NLS.bind("The ID built for an element of type {0} doesn't contains \"GUID\" neither \"OLDID\" strings.", element.eClass())); //$NON-NLS-1$ +// } + return result; + } + + /** + * + * @param eobject + * an eobject + * @return + * the current XMI_ID for this object + */ + public static final String getXMI_ID(final EObject eobject) { + final Resource res = eobject.eResource(); + if (res instanceof XMIResource) { + return ((XMIResource) res).getID(eobject); + } + Activator.log.error(NLS.bind("The resource of {0} is not a XMIResource", eobject), null); //$NON-NLS-1$ + return null; + } +} |