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