blob: 6f787f03f461d27fee531b9b21c9823851f5218c [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2019 CEA LIST, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.interoperability.sysml16.sysml14.xmi.helper;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.gmf.runtime.notation.Bendpoints;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Connector;
import org.eclipse.gmf.runtime.notation.DecorationNode;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.IdentityAnchor;
import org.eclipse.gmf.runtime.notation.Location;
import org.eclipse.gmf.runtime.notation.Shape;
import org.eclipse.gmf.runtime.notation.StringValueStyle;
import org.eclipse.gmf.runtime.notation.Style;
import org.eclipse.papyrus.infra.viewpoints.style.PapyrusViewStyle;
/**
* This class defines the needed methods to preserve or create the Notation XMI identifiers.
*/
@SuppressWarnings("deprecation")
public class NotationXMIIDHelper {
/**
* The diagram compatibility version identifier.
*/
private static final String DIAGRAM_COMPATIBILITY_VERSION = "diagram_compatibility_version"; //$NON-NLS-1$
/**
* The Bendpoints identifier.
*/
private static final String BENDPOINTS = "bendpoints"; //$NON-NLS-1$
/**
* The Bounds identifier.
*/
private static final String BOUNDS = "bounds"; //$NON-NLS-1$
/**
* The Connector identifier.
*/
private static final String CONNECTOR = "connector"; //$NON-NLS-1$
/**
* The IdentityAnchor identifier.
*/
private static final String IDENTITY_ANCHOR = "identityAnchor"; //$NON-NLS-1$
/**
* The Location identifier.
*/
private static final String LOCATION = "location"; //$NON-NLS-1$
/**
* The PapyrusViewStyle identifier.
*/
private static final String PAPYRUS_VIEW_STYLE = "papyrusViewStyle"; //$NON-NLS-1$
/**
* The Shape identifier.
*/
private static final String SHAPE = "shape"; //$NON-NLS-1$
/**
* The 'from' separator in identifier.
*/
private static final String FROM = "_from_"; //$NON-NLS-1$
/**
* The 'Of' separator in identifier.
*/
private static final String OF = "_Of_"; //$NON-NLS-1$
/**
* The 'to' separator in identifier.
*/
private static final String TO = "_to_"; //$NON-NLS-1$
/**
* The underscore separator.
*/
private static final String UNDERSCORE = "_"; //$NON-NLS-1$
/**
* This allows to calculate the identifiers of created Notation elements.
*
* @param res
* The Notation Resource.
* @param current
* The object to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateNeededId(final XMIResource res, final Object current, final Map<EObject, String> oldIds) {
if (current instanceof DecorationNode) {
calculateDecorationNode(res, (DecorationNode) current, oldIds);
} else if (current instanceof Diagram) {
calculateDiagram(res, (Diagram) current, oldIds);
} else if (current instanceof Style) {
calculateStyle(res, (Style) current, oldIds);
} else if (current instanceof Bounds) {
calculateBounds(res, (Bounds) current, oldIds);
} else if (current instanceof Location) {
calculateLocation(res, (Location) current, oldIds);
} else if (current instanceof EAnnotation) {
calculateEAnnotation(res, (EAnnotation) current, oldIds);
} else if (current instanceof Bendpoints) {
calculateBendpoints(res, (Bendpoints) current, oldIds);
} else if (current instanceof IdentityAnchor) {
calculateIdentityAnchor(res, (IdentityAnchor) current, oldIds);
}
}
/**
* This allows to calculate the identifiers of created DecorationNode.
*
* @param res
* The Notation Resource.
* @param decorationNode
* The DecorationNode to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateDecorationNode(final XMIResource res, final DecorationNode decorationNode, final Map<EObject, String> oldIds) {
if (!oldIds.containsKey(decorationNode)) {
final String containerID = ((XMIResource) decorationNode.eContainer().eResource()).getID(decorationNode.eContainer());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(decorationNode.getType());
stringBuilder.append(OF);
stringBuilder.append(containerID);
// Manage the existing connector id with incremental suffix item if needed
stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);
res.setID(decorationNode, stringBuilder.toString());
oldIds.put(decorationNode, stringBuilder.toString());
}
}
/**
* This allows to calculate the identifiers of converted Diagram.
*
* @param res
* The Notation Resource.
* @param diagram
* The Diagram to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateDiagram(final XMIResource res, final Diagram diagram, final Map<EObject, String> oldIds) {
StringValueStyle compatibilityVersion = null;
Set<PapyrusViewStyle> papyrusViewStyles = new HashSet<>();
@SuppressWarnings("unchecked")
final Iterator<EObject> styles = diagram.getStyles().iterator();
while (styles.hasNext()) {
final EObject style = styles.next();
if (style instanceof PapyrusViewStyle) {
papyrusViewStyles.add((PapyrusViewStyle) style);
} else if (style instanceof StringValueStyle && ((StringValueStyle) style).getName().equals("diagram_compatibility_version")) {
compatibilityVersion = (StringValueStyle) style;
}
}
final String diagramID = ((XMIResource) diagram.eResource()).getID(diagram);
if (null != compatibilityVersion && !oldIds.containsKey(compatibilityVersion)) {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(DIAGRAM_COMPATIBILITY_VERSION);
stringBuilder.append(OF);
stringBuilder.append(diagramID);
res.setID(compatibilityVersion, stringBuilder.toString());
oldIds.put(compatibilityVersion, stringBuilder.toString());
}
for (final PapyrusViewStyle papyrusViewStyle : papyrusViewStyles) {
if (!oldIds.containsKey(papyrusViewStyle)) {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(PAPYRUS_VIEW_STYLE);
stringBuilder.append(((XMIResource) papyrusViewStyle.getOwner().eResource()).getID(papyrusViewStyle.getOwner()));
stringBuilder.append(OF);
stringBuilder.append(diagramID);
res.setID(papyrusViewStyle, stringBuilder.toString());
oldIds.put(papyrusViewStyle, stringBuilder.toString());
}
}
}
/**
* This allows to calculate the identifiers of created Style.
*
* @param res
* The Notation Resource.
* @param style
* The Style to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateStyle(final XMIResource res, final Style style, final Map<EObject, String> oldIds) {
if (!oldIds.containsKey(style)) {
final String containerID = ((XMIResource) style.eContainer().eResource()).getID(style.eContainer());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(style.eClass().getName());
stringBuilder.append(OF);
stringBuilder.append(containerID);
// Manage the existing connector id with incremental suffix item if needed
stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);
res.setID(style, stringBuilder.toString());
oldIds.put(style, stringBuilder.toString());
}
}
/**
* This allows to calculate the identifiers of created Bounds.
*
* @param res
* The Notation Resource.
* @param bounds
* The Bounds to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateBounds(final XMIResource res, final Bounds bounds, final Map<EObject, String> oldIds) {
if (!oldIds.containsKey(bounds)) {
final String containerID = ((XMIResource) bounds.eContainer().eResource()).getID(bounds.eContainer());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(BOUNDS);
stringBuilder.append(OF);
stringBuilder.append(containerID);
// Manage the existing connector id with incremental suffix item if needed
stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);
res.setID(bounds, stringBuilder.toString());
oldIds.put(bounds, stringBuilder.toString());
}
}
/**
* This allows to calculate the identifiers of created Location.
*
* @param res
* The Notation Resource.
* @param location
* The Location to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateLocation(final XMIResource res, final Location location, final Map<EObject, String> oldIds) {
if (!oldIds.containsKey(location)) {
final String containerID = ((XMIResource) location.eContainer().eResource()).getID(location.eContainer());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(LOCATION);
stringBuilder.append(OF);
stringBuilder.append(containerID);
// Manage the existing connector id with incremental suffix item if needed
stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);
res.setID(location, stringBuilder.toString());
oldIds.put(location, stringBuilder.toString());
}
}
/**
* This allows to calculate the identifiers of created EAnnotation and details.
*
* @param res
* The Notation Resource.
* @param eAnnotation
* The EAnnotation to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateEAnnotation(final XMIResource res, final EAnnotation eAnnotation, final Map<EObject, String> oldIds) {
final String containerID = ((XMIResource) eAnnotation.eContainer().eResource()).getID(eAnnotation.eContainer());
String eAnnotationID = null;
if (!oldIds.containsKey(eAnnotation)) {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(eAnnotation.getSource());
stringBuilder.append(OF);
stringBuilder.append(containerID);
eAnnotationID = stringBuilder.toString();
res.setID(eAnnotation, eAnnotationID);
oldIds.put(eAnnotation, eAnnotationID);
} else {
eAnnotationID = oldIds.get(eAnnotation);
}
for (final Entry<String, String> detail : eAnnotation.getDetails()) {
if (detail instanceof EStringToStringMapEntryImpl && !oldIds.containsKey((EStringToStringMapEntryImpl) detail)) {
final StringBuilder eAnnotationStringBuilder = new StringBuilder();
eAnnotationStringBuilder.append(detail.getKey());
eAnnotationStringBuilder.append(OF);
eAnnotationStringBuilder.append(eAnnotationID);
res.setID((EStringToStringMapEntryImpl) detail, eAnnotationStringBuilder.toString());
oldIds.put((EStringToStringMapEntryImpl) detail, eAnnotationStringBuilder.toString());
}
}
}
/**
* This allows to calculate the identifiers of created Shape.
*
* @param res
* The Notation Resource.
* @param shape
* The Shape to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateShape(final XMIResource res, final Shape shape, final Map<EObject, String> oldIds) {
if (!oldIds.containsKey(shape)) {
final String elementID = ((XMIResource) shape.getElement().eResource()).getID(shape.getElement());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(SHAPE);
stringBuilder.append(OF);
stringBuilder.append(elementID);
// Manage the existing shape id with incremental suffix item if needed
stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);
res.setID(shape, stringBuilder.toString());
oldIds.put(shape, stringBuilder.toString());
}
}
/**
* This allows to calculate the identifiers of created Connector.
*
* @param res
* The Notation Resource.
* @param connector
* The Connector to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateConnector(final XMIResource res, final Connector connector, final Map<EObject, String> oldIds) {
if (!oldIds.containsKey(connector)) {
final String sourceID = ((XMIResource) connector.getSource().eResource()).getID(connector.getSource());
final String targetID = ((XMIResource) connector.getTarget().eResource()).getID(connector.getTarget());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(CONNECTOR);
stringBuilder.append(FROM);
stringBuilder.append(sourceID);
stringBuilder.append(TO);
stringBuilder.append(targetID);
// Manage the existing connector id with incremental suffix item if needed
stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);
res.setID(connector, stringBuilder.toString());
oldIds.put(connector, stringBuilder.toString());
}
}
/**
* This allows to calculate the identifiers of created Bendpoints.
*
* @param res
* The Notation Resource.
* @param bendpoints
* The Bendpoints to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateBendpoints(final XMIResource res, final Bendpoints bendpoints, final Map<EObject, String> oldIds) {
if (!oldIds.containsKey(bendpoints)) {
final String elementID = ((XMIResource) bendpoints.eContainer().eResource()).getID(bendpoints.eContainer());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(BENDPOINTS);
stringBuilder.append(OF);
stringBuilder.append(elementID);
// Manage the existing connector id with incremental suffix item if needed
stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);
res.setID(bendpoints, stringBuilder.toString());
oldIds.put(bendpoints, stringBuilder.toString());
}
}
/**
* This allows to calculate the identifiers of created IdentityAnchor.
*
* @param res
* The Notation Resource.
* @param identityAnchor
* The IdentityAnchor to manage its identifier.
* @param oldIds
* The existing objects and their identifiers.
*/
public static void calculateIdentityAnchor(final XMIResource res, final IdentityAnchor identityAnchor, final Map<EObject, String> oldIds) {
if (!oldIds.containsKey(identityAnchor)) {
final String elementID = ((XMIResource) identityAnchor.eContainer().eResource()).getID(identityAnchor.eContainer());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(IDENTITY_ANCHOR);
stringBuilder.append(OF);
stringBuilder.append(elementID);
// Manage the existing connector id with incremental suffix item if needed
stringBuilder = incrementStringBuilder(stringBuilder.toString(), oldIds);
res.setID(identityAnchor, stringBuilder.toString());
oldIds.put(identityAnchor, stringBuilder.toString());
}
}
/**
* This allows to suffix the initial string builder if the id already exist.
*
* @param initialString
* The initial string builder.
* @param oldIds
* The existing objects and their identifiers.
* @return The string builder incremented if needed.
*/
protected static StringBuilder incrementStringBuilder(final String initialString, final Map<EObject, String> oldIds) {
StringBuilder subStringBuilder = new StringBuilder(initialString);
boolean idAlreadyExist = oldIds.containsValue(initialString);
int incremental = 2;
while (idAlreadyExist) {
subStringBuilder = new StringBuilder(initialString);
subStringBuilder.append(UNDERSCORE);
subStringBuilder.append(incremental);
if (!oldIds.containsValue(subStringBuilder.toString())) {
idAlreadyExist = false;
}
incremental++;
}
return subStringBuilder;
}
}