From 1f0de49cbd279bee42be069c4bd53225faab215c Mon Sep 17 00:00:00 2001 From: antelder Date: Wed, 29 Sep 2010 07:10:57 +0000 Subject: TUSCANY-3679: Apply changes to update sdo impl to use EMF v2.5. Thanks to Elio Damaggio and Florian Pinel for the work git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1002496 13f79535-47bb-0310-9956-ffa450edef68 --- .../sdo/helper/CrossScopeCopyHelperImpl.java | 255 +++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/helper/CrossScopeCopyHelperImpl.java (limited to 'sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/helper/CrossScopeCopyHelperImpl.java') diff --git a/sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/helper/CrossScopeCopyHelperImpl.java b/sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/helper/CrossScopeCopyHelperImpl.java new file mode 100644 index 0000000000..3f51876035 --- /dev/null +++ b/sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/helper/CrossScopeCopyHelperImpl.java @@ -0,0 +1,255 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sdo.helper; + +import java.util.Iterator; +import java.util.Map; + +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.util.EcoreUtil; +import org.eclipse.emf.ecore.util.FeatureMap; +import org.eclipse.emf.ecore.util.FeatureMapUtil; +import org.eclipse.emf.ecore.util.InternalEList; +import org.eclipse.emf.ecore.util.EcoreUtil.Copier; + +import commonj.sdo.DataObject; +import commonj.sdo.Type; +import commonj.sdo.helper.CopyHelper; +import commonj.sdo.helper.TypeHelper; + +/** + * A CopyHelper implementation that creates the copy objects in a specific metadata scope. + * The target scope must contain a compatible version of the Types needed to create the copy objects. + */ +public class CrossScopeCopyHelperImpl implements CopyHelper +{ + protected TypeHelper scope; + + public CrossScopeCopyHelperImpl(TypeHelper targetScope) + { + scope = targetScope; + } + + public DataObject copyShallow(DataObject dataObject) + { + Copier copier = new CrossScopeCopier() + { + protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) + { + } + protected void copyAttribute(EAttribute eAttribute, EObject eObject, EObject copyEObject) + { + if (eObject.eIsSet(eAttribute) && !FeatureMapUtil.isFeatureMap(eAttribute)) + { + super.copyAttribute(eAttribute,eObject,copyEObject); + } + } + }; + EObject result = copier.copy((EObject)dataObject); + copier.copyReferences(); + return (DataObject)result; + } + + public DataObject copy(DataObject dataObject) + { + Copier copier = new CrossScopeCopier(); + DataObject result = (DataObject)copier.copy((EObject)dataObject); + copier.copyReferences(); + return (DataObject)result; + } + + protected class CrossScopeCopier extends EcoreUtil.Copier + { + protected boolean useOriginalReferences = false; + + protected EClass getTarget(EClass eClass) + { + EClass target = (EClass)get(eClass); + if (target == null) + { + Type type = (Type)eClass; + target = (EClass)scope.getType(type.getURI(), type.getName()); + } + return target; + } + + protected EStructuralFeature getTarget(EStructuralFeature eStructuralFeature) + { + EClass eClass = getTarget(eStructuralFeature.getEContainingClass()); + EStructuralFeature targetEf = eClass.getEStructuralFeature(eStructuralFeature.getName()); + return targetEf; + } + + /** + * This Method WILL BE REMOVED when EMF 3.0 is available + */ + public void copyReferences() + { + for (Iterator i = entrySet().iterator(); i.hasNext();) + { + Map.Entry entry = (Map.Entry)i.next(); + EObject eObject = (EObject)entry.getKey(); + EObject copyEObject = (EObject)entry.getValue(); + EClass eClass = eObject.eClass(); + for (int j = 0, size = eClass.getFeatureCount(); j < size; ++j) + { + EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(j); + if (eStructuralFeature.isChangeable() && !eStructuralFeature.isDerived()) + { + if (eStructuralFeature instanceof EReference) + { + EReference eReference = (EReference)eStructuralFeature; + if (!eReference.isContainment() && !eReference.isContainer()) + { + copyReference(eReference, eObject, copyEObject); + } + } + else if (FeatureMapUtil.isFeatureMap(eStructuralFeature)) + { + FeatureMap featureMap = (FeatureMap)eObject.eGet(eStructuralFeature); + FeatureMap copyFeatureMap = (FeatureMap)copyEObject.eGet(getTarget(eStructuralFeature)); + int copyFeatureMapSize = copyFeatureMap.size(); + for (int k = 0, featureMapSize = featureMap.size(); k < featureMapSize; ++k) + { + EStructuralFeature feature = featureMap.getEStructuralFeature(k); + if (feature instanceof EReference) + { + Object referencedEObject = featureMap.getValue(k); + Object copyReferencedEObject = get(referencedEObject); + if (copyReferencedEObject == null && referencedEObject != null) + { + EReference reference = (EReference)feature; + if (!useOriginalReferences || reference.isContainment() || reference.getEOpposite() != null) + { + continue; + } + copyReferencedEObject = referencedEObject; + } + // If we can't add it, it must aleady be in the list so find it and move it to the end. + // + if (!copyFeatureMap.add(feature, copyReferencedEObject)) + { + for (int l = 0; l < copyFeatureMapSize; ++l) + { + if (copyFeatureMap.getEStructuralFeature(l) == feature && copyFeatureMap.getValue(l) == copyReferencedEObject) + { + copyFeatureMap.move(copyFeatureMap.size() - 1, l); + --copyFeatureMapSize; + break; + } + } + } + } + else + { + copyFeatureMap.add(featureMap.get(k)); + } + } + } + } + } + } + } + + /** + * This Method WILL BE REMOVED when EMF 3.0 is available + */ + protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) + { + if (eObject.eIsSet(eReference)) + { + if (eReference.isMany()) + { + InternalEList source = (InternalEList)eObject.eGet(eReference); + InternalEList target = (InternalEList)copyEObject.eGet(getTarget(eReference)); + if (source.isEmpty()) + { + target.clear(); + } + else + { + boolean isBidirectional = eReference.getEOpposite() != null; + int index = 0; + for (Iterator k = resolveProxies ? source.iterator() : source.basicIterator(); k.hasNext();) + { + Object referencedEObject = k.next(); + Object copyReferencedEObject = get(referencedEObject); + 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 + { + target.addUnique(index, copyReferencedEObject); + } + ++index; + } + } + } + } + else + { + Object referencedEObject = eObject.eGet(eReference, resolveProxies); + if (referencedEObject == null) + { + copyEObject.eSet(getTarget(eReference), null); + } + else + { + Object copyReferencedEObject = get(referencedEObject); + if (copyReferencedEObject == null) + { + if (useOriginalReferences && eReference.getEOpposite() == null) + { + copyEObject.eSet(getTarget(eReference), referencedEObject); + } + } + else + { + copyEObject.eSet(getTarget(eReference), copyReferencedEObject); + } + } + } + } + } + } +} -- cgit v1.2.3