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);
-		}
-	}
-
-}