Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brörkens2013-08-16 10:56:26 +0000
committerMark Brörkens2013-08-16 10:56:26 +0000
commitbd0bed78246b36e1a603a213cbd8c1a596ff5cd5 (patch)
tree16113a104bc969682f92301b06ade70857fc7086
parentca39ccfcc4abcf072d514c79827cf75bf3fba4c5 (diff)
downloadorg.eclipse.rmf-bd0bed78246b36e1a603a213cbd8c1a596ff5cd5.tar.gz
org.eclipse.rmf-bd0bed78246b36e1a603a213cbd8c1a596ff5cd5.tar.xz
org.eclipse.rmf-bd0bed78246b36e1a603a213cbd8c1a596ff5cd5.zip
RESOLVED - bug 400951: Analyze potential side effects of
setIntrinsicIDToEObjectMap https://bugs.eclipse.org/bugs/show_bug.cgi?id=400951 added adapter that creates missing IDs as soon as an EObject that has an IDAttribute is added to the containment tree of the resource. Lookup caches for IDs and EObjects in a resource are implemented and are updated whenever in id is changed or EObjects with ID are removed or added.
-rw-r--r--org.eclipse.rmf.serialization2/src/org/eclipse/rmf/serialization/XMLPersistenceMappingResourceImpl.java238
-rw-r--r--org.eclipse.rmf.tests.serialization/resources/input/org.eclipse.rmf.tests.serialization.adapter/minimal.xml3
-rw-r--r--org.eclipse.rmf.tests.serialization/resources/input/org.eclipse.rmf.tests.serialization.adapter/minimalWithId.xml3
-rw-r--r--org.eclipse.rmf.tests.serialization/src/org/eclipse/rmf/tests/serialization/adapter/IDAdapterTests.java327
4 files changed, 567 insertions, 4 deletions
diff --git a/org.eclipse.rmf.serialization2/src/org/eclipse/rmf/serialization/XMLPersistenceMappingResourceImpl.java b/org.eclipse.rmf.serialization2/src/org/eclipse/rmf/serialization/XMLPersistenceMappingResourceImpl.java
index 6528cfaf..b8048a8d 100644
--- a/org.eclipse.rmf.serialization2/src/org/eclipse/rmf/serialization/XMLPersistenceMappingResourceImpl.java
+++ b/org.eclipse.rmf.serialization2/src/org/eclipse/rmf/serialization/XMLPersistenceMappingResourceImpl.java
@@ -11,14 +11,25 @@
package org.eclipse.rmf.serialization;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.xml.XMLConstants;
import org.apache.xerces.impl.Constants;
+import org.eclipse.emf.common.notify.Notification;
+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.EAttribute;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.ecore.xmi.XMLLoad;
import org.eclipse.emf.ecore.xmi.XMLOptions;
@@ -35,6 +46,205 @@ public class XMLPersistenceMappingResourceImpl extends XMLResourceImpl implement
// This is a temporal HACK
public boolean enableSchemaValidation = false;
+ class IdAdapter extends EContentAdapter {
+ public IdAdapter() {
+ super();
+ }
+
+ @Override
+ public boolean isAdapterForType(Object type) {
+ // TODO Auto-generated method stub
+ return super.isAdapterForType(type);
+ }
+
+ @Override
+ public void notifyChanged(Notification n) {
+ assert null != n.getNotifier();
+ super.notifyChanged(n); // the superclass handles adding/removing this Adapter to new Books
+
+ Object notifier_ = n.getNotifier();
+ if (!n.isTouch()) {
+ if (notifier_ instanceof EObject) {
+ Object feature = n.getFeature();
+ if (feature instanceof EAttribute) {
+ // handle changed id
+ EAttribute attribute = (EAttribute) feature;
+ if (attribute.isID()) {
+ String newId = n.getNewStringValue();
+ String oldId = n.getOldStringValue();
+ EObject objectWithId = (EObject) n.getNotifier();
+ switch (n.getEventType()) {
+ case Notification.SET:
+ if (null == newId) {
+ eObjectToIDMap.remove(objectWithId);
+ } else {
+ eObjectToIDMap.put(objectWithId, newId);
+ idToEObjectMap.put(newId, objectWithId);
+ }
+
+ if (null != oldId) {
+ idToEObjectMap.remove(oldId);
+ }
+ break;
+ case Notification.UNSET:
+ eObjectToIDMap.remove(objectWithId);
+ idToEObjectMap.remove(oldId);
+ break;
+ }
+ }
+ } else {
+ // handle removed or added objects
+ EReference reference = (EReference) feature;
+ if (reference.isContainment()) {
+
+ switch (n.getEventType()) {
+ case Notification.SET:
+ case Notification.ADD:
+ handleNewObjectAndSubObjects((EObject) n.getNewValue());
+ break;
+ case Notification.ADD_MANY:
+ EList<EObject> newObjects = (EList<EObject>) n.getNewValue();
+ int size = newObjects.size();
+ for (int i = 0; i < size; i++) {
+ handleNewObjectAndSubObjects(newObjects.get(i));
+ }
+ break;
+ case Notification.UNSET:
+ case Notification.REMOVE:
+ handleRemoveObjectAndSubObjects((EObject) n.getOldValue());
+ break;
+ case Notification.REMOVE_MANY:
+ EList<EObject> removeObjects = (EList<EObject>) n.getOldValue();
+ size = removeObjects.size();
+ for (int i = 0; i < size; i++) {
+ handleRemoveObjectAndSubObjects(removeObjects.get(i));
+ }
+ break;
+ }
+
+ }
+ }
+
+ } else if (notifier_ instanceof Resource) {
+ // feature is null
+ int featureID = n.getFeatureID(Resource.class);
+ if (Resource.RESOURCE__CONTENTS == featureID) {
+ switch (n.getEventType()) {
+ case Notification.SET:
+ case Notification.ADD:
+ handleNewObjectAndSubObjects((EObject) n.getNewValue());
+ break;
+ case Notification.ADD_MANY:
+ EList<EObject> newObjects = (EList<EObject>) n.getNewValue();
+ int size = newObjects.size();
+ for (int i = 0; i < size; i++) {
+ handleNewObjectAndSubObjects(newObjects.get(i));
+ }
+ break;
+ case Notification.UNSET:
+ case Notification.REMOVE:
+ handleRemoveObjectAndSubObjects((EObject) n.getOldValue());
+ break;
+ case Notification.REMOVE_MANY:
+ EList<EObject> removeObjects = (EList<EObject>) n.getOldValue();
+ size = removeObjects.size();
+ for (int i = 0; i < size; i++) {
+ handleRemoveObjectAndSubObjects(removeObjects.get(i));
+ }
+ break;
+ }
+ }
+ } else if (notifier_ instanceof ResourceSet) {
+ // NOP
+ } else {
+ // NOP
+ }
+
+ } // end if isTouch
+
+ }// end notifyChanged
+
+ void handleNewObjectAndSubObjects(EObject objectWithId) {
+ if (null != objectWithId) {
+ handleNewObject(objectWithId);
+ }
+ TreeIterator<EObject> iterator = objectWithId.eAllContents();
+ while (iterator.hasNext()) {
+ handleNewObject(iterator.next());
+ }
+ }
+
+ void handleNewObject(EObject objectWithId) {
+ assert null != objectWithId;
+ EAttribute idAttribute = objectWithId.eClass().getEIDAttribute();
+ if (null != idAttribute) {
+ String id = (String) objectWithId.eGet(idAttribute);
+ if (id == null || 0 == id.length()) {
+ id = EcoreUtil.generateUUID();
+ objectWithId.eSet(idAttribute, id);
+ // id map gets updated by notification on setId
+ } else {
+ eObjectToIDMap.put(objectWithId, id);
+ idToEObjectMap.put(id, objectWithId);
+ }
+ }
+ }
+
+ void handleRemoveObjectAndSubObjects(EObject objectWithId) {
+ if (null != objectWithId) {
+ handleRemoveObject(objectWithId);
+ }
+ TreeIterator<EObject> iterator = objectWithId.eAllContents();
+ while (iterator.hasNext()) {
+ handleRemoveObject(iterator.next());
+ }
+ }
+
+ void handleRemoveObject(EObject objectWithId) {
+ assert null != objectWithId;
+ String id = eObjectToIDMap.remove(objectWithId);
+ if (null != id) {
+ idToEObjectMap.remove(id);
+ }
+ }
+
+ }
+
+ class ResourceHandlerImpl implements ResourceHandler {
+
+ ResourceHandlerImpl(Resource resource) {
+ super();
+ }
+
+ public void preLoad(XMLResource resource, InputStream inputStream, Map<?, ?> options) {
+ // NOP
+ }
+
+ public void postLoad(XMLResource resource, InputStream inputStream, Map<?, ?> options) {
+ // register ContentAdapter for setting IDs and updating the intrinsic Id to EObject map
+ System.out.println("postLoadActions");
+ /*
+ * EList<EObject> contents = resource.getContents(); int size = contents.size(); for (int i = 0; i < size;
+ * i++) { contents.get(i).eAdapters().add(idAdapter); } // set the id maps TreeIterator<EObject> iterator =
+ * resource.getAllContents(); Map<String, EObject> id2eObjectMap = getIDToEObjectMap(); Map<EObject, String>
+ * eObject2IdMap = getEObjectToIDMap(); while (iterator.hasNext()) { EObject eObject = iterator.next();
+ * String id = EcoreUtil.getID(eObject); if (null != id && 0 < id.length()) { id2eObjectMap.put(id,
+ * eObject); eObject2IdMap.put(eObject, id); } }
+ */
+ }
+
+ public void preSave(XMLResource resource, OutputStream outputStream, Map<?, ?> options) {
+ // NOP
+
+ }
+
+ public void postSave(XMLResource resource, OutputStream outputStream, Map<?, ?> options) {
+ // NOP
+
+ }
+
+ }
+
public XMLPersistenceMappingResourceImpl() {
super();
initDefaultOptions();
@@ -74,7 +284,22 @@ public class XMLPersistenceMappingResourceImpl extends XMLResourceImpl implement
return object;
}
+ /**
+ * Initializes the resource. Is called by the constructors of XMLResourceImpl
+ */
+ @Override
+ protected void init() {
+ encoding = "UTF-8";
+ xmlVersion = "1.0";
+ // enable id creation and maintenance
+ idToEObjectMap = new HashMap<String, EObject>();
+ eObjectToIDMap = new HashMap<EObject, String>();
+ eAdapters().add(new IdAdapter());
+
+ }
+
public void initDefaultOptions() {
+ ResourceHandler resourceHandler = new ResourceHandlerImpl(this);
// ========= default save options ===================
Map<Object, Object> saveOptions = getDefaultSaveOptions();
// set encoding to UTF-8
@@ -89,6 +314,8 @@ public class XMLPersistenceMappingResourceImpl extends XMLResourceImpl implement
saveOptions.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.FALSE);
+ saveOptions.put(XMLResource.OPTION_RESOURCE_HANDLER, resourceHandler);
+
// ========= default load options ===================
Map<Object, Object> loadOptions = getDefaultLoadOptions();
// get XML names and attribute/value information from extended metadata
@@ -108,6 +335,13 @@ public class XMLPersistenceMappingResourceImpl extends XMLResourceImpl implement
// Performance enhancement
loadOptions.put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, Boolean.TRUE);
+ loadOptions.put(XMLResource.OPTION_RESOURCE_HANDLER, resourceHandler);
+
+ // defer attachment of object tree created during load to end of load process.
+ // this creating notifications by EContentAdapters that might be registered for the resource or resource set
+ // during load
+ loadOptions.put(XMLResource.OPTION_DEFER_ATTACHMENT, Boolean.TRUE);
+
// Retrieve application-defined XMLReader features (see http://xerces.apache.org/xerces2-j/features.html for
// available features and their details)
Map<String, Boolean> parserFeatures = new HashMap<String, Boolean>();
@@ -141,10 +375,6 @@ public class XMLPersistenceMappingResourceImpl extends XMLResourceImpl implement
loadOptions.put(XMLResource.OPTION_XML_OPTIONS, xmlOptions);
- // Sets the map used to cache the EObject identified by the value of its ID feature.
- // TODO: This is related to https://git.eclipse.org/r/#/c/8251/ and should be reviewed by Mark.
- setIntrinsicIDToEObjectMap(new HashMap<String, EObject>());
-
}
}
diff --git a/org.eclipse.rmf.tests.serialization/resources/input/org.eclipse.rmf.tests.serialization.adapter/minimal.xml b/org.eclipse.rmf.tests.serialization/resources/input/org.eclipse.rmf.tests.serialization.adapter/minimal.xml
new file mode 100644
index 00000000..36df2871
--- /dev/null
+++ b/org.eclipse.rmf.tests.serialization/resources/input/org.eclipse.rmf.tests.serialization.adapter/minimal.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<nodes:NODE xmlns:nodes="http://www.eclipse.org/rmf/serialization/model/nodes.ecore">
+</nodes:NODE>
diff --git a/org.eclipse.rmf.tests.serialization/resources/input/org.eclipse.rmf.tests.serialization.adapter/minimalWithId.xml b/org.eclipse.rmf.tests.serialization/resources/input/org.eclipse.rmf.tests.serialization.adapter/minimalWithId.xml
new file mode 100644
index 00000000..6b37aadc
--- /dev/null
+++ b/org.eclipse.rmf.tests.serialization/resources/input/org.eclipse.rmf.tests.serialization.adapter/minimalWithId.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<nodes:NODE xmlns:nodes="http://www.eclipse.org/rmf/serialization/model/nodes.ecore" name="root">
+</nodes:NODE>
diff --git a/org.eclipse.rmf.tests.serialization/src/org/eclipse/rmf/tests/serialization/adapter/IDAdapterTests.java b/org.eclipse.rmf.tests.serialization/src/org/eclipse/rmf/tests/serialization/adapter/IDAdapterTests.java
new file mode 100644
index 00000000..de3c7321
--- /dev/null
+++ b/org.eclipse.rmf.tests.serialization/src/org/eclipse/rmf/tests/serialization/adapter/IDAdapterTests.java
@@ -0,0 +1,327 @@
+/**
+ * Copyright (c) 2013 itemis AG.
+ * 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:
+ * itemis AG - initial API and implementation
+ */
+package org.eclipse.rmf.tests.serialization.adapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.rmf.serialization.XMLPersistenceMappingResourceFactoryImpl;
+import org.eclipse.rmf.serialization.XMLPersistenceMappingResourceImpl;
+import org.eclipse.rmf.tests.serialization.model.nodes.Node;
+import org.eclipse.rmf.tests.serialization.model.nodes.NodesFactory;
+import org.eclipse.rmf.tests.serialization.model.nodes.NodesPackage;
+import org.eclipse.rmf.tests.serialization.util.AbstractTestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+// Junit 3.8 test
+@SuppressWarnings("nls")
+public class IDAdapterTests extends AbstractTestCase {
+
+ static final String INPUT_PATH = "org.eclipse.rmf.tests.serialization.adapter/";
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ EPackage.Registry.INSTANCE.put(NodesPackage.eNS_URI, NodesPackage.eINSTANCE);
+ }
+
+ @Test
+ public void testIdOnLoad() {
+ String inputFileName = INPUT_PATH + "minimal.xml";
+ try {
+ EObject modelRoot = loadInputFile(inputFileName, new XMLPersistenceMappingResourceFactoryImpl(), null);
+ assertTrue(modelRoot instanceof Node);
+ Node rootNode = (Node) modelRoot;
+ assertTrue(rootNode.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ assertTrue(ex.getMessage(), false);
+ }
+ }
+
+ @Test
+ public void testIdOnLoadNotModified() {
+ String inputFileName = INPUT_PATH + "minimalWithId.xml";
+ try {
+ EObject modelRoot = loadInputFile(inputFileName, new XMLPersistenceMappingResourceFactoryImpl(), null);
+ assertTrue(modelRoot instanceof Node);
+ Node rootNode = (Node) modelRoot;
+ assertEquals("root", rootNode.getName());
+
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ assertTrue(ex.getMessage(), false);
+ }
+ }
+
+ @Test
+ public void testIdForNewObjectsAfterLoad1() {
+ String inputFileName = INPUT_PATH + "minimal.xml";
+ try {
+ EObject modelRoot = loadInputFile(inputFileName, new XMLPersistenceMappingResourceFactoryImpl(), null);
+ assertTrue(modelRoot instanceof Node);
+ Node rootNode = (Node) modelRoot;
+ assertTrue(rootNode.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertSame(1, ((XMLResource) modelRoot.eResource()).getEObjectToIDMap().size());
+
+ // test set
+ Node subNode = NodesFactory.eINSTANCE.createNode();
+ rootNode.setEReference_Contained0100Single(subNode);
+ assertTrue(subNode.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertSame(2, ((XMLResource) modelRoot.eResource()).getEObjectToIDMap().size());
+
+ // test add single
+ rootNode.getEReference_Contained1100Many().add(NodesFactory.eINSTANCE.createNode());
+ assertTrue(5 < rootNode.getEReference_Contained1100Many().get(0).getName().length());
+ assertSame(3, ((XMLResource) modelRoot.eResource()).getEObjectToIDMap().size());
+
+ // test add many
+ List<Node> newNodes = new ArrayList<Node>();
+ for (int i = 0; i < 5; i++) {
+ newNodes.add(NodesFactory.eINSTANCE.createNode());
+ }
+ rootNode.getEReference_Contained0100Many().addAll(newNodes);
+ for (int i = 0; i < 5; i++) {
+ assertTrue(5 < rootNode.getEReference_Contained0100Many().get(i).getName().length());
+ }
+ assertSame(8, ((XMLResource) modelRoot.eResource()).getEObjectToIDMap().size());
+
+ } catch (Exception ex) {
+ assertTrue(ex.getMessage(), false);
+ }
+ }
+
+ @Test
+ public void testIdForNewObjectsAfterLoad2() {
+ String inputFileName = INPUT_PATH + "minimal.xml";
+ try {
+ EObject modelRoot = loadInputFile(inputFileName, new XMLPersistenceMappingResourceFactoryImpl(), null);
+ assertTrue(modelRoot instanceof Node);
+ Node rootNode = (Node) modelRoot;
+ assertTrue(rootNode.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertSame(1, ((XMLResource) modelRoot.eResource()).getEObjectToIDMap().size());
+
+ // test set
+ Node sub1Node = NodesFactory.eINSTANCE.createNode();
+ Node sub2Node = NodesFactory.eINSTANCE.createNode();
+ Node sub3Node = NodesFactory.eINSTANCE.createNode();
+ Node sub4Node = NodesFactory.eINSTANCE.createNode();
+ sub4Node.setName("sub4Node");
+
+ sub1Node.setEReference_Contained0101Single(sub2Node);
+ sub2Node.setEReference_Contained0101Single(sub3Node);
+ sub3Node.setEReference_Contained0101Single(sub4Node);
+
+ assertFalse(sub1Node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertFalse(sub2Node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertFalse(sub3Node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertTrue(sub4Node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertEquals("sub4Node", sub4Node.getName());
+ assertSame(1, ((XMLResource) modelRoot.eResource()).getEObjectToIDMap().size());
+
+ // set
+ rootNode.setEReference_Contained0100Single(sub1Node);
+
+ assertTrue(sub1Node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertTrue(sub2Node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertTrue(sub3Node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertTrue(sub4Node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertEquals("sub4Node", sub4Node.getName());
+ assertSame(5, ((XMLResource) modelRoot.eResource()).getEObjectToIDMap().size());
+
+ } catch (Exception ex) {
+ assertTrue(ex.getMessage(), false);
+ }
+ }
+
+ @Test
+ public void testAddNewElementToEmptyResource() {
+ Resource resource = new XMLPersistenceMappingResourceImpl();
+ Node node = NodesFactory.eINSTANCE.createNode();
+ Node subNode = NodesFactory.eINSTANCE.createNode();
+ node.getEReference_Contained0100Many().add(subNode);
+ assertFalse(node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertFalse(subNode.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+
+ resource.getContents().add(node);
+ assertTrue(node.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ assertTrue(subNode.eIsSet(NodesPackage.eINSTANCE.getNode_Name()));
+ }
+
+ @Test
+ public void testIdMapSet() {
+ XMLResource resource = new XMLPersistenceMappingResourceImpl();
+ String nodeName = "root";
+ String subNodeName = "subNode";
+ Node node = NodesFactory.eINSTANCE.createNode();
+ node.setName(nodeName);
+ Node subNode = NodesFactory.eINSTANCE.createNode();
+ subNode.setName(subNodeName);
+ node.setEReference_Contained0100Single(subNode);
+
+ assertNull(resource.getEObject(nodeName));
+ assertNull(resource.getID(node));
+ assertNull(resource.getEObject(subNodeName));
+ assertNull(resource.getID(subNode));
+
+ resource.getContents().add(node);
+ assertSame(node, resource.getEObject(nodeName));
+ assertSame(nodeName, resource.getID(node));
+
+ assertSame(subNode, resource.getEObject(subNodeName));
+ assertSame(subNodeName, resource.getID(subNode));
+ }
+
+ @Test
+ public void testIdMapAdd() {
+ XMLResource resource = new XMLPersistenceMappingResourceImpl();
+ String nodeName = "root";
+ String subNodeName = "subNode";
+ Node node = NodesFactory.eINSTANCE.createNode();
+ node.setName(nodeName);
+ Node subNode = NodesFactory.eINSTANCE.createNode();
+ subNode.setName(subNodeName);
+ node.getEReference_Contained0100Many().add(subNode);
+
+ assertNull(resource.getEObject(nodeName));
+ assertNull(resource.getID(node));
+ assertNull(resource.getEObject(subNodeName));
+ assertNull(resource.getID(subNode));
+
+ resource.getContents().add(node);
+ assertSame(node, resource.getEObject(nodeName));
+ assertSame(nodeName, resource.getID(node));
+
+ assertSame(subNode, resource.getEObject(subNodeName));
+ assertSame(subNodeName, resource.getID(subNode));
+ }
+
+ @Test
+ public void testIdMapAddMany() {
+ XMLResource resource = new XMLPersistenceMappingResourceImpl();
+ String node1Name = "node1";
+ String node2Name = "node2";
+ Node node1 = NodesFactory.eINSTANCE.createNode();
+ node1.setName(node1Name);
+ Node node2 = NodesFactory.eINSTANCE.createNode();
+ node2.setName(node2Name);
+ List<Node> nodes = new ArrayList<Node>(2);
+ nodes.add(node1);
+ nodes.add(node2);
+
+ assertNull(resource.getEObject(node1Name));
+ assertNull(resource.getID(node1));
+ assertNull(resource.getEObject(node2Name));
+ assertNull(resource.getID(node2));
+
+ resource.getContents().addAll(nodes);
+
+ assertSame(node1, resource.getEObject(node1Name));
+ assertSame(node1Name, resource.getID(node1));
+
+ assertSame(node2, resource.getEObject(node2Name));
+ assertSame(node2Name, resource.getID(node2));
+ }
+
+ @Test
+ public void testIdMapMove() {
+ XMLResource resource = new XMLPersistenceMappingResourceImpl();
+ String nodeName = "root";
+ String subNodeName = "subNode";
+ Node node = NodesFactory.eINSTANCE.createNode();
+ node.setName(nodeName);
+ Node subNode = NodesFactory.eINSTANCE.createNode();
+ subNode.setName(subNodeName);
+ node.getEReference_Contained0100Many().add(subNode);
+
+ assertNull(resource.getEObject(nodeName));
+ assertNull(resource.getID(node));
+ assertNull(resource.getEObject(subNodeName));
+ assertNull(resource.getID(subNode));
+
+ resource.getContents().add(node);
+ assertSame(node, resource.getEObject(nodeName));
+ assertSame(nodeName, resource.getID(node));
+ assertSame(subNode, resource.getEObject(subNodeName));
+ assertSame(subNodeName, resource.getID(subNode));
+
+ node.setEReference_Contained0100Single(subNode);
+ assertSame(node, resource.getEObject(nodeName));
+ assertSame(nodeName, resource.getID(node));
+ assertSame(subNode, resource.getEObject(subNodeName));
+ assertSame(subNodeName, resource.getID(subNode));
+ }
+
+ @Test
+ public void testIdMapRemove() {
+ XMLResource resource = new XMLPersistenceMappingResourceImpl();
+ String nodeName = "root";
+ String subNodeName = "subNode";
+ Node node = NodesFactory.eINSTANCE.createNode();
+ node.setName(nodeName);
+ Node subNode = NodesFactory.eINSTANCE.createNode();
+ subNode.setName(subNodeName);
+ node.getEReference_Contained0100Many().add(subNode);
+
+ assertNull(resource.getEObject(nodeName));
+ assertNull(resource.getID(node));
+ assertNull(resource.getEObject(subNodeName));
+ assertNull(resource.getID(subNode));
+
+ resource.getContents().add(node);
+ assertSame(node, resource.getEObject(nodeName));
+ assertSame(nodeName, resource.getID(node));
+ assertSame(subNode, resource.getEObject(subNodeName));
+ assertSame(subNodeName, resource.getID(subNode));
+
+ node.getEReference_Contained0100Many().remove(subNode);
+ assertSame(node, resource.getEObject(nodeName));
+ assertSame(nodeName, resource.getID(node));
+ assertNull(resource.getEObject(subNodeName));
+ assertNull(resource.getID(subNode));
+
+ resource.getContents().remove(node);
+ assertNull(resource.getEObject(nodeName));
+ assertNull(resource.getID(node));
+ assertNull(resource.getEObject(subNodeName));
+ assertNull(resource.getID(subNode));
+ }
+
+ @Test
+ public void testIdMapRename() {
+ XMLResource resource = new XMLPersistenceMappingResourceImpl();
+ String nodeName = "root";
+ String newNodeName = "new_root";
+ Node node = NodesFactory.eINSTANCE.createNode();
+ node.setName(nodeName);
+
+ assertNull(resource.getEObject(nodeName));
+ assertNull(resource.getID(node));
+
+ resource.getContents().add(node);
+ assertNull(resource.getEObject(newNodeName));
+ assertSame(node, resource.getEObject(nodeName));
+ assertSame(nodeName, resource.getID(node));
+
+ node.setName(newNodeName);
+ assertNull(resource.getEObject(nodeName));
+ assertSame(node, resource.getEObject(newNodeName));
+ assertSame(newNodeName, resource.getID(node));
+ }
+
+}

Back to the top