Manage the generation of UUID directly in the class
ReqIF10ResourceImpl.java.
For every object added (Via Contextual Menu, D&D, Copy/Paste, ...) a new
identifier is generated.
The IdAdapter.java class is no longer needed so it was deleted.
Change-Id: I6ff1460a7f36467fb1cc3ab5e757fbfd2cea6e4d
Signed-off-by: Hussein MHANNA <hussein.mhanna@all4tec.net>
diff --git a/org.eclipse.rmf.reqif10.serialization/src/org/eclipse/rmf/reqif10/serialization/ReqIF10ResourceImpl.java b/org.eclipse.rmf.reqif10.serialization/src/org/eclipse/rmf/reqif10/serialization/ReqIF10ResourceImpl.java
index 79cd7db..edcb920 100644
--- a/org.eclipse.rmf.reqif10.serialization/src/org/eclipse/rmf/reqif10/serialization/ReqIF10ResourceImpl.java
+++ b/org.eclipse.rmf.reqif10.serialization/src/org/eclipse/rmf/reqif10/serialization/ReqIF10ResourceImpl.java
@@ -10,55 +10,119 @@
*/
package org.eclipse.rmf.reqif10.serialization;
-import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.XMLSave;
+import org.eclipse.emf.ecore.xmi.impl.XMLMapImpl;
+import org.eclipse.rmf.internal.serialization.XMLPersistenceMappingSaveImpl;
+import org.eclipse.rmf.reqif10.Identifiable;
import org.eclipse.rmf.reqif10.ReqIF10Package;
import org.eclipse.rmf.reqif10.xhtml.XhtmlPackage;
-import org.eclipse.rmf.serialization.IdAdapter;
import org.eclipse.rmf.serialization.XMLPersistenceMappingResourceImpl;
public class ReqIF10ResourceImpl extends XMLPersistenceMappingResourceImpl {
public ReqIF10ResourceImpl() {
super();
- initDefaultOptions();
}
public ReqIF10ResourceImpl(URI uri) {
super(uri);
- initDefaultOptions();
- }
-
- @Override
- protected void init() {
- super.init();
- // enable id creation and maintenance
- idToEObjectMap = new HashMap<String, EObject>();
- eObjectToIDMap = new HashMap<EObject, String>();
- Collection<EPackage> createIdForPackageSet = new HashSet<EPackage>();
- createIdForPackageSet.add(ReqIF10Package.eINSTANCE);
- eAdapters().add(new IdAdapter(idToEObjectMap, eObjectToIDMap, createIdForPackageSet));
}
@Override
public void initDefaultOptions() {
super.initDefaultOptions();
+ // ========= create options map===================
+ final XMLResource.XMLMap optionsMap = new XMLMapImpl();
+ optionsMap
+ .setIDAttributeName(ReqIF10Package.Literals.IDENTIFIABLE__IDENTIFIER
+ .getName());
+
// ========= default save options ===================
Map<Object, Object> saveOptions = getDefaultSaveOptions();
Map<String, String> namespaceToPrefixMap = new HashMap<String, String>();
namespaceToPrefixMap.put(ReqIF10Package.eNS_URI, ""); //$NON-NLS-1$
namespaceToPrefixMap.put(XhtmlPackage.eNS_URI, "xhtml"); //$NON-NLS-1$
saveOptions.put(OPTION_NAMEPSACE_TO_PREFIX_MAP, namespaceToPrefixMap);
-
+ saveOptions.put(XMLResource.OPTION_XML_MAP, optionsMap);
+
// ========= default load options ===================
Map<Object, Object> loadOptions = getDefaultLoadOptions();
+ loadOptions.put(XMLResource.OPTION_XML_MAP, optionsMap);
}
+ /**
+ * Return <code>true</code>.
+ *
+ * @return <code>true</code>.
+ *
+ * @see org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl#useUUIDs()
+ */
+ @Override
+ protected boolean useUUIDs() {
+ return true;
+ }
+
+ /**
+ * Return <code>false</code>.
+ *
+ * @return <code>false</code>.
+ *
+ * @see org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl#assignIDsWhileLoading()
+ */
+ @Override
+ protected final boolean assignIDsWhileLoading() {
+ return false;
+ }
+
+ /**
+ * Sets the ID of the object. The default implementation will update the
+ * {@link #eObjectToIDMap}. This behavior is override to set the ID in a
+ * object's specific attribute to set the id in the
+ * {@link Identifiable#setIdentifier(String)} and call the super method.
+ *
+ * @param eObject
+ * : The object where the Id must be set.
+ * @param id
+ * : The object's Id.
+ * @see org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl#setID(org.eclipse.emf.ecore.EObject,
+ * java.lang.String)
+ */
+ @Override
+ public void setID(final EObject eObject, final String id) {
+ final EAttribute idAttribute = eObject.eClass().getEIDAttribute();
+ if ((idAttribute != null) && (id != null)) {
+ eObject.eSet(idAttribute, id);
+ }
+ super.setID(eObject, id);
+ }
+
+ /**
+ * Create a new XMLSave implementation, with our specific implementation to
+ * avoid the save of the id of an {@link EObject} twice via the
+ * {@link Identifiable#getIdentifier()} and the #idToEObjectMap.
+ *
+ * @return The XMLSave created
+ *
+ * @see org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl#createXMLSave()
+ */
+ @Override
+ protected XMLSave createXMLSave() {
+ return new XMLPersistenceMappingSaveImpl(createXMLHelper()) {
+
+ @Override
+ protected void saveElementID(final EObject o) {
+ // As the identifier is an EStructuralFeture of the Identifiable
+ // class, so we ignore the save of the element id from the map.
+ this.saveFeatures(o);
+ }
+ };
+ }
}
diff --git a/org.eclipse.rmf.serialization/META-INF/MANIFEST.MF b/org.eclipse.rmf.serialization/META-INF/MANIFEST.MF
index 5f4b70d..a2ae1c4 100644
--- a/org.eclipse.rmf.serialization/META-INF/MANIFEST.MF
+++ b/org.eclipse.rmf.serialization/META-INF/MANIFEST.MF
@@ -9,6 +9,7 @@
org.eclipse.emf.ecore.xmi;bundle-version="2.7.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.eclipse.rmf.serialization
+Export-Package: org.eclipse.rmf.internal.serialization,
+ org.eclipse.rmf.serialization
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
diff --git a/org.eclipse.rmf.serialization/src/org/eclipse/rmf/serialization/IdAdapter.java b/org.eclipse.rmf.serialization/src/org/eclipse/rmf/serialization/IdAdapter.java
deleted file mode 100644
index 0de7ac2..0000000
--- a/org.eclipse.rmf.serialization/src/org/eclipse/rmf/serialization/IdAdapter.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/**
- * Copyright (c) 2013 itemis AG 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:
- * Mark Broerkens - initial API and implementation
- *
- */
-package org.eclipse.rmf.serialization;
-
-import java.util.Collection;
-import java.util.Map;
-
-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.ecore.EAttribute;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EPackage;
-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;
-
-public class IdAdapter extends EContentAdapter {
- final Map<String, EObject> idToEObjectMap;
- final Map<EObject, String> eObjectToIDMap;
- final Collection<EPackage> createIdForPackages;
-
- public IdAdapter(Map<String, EObject> idToEObjectMap, Map<EObject, String> eObjectToIDMap, Collection<EPackage> createIdForPackages) {
- super();
- this.idToEObjectMap = idToEObjectMap;
- this.eObjectToIDMap = eObjectToIDMap;
- this.createIdForPackages = createIdForPackages;
- }
-
- @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()) && createIdForPackages.contains(objectWithId.eClass().getEPackage())) {
- 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);
- }
- }
-
-}