[528762] Customizing binary serialization for UML models.
diff --git a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/resource/UMLResourceImpl.java b/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/resource/UMLResourceImpl.java
index 6a13291..a87fb16 100644
--- a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/resource/UMLResourceImpl.java
+++ b/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/internal/resource/UMLResourceImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011 IBM Corporation, CEA, and others.
+ * Copyright (c) 2005, 2018 IBM Corporation, CEA, 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
@@ -8,16 +8,44 @@
* Contributors:
* IBM - initial API and implementation
* Kenn Hussey (CEA) - 327039
+ * Kenn Hussey - 528762
*
- * $Id: UMLResourceImpl.java,v 1.4 2006/12/14 15:49:34 khussey Exp $
*/
package org.eclipse.uml2.uml.internal.resource;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.lang.reflect.InvocationTargetException;
+
+import java.util.Map;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl.BinaryIO.Version;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EGenericType;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl.EObjectOutputStream;
+
import org.eclipse.emf.ecore.xmi.XMLLoad;
import org.eclipse.emf.ecore.xmi.XMLSave;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;
/**
@@ -31,6 +59,443 @@
extends XMIResourceImpl
implements UMLResource {
+ protected static abstract class EStructuralFeatureWrapper
+ implements EStructuralFeature.Internal {
+
+ protected EStructuralFeature.Internal eStructuralFeature;
+
+ protected EStructuralFeatureWrapper(
+ EStructuralFeature.Internal eStructuralFeature) {
+ this.eStructuralFeature = eStructuralFeature;
+ }
+
+ public boolean isTransient() {
+ return eStructuralFeature.isTransient();
+ }
+
+ public void setTransient(boolean value) {
+ eStructuralFeature.setTransient(value);
+ }
+
+ public boolean isVolatile() {
+ return eStructuralFeature.isVolatile();
+ }
+
+ public void setVolatile(boolean value) {
+ eStructuralFeature.setVolatile(value);
+ }
+
+ public boolean isChangeable() {
+ return eStructuralFeature.isChangeable();
+ }
+
+ public void setChangeable(boolean value) {
+ eStructuralFeature.setChangeable(value);
+ }
+
+ public String getDefaultValueLiteral() {
+ return eStructuralFeature.getDefaultValueLiteral();
+ }
+
+ public void setDefaultValueLiteral(String value) {
+ eStructuralFeature.setDefaultValueLiteral(value);
+ }
+
+ public Object getDefaultValue() {
+ return eStructuralFeature.getDefaultValue();
+ }
+
+ public void setDefaultValue(Object value) {
+ eStructuralFeature.setDefaultValue(value);
+ }
+
+ public boolean isUnsettable() {
+ return eStructuralFeature.isUnsettable();
+ }
+
+ public void setUnsettable(boolean value) {
+ eStructuralFeature.setUnsettable(value);
+ }
+
+ public boolean isDerived() {
+ return eStructuralFeature.isDerived();
+ }
+
+ public void setDerived(boolean value) {
+ eStructuralFeature.setDerived(value);
+ }
+
+ public EClass getEContainingClass() {
+ return eStructuralFeature.getEContainingClass();
+ }
+
+ public int getFeatureID() {
+ return eStructuralFeature.getFeatureID();
+ }
+
+ public Class<?> getContainerClass() {
+ return eStructuralFeature.getContainerClass();
+ }
+
+ public boolean isOrdered() {
+ return eStructuralFeature.isOrdered();
+ }
+
+ public void setOrdered(boolean value) {
+ eStructuralFeature.setOrdered(value);
+ }
+
+ public boolean isUnique() {
+ return eStructuralFeature.isUnique();
+ }
+
+ public void setUnique(boolean value) {
+ eStructuralFeature.setUnique(value);
+ }
+
+ public int getLowerBound() {
+ return eStructuralFeature.getLowerBound();
+ }
+
+ public void setLowerBound(int value) {
+ eStructuralFeature.setLowerBound(value);
+ }
+
+ public int getUpperBound() {
+ return eStructuralFeature.getUpperBound();
+ }
+
+ public void setUpperBound(int value) {
+ eStructuralFeature.setUpperBound(value);
+ }
+
+ public boolean isMany() {
+ return eStructuralFeature.isMany();
+ }
+
+ public boolean isRequired() {
+ return eStructuralFeature.isRequired();
+ }
+
+ public EClassifier getEType() {
+ return eStructuralFeature.getEType();
+ }
+
+ public void setEType(EClassifier value) {
+ eStructuralFeature.setEType(value);
+ }
+
+ public EGenericType getEGenericType() {
+ return eStructuralFeature.getEGenericType();
+ }
+
+ public void setEGenericType(EGenericType value) {
+ eStructuralFeature.setEGenericType(value);
+ }
+
+ public String getName() {
+ return eStructuralFeature.getName();
+ }
+
+ public void setName(String value) {
+ eStructuralFeature.setName(value);
+ }
+
+ public EList<EAnnotation> getEAnnotations() {
+ return eStructuralFeature.getEAnnotations();
+ }
+
+ public EAnnotation getEAnnotation(String source) {
+ return eStructuralFeature.getEAnnotation(source);
+ }
+
+ public EClass eClass() {
+ return eStructuralFeature.eClass();
+ }
+
+ public Resource eResource() {
+ return eStructuralFeature.eResource();
+ }
+
+ public EObject eContainer() {
+ return eStructuralFeature.eContainer();
+ }
+
+ public EStructuralFeature eContainingFeature() {
+ return eStructuralFeature.eContainingFeature();
+ }
+
+ public org.eclipse.emf.ecore.EReference eContainmentFeature() {
+ return eStructuralFeature.eContainmentFeature();
+ }
+
+ public EList<EObject> eContents() {
+ return eStructuralFeature.eContents();
+ }
+
+ public TreeIterator<EObject> eAllContents() {
+ return eStructuralFeature.eAllContents();
+ }
+
+ public boolean eIsProxy() {
+ return eStructuralFeature.eIsProxy();
+ }
+
+ public EList<EObject> eCrossReferences() {
+ return eStructuralFeature.eCrossReferences();
+ }
+
+ public Object eGet(EStructuralFeature feature) {
+ return eStructuralFeature.eGet(feature);
+ }
+
+ public Object eGet(EStructuralFeature feature, boolean resolve) {
+ return eStructuralFeature.eGet(feature, resolve);
+ }
+
+ public void eSet(EStructuralFeature feature, Object newValue) {
+ eStructuralFeature.eSet(feature, newValue);
+ }
+
+ public boolean eIsSet(EStructuralFeature feature) {
+ return eStructuralFeature.eIsSet(feature);
+ }
+
+ public void eUnset(EStructuralFeature feature) {
+ eStructuralFeature.eUnset(feature);
+ }
+
+ public Object eInvoke(EOperation operation, EList<?> arguments)
+ throws InvocationTargetException {
+ return eStructuralFeature.eInvoke(operation, arguments);
+ }
+
+ public EList<Adapter> eAdapters() {
+ return eStructuralFeature.eAdapters();
+ }
+
+ public boolean eDeliver() {
+ return eStructuralFeature.eDeliver();
+ }
+
+ public void eSetDeliver(boolean deliver) {
+ eStructuralFeature.eSetDeliver(deliver);
+ }
+
+ public void eNotify(Notification notification) {
+ eStructuralFeature.eNotify(notification);
+ }
+
+ public boolean eNotificationRequired() {
+ return eStructuralFeature.eNotificationRequired();
+ }
+
+ public String eURIFragmentSegment(EStructuralFeature eFeature,
+ EObject eObject) {
+ return eStructuralFeature.eURIFragmentSegment(eFeature, eObject);
+ }
+
+ public EObject eObjectForURIFragmentSegment(String uriFragmentSegment) {
+ return eStructuralFeature
+ .eObjectForURIFragmentSegment(uriFragmentSegment);
+ }
+
+ public void eSetClass(EClass eClass) {
+ eStructuralFeature.eSetClass(eClass);
+ }
+
+ public Setting eSetting(EStructuralFeature feature) {
+ return eStructuralFeature.eSetting(feature);
+ }
+
+ public int eBaseStructuralFeatureID(int derivedFeatureID,
+ Class<?> baseClass) {
+ return eStructuralFeature.eBaseStructuralFeatureID(derivedFeatureID,
+ baseClass);
+ }
+
+ public int eContainerFeatureID() {
+ return eStructuralFeature.eContainerFeatureID();
+ }
+
+ public int eDerivedStructuralFeatureID(int baseFeatureID,
+ Class<?> baseClass) {
+ return eStructuralFeature.eDerivedStructuralFeatureID(baseFeatureID,
+ baseClass);
+ }
+
+ public int eDerivedOperationID(int baseOperationID,
+ Class<?> baseClass) {
+ return eStructuralFeature.eDerivedOperationID(baseOperationID,
+ baseClass);
+ }
+
+ public NotificationChain eSetResource(
+ org.eclipse.emf.ecore.resource.Resource.Internal resource,
+ NotificationChain notifications) {
+ return eStructuralFeature.eSetResource(resource, notifications);
+ }
+
+ public NotificationChain eInverseAdd(InternalEObject otherEnd,
+ int featureID, Class<?> baseClass,
+ NotificationChain notifications) {
+ return eStructuralFeature.eInverseAdd(otherEnd, featureID,
+ baseClass, notifications);
+ }
+
+ public NotificationChain eInverseRemove(InternalEObject otherEnd,
+ int featureID, Class<?> baseClass,
+ NotificationChain notifications) {
+ return eStructuralFeature.eInverseRemove(otherEnd, featureID,
+ baseClass, notifications);
+ }
+
+ public NotificationChain eBasicSetContainer(
+ InternalEObject newContainer, int newContainerFeatureID,
+ NotificationChain notifications) {
+ return eStructuralFeature.eBasicSetContainer(newContainer,
+ newContainerFeatureID, notifications);
+ }
+
+ public NotificationChain eBasicRemoveFromContainer(
+ NotificationChain notifications) {
+ return eStructuralFeature.eBasicRemoveFromContainer(notifications);
+ }
+
+ public URI eProxyURI() {
+ return eStructuralFeature.eProxyURI();
+ }
+
+ public void eSetProxyURI(URI uri) {
+ eStructuralFeature.eSetProxyURI(uri);
+ }
+
+ public EObject eResolveProxy(InternalEObject proxy) {
+ return eStructuralFeature.eResolveProxy(proxy);
+ }
+
+ public InternalEObject eInternalContainer() {
+ return eStructuralFeature.eInternalContainer();
+ }
+
+ public org.eclipse.emf.ecore.resource.Resource.Internal eInternalResource() {
+ return eStructuralFeature.eInternalResource();
+ }
+
+ public org.eclipse.emf.ecore.resource.Resource.Internal eDirectResource() {
+ return eStructuralFeature.eDirectResource();
+ }
+
+ public EStore eStore() {
+ return eStructuralFeature.eStore();
+ }
+
+ public void eSetStore(EStore store) {
+ eStructuralFeature.eSetStore(store);
+ }
+
+ public Object eGet(EStructuralFeature eFeature, boolean resolve,
+ boolean coreType) {
+ return eStructuralFeature.eGet(eFeature, resolve, coreType);
+ }
+
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ return eStructuralFeature.eGet(featureID, resolve, coreType);
+ }
+
+ public void eSet(int featureID, Object newValue) {
+ eStructuralFeature.eSet(featureID, newValue);
+ }
+
+ public void eUnset(int featureID) {
+ eStructuralFeature.eUnset(featureID);
+ }
+
+ public boolean eIsSet(int featureID) {
+ return eStructuralFeature.eIsSet(featureID);
+ }
+
+ public Object eInvoke(int operationID, EList<?> arguments)
+ throws InvocationTargetException {
+ return eStructuralFeature.eInvoke(operationID, arguments);
+ }
+
+ public SettingDelegate getSettingDelegate() {
+ return eStructuralFeature.getSettingDelegate();
+ }
+
+ public void setSettingDelegate(SettingDelegate settingDelegate) {
+ eStructuralFeature.setSettingDelegate(settingDelegate);
+ }
+
+ public boolean isFeatureMap() {
+ return eStructuralFeature.isFeatureMap();
+ }
+
+ public org.eclipse.emf.ecore.util.FeatureMap.Entry.Internal getFeatureMapEntryPrototype() {
+ return eStructuralFeature.getFeatureMapEntryPrototype();
+ }
+
+ public void setFeatureMapEntryPrototype(
+ org.eclipse.emf.ecore.util.FeatureMap.Entry.Internal prototype) {
+ eStructuralFeature.setFeatureMapEntryPrototype(prototype);
+ }
+
+ public boolean isID() {
+ return eStructuralFeature.isID();
+ }
+
+ public boolean isResolveProxies() {
+ return eStructuralFeature.isResolveProxies();
+ }
+
+ public boolean isContainer() {
+ return eStructuralFeature.isContainer();
+ }
+
+ public boolean isContainment() {
+ return eStructuralFeature.isContainment();
+ }
+
+ public org.eclipse.emf.ecore.EReference getEOpposite() {
+ return eStructuralFeature.getEOpposite();
+ }
+
+ }
+
+ protected static class EReferenceWrapper
+ extends EStructuralFeatureWrapper
+ implements EReference {
+
+ protected EReferenceWrapper(EReference eReference) {
+ super((EStructuralFeature.Internal) eReference);
+ }
+
+ protected EReference getEReference() {
+ return (EReference) eStructuralFeature;
+ }
+
+ public void setContainment(boolean value) {
+ getEReference().setContainment(value);
+ }
+
+ public void setResolveProxies(boolean value) {
+ getEReference().setResolveProxies(value);
+ }
+
+ public void setEOpposite(EReference value) {
+ getEReference().setEOpposite(value);
+ }
+
+ public EClass getEReferenceType() {
+ return getEReference().getEReferenceType();
+ }
+
+ public EList<EAttribute> getEKeys() {
+ return getEReference().getEKeys();
+ }
+ }
+
/**
* Creates an instance of the resource.
* <!-- begin-user-doc -->
@@ -62,4 +527,40 @@
return true;
}
+ @Override
+ protected EObjectOutputStream createEObjectOutputStream(
+ OutputStream outputStream, Map<?, ?> options, Version version,
+ final URIHandler uriHandler)
+ throws IOException {
+ return new EObjectOutputStream(outputStream, options, version) {
+
+ @Override
+ protected URI deresolve(URI uri) {
+ return uriHandler == null
+ ? super.deresolve(uri)
+ : uriHandler.deresolve(uri);
+ }
+
+ @Override
+ protected EStructuralFeatureData createEStructuralFeatureData(
+ EStructuralFeature.Internal eStructuralFeature) {
+
+ if (eStructuralFeature == UMLPackage.Literals.ACTIVITY__GROUP
+ || eStructuralFeature == UMLPackage.Literals.ACTIVITY__NODE) {
+
+ eStructuralFeature = new EReferenceWrapper(
+ (EReference) eStructuralFeature) {
+
+ public boolean isTransient() {
+ return false;
+ }
+ };
+ }
+
+ return super.createEStructuralFeatureData(eStructuralFeature);
+ }
+
+ };
+ }
+
} //UMLResourceImpl
diff --git a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug528762Test.java b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug528762Test.java
new file mode 100644
index 0000000..5603616
--- /dev/null
+++ b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug528762Test.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2018 CEA 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:
+ * Sebastien Revol (CEA) - initial API and implementation
+ * Kenn Hussey - 528762
+ *
+ */
+package org.eclipse.uml2.uml.bug.tests;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+import org.eclipse.uml2.uml.Activity;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.UMLPackage;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class Bug528762Test
+ extends TestCase {
+
+ public Bug528762Test() {
+ super();
+ }
+
+ public static Test suite() {
+ return new TestSuite(Bug512520Test.class, "Bug 528762 tests"); //$NON-NLS-1$
+ }
+
+
+ public void testBinarySerialization() {
+ Model model = UMLFactory.eINSTANCE.createModel();
+ model.setName("modelName"); //$NON-NLS-1$
+ String activityName = "activity"; //$NON-NLS-1$
+
+ Activity activity = (Activity) model.createOwnedType(activityName,
+ UMLPackage.eINSTANCE.getActivity());
+
+ for (int i = 0; i < 10; i++) {
+ activity.createOwnedNode("action" + i, //$NON-NLS-1$
+ UMLPackage.eINSTANCE.getOpaqueAction());
+ }
+ assertEquals(10, activity.getOwnedNodes().size());
+ assertEquals(10, activity.getNodes().size());
+
+ try {
+ URI tmpURI = URI.createFileURI("Bug528762.uml"); //$NON-NLS-1$
+ ResourceSet resSet = new ResourceSetImpl();
+ Resource outputResource = resSet.createResource(tmpURI);
+ outputResource.getContents().add(model);
+
+ Map<Object, Object> options = new HashMap<Object, Object>();
+
+ options.put(XMIResource.OPTION_BINARY, Boolean.TRUE);
+ outputResource.save(options);
+
+ resSet = new ResourceSetImpl();
+
+ outputResource.unload();
+ outputResource.eAdapters().clear();
+
+ resSet.getResources().clear();
+ resSet.eAdapters().clear();
+
+ outputResource = resSet.createResource(tmpURI);
+
+ outputResource.unload();
+ outputResource.eAdapters().clear();
+
+ resSet.getResources().clear();
+ resSet.eAdapters().clear();
+
+ outputResource.unload();
+
+ outputResource.load(options);
+
+ model = (Model) outputResource.getContents().get(0);
+ activity = (Activity) model.getPackagedElement(activityName, false,
+ UMLPackage.eINSTANCE.getActivity(), false);
+ assertEquals(10, activity.getOwnedNodes().size());
+ assertEquals(10, activity.getNodes().size());
+
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ fail();
+ }
+ }
+
+}
diff --git a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java
index 2a939e1..ce507c2 100644
--- a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java
+++ b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017 CEA, Christian W. Damus, and others.
+ * Copyright (c) 2013, 2018 CEA, Christian W. Damus, 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
@@ -11,7 +11,7 @@
* Manuel Bork <bork@yatta.de> (Yatta Solutions GmbH) - 421756, 422000
* Kenn Hussey (CEA) - 424895, 511674, 512520
* Christian W. Damus - 444588, 497359, 501740
- * Kenn Hussey - 526679
+ * Kenn Hussey - 526679, 528762
*
*/
package org.eclipse.uml2.uml.bug.tests;
@@ -67,6 +67,7 @@
result.addTest(Bug501740Test.suite());
result.addTest(Bug511674Test.suite());
result.addTest(Bug512520Test.suite());
+ result.addTest(Bug528762Test.suite());
// keep this one at the end because it runs long
result.addTest(Bug332057Test.suite());