/******************************************************************************* * Copyright (c) 2005 IBM Corporation 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.bpel.common.extension.model.impl; import java.util.AbstractCollection; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import org.eclipse.bpel.common.extension.model.Extension; import org.eclipse.bpel.common.extension.model.ExtensionMap; import org.eclipse.bpel.common.extension.model.ExtensionmodelFactory; import org.eclipse.bpel.common.extension.model.ExtensionmodelPackage; import org.eclipse.bpel.common.extension.model.adapters.ExtendedObjectAdapter; import org.eclipse.bpel.common.extension.model.adapters.ExtendedObjectUserAdapter; import org.eclipse.bpel.common.extension.model.adapters.impl.ExtendedObjectAdapterImpl; import org.eclipse.bpel.common.extension.model.adapters.impl.ExtendedObjectUserAdapterImpl; import org.eclipse.bpel.common.extension.model.adapters.impl.ExtensionAdapterImpl; import org.eclipse.bpel.common.extension.model.adapters.impl.ExtensionMapAdapterImpl; import org.eclipse.bpel.common.extension.model.notify.ExtensionModelNotification; import org.eclipse.bpel.common.extension.model.notify.impl.ExtensionModelNotificationImpl; import org.eclipse.bpel.common.extension.model.util.ExtensionmodelAdapterFactory; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.emf.ecore.impl.EObjectImpl; import org.eclipse.emf.ecore.util.EObjectContainmentEList; import org.eclipse.emf.ecore.util.InternalEList; /** * <!-- begin-user-doc --> * An implementation of the model object '<em><b>Extension Set</b></em>'. * <!-- end-user-doc --> * <p> * The following features are implemented: * <ul> * <li>{@link org.eclipse.bpel.common.extension.model.impl.ExtensionMapImpl#getNamespace <em>Namespace</em>}</li> * <li>{@link org.eclipse.bpel.common.extension.model.impl.ExtensionMapImpl#getExtensions <em>Extensions</em>}</li> * </ul> * </p> * * @generated */ public class ExtensionMapImpl extends EObjectImpl implements ExtensionMap { /** * The default value of the '{@link #getNamespace() <em>Namespace</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getNamespace() * @generated * @ordered */ protected static final String NAMESPACE_EDEFAULT = null; /** * The cached value of the '{@link #getNamespace() <em>Namespace</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getNamespace() * @generated * @ordered */ protected String namespace = NAMESPACE_EDEFAULT; /** * The cached value of the '{@link #getExtensions() <em>Extensions</em>}' containment reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getExtensions() * @generated * @ordered */ protected EList<Extension> extensions = null; /** * The value of the user adapter if one has been instantiated via the initializeAdapter() * method. This attribute is not modeled as it is not required to * serialize its value. * @customized */ private ExtendedObjectUserAdapter userAdapter = null; /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ protected ExtensionMapImpl() { super(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override protected EClass eStaticClass() { return ExtensionmodelPackage.eINSTANCE.getExtensionMap(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String getNamespace() { return namespace; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setNamespace(String newNamespace) { String oldNamespace = namespace; namespace = newNamespace; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE, oldNamespace, namespace)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<Extension> getExtensions() { if (extensions == null) { extensions = new EObjectContainmentEList<Extension>(Extension.class, this, ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS); } return extensions; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @customized */ public void initializeAdapter() { ExtensionmodelAdapterFactory factory = new ExtensionmodelAdapterFactory(); if (userAdapter == null) userAdapter = (ExtendedObjectUserAdapter)factory.createEObjectAdapter(); userAdapter.setExtensionMap(this); Set<EObject> extendedObjects = this.keySet(); for (Iterator<EObject> iter = extendedObjects.iterator(); iter.hasNext();) { EObject element = iter.next(); adaptEObject(element,userAdapter); } } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs) { if (featureID >= 0) { switch (eDerivedStructuralFeatureID(featureID, baseClass)) { case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS: return ((InternalEList)getExtensions()).basicRemove(otherEnd, msgs); default: return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs); } } return eBasicSetContainer(null, featureID, msgs); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public Object eGet(EStructuralFeature eFeature, boolean resolve) { switch (eDerivedStructuralFeatureID(eFeature)) { case ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE: return getNamespace(); case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS: return getExtensions(); } return eDynamicGet(eFeature, resolve); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public void eSet(EStructuralFeature eFeature, Object newValue) { switch (eDerivedStructuralFeatureID(eFeature)) { case ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE: setNamespace((String)newValue); return; case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS: getExtensions().clear(); getExtensions().addAll((Collection)newValue); return; } eDynamicSet(eFeature, newValue); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public void eUnset(EStructuralFeature eFeature) { switch (eDerivedStructuralFeatureID(eFeature)) { case ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE: setNamespace(NAMESPACE_EDEFAULT); return; case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS: getExtensions().clear(); return; } eDynamicUnset(eFeature); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public boolean eIsSet(EStructuralFeature eFeature) { switch (eDerivedStructuralFeatureID(eFeature)) { case ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE: return NAMESPACE_EDEFAULT == null ? namespace != null : !NAMESPACE_EDEFAULT.equals(namespace); case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS: return extensions != null && !extensions.isEmpty(); } return eDynamicIsSet(eFeature); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public String toString() { if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); result.append(" (namespace: "); result.append(namespace); result.append(')'); return result.toString(); } /** * This is the Map entrySet. * @param <K> * @param <V> */ public class EntrySet<K,V> extends java.util.AbstractSet<Map.Entry<K,V>> { /** * ESet constructor comment. */ protected EntrySet() { super(); } /** * @see java.util.AbstractCollection#iterator() */ @Override public java.util.Iterator<Map.Entry<K,V>> iterator () { return new EIterator<Map.Entry<K,V>> () { @Override protected Map.Entry<K,V> next(Extension extension) { return new Entry (extension.getExtendedObject(), extension.getExtensionObject()); } }; } /** * @see java.util.AbstractCollection#size() */ @Override public int size() { int n=0; for (Iterator<?> i=iterator(); i.hasNext(); ) { i.next(); n++; } return n; } } /** * This is the Map entrySet. */ public class KeySet extends java.util.AbstractSet<EObject> { /** * ESet constructor comment. */ protected KeySet() { super(); } /** * @see java.util.AbstractCollection#iterator() */ @Override public java.util.Iterator<EObject> iterator() { return new EIterator<EObject>() { @Override protected EObject next (Extension extension) { return extension.getExtendedObject(); } }; } /** * @see java.util.AbstractCollection#size() */ @Override public int size() { int n=0; for (Iterator<?> i=iterator(); i.hasNext(); ) { i.next(); n++; } return n; } } /** * This is the Map entrySet. */ public class Values extends AbstractCollection<EObject> { /** * ESet constructor comment. */ protected Values() { super(); } /** * @see java.util.AbstractCollection#iterator() */ @Override public java.util.Iterator<EObject> iterator() { return new EIterator<EObject>() { @Override protected EObject next (Extension extension) { return extension.getExtensionObject() ; } }; } /** * @see java.util.AbstractCollection#size() */ @Override public int size() { int n=0; for (Iterator<?> i=iterator(); i.hasNext(); ) { i.next(); n++; } return n; } } /** * This is the map entry iterator. * @param <T> */ public abstract class EIterator<T> implements java.util.Iterator<T> { Iterator<Extension> fieldListIterator; /** * EIterator constructor comment. */ public EIterator() { super(); fieldListIterator = getExtensions().iterator(); } /** * Returns <tt>true</tt> if the iteration has more elements. (In other * words, returns <tt>true</tt> if <tt>next</tt> would return an element * rather than throwing an exception.) * * @return <tt>true</tt> if the iterator has more elements. */ public boolean hasNext() { return fieldListIterator.hasNext(); } /** * Returns the next element in the iteration. * @return the next element in the iteration. * @exception NoSuchElementException iteration has no more elements. */ public T next() { Extension object = fieldListIterator.next(); if (object == null) { return null; } return next (object); } protected abstract T next (Extension extension) ; /** * * Removes from the underlying collection the last element returned by the * iterator (optional operation). This method can be called only once per * call to <tt>next</tt>. The behavior of an iterator is unspecified if * the underlying collection is modified while the iteration is in * progress in any way other than by calling this method. * * @exception UnsupportedOperationException if the <tt>remove</tt> * operation is not supported by this Iterator. * @exception IllegalStateException if the <tt>next</tt> method has not * yet been called, or the <tt>remove</tt> method has already * been called after the last call to the <tt>next</tt> * method. */ public void remove() { fieldListIterator.remove(); } } /** * Map entry. * @param <K> * @param <V> */ public class Entry<K,V> implements Map.Entry<K,V> { K key; V value; /** * @param aKey * @param aValue */ public Entry (K aKey, V aValue) { this.key = aKey; this.value = aValue; } /** * @see java.util.Map.Entry#getKey() */ public K getKey() { return key; } /** * @see java.util.Map.Entry#getValue() */ public V getValue() { return value; } /** * @see java.util.Map.Entry#setValue(java.lang.Object) */ public V setValue(V aValue) { V oldValue = this.value; this.value = aValue; return oldValue; } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object o) { if (!(o instanceof Map.Entry)) { return false; } Map.Entry<?,?> e = (Map.Entry<?,?>) o; return (key == null ? e.getKey() == null : key.equals(e.getKey())) && (value == null ? e.getValue() == null : value.equals(e.getValue())); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return key == null ? 0 : key.hashCode(); } /** * @see java.lang.Object#toString() */ @SuppressWarnings("nls") @Override public String toString() { return key + "=" + value; } } /** * @see java.util.Map#size() */ public int size() { return getExtensions().size(); } /** (non-Javadoc) * @see java.util.Map#isEmpty() */ public boolean isEmpty() { return getExtensions().isEmpty(); } /** * @see java.util.Map#containsKey(java.lang.Object) */ public boolean containsKey(Object extendedObject) { if ( extendedObject != null ) { for (Extension extension : getExtensions()) { if(extension.getExtendedObject().equals(extendedObject)){ return true; } } } return false; } /** * @see java.util.Map#containsValue(java.lang.Object) */ public boolean containsValue (Object extensionObject) { if (extensionObject != null) { for (Extension extension : getExtensions()) { if (extension.getExtensionObject().equals(extensionObject)){ return true; } } } return false; } /** * @see java.util.Map#get(java.lang.Object) * @generated NOT */ public EObject get(Object extendedObject) { EObject extension = null; extension = getExtensionObject((EObject)extendedObject); if (extension!=null) { return ((Extension)extension).getExtensionObject(); } return null; } /** * @param extendedObject * @param extensionObject * @return the previous object * @see java.util.Map#put(java.lang.Object, java.lang.Object) * @generated NOT */ public EObject put(EObject extendedObject, EObject extensionObject) { EObject originalObject = null; if(extendedObject != null && extensionObject!= null){ Extension extension = getExtensionObject( extendedObject ); if(extension!= null) originalObject = extension.getExtensionObject(); else { extension = ExtensionmodelFactory.eINSTANCE.createExtension(); getExtensions().add(extension); } extension.setExtendedObject(extendedObject); extension.setExtensionObject(extensionObject); ExtensionmodelAdapterFactory adapterFactory = new ExtensionmodelAdapterFactory(); ExtendedObjectAdapter extAdptr = (ExtendedObjectAdapter) adapterFactory.createExtendedObjectAdapter(); extAdptr.setExtension(extension); extAdptr.setNamespace(getNamespace()); adaptEObject(extendedObject,extAdptr); adapterFactory.adapt(extension,ExtensionAdapterImpl.class); if(userAdapter == null) initializeAdapter(); else adaptEObject(extendedObject,userAdapter); if (eNotificationRequired()) eNotify(new ExtensionModelNotificationImpl(this, Notification.ADD, ExtensionModelNotification.EXTENSION_MAP_PUT, extendedObject, originalObject)); return originalObject; } return null; } /** * @see java.util.Map#remove(java.lang.Object) */ public EObject remove (Object extendedObject) { if (extendedObject == null) { return null; } Extension extensionObject = getExtensionObject((EObject)extendedObject); if(getExtensions().contains(extensionObject)){ Object oldExtension = extensionObject.getExtensionObject(); getExtensions().remove(extensionObject); if (eNotificationRequired()) eNotify(new ExtensionModelNotificationImpl(this, Notification.REMOVE, ExtensionModelNotification.EXTENSION_MAP_REMOVE, extendedObject, oldExtension)); } // Remove adapter if one exists removeAdapters((EObject) extendedObject); if(extensionObject != null) { return extensionObject.getExtensionObject(); } return null; } /** * @see java.util.Map#putAll(java.util.Map) */ public void putAll(Map<? extends EObject, ? extends EObject> extendedObjectMap) { Map<EObject,EObject> originalMap = null; if (eNotificationRequired()){ originalMap = buildMap(); } if(extendedObjectMap != null && !extendedObjectMap.isEmpty()) { for (Map.Entry<? extends EObject, ? extends EObject> entry : extendedObjectMap.entrySet()) { put(entry.getKey(),entry.getValue()); } } if (eNotificationRequired()) eNotify(new ExtensionModelNotificationImpl(this, Notification.ADD_MANY, ExtensionModelNotification.EXTENSION_MAP_PUTALL, originalMap, null)); } /** * @see java.util.Map#clear() */ public void clear() { Map<EObject,EObject> originalMap = null; if (eNotificationRequired() && !getExtensions().isEmpty()){ originalMap = buildMap(); } getExtensions().clear(); if (originalMap != null){ int et = Notification.REMOVE_MANY; if(originalMap.size() == 1) et = Notification.REMOVE; eNotify(new ExtensionModelNotificationImpl(this, et, ExtensionModelNotification.EXTENSION_MAP_CLEAR, originalMap, null)); } } /** * @see java.util.Map#keySet() */ public Set<EObject> keySet() { return new KeySet (); } /** * @see java.util.Map#values() */ public Collection<EObject> values() { return new Values (); } /** * @see java.util.Map#entrySet() */ public Set<java.util.Map.Entry<EObject, EObject>> entrySet() { return new EntrySet<EObject,EObject>(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @customized */ private Extension getExtensionObject (EObject extendedObject) { Extension extension = null; if (extendedObject!=null) { // First check if the is an adapted associated with this object. // If there is, the adapter points to the Extension object. Return this // object. for(Adapter element : extendedObject.eAdapters()) { if(element instanceof ExtendedObjectAdapter && ((ExtendedObjectAdapter)element).getNamespace().equals(getNamespace())){ extension = ((ExtendedObjectAdapter)element).getExtension(); break; } } // Was the extension found though the adapter? Not if it's null. // There is no adapter associated with this bject so we must search the // Extension list. Once the Extension is found, associate an adapter with this // object to improve performance in future queries. if( extension == null){ EList<Extension> extensions = getExtensions(); int len = extensions.size(); for (int i = 0; i < len; ++i) { Extension ext = extensions.get(i); EObject extObject = ext.getExtendedObject(); if (extObject != null) { if (ext.getExtendedObject().equals(extendedObject)) { extension = ext; ExtensionmodelAdapterFactory adapterFactory = new ExtensionmodelAdapterFactory(); ExtendedObjectAdapter extAdptr = (ExtendedObjectAdapter) adapterFactory .createExtendedObjectAdapter(); extAdptr.setExtension(extension); extAdptr.setNamespace(getNamespace()); ExtensionmodelFactory.eINSTANCE.adaptEObject(extendedObject,extAdptr); adapterFactory.adapt(extension,ExtensionAdapterImpl.class); break; } else if (extObject.eIsProxy()) { // Bugzilla 330513 // this thing has not been resolved - the extension // model is out of sync with the BPEL model so remove // this extension from the model extensions.remove(i--); --len; } } } } } return extension; } /** * @return ExtendedObjectUserAdapter * @customized */ public ExtendedObjectUserAdapter getUserAdapter() { return userAdapter; } /** * Method adaptEObject. * This method associates an adapter to a model object. * @param target - object to which the adaptor is to be associated * @param adapter - adapter to asociate to target * @customized */ private void adaptEObject(EObject target, Adapter adapter) { if(target != null && adapter != null){ for (Adapter next : target.eAdapters()) { if ((adapter instanceof ExtendedObjectUserAdapter && next instanceof ExtendedObjectUserAdapter && ((ExtendedObjectUserAdapter)next).getNamespace().equals(getNamespace()))|| (adapter instanceof ExtendedObjectAdapter && next instanceof ExtendedObjectAdapter && ((ExtendedObjectAdapter)next).getNamespace().equals(getNamespace()))) return; } target.eAdapters().add(adapter); } } /** * @customized */ private void removeAdapters(EObject target) { if(target != null){ EList<Adapter> removeAdapterList = new BasicEList<Adapter>(); for (Adapter adapter : target.eAdapters()) { if ((adapter instanceof ExtendedObjectUserAdapter && ((ExtendedObjectUserAdapter)adapter).getNamespace().equals(getNamespace()))|| (adapter instanceof ExtendedObjectAdapter && ((ExtendedObjectAdapter)adapter).getNamespace().equals(getNamespace()))) removeAdapterList.add(adapter); } for(Adapter next : removeAdapterList) { target.eAdapters().remove(next); } } } private Map<EObject,EObject> buildMap(){ boolean buildMap = false; for (Adapter element : eAdapters()) { if(!(element instanceof ExtendedObjectAdapterImpl) && !(element instanceof ExtendedObjectUserAdapterImpl) && !(element instanceof ExtensionAdapterImpl) && !(element instanceof ExtensionMapAdapterImpl)){ buildMap = true; break; } } if(!buildMap) return null; Map<EObject,EObject> map = new HashMap<EObject,EObject>(); for (Extension element : getExtensions()) { map.put(element.getExtendedObject(), element.getExtensionObject()); } return map; } } //ExtensionMapImpl