/**
* Copyright (c) 2002-2007 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 - Initial API and implementation
*/
package org.eclipse.emf.ecore.util;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
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.BasicEMap;
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;
public class EcoreEMap<K, V> extends BasicEMap<K, V> implements InternalEList.Unsettable<Map.Entry<K, V>>, EStructuralFeature.Setting
{
private static final long serialVersionUID = 1L;
public static class Unsettable<K, V> extends EcoreEMap<K, V>
{
private static final long serialVersionUID = 1L;
public Unsettable(EClass entryEClass, Class<?> entryClass, InternalEObject owner, int featureID)
{
super(entryEClass, entryClass, null);
delegateEList = new UnsettableDelegateEObjectContainmentEList<Entry<K, V>>(entryClass, owner, featureID);
}
public Unsettable(EClass entryEClass, Class<?> entryClass, InternalEObject owner, int featureID, int inverseFeatureID)
{
super(entryEClass, entryClass, null);
delegateEList = new UnsettableDelegateEObjectContainmentWithInverseEList<Entry<K, V>>(entryClass, owner, featureID, inverseFeatureID);
}
protected class UnsettableDelegateEObjectContainmentEList<E extends Object & Entry<K, V>> extends DelegateEObjectContainmentEList<E>
{
private static final long serialVersionUID = 1L;
protected boolean isSet;
public UnsettableDelegateEObjectContainmentEList(Class<?> dataClass, InternalEObject owner, int featureID)
{
super(dataClass, owner, featureID);
}
@Override
protected void didChange()
{
isSet = true;
}
@Override
public boolean isSet()
{
return isSet;
}
@Override
public void unset()
{
super.unset();
if (isNotificationRequired())
{
boolean oldIsSet = isSet;
isSet = false;
owner.eNotify(createNotification(Notification.UNSET, oldIsSet, false));
}
else
{
isSet = false;
}
}
}
protected class UnsettableDelegateEObjectContainmentWithInverseEList<E extends Object & Entry<K, V>> extends DelegateEObjectContainmentWithInverseEList<E>
{
private static final long serialVersionUID = 1L;
protected boolean isSet;
public UnsettableDelegateEObjectContainmentWithInverseEList(Class<?> dataClass, InternalEObject owner, int featureID, int inverseFeatureID)
{
super(dataClass, owner, featureID, inverseFeatureID);
}
@Override
protected void didChange()
{
isSet = true;
}
@Override
public boolean isSet()
{
return isSet;
}
@Override
public void unset()
{
super.unset();
if (isNotificationRequired())
{
boolean oldIsSet = isSet;
isSet = false;
owner.eNotify(createNotification(Notification.UNSET, oldIsSet, false));
}
else
{
isSet = false;
}
}
}
}
protected EClass entryEClass;
protected Class<?> entryClass;
public EcoreEMap(EClass entryEClass, Class<?> entryClass, InternalEObject owner, int featureID)
{
this.entryClass = entryClass;
assert entryClass != null && BasicEMap.Entry.class.isAssignableFrom(entryClass) : "A class derived from org.eclipse.emf.common.util.BasicEMap.Entry is required: " + entryClass;
this.entryEClass = entryEClass;
delegateEList = new DelegateEObjectContainmentEList<Entry<K, V>>(entryClass, owner, featureID);
}
/**
* @since 2.7
*/
public EcoreEMap(EClass entryEClass, Class<?> entryClass, InternalEObject owner, int featureID, int inverseFeatureID)
{
this.entryClass = entryClass;
assert entryClass != null && BasicEMap.Entry.class.isAssignableFrom(entryClass) : "A class derived from org.eclipse.emf.common.util.BasicEMap.Entry is required: " + entryClass;
this.entryEClass = entryEClass;
delegateEList = new DelegateEObjectContainmentWithInverseEList<Entry<K, V>>(entryClass, owner, featureID, inverseFeatureID);
}
public EcoreEMap(EClass entryEClass, Class<?> entryClass, EList<Entry<K, V>> delegateEList)
{
this.entryClass = entryClass;
assert entryClass != null && BasicEMap.Entry.class.isAssignableFrom(entryClass) : "A class derived from org.eclipse.emf.common.util.BasicEMap.Entry is required: " + entryClass;
this.entryEClass = entryEClass;
this.delegateEList = delegateEList;
}
@Override
protected void initializeDelegateEList()
{
// Do nothing.
}
protected class DelegateEObjectContainmentEList<E extends Object & Entry<K, V>> extends EObjectContainmentEList<E>
{
private static final long serialVersionUID = 1L;
public DelegateEObjectContainmentEList(Class<?> entryClass, InternalEObject owner, int featureID)
{
super(entryClass, owner, featureID);
}
@Override
protected void didAdd(int index, E newObject)
{
EcoreEMap.this.doPut(newObject);
}
@Override
protected void didSet(int index, E newObject, E oldObject)
{
didRemove(index, oldObject);
if (oldObject == newObject)
{
oldObject.setHash(hashOf(newObject.getKey()));
}
didAdd(index, newObject);
}
@Override
protected void didRemove(int index, E oldObject)
{
EcoreEMap.this.doRemove(oldObject);
}
@Override
protected void didClear(int size, Object [] oldObjects)
{
EcoreEMap.this.doClear();
}
@Override
protected void didMove(int index, E movedObject, int oldIndex)
{
EcoreEMap.this.doMove(movedObject);
}
}
/**
* @since 2.7
*/
protected class DelegateEObjectContainmentWithInverseEList<E extends Object & Entry<K, V>> extends DelegateEObjectContainmentEList<E>
{
private static final long serialVersionUID = 1L;
protected final int inverseFeatureID;
public DelegateEObjectContainmentWithInverseEList(Class<?> entryClass, InternalEObject owner, int featureID, int inverseFeatureID)
{
super(entryClass, owner, featureID);
this.inverseFeatureID = inverseFeatureID;
}
@Override
protected boolean hasNavigableInverse()
{
return true;
}
@Override
public int getInverseFeatureID()
{
return inverseFeatureID;
}
@Override
public Class<?> getInverseFeatureClass()
{
return dataClass;
}
}
@Override
protected BasicEList<Entry<K, V>> newList()
{
return
new BasicEList<Entry<K, V>>()
{
private static final long serialVersionUID = 1L;
@Override
public Object [] newData(int listCapacity)
{
return (Object [])Array.newInstance(entryClass, listCapacity);
}
};
}
@Override
protected Entry<K, V> newEntry(int hash, K key, V value)
{
@SuppressWarnings("unchecked") Entry<K, V> entry = (Entry<K, V>)entryEClass.getEPackage().getEFactoryInstance().create(entryEClass);
entry.setHash(hash);
entry.setKey(key);
entry.setValue(value);
return entry;
}
public Entry<K, V> basicGet(int index)
{
return ((InternalEList<Entry<K, V>>)delegateEList).basicGet(index);
}
@SuppressWarnings("unchecked")
public List<Map.Entry<K, V>> basicList()
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicList();
}
/**
* Returns an iterator that yields unresolved values.
*/
@SuppressWarnings("unchecked")
public Iterator<Map.Entry<K, V>> basicIterator()
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicIterator();
}
/**
* Returns a list iterator that yields unresolved values.
*/
@SuppressWarnings("unchecked")
public ListIterator<Map.Entry<K, V>> basicListIterator()
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicListIterator();
}
/**
* Returns a list iterator that yields unresolved values.
*/
@SuppressWarnings("unchecked")
public ListIterator<Map.Entry<K, V>> basicListIterator(int index)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicListIterator(index);
}
@SuppressWarnings("unchecked")
public boolean basicContains(Object object)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicContains(object);
}
@SuppressWarnings("unchecked")
public boolean basicContainsAll(Collection<?> collection)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicContainsAll(collection);
}
@SuppressWarnings("unchecked")
public int basicIndexOf(Object object)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicIndexOf(object);
}
@SuppressWarnings("unchecked")
public int basicLastIndexOf(Object object)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicLastIndexOf(object);
}
/**
* Returns the array with unresolved values.
*/
@SuppressWarnings("unchecked")
public Object[] basicToArray()
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicToArray();
}
/**
* Returns the array with unresolved values.
*/
@SuppressWarnings("unchecked")
public <T> T [] basicToArray(T [] array)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicToArray(array);
}
/**
* Remove the object with without updating the inverse.
*/
public NotificationChain basicRemove(Object object, NotificationChain notifications)
{
return ((InternalEList<?>)delegateEList).basicRemove(object, notifications);
}
/**
* Add the object without updating the inverse.
*/
@SuppressWarnings("unchecked")
public NotificationChain basicAdd(Map.Entry<K, V> object, NotificationChain notifications)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).basicAdd(object, notifications);
}
/**
* Add the object without verifying uniqueness.
*/
@SuppressWarnings("unchecked")
public void addUnique(Map.Entry<K, V> object)
{
((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).addUnique(object);
}
/**
* Add the object without verifying uniqueness.
*/
@SuppressWarnings("unchecked")
public void addUnique(int index, Map.Entry<K, V> object)
{
((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).addUnique(index, object);
}
/**
* Add the objects without verifying uniqueness.
*/
@SuppressWarnings("unchecked")
public boolean addAllUnique(Collection<? extends Map.Entry<K, V>> collection)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).addAllUnique(collection);
}
/**
* Add the objects without verifying uniqueness.
*/
@SuppressWarnings("unchecked")
public boolean addAllUnique(int index, Collection<? extends Map.Entry<K, V>> collection)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).addAllUnique(collection);
}
/**
* Set the object without verifying uniqueness.
*/
@SuppressWarnings("unchecked")
public Map.Entry<K, V> setUnique(int index, Map.Entry<K, V> object)
{
return ((InternalEList<Map.Entry<K, V>>)(InternalEList<?>)delegateEList).setUnique(index, object);
}
public EObject getEObject()
{
return ((EStructuralFeature.Setting)delegateEList).getEObject();
}
public EStructuralFeature getEStructuralFeature()
{
return ((EStructuralFeature.Setting)delegateEList).getEStructuralFeature();
}
public Object get(boolean resolve)
{
return ((EStructuralFeature.Setting)delegateEList).get(resolve);
}
public void set(Object value)
{
if (value instanceof Map<?, ?>)
{
((EStructuralFeature.Setting)delegateEList).unset();
@SuppressWarnings("unchecked") Map<? extends K, ? extends V> mapValue = (Map<? extends K, ? extends V>)value;
putAll(mapValue);
}
else
{
((EStructuralFeature.Setting)delegateEList).set(value);
}
}
public boolean isSet()
{
return ((EStructuralFeature.Setting)delegateEList).isSet();
}
public void unset()
{
((EStructuralFeature.Setting)delegateEList).unset();
}
}