/**
* Copyright (c) 2003-2011 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.change.impl;
import com.google.gwt.user.client.rpc.GwtTransient;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.DelegatingEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.change.ChangeFactory;
import org.eclipse.emf.ecore.change.ChangeKind;
import org.eclipse.emf.ecore.change.ChangePackage;
import org.eclipse.emf.ecore.change.FeatureMapEntry;
import org.eclipse.emf.ecore.change.FeatureChange;
import org.eclipse.emf.ecore.change.ListChange;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.util.EDataTypeEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectResolvingEList;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>List Change</b></em>'.
* <!-- end-user-doc -->
* <p>
* The following features are implemented:
* <ul>
* <li>{@link org.eclipse.emf.ecore.change.impl.ListChangeImpl#getKind <em>Kind</em>}</li>
* <li>{@link org.eclipse.emf.ecore.change.impl.ListChangeImpl#getDataValues <em>Data Values</em>}</li>
* <li>{@link org.eclipse.emf.ecore.change.impl.ListChangeImpl#getIndex <em>Index</em>}</li>
* <li>{@link org.eclipse.emf.ecore.change.impl.ListChangeImpl#getMoveToIndex <em>Move To Index</em>}</li>
* <li>{@link org.eclipse.emf.ecore.change.impl.ListChangeImpl#getValues <em>Values</em>}</li>
* <li>{@link org.eclipse.emf.ecore.change.impl.ListChangeImpl#getReferenceValues <em>Reference Values</em>}</li>
* <li>{@link org.eclipse.emf.ecore.change.impl.ListChangeImpl#getFeature <em>Feature</em>}</li>
* <li>{@link org.eclipse.emf.ecore.change.impl.ListChangeImpl#getFeatureMapEntryValues <em>Feature Map Entry Values</em>}</li>
* </ul>
* </p>
*
* @generated
*/
public class ListChangeImpl extends EObjectImpl implements ListChange
{
/**
* The default value of the '{@link #getKind() <em>Kind</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getKind()
* @generated
* @ordered
*/
protected static final ChangeKind KIND_EDEFAULT = ChangeKind.ADD_LITERAL;
/**
* The cached value of the '{@link #getKind() <em>Kind</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getKind()
* @generated
* @ordered
*/
@GwtTransient
protected ChangeKind kind = KIND_EDEFAULT;
/**
* The cached value of the '{@link #getDataValues() <em>Data Values</em>}' attribute list.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getDataValues()
* @generated
* @ordered
*/
@GwtTransient
protected EList<String> dataValues;
/**
* The default value of the '{@link #getIndex() <em>Index</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getIndex()
* @generated
* @ordered
*/
protected static final int INDEX_EDEFAULT = -1;
/**
* The cached value of the '{@link #getIndex() <em>Index</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getIndex()
* @generated
* @ordered
*/
@GwtTransient
protected int index = INDEX_EDEFAULT;
/**
* The default value of the '{@link #getMoveToIndex() <em>Move To Index</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getMoveToIndex()
* @generated
* @ordered
*/
protected static final int MOVE_TO_INDEX_EDEFAULT = 0;
/**
* The cached value of the '{@link #getMoveToIndex() <em>Move To Index</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getMoveToIndex()
* @generated
* @ordered
*/
@GwtTransient
protected int moveToIndex = MOVE_TO_INDEX_EDEFAULT;
/**
* The cached value of the '{@link #getReferenceValues() <em>Reference Values</em>}' reference list.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getReferenceValues()
* @generated
* @ordered
*/
@GwtTransient
protected EList<EObject> referenceValues;
/**
* The cached value of the '{@link #getFeature() <em>Feature</em>}' reference.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getFeature()
* @generated
* @ordered
*/
@GwtTransient
protected EStructuralFeature feature;
/**
* The cached value of the '{@link #getFeatureMapEntryValues() <em>Feature Map Entry Values</em>}' containment reference list.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getFeatureMapEntryValues()
* @generated
* @ordered
*/
@GwtTransient
protected EList<FeatureMapEntry> featureMapEntryValues;
/**
* The data value delegating list is used to ensure that the elements
* are properly converted to and from strings when added and removed
* from the dataValues list.
*/
@GwtTransient
protected EList<Object> dataValueDelegatingList = null;
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected ListChangeImpl()
{
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass()
{
return ChangePackage.Literals.LIST_CHANGE;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public ChangeKind getKind()
{
return kind;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setKind(ChangeKind newKind)
{
ChangeKind oldKind = kind;
kind = newKind == null ? KIND_EDEFAULT : newKind;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, ChangePackage.LIST_CHANGE__KIND, oldKind, kind));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public EList<String> getDataValues()
{
if (dataValues == null)
{
dataValues = new EDataTypeEList<String>(String.class, this, ChangePackage.LIST_CHANGE__DATA_VALUES);
}
return dataValues;
}
/**
* Creates the data value delegating list
*/
protected EList<Object> createDataValueDelegatingList()
{
if (FeatureMapUtil.isFeatureMap(getFeature()))
{
return
new DelegatingEList<Object>()
{
private static final long serialVersionUID = 1L;
@SuppressWarnings("unchecked")
@Override
protected List<Object> delegateList()
{
return (List<Object>)(List<?>)getFeatureMapEntryValues();
}
@Override
protected Object validate(int index, Object object)
{
if (object instanceof FeatureMapEntry)
{
return object;
}
else
{
FeatureMap.Entry entry = (FeatureMap.Entry)object;
return createFeatureMapEntry(entry.getEStructuralFeature(), entry.getValue());
}
}
};
}
else
{
return
new DelegatingEList<Object>()
{
private static final long serialVersionUID = 1L;
@SuppressWarnings("unchecked")
@Override
protected List<Object> delegateList()
{
return (List<Object>)(List<?>)getDataValues();
}
@Override
protected Object resolve(int index, Object object)
{
EDataType type = (EDataType)getFeature().getEType();
return EcoreUtil.createFromString(type, (String)object);
}
@Override
protected Object validate(int index, Object object)
{
EDataType type = (EDataType)getFeature().getEType();
return EcoreUtil.convertToString(type, object);
}
};
}
}
protected FeatureMapEntry createFeatureMapEntry(EStructuralFeature feature, Object value)
{
return ChangeFactory.eINSTANCE.createFeatureMapEntry(feature, value);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public int getIndex()
{
return index;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setIndex(int newIndex)
{
int oldIndex = index;
index = newIndex;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, ChangePackage.LIST_CHANGE__INDEX, oldIndex, index));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public int getMoveToIndex()
{
return moveToIndex;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setMoveToIndex(int newMoveToIndex)
{
int oldMoveToIndex = moveToIndex;
moveToIndex = newMoveToIndex;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, ChangePackage.LIST_CHANGE__MOVE_TO_INDEX, oldMoveToIndex, moveToIndex));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public EList<EObject> getReferenceValues()
{
if (referenceValues == null)
{
referenceValues = new EObjectResolvingEList<EObject>(EObject.class, this, ChangePackage.LIST_CHANGE__REFERENCE_VALUES);
}
return referenceValues;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public EStructuralFeature getFeatureGen()
{
if (feature != null && feature.eIsProxy())
{
InternalEObject oldFeature = (InternalEObject)feature;
feature = (EStructuralFeature)eResolveProxy(oldFeature);
if (feature != oldFeature)
{
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.RESOLVE, ChangePackage.LIST_CHANGE__FEATURE, oldFeature, feature));
}
}
return feature;
}
public EStructuralFeature getFeature()
{
EStructuralFeature result = getFeatureGen();
if (result == null)
{
EObject container = eContainer();
if (container instanceof FeatureChange)
{
result = ((FeatureChange)container).getFeature();
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public EStructuralFeature basicGetFeature()
{
return feature;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void setFeature(EStructuralFeature newFeature)
{
EStructuralFeature oldFeature = feature;
feature = newFeature;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, ChangePackage.LIST_CHANGE__FEATURE, oldFeature, feature));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public EList<FeatureMapEntry> getFeatureMapEntryValues()
{
if (featureMapEntryValues == null)
{
featureMapEntryValues = new EObjectContainmentEList<FeatureMapEntry>(FeatureMapEntry.class, this, ChangePackage.LIST_CHANGE__FEATURE_MAP_ENTRY_VALUES);
}
return featureMapEntryValues;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public EList<Object> getValues()
{
EStructuralFeature feature = getFeature();
if (feature instanceof EAttribute)
{
if (dataValueDelegatingList == null)
{
dataValueDelegatingList = createDataValueDelegatingList();
}
return dataValueDelegatingList;
}
else
{
@SuppressWarnings("unchecked") EList<Object> result = (EList<Object>)(List<?>)getReferenceValues();
return result;
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void setValues(EList<?> values)
{
EList<Object> featureValues = getValues();
featureValues.clear();
featureValues.addAll(values);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void apply(EList<Object> originalList)
{
process(originalList, false, true);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void applyAndReverse(EList<Object> originalList)
{
process(originalList, true, true);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void reverse(EList<Object> originalList)
{
process(originalList, true, false);
}
protected void process(EList<Object> originalList, boolean reverse, boolean apply)
{
switch (getKind().getValue())
{
case ChangeKind.ADD:
if (index == -1)
{
if (reverse)
{
index = originalList.size();
}
if (apply)
{
originalList.addAll(getValues());
}
}
else if (apply)
{
originalList.addAll(index, getValues());
}
if (reverse)
{
if (getValues().size() == 1)
{
getValues().clear();
}
setKind(ChangeKind.REMOVE_LITERAL);
}
break;
case ChangeKind.REMOVE:
int removeCount;
if (getValues().isEmpty())
{
if (reverse)
{
getValues().add(originalList.get(getIndex()));
}
removeCount = 1;
}
else
{
removeCount = getValues().size();
}
if (apply)
{
for (int i = 0; i < removeCount; ++i)
{
originalList.remove(index);
}
}
if (reverse)
{
setKind(ChangeKind.ADD_LITERAL);
}
break;
case ChangeKind.MOVE:
if (apply)
{
originalList.move(moveToIndex, index);
}
if (reverse)
{
int temp = moveToIndex;
setMoveToIndex(index);
setIndex(temp);
}
break;
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
{
switch (featureID)
{
case ChangePackage.LIST_CHANGE__FEATURE_MAP_ENTRY_VALUES:
return ((InternalEList<?>)getFeatureMapEntryValues()).basicRemove(otherEnd, msgs);
}
return super.eInverseRemove(otherEnd, featureID, msgs);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType)
{
switch (featureID)
{
case ChangePackage.LIST_CHANGE__KIND:
return getKind();
case ChangePackage.LIST_CHANGE__DATA_VALUES:
return getDataValues();
case ChangePackage.LIST_CHANGE__INDEX:
return getIndex();
case ChangePackage.LIST_CHANGE__MOVE_TO_INDEX:
return getMoveToIndex();
case ChangePackage.LIST_CHANGE__VALUES:
return getValues();
case ChangePackage.LIST_CHANGE__REFERENCE_VALUES:
return getReferenceValues();
case ChangePackage.LIST_CHANGE__FEATURE:
if (resolve) return getFeature();
return basicGetFeature();
case ChangePackage.LIST_CHANGE__FEATURE_MAP_ENTRY_VALUES:
return getFeatureMapEntryValues();
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@SuppressWarnings("unchecked")
@Override
public void eSet(int featureID, Object newValue)
{
switch (featureID)
{
case ChangePackage.LIST_CHANGE__KIND:
setKind((ChangeKind)newValue);
return;
case ChangePackage.LIST_CHANGE__DATA_VALUES:
getDataValues().clear();
getDataValues().addAll((Collection<? extends String>)newValue);
return;
case ChangePackage.LIST_CHANGE__INDEX:
setIndex((Integer)newValue);
return;
case ChangePackage.LIST_CHANGE__MOVE_TO_INDEX:
setMoveToIndex((Integer)newValue);
return;
case ChangePackage.LIST_CHANGE__VALUES:
getValues().clear();
getValues().addAll((Collection<? extends Object>)newValue);
return;
case ChangePackage.LIST_CHANGE__REFERENCE_VALUES:
getReferenceValues().clear();
getReferenceValues().addAll((Collection<? extends EObject>)newValue);
return;
case ChangePackage.LIST_CHANGE__FEATURE:
setFeature((EStructuralFeature)newValue);
return;
case ChangePackage.LIST_CHANGE__FEATURE_MAP_ENTRY_VALUES:
getFeatureMapEntryValues().clear();
getFeatureMapEntryValues().addAll((Collection<? extends FeatureMapEntry>)newValue);
return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eUnset(int featureID)
{
switch (featureID)
{
case ChangePackage.LIST_CHANGE__KIND:
setKind(KIND_EDEFAULT);
return;
case ChangePackage.LIST_CHANGE__DATA_VALUES:
getDataValues().clear();
return;
case ChangePackage.LIST_CHANGE__INDEX:
setIndex(INDEX_EDEFAULT);
return;
case ChangePackage.LIST_CHANGE__MOVE_TO_INDEX:
setMoveToIndex(MOVE_TO_INDEX_EDEFAULT);
return;
case ChangePackage.LIST_CHANGE__VALUES:
getValues().clear();
return;
case ChangePackage.LIST_CHANGE__REFERENCE_VALUES:
getReferenceValues().clear();
return;
case ChangePackage.LIST_CHANGE__FEATURE:
setFeature((EStructuralFeature)null);
return;
case ChangePackage.LIST_CHANGE__FEATURE_MAP_ENTRY_VALUES:
getFeatureMapEntryValues().clear();
return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public boolean eIsSet(int featureID)
{
switch (featureID)
{
case ChangePackage.LIST_CHANGE__KIND:
return kind != KIND_EDEFAULT;
case ChangePackage.LIST_CHANGE__DATA_VALUES:
return dataValues != null && !dataValues.isEmpty();
case ChangePackage.LIST_CHANGE__INDEX:
return index != INDEX_EDEFAULT;
case ChangePackage.LIST_CHANGE__MOVE_TO_INDEX:
return moveToIndex != MOVE_TO_INDEX_EDEFAULT;
case ChangePackage.LIST_CHANGE__VALUES:
return !getValues().isEmpty();
case ChangePackage.LIST_CHANGE__REFERENCE_VALUES:
return referenceValues != null && !referenceValues.isEmpty();
case ChangePackage.LIST_CHANGE__FEATURE:
return feature != null;
case ChangePackage.LIST_CHANGE__FEATURE_MAP_ENTRY_VALUES:
return featureMapEntryValues != null && !featureMapEntryValues.isEmpty();
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public String toString()
{
if (eIsProxy()) return super.toString();
StringBuffer result = new StringBuffer(super.toString());
result.append(" (kind: ");
result.append(kind);
result.append(", dataValues: ");
result.append(dataValues);
result.append(", index: ");
result.append(index);
result.append(", moveToIndex: ");
result.append(moveToIndex);
result.append(')');
return result.toString();
}
} //ListChangeImpl