blob: e7b81372a583b7d0367be679b364465319e438c6 [file] [log] [blame]
/*****************************************************************************
* 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:
* Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.interoperability.sysml14.sysml.xmi.helper;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.m2m.internal.qvt.oml.library.Context;
import org.eclipse.papyrus.uml.m2m.qvto.common.utils.TraceHelper;
import org.eclipse.uml2.uml.util.UMLUtil;
/**
* This class allows to preserve (and create) XMI identifiers to have same transformation results when transformations are done several time for a same project.
*/
@SuppressWarnings("restriction")
public class PreserveXMIIDHelper {
/**
* The context of the QVTo transformation.
*/
private Context context;
/**
* The helper to use to manipulate QVTo trace.
*/
private TraceHelper helper = new TraceHelper();
/**
* Constructor.
*
* @param context
* The context of the QVTo transformation.
*/
public PreserveXMIIDHelper(final Context context) {
this.context = context;
}
/**
* This allows to keep (and create) XMI identifiers for the UML Resource elements.
*
* @param res
* The UML Resource.
* @param oldIds
* The existing objects and their identifiers.
*/
public void keepIdForUMLResource(final XMIResource res, final Map<EObject, String> oldIds) {
// The list of stereotype applications that will be managed in a second run
final Set<EObject> eObjectForSecondRun = new HashSet<EObject>();
// Loop the first time for the non stereotype application
final TreeIterator<EObject> iter = res.getAllContents();
while (iter.hasNext()) {
final EObject current = iter.next();
if (isStereotypeApplication(current)) {
// looking for the SysML1.1 object in the QVto trace
final Object result = helper.traceFrom(context, current, null);
if (oldIds.containsKey(result)) {
// Get the old if of stereotype and apply it to the new one
final String oldId = oldIds.get(result);
res.setID(current, oldId);
// Calculate if more than the stereotype application must be needed for the ID calculation
SysMLXMIIDHelper.calculateMoreNeededId(res, current, oldId, oldIds);
} else {
// Add the stereotype application to the list that will be managed in a second run because they are created
eObjectForSecondRun.add(current);
}
} else {
// Calculate if more than the stereotype application must be needed for the ID calculation
UMLXMIIDHelper.calculateNeededId(res, current, oldIds);
}
}
// Second run the needed objects
for (final EObject current : eObjectForSecondRun) {
if (!oldIds.containsKey(current)) {
// If the object is not an existing one, check if this is a SysML stereotyped created element
if (SysMLXMIIDHelper.isStereotypedElementCreated(current)) {
SysMLXMIIDHelper.calculateCreateStereotypedElement(res, current);
// If the object is not an existing one, check if this is a UML stereotyped created element
} else if (UMLXMIIDHelper.isStereotypedElementCreated(current)) {
UMLXMIIDHelper.calculateCreateStereotypedElement(res, current);
}
}
}
}
/**
* This allows to keep (and create) XMI identifiers for the Notation Resource elements.
*
* @param res
* The Notation Resource.
* @param oldIds
* The existing objects and their identifiers.
*/
public void keepIdForNotationResource(final XMIResource res, final Map<EObject, String> oldIds) {
// Loop the first time for the non stereotype application
final TreeIterator<EObject> iter = res.getAllContents();
while (iter.hasNext()) {
final EObject current = iter.next();
NotationXMIIDHelper.calculateNeededId(res, current, oldIds);
}
}
/**
* This allows to determinate if the object is a stereotype application.
*
* @param eobject
* The eobject to check.
* @return
* <code>true</code> when the element represents a stereotype application, <code>false</code> otherwise.
*/
protected boolean isStereotypeApplication(final EObject eobject) {
return null != UMLUtil.getBaseElement(eobject);
}
}