Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/LazyCopier.java')
-rw-r--r--extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/LazyCopier.java1044
1 files changed, 0 insertions, 1044 deletions
diff --git a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/LazyCopier.java b/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/LazyCopier.java
deleted file mode 100644
index 9ce3514fce5..00000000000
--- a/extraplugins/qompass-designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/transformations/LazyCopier.java
+++ /dev/null
@@ -1,1044 +0,0 @@
-/*****************************************************************************
- * Copyright (c) 2013 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:
- * Ansgar Radermacher ansgar.radermacher@cea.fr
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.qompass.designer.core.transformations;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.emf.common.util.BasicEList;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EAttribute;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
-import org.eclipse.emf.ecore.util.InternalEList;
-import org.eclipse.emf.ecore.xmi.XMLResource;
-import org.eclipse.papyrus.qompass.designer.core.Log;
-import org.eclipse.papyrus.qompass.designer.core.listeners.PostCopyListener;
-import org.eclipse.papyrus.qompass.designer.core.listeners.PreCopyListener;
-import org.eclipse.uml2.uml.Behavior;
-import org.eclipse.uml2.uml.Class;
-import org.eclipse.uml2.uml.Classifier;
-import org.eclipse.uml2.uml.Element;
-import org.eclipse.uml2.uml.Feature;
-import org.eclipse.uml2.uml.LiteralBoolean;
-import org.eclipse.uml2.uml.LiteralInteger;
-import org.eclipse.uml2.uml.LiteralNull;
-import org.eclipse.uml2.uml.LiteralString;
-import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
-import org.eclipse.uml2.uml.MultiplicityElement;
-import org.eclipse.uml2.uml.NamedElement;
-import org.eclipse.uml2.uml.Namespace;
-import org.eclipse.uml2.uml.OpaqueExpression;
-import org.eclipse.uml2.uml.Operation;
-import org.eclipse.uml2.uml.Package;
-import org.eclipse.uml2.uml.PackageableElement;
-import org.eclipse.uml2.uml.Property;
-import org.eclipse.uml2.uml.Slot;
-import org.eclipse.uml2.uml.Stereotype;
-import org.eclipse.uml2.uml.ValueSpecification;
-import org.eclipse.uml2.uml.util.UMLUtil;
-
-/**
- * A specific copier that enables to make iterative and shallow copies of model elements
- * from a source to a target model. It also supports copy-listeners, i.e. listeners that
- * might apply modifications before and after an element is copied.
- * This class is very useful for model transformations that make a lazy copy of elements,
- * i.e. copy only elements that are needed in the target model.
- *
- * Iterative means that you can copy one element after another, i.e. you do not need
- * to copy all elements in a single call.
- * Shallow means that some elements are incomplete copies. For instance, if you copy an
- * attribute of a class into the target model, the copy routine will create the attribute within
- * a shallow copy of the original class. The created class is a kind of shallow "container". It
- * is required, since we can't create the attribute without having a class, but it would initially
- * only contain the attribute that we copy. This class would have the same qualified name as the
- * original, i.e. it would be created within shallow packages.
- * A shallow copy can be transformed into a "real" copy
- * by explicitly copying it.
- *
- */
-public class LazyCopier extends Copier {
-
- public enum CopyStatus {
- /**
- * The status is not known, in most cases this indicates that the object has not yet been copied.
- */
- UNKNOWN,
-
- /**
- * A full copy obtained via the copy function. Full means that the contained features have been completely
- * copied
- */
- FULL,
-
- /**
- * A full copy in progress. Intermediate state of a target element after creation within the copy function,
- * before all attributes & references have been copied.
- */
- INPROGRESS,
-
- /**
- * A shallow copy, i.e. a copy only containing a subset of the original element. These are typically containers
- * for copied objects and avoids that the copies are not enclosed in an object. A shallow copy may become a full
- * copy later on.
- */
- SHALLOW
- }
-
- /**
- *
- * @param source
- * source package (root)
- * @param target
- * target package (root)
- * @param copyExtResources_
- * copy elements that are not within the same resource instead of referencing them.
- * @param copyID
- * copyID true, if XML IDs should be copied as well.
- */
- public LazyCopier(Package source, Package target, boolean copyExtResources_, boolean copyID) {
- this.source = source;
- this.target = target;
- // useOriginalReferences = false;
- copyExtReferences = copyExtResources_;
- preCopyListeners = new BasicEList<PreCopyListener>();
- postCopyListeners = new BasicEList<PostCopyListener>();
- templateMapInfo = new HashMap<EObject, Map<EObject, EObject>>();
- standardMap = new HashMap<EObject, EObject>();
- statusMap = new HashMap<EObject, CopyStatus>();
- boundPackages = new Stack<Namespace>();
- if (copyExtReferences) {
- // original source package becomes a sub-package in the target model
- Package newSourceRoot = target.createNestedPackage(source.getName());
- put(source, newSourceRoot);
- setStatus(newSourceRoot, CopyStatus.SHALLOW);
- }
- else {
- put(source, target);
- setStatus(target, CopyStatus.SHALLOW);
- }
- this.copyID = copyID;
- if (copyID) {
- copyID(source, target);
- }
- };
-
- /**
- *
- */
- private static final long serialVersionUID = -1664013545661635289L;
-
- /**
- * Source model within a transformation
- */
-
- public Package source;
-
- /**
- * Target model within a transformation
- */
- public Package target;
-
- /**
- * if true, copy packages or elements that are imported into the target
- * model
- */
- public boolean copyExtReferences;
-
- /**
- * Bound package template
- */
- protected Namespace boundPackage;
-
- /**
- * Map to identify target objects when given source objects
- */
- protected Map<EObject, EObject> standardMap;
-
- /**
- * Map to identify target objects when given source objects
- */
- protected Map<EObject, EObject> templateMap;
-
- /**
- * Set of maps for template instantiations
- */
- protected Map<EObject, Map<EObject, EObject>> templateMapInfo;
-
- /**
- * Map using a target EObject as key
- */
- protected Map<EObject, CopyStatus> statusMap;
-
- protected boolean copyID;
-
- /**
- * Elements within package templates must be treated differently, we have to ensure that:
- * (1) several instantiations with same binding of the same package template do not lead to double copies
- * (yet, it may be possible that a 2nd instantiation adds contents, e.g. the trace package template could be
- * instantiated containing only OTF trace (and superclasses), a second instantiation might add a different trace
- * implementation)
- * (2) several instantiations with different binding do not prevent classes from being copied that have already
- * been copied earlier.
- * The solution is to use a different map for the elements with package template. This map is instantiated once
- * for each binding (managed by the TemplateInstantiation class)
- */
- public Map<EObject, EObject> getMap(EObject sourceEObj) {
- boolean withinTemplate = withinTemplate(sourceEObj);
- return withinTemplate ?
- templateMap :
- standardMap;
- }
-
- @Override
- public EObject get(Object sourceEObj) {
- if (sourceEObj instanceof EObject) {
- Map<EObject, EObject> map = getMap((EObject) sourceEObj);
- return map.get(sourceEObj);
- }
- return null;
- }
-
- @Override
- public EObject put(EObject sourceEObj, EObject targetEObj) {
- if (sourceEObj instanceof EObject) {
- Map<EObject, EObject> map = getMap(sourceEObj);
- return map.put(sourceEObj, targetEObj);
- }
- return null;
- }
-
- /**
- * Put a pair into the copy map. Unlike the standard put operation,
- * the target object is marked as full copy.
- * Just using the put operation lead to bug 422899 - [QDesigner] Regression in
- * template instantiation
- *
- * @return
- */
- public EObject putPair(EObject sourceEObj, EObject targetEObj) {
- EObject target = put(sourceEObj, targetEObj);
- setStatus(targetEObj, CopyStatus.FULL);
- return target;
- }
-
- @Override
- public boolean containsKey(Object sourceEObj) {
- if (sourceEObj instanceof EObject) {
- Map<EObject, EObject> map = getMap((EObject) sourceEObj);
- return map.containsKey(sourceEObj);
- }
- return false;
- }
-
- @Override
- public EObject remove(Object sourceEObj) {
- if (sourceEObj instanceof EObject) {
- Map<EObject, EObject> map = getMap((EObject) sourceEObj);
- return map.remove(sourceEObj);
- }
- return null;
- }
-
- /**
- * Set the status of a copy object
- *
- * @param targetEObj
- * @param status
- */
- public void setStatus(EObject targetEObj, CopyStatus status) {
- statusMap.put(targetEObj, status);
- }
-
- /**
- * return true, if a shallow copy of the passed EObject exists
- *
- * @param sourceEObj
- * @return
- */
- public CopyStatus getStatus(EObject targetEObj) {
- if (targetEObj != null) {
- CopyStatus status = statusMap.get(targetEObj);
- if (status != null) {
- return status;
- }
- }
- return CopyStatus.UNKNOWN;
- }
-
- /**
- * Set the reference of a bound package template. It must be a member of the target model.
- * Setting the package template is required to assure that elements that are part of a different
- * resource get copied (if the copyExtReferences flag is set to false, copying would not be done otherwise)
- *
- * @param packageTemplate
- * Reference to package (with a template signature) in source model that should be instantiated
- * @param boundPackage
- * Reference to (an initially empty) package in which the packate template will be instantiated
- * during the copy process
- */
- public void setPackageTemplate(Namespace packageTemplate, Namespace boundPackage) {
- this.boundPackage = boundPackage;
- if (packageTemplate == null) {
- return;
- }
- templateMap =
- templateMapInfo.get(boundPackage);
- if (templateMap == null) {
- templateMap = new HashMap<EObject, EObject>();
- templateMapInfo.put(boundPackage, templateMap);
- }
- // declare relation between packageTemplate and bound package
- // but: the owner of the package template is not equal to the packageTemplate (e.g. perClass)
- // since we can extend package templates in different models.
- standardMap.put(packageTemplate, boundPackage);
- }
-
- public void pushPackageTemplate() {
- boundPackages.push(boundPackage);
- }
-
- public void popPackageTemplate() {
- boundPackage = boundPackages.pop();
- templateMap =
- templateMapInfo.get(boundPackage);
- }
-
- private Stack<Namespace> boundPackages;
-
- /**
- * Remove an element and its children from the map to enable subsequent copies, in particular if the
- * same element (e.g. an operation) is bound multiple times within a template instantiation.
- * TODO: there must be a better way to do this.
- *
- * @param element
- */
- public void removeForCopy(EObject element) {
- templateMap.remove(element);
- if (element instanceof Element) {
- // also remove applied stereotypes
- for (EObject stereoApplication : ((Element) element).getStereotypeApplications()) {
- removeForCopy(stereoApplication);
- }
- }
- EClass eClass = element.eClass();
- for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i)
- {
- EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i);
- if (eStructuralFeature.isChangeable() && !eStructuralFeature.isDerived())
- {
- if (eStructuralFeature instanceof EAttribute) {
- // copyAttribute((EAttribute)eStructuralFeature, sourceEObj, targetEObj);
- }
- else {
- EReference eReference = (EReference) eStructuralFeature;
- if (eReference.isContainment()) {
- for (EObject ref : getRefs(eReference, element)) {
- removeForCopy(ref);
- }
- }
- else if (!eReference.isContainer()) {
- // not contained, but copy reference as well
-
- }
- }
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- public EList<EObject> getRefs(EReference eReference, EObject eObject) {
- EList<EObject> refs = new BasicEList<EObject>();
- if (eObject.eIsSet(eReference)) {
- if (eReference.isMany()) {
- // @SuppressWarnings("unchecked")
- refs.addAll((List<EObject>) eObject.eGet(eReference));
- } else {
- refs.add((EObject) eObject.eGet(eReference));
- }
- }
- return refs;
- }
-
- /**
- * Check whether the passed element (within the source model) is within a
- * a template, i.e. one of is owners is mapped towards the bound package in
- * the target model. Note that multiple owners in the source model may be
- * mapped to the same bound package.
- *
- * @param element
- * @return
- */
- public boolean withinTemplate(EObject element) {
- if (boundPackage != null) {
- EObject owner = element;
- if ((element.eContainer() == null) &&
- !(element instanceof Element)) { // has no eContainer and is not a UML element => likely to be a be a stereotype application.
- // it is important not to call getBaseElement for all eobjects, since its execution can take
- // quite a while (in particular, if not called on a stereotype application)
- Element base = UMLUtil.getBaseElement(owner);
- if (base != null) {
- owner = base; // containment check is done with base element
- }
- }
- while (owner != null) {
- owner = owner.eContainer();
- if (get(owner) == boundPackage) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Returns a copy of the given eObject.
- *
- * Normally, we do not want to copy elements that are from a different
- * resource. There are two exceptions (1) if this is explicitly specified
- * (for producing "complete" models) (2) if we want to copy elements from a
- * template into the target model.
- *
- * @param sourceEObj
- * the object to copy.
- * @return the copy.
- */
- @SuppressWarnings("unchecked")
- @Override
- public EObject copy(EObject sourceEObj) {
- if (sourceEObj == null) {
- // this case may happen, if elements are systematically copied without checking for
- // null references in the application code (e.g. if we copy a part-with-port which might
- // be null in case of delegation or connectors without ports
- return null;
- }
-
-
- EObject targetEObj = get(sourceEObj);
-
- CopyStatus status = getStatus(targetEObj);
-
- if (status == CopyStatus.FULL || status == CopyStatus.INPROGRESS) {
- // copy already exists, return targetEObj
- return targetEObj;
- }
-
- boolean withinTemplate = withinTemplate(sourceEObj);
- boolean sameResource = (sourceEObj.eResource() == source.eResource());
- if (!sameResource && !copyExtReferences && !withinTemplate) {
- // do not copy if within different resource, unless
- // 1. copyImports
- // 2. within package template
- return sourceEObj;
- }
-
- if (sourceEObj instanceof Stereotype) {
- // do not copy Stereotypes, as it would imply copying meta-model elements (the base_X
- // attribute of the stereotype is typed with a meta-model element)
- return sourceEObj;
- }
-
- for (PreCopyListener listener : preCopyListeners) {
- EObject result = listener.preCopyEObject(this, sourceEObj);
- if (result != sourceEObj) {
- return result;
- }
- }
-
- if (sourceEObj instanceof NamedElement) {
- String name = ((NamedElement) sourceEObj).getQualifiedName();
- if ((name != null) && name.startsWith("uml::")) { //$NON-NLS-1$
- Log.log(IStatus.ERROR, Log.TRAFO_COPY, "copy for meta-model element \"" + name + //$NON-NLS-1$
- "\" requested. Return original element"); //$NON-NLS-1$
- return sourceEObj;
- }
- }
- // additional sanity check: want to avoid copying (instead of instantiating) elements
- // of a package template
- if ((sourceEObj instanceof Package) && (!withinTemplate)) {
- if (((Package) sourceEObj).getOwnedTemplateSignature() != null) {
- Log.log(IStatus.WARNING, Log.TRAFO_COPY, "warning: copying a package template without instantiating a template"); //$NON-NLS-1$
- }
- }
-
- if (status == CopyStatus.SHALLOW) {
- // copy exists, but was a shallow copy, change status to INPROGRESS
- setStatus(targetEObj, CopyStatus.INPROGRESS);
- }
- else {
- targetEObj = createCopy(sourceEObj);
- put(sourceEObj, targetEObj);
- setStatus(targetEObj, CopyStatus.INPROGRESS);
- if (copyID) {
- copyID(sourceEObj, targetEObj);
- }
- // creates a shallow copy of the container. This container will update containment references (such as packagedElement)
- // and thus update links
- createShallowContainer(sourceEObj);
- }
- EClass eClass = sourceEObj.eClass();
- for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i)
- {
- EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i);
- if (eStructuralFeature.isChangeable() && !eStructuralFeature.isDerived())
- {
- if (eStructuralFeature instanceof EAttribute) {
- copyAttribute((EAttribute) eStructuralFeature, sourceEObj, targetEObj);
- }
- else {
- EReference eReference = (EReference) eStructuralFeature;
- if (eReference.isContainment()) {
- copyContainment(eReference, sourceEObj, targetEObj);
- }
- // some containment relationships require copying the container completely
- // e.g. if an owned template signature is referenced, we need to follow the "template"
- // reference, which subsets the "owner" relationship.
- // e.g. if an operation is referenced, we need to copy the whole interface
- // Currently: only the standard owning reference is not copied recursively.
-
- else if (!eReference.getName().equals("owner") && //$NON-NLS-1$
- (!eReference.getName().equals("owningInstance"))) { //$NON-NLS-1$
- Object feature = sourceEObj.eGet(eStructuralFeature);
- if (feature instanceof Element) {
- copy((Element) feature);
- } else if (feature instanceof EList) {
- copyAll((EList<Object>) feature);
- }
- copyReference(eReference, sourceEObj, targetEObj);
- }
- }
- }
- else if ((eStructuralFeature instanceof EReference)) {
- if (eStructuralFeature.getName().equals("clientDependency")) { //$NON-NLS-1$
- Object feature = sourceEObj.eGet(eStructuralFeature);
-
- if (feature instanceof Element) {
- copy((Element) feature);
- } else if (feature instanceof EList) {
- copyAll((EList<Object>) feature);
- }
- }
- }
- }
- copyProxyURI(sourceEObj, targetEObj);
- copyID(sourceEObj, targetEObj);
- copyStereotypes(sourceEObj);
- setStatus(targetEObj, CopyStatus.FULL);
-
- for (PostCopyListener listener : postCopyListeners) {
- listener.postCopyEObject(this, targetEObj);
- }
-
- return targetEObj;
- }
-
- /**
- * @param sourceEObj
- * @return a copy, if it already exists. If it does not exist, return the
- * source object itself, if no copy is required, otherwise return null.
- */
- public EObject noCopy(EObject sourceEObj) {
- boolean withinTemplate = withinTemplate(sourceEObj);
- boolean sameResource = (sourceEObj.eResource() == source.eResource());
- if (!sameResource && !copyExtReferences && !withinTemplate) {
- return sourceEObj;
- }
- else {
- return get(sourceEObj);
- }
- }
-
- /**
- * Copy stereotype applications. Since stereotype applications are not part of the containment of an eObject, they are not copied by the
- * generic function.
- * A problem of copying stereotypes is that it may drag whole hierarchies with it, for instance if we copy the base_ attributes,
- * we transform a shallow copy into a normal copy.
- * => always make shallow copies of packages, never shallow copies of classes? [the split into fragments is solved, but the split of the system component???]
- */
- public void copyStereotypes(EObject sourceEObj, boolean duringShallow) {
- if (sourceEObj instanceof Element) {
-
- for (EObject stereoApplication : ((Element) sourceEObj).getStereotypeApplications()) {
- EObject copiedStereoApplication = (duringShallow) ?
- shallowCopy(stereoApplication) :
- copy(stereoApplication);
-
- if (copiedStereoApplication != null) {
- // UMLUtil.setBaseElement(copiedStereoApplication, (Element) get(sourceEObj));
- // add copied stereotype application to the resource (as top-level objects).
- if (!target.eResource().getContents().contains(copiedStereoApplication)) {
- target.eResource().getContents().add(copiedStereoApplication);
- }
- }
- }
- }
- }
-
- public void copyStereotypes(EObject sourceEObj) {
- copyStereotypes(sourceEObj, false);
- }
-
- public void shallowCopyStereotypes(EObject sourceEObj) {
- copyStereotypes(sourceEObj, true);
- }
-
- /**
- * Copy the containment of an element with respect to a certain reference
- *
- * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyContainment(org.eclipse.emf.ecore.EReference, org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
- * Differences to referenced function in ECoreUtil
- * - If an element in copyAll is null, it is not added
- * - List elements are always cleared before copying, since the list elements may already have been
- * partially filled by a previous shallow copy
- *
- * @param eReference
- * a reference, such as for instance packagedElement (the
- * caller needs to check, is this reference is a containment reference).
- * @param eObject
- * the source eObject
- * @param copyEObject
- * the copy of this eObject
- */
- @Override
- protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) {
- if (eObject.eIsSet(eReference)) {
- if (eReference.isMany()) {
- @SuppressWarnings("unchecked")
- List<EObject> source = (List<EObject>) eObject.eGet(eReference);
- @SuppressWarnings("unchecked")
- List<EObject> target = (List<EObject>) copyEObject.eGet(getTarget(eReference));
- // do not clear (would remove elements that are added by copy listeners)
- // But: better enforce exact copy? (listeners could only add in a post-copy step)
- // target.clear();
- if (!source.isEmpty()) {
- for (EObject copyEObj : copyAll(source)) {
- if (copyEObj != null) {
- target.add(copyEObj);
- }
- }
- }
- } else {
- EObject childEObject = (EObject) eObject.eGet(eReference);
- copyEObject.eSet(getTarget(eReference), childEObject == null ? null : copy(childEObject));
- }
- }
- }
-
- /**
- * Copy the containment in a "shallow" way, i.e. copy references to contained objects, if these exist already.
- * If called for instance for a package, it will add those elements to the packagedElements list of the
- * target package, that have already been copied.
- *
- * @param eReference
- * @param eObject
- * @param copyEObject
- */
- protected void shallowCopyContainment(EReference eReference, EObject eObject, EObject copyEObject) {
- if (eObject.eIsSet(eReference)) {
- if (eReference.isMany()) {
- @SuppressWarnings("unchecked")
- List<EObject> source = (List<EObject>) eObject.eGet(eReference);
- @SuppressWarnings("unchecked")
- List<EObject> target = (List<EObject>) copyEObject.eGet(getTarget(eReference));
- if (source.isEmpty()) {
- target.clear();
- } else {
- for (EObject sourceEObj : source) {
- // if eObject has already been copied, add it to target
- // don't add, if copyEObj is identical to sourceEObj. This would imply manipulating an
- // element of the source model.
- EObject copyEObj = noCopy(sourceEObj);
- if ((copyEObj != null) && (copyEObj != sourceEObj) && (!target.contains(copyEObj))) {
- try {
- target.add(copyEObj);
- }
- catch (Exception e) {
- System.err.println(e);
- }
- }
- }
- }
- } else {
- EObject childEObject = (EObject) eObject.eGet(eReference);
- // get will return null, if object should not be copied. In this case, we do not want to replace
- copyEObject.eSet(getTarget(eReference), childEObject == null ? null : noCopy(childEObject));
- }
- }
- }
-
- /**
- * Create a "shallow" container for an object, i.e. create (recursively) the owner without
- * adding all other children of this owner (e.g. in case of a package, the package itself will
- * be created, but not all elements within that package).
- *
- * @param sourceEObj
- */
- public void createShallowContainer(EObject sourceEObj) {
- EObject owner = sourceEObj.eContainer();
- EObject copy = null;
- EObject lastSource = null;
- EList<EObject> copyStereoList = new BasicEList<EObject>();
- while (owner != null) {
- if (containsKey(owner)) {
- // owner is in map, still need to re-copy (update) the containment
- // references, since one of the children did not exist before
- //
- shallowCopy(owner);
- if (lastSource != null) {
- // StUtils.copyStereotypes(this, (Element)lastSource, (Element)copy);
- }
- return;
- // break;
- }
- copy = shallowCopy(owner);
- // copyStereoList.add(sourceEObj);
- owner = owner.eContainer();
- }
- // copy the stereotypes after the container has been created completely
- for (EObject copyStereo : copyStereoList) {
- copyStereotypes(copyStereo);
- }
- if (copy instanceof PackageableElement) {
- // if we copy external resources, we might reach the "top" on the source level
- // which becomes a sub-package of the new model.
- target.getPackagedElements().add((PackageableElement) copy);
- }
- }
-
- /**
- * Make a shallow copy of an element, i.e. only create the element itself and not
- * all of its contents. If a subset of the containing elements already exist in the copied
- * model, update the containment references pointing to these. The function may be called
- * multiple times in order to add elements to the containment references that
- * have been copied since the previous call (i.e. it is possible to make a shallow copy
- * of a package after a single class within it has been copied. It may be called again,
- * once a second class within the package has been copied => the packagedElements reference
- * of the package will be updated).
- *
- * It is important that the implementation of this object does not make recursive calls.
- * In particular, stereotypes are based on shallow copy as well. This means that stereotype
- * attributes that reference other model elements will only be initialized if these elements
- * exist already.
- *
- * @param sourceEObj
- * @return
- */
- public EObject shallowCopy(EObject sourceEObj) {
- boolean first = false;
- EObject targetEObj = get(sourceEObj);
- if (targetEObj == null) {
- targetEObj = createCopy(sourceEObj);
- put(sourceEObj, targetEObj);
- setStatus(targetEObj, CopyStatus.SHALLOW);
- if (copyID) {
- copyID(sourceEObj, targetEObj);
- }
- first = true;
- }
- else if (getStatus(targetEObj) == CopyStatus.FULL) {
- // object has already been completely copied. Nothing to do, return targetEObj.
- // Note that this implies that the update of references below is called for full copies
- // in progress and shallow copies. The former assures that all copied elements have an
- // eContainer during the call of pre-copy listeners (example: if a class is copied, its
- // operations are recursively copied, the ownedOperation relationship is only updated
- // *afterwards* by the code within the (full) copy operation).
- return targetEObj;
- }
-
- shallowCopyStereotypes(sourceEObj);
-
- EClass eClass = sourceEObj.eClass();
-
- for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i) {
- EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i);
- if (eStructuralFeature.isChangeable() && !eStructuralFeature.isDerived()) {
- if (eStructuralFeature instanceof EAttribute) {
- // copy all attributes during first pass after creation of target object
- if (first) {
- copyAttribute((EAttribute) eStructuralFeature, sourceEObj, targetEObj);
- }
- } else {
- EReference eReference = (EReference) eStructuralFeature;
- // create a shallow copy of the containment: update only references already in the copy map
- if (sourceEObj != targetEObj) {
- shallowCopyContainment(eReference, sourceEObj, targetEObj);
- }
- }
- }
- }
- return targetEObj;
- }
-
- @SuppressWarnings("unchecked")
- public <T extends Element> T getCopy(T source) {
- return (T) copy(source);
- }
-
- public EList<PreCopyListener> preCopyListeners;
-
- public EList<PostCopyListener> postCopyListeners;
-
- /**
- * Called to handle the copying of a cross reference;
- * this adds values or sets a single value as appropriate for the multiplicity
- * while omitting any bidirectional reference that isn't in the copy map.
- *
- * @param eReference
- * the reference to copy.
- * @param eObject
- * the object from which to copy.
- * @param copyEObject
- * the object to copy to.
- */
- @Override
- protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject)
- {
- if (eObject.eIsSet(eReference)) {
- if (eReference.isMany()) {
- @SuppressWarnings("unchecked")
- InternalEList<EObject> source = (InternalEList<EObject>) eObject.eGet(eReference);
- @SuppressWarnings("unchecked")
- InternalEList<EObject> target = (InternalEList<EObject>) copyEObject.eGet(getTarget(eReference));
- if (source.isEmpty()) {
- target.clear();
- }
- else {
- boolean isBidirectional = eReference.getEOpposite() != null;
- int index = 0;
- for (Iterator<EObject> k = resolveProxies ? source.iterator() : source.basicIterator(); k.hasNext();) {
- EObject referencedEObject = k.next();
- EObject copyReferencedEObject = get(referencedEObject);
- // check filters (modification compared to method in superclass)
- boolean noCopy = false;
- for (PreCopyListener listener : preCopyListeners) {
- EObject result = listener.preCopyEObject(this, referencedEObject);
- if (result != referencedEObject) {
- copyReferencedEObject = result;
- noCopy = (result == null);
- break;
- }
- }
- if (noCopy) {
- continue;
- }
- if (copyReferencedEObject == null) {
- if (useOriginalReferences && !isBidirectional) {
- target.addUnique(index, referencedEObject);
- ++index;
- }
- }
- else {
- if (isBidirectional) {
- int position = target.indexOf(copyReferencedEObject);
- if (position == -1) {
- target.addUnique(index, copyReferencedEObject);
- }
- else if (index != position) {
- target.move(index, copyReferencedEObject);
- }
- }
- else if (!target.contains(copyReferencedEObject)) {
- // TODO: does not allow multiple identical elements in the list. Problematic?
- // Check above is necessary, since some references that are not
- // part of the containment may have already been copied (e.g. in case of
- // a TemplateSignature "ownedParameter" subsets "parameter", thus copying
- // ownedParameter as part of the containment adds a template parameter)
- target.addUnique(index, copyReferencedEObject);
- }
- ++index;
- }
- }
- }
- }
- else {
- Object referencedEObject = eObject.eGet(eReference, resolveProxies);
- if (referencedEObject == null) {
- copyEObject.eSet(getTarget(eReference), null);
- }
- else if (referencedEObject instanceof EObject) {
- // difference to original code in EcoreUtil: we obtain a copy (which might be null or the
- // source object) of the referenced EObject. This assures that we only set a value of a
- // reference to something we actually want to have in the target model.
- // Specific problematic case in original code: classifierBehavior is a reference, but assigning such
- // a behavior will also add an owned behavior. If we assign a referencedEObject (a behavior) from the
- // source model in the target, we will actually remove it from the source model (as it is uniquely owned).
- EObject copyReferencedEObject = copy((EObject) referencedEObject);
- if (copyReferencedEObject != null) {
- copyEObject.eSet(getTarget(eReference), copyReferencedEObject);
- }
- }
- }
- }
- }
-
- /**
- * Copy all methods from the passed source-model class.
- * This function is useful, if the passed class only exist
- * as a shallow copy.
- *
- * @param source
- * A class within the source model
- */
- public void copyMethods(Class source) {
- for (Behavior method : source.getOwnedBehaviors()) {
- getCopy(method);
- }
- }
-
- /**
- * Copy all attributes from the source-model classifier
- * This function is useful, if the passed class only exist
- * as a shallow copy.
- *
- * @param source
- * A classifier within the source model
- */
- public void copyAttributes(Classifier source) {
- for (Property attribute : source.getAttributes()) {
- getCopy(attribute);
- }
- }
-
- /**
- * copy all operations from the source-model classifier.
- * This function is useful, if the passed class only exist
- * as a shallow copy.
- *
- * @param source
- * A classifier within the source model
- */
- public void copyOperations(Classifier source) {
- for (Operation operation : source.getOperations()) {
- getCopy(operation);
- }
- }
-
- // TODO: the functions that follow are static and should not be part of this class
- // as they use a different way of copying things.
-
-
- public static void copyFeatureModifiers(Feature source, Feature target) {
- target.setIsStatic(source.isStatic());
- target.setIsLeaf(source.isLeaf());
- }
-
- public static void copyMultElemModifiers(MultiplicityElement source, MultiplicityElement target) {
- target.setIsOrdered(source.isOrdered());
- target.setIsUnique(source.isUnique());
- target.setLower(source.getLower());
- target.setUpper(source.getUpper());
- }
-
- /**
- * Copy a value to a target slot
- *
- * @param smValue
- * @param target
- * @return
- */
- public static ValueSpecification copyValue(ValueSpecification value, Slot target) {
- ValueSpecification newValue = target.createValue(value.getName(), value.getType(), value.eClass());
- return copyValue(value, newValue);
- }
-
- public static ValueSpecification copyDefaultValue(Property source, Property target) {
- ValueSpecification value = source.getDefaultValue();
- if (value != null) {
- ValueSpecification newValue = target.createDefaultValue(value.getName(), value.getType(), value.eClass());
- return copyValue(value, newValue);
- } else {
- return null;
- }
- }
-
- public static ValueSpecification copyValue(ValueSpecification smValue, ValueSpecification tmValue) {
- if (smValue instanceof OpaqueExpression) {
- OpaqueExpression oeValue = (OpaqueExpression) smValue;
- OpaqueExpression noeValue = (OpaqueExpression) tmValue;
- for (String language : oeValue.getLanguages()) {
- noeValue.getLanguages().add(language);
- }
- for (String body : oeValue.getBodies()) {
- noeValue.getBodies().add(body);
- }
- } else if (smValue instanceof LiteralString) {
- ((LiteralString) tmValue).setValue(((LiteralString) smValue).getValue());
- } else if (smValue instanceof LiteralInteger) {
- ((LiteralInteger) tmValue).setValue(((LiteralInteger) smValue).getValue());
- } else if (smValue instanceof LiteralUnlimitedNatural) {
- ((LiteralUnlimitedNatural) tmValue).setValue(((LiteralUnlimitedNatural) smValue).getValue());
- } else if (smValue instanceof LiteralBoolean) {
- ((LiteralBoolean) tmValue).setValue(((LiteralBoolean) smValue).booleanValue());
- } else if (smValue instanceof LiteralNull) {
- }
- return tmValue;
- }
-
- /**
- * Copy the (XML) ID from the source to the destination model element. This
- * is useful, if you want to create a diagram for (parts of) the generated
- * target model. Otherwise, the IDs would change with each generation and
- * references from the diagram to model elements would break (of course,
- * they could still break, for instance if structural modifications of the
- * source model are made).
- *
- * @param source
- * source model element
- * @param dest
- * corresponding target model element
- */
- public static void copyID(EObject source, EObject target) {
- copyID(source, target, ""); //$NON-NLS-1$
- }
-
- /**
- * Copy the (XML) ID from the source to the destination model element.
- * Prefix the ID with a string passed as parameter
- *
- * @param source
- * source model element
- * @param dest
- * corresponding target model element
- * @param prefix
- * a prefix for the target model ID
- */
- @SuppressWarnings("deprecation")
- public static void copyID(EObject source, EObject target, String prefix) {
- Resource resourceSource = source.eResource();
- Resource resourceTarget = target.eResource();
- // TODO: use EcoreUtil getURI (InternalEObject) instead?
-
- if ((resourceSource instanceof XMLResource) && (resourceTarget instanceof XMLResource)) {
- XMLResource xmlResSource = (XMLResource) resourceSource;
- XMLResource xmlResTarget = (XMLResource) resourceTarget;
- String id = prefix + xmlResSource.getID(source);
- int counter = 0;
- String uniqueID = id;
- while (xmlResTarget.getIDToEObjectMap().containsKey(uniqueID)) {
- uniqueID = id + counter;
- counter++;
- }
- xmlResTarget.setID(target, uniqueID);
- }
- }
-}

Back to the top