/** * <copyright> * * Copyright (c) 2009 Springsite BV (The Netherlands) 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: * Martin Taal - Initial API and implementation * * </copyright> * * $Id: PersistentStoreAdapter.java,v 1.1 2009/03/15 08:09:24 mtaal Exp $ */ package org.eclipse.emf.teneo.type; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.ecore.EStructuralFeature; /** * Keeps a list of PersistentLists by efeature. Is used when a new object is * persisted and the OR-layer wants to replace the list implementation. * * This adapter keeps the PersistentList and ensures that any updates in the * original list are also done in the persistent store. * * This adapter only operates in case the target object is not read from the * persistent store but is persisted there for the first time. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> * @version $Revision: 1.1 $ */ public class PersistentStoreAdapter implements Adapter { private static final long serialVersionUID = 1L; private Notifier target; private boolean targetCreatedByORM; private Map<EStructuralFeature, Object> storeCollections = new HashMap<EStructuralFeature, Object>(); public void addStoreCollection(EStructuralFeature eFeature, Object storeCollection) { // note that when refresh is called on a persisted object // then this call replaces the current collection storeCollections.put(eFeature, storeCollection); } public Object getStoreCollection(EStructuralFeature eFeature) { return storeCollections.get(eFeature); } /* * (non-Javadoc) * * @see org.eclipse.emf.common.notify.Adapter#getTarget() */ public Notifier getTarget() { return target; } /* * (non-Javadoc) * * @see * org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object) */ public boolean isAdapterForType(Object type) { return true; } /* * (non-Javadoc) * * @see * org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common * .notify.Notification) */ public void notifyChanged(Notification notification) { final EStructuralFeature eFeature = (EStructuralFeature) notification .getFeature(); final Object collectionObject = storeCollections.get(eFeature); if (collectionObject == null) { return; } @SuppressWarnings("unchecked") final List<Object> list = (collectionObject instanceof List ? (List<Object>) collectionObject : null); final Map<Object, Object> map = (collectionObject instanceof Map<?, ?> ? (Map<Object, Object>) collectionObject : null); switch (notification.getEventType()) { case Notification.ADD: if (list != null) { if (notification.getPosition() != Notification.NO_INDEX) { list.add(notification.getPosition(), replaceValue( notification.getNewValue(), eFeature)); } else { list .add(replaceValue(notification.getNewValue(), eFeature)); } } if (map != null) { final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) notification .getNewValue(); map.put(entry.getKey(), entry.getValue()); } break; case Notification.ADD_MANY: if (list != null) { if (notification.getPosition() != Notification.NO_INDEX) { list.addAll(notification.getPosition(), replaceValues((List<Object>) notification .getNewValue(), eFeature)); } else { list.addAll(replaceValues((List<Object>) notification .getNewValue(), eFeature)); } } if (map != null) { for (Object o : (List<?>) notification.getNewValue()) { final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; map.put(entry.getKey(), entry.getValue()); } } break; case Notification.REMOVE: if (list != null) { if (notification.getPosition() != Notification.NO_INDEX) { list.remove(notification.getPosition()); } else { list.remove(replaceValue(notification.getOldValue(), eFeature)); } } if (map != null) { final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) notification .getNewValue(); map.remove(entry.getKey()); } break; case Notification.REMOVE_MANY: if (list != null) { list.removeAll(replaceValues((List<Object>) notification .getOldValue(), eFeature)); } if (map != null) { for (Object o : (List<?>) notification.getNewValue()) { final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o; map.remove(entry.getKey()); } } break; case Notification.MOVE: if (list != null) { final int oldPosition = (Integer) notification.getOldValue(); final int newPosition = notification.getPosition(); final Object o = list.remove(oldPosition); if (o != notification.getNewValue()) { throw new IllegalStateException( "Persistent list and EList are out of sync"); } list.add(newPosition, o); } break; case Notification.SET: if (list != null) { final int position = notification.getPosition(); list.set(position, replaceValue(notification.getNewValue(), eFeature)); } break; } } /* * (non-Javadoc) * * @see * org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common * .notify.Notifier) */ public void setTarget(Notifier newTarget) { target = newTarget; } /** * @return the targetCreatedByORM */ public boolean isTargetCreatedByORM() { return targetCreatedByORM; } /** * @param targetCreatedByORM * the targetCreatedByORM to set */ public void setTargetCreatedByORM(boolean targetCreatedByORM) { this.targetCreatedByORM = targetCreatedByORM; } /** * @return the storeCollections */ public Map<EStructuralFeature, Object> getStoreCollections() { return storeCollections; } protected Object replaceValue(Object value, EStructuralFeature eFeature) { return value; } protected List<Object> replaceValues(List<Object> values, EStructuralFeature eFeature) { return values; } }