/**
* <copyright>
*
* Copyright (c) 2008 Matthew Hall 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:
* Matthew Hall - initial API and implementation (bug 194734)
* Matthew Hall - bugs 195222, 264307, 265561
* Tom Schindl <tom.schindl@bestsolution.at> - port to EMF in 262160
* </copyright>
*
* $Id: EMFListProperty.java,v 1.4 2010/04/05 15:30:53 emerks Exp $
*/
package org.eclipse.emf.databinding.internal;
import java.util.AbstractSequentialList;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.core.databinding.observable.list.ListDiff;
import org.eclipse.core.databinding.property.INativePropertyListener;
import org.eclipse.core.databinding.property.IProperty;
import org.eclipse.core.databinding.property.ISimplePropertyListener;
import org.eclipse.core.databinding.property.list.SimpleListProperty;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
/**
* <p><b>PROVISIONAL:</b> This API is subject to arbitrary change, including renaming or removal.</p>
*
* @since 2.5
*/
public class EMFListProperty extends SimpleListProperty
{
private EStructuralFeature eStructuralFeature;
/**
* @param eStructuralFeature
*/
public EMFListProperty(EStructuralFeature eStructuralFeature)
{
this.eStructuralFeature = eStructuralFeature;
}
/**
* @return the feature
*/
protected EStructuralFeature getFeature()
{
return eStructuralFeature;
}
public Object getElementType()
{
return eStructuralFeature;
}
@Override
protected List< ? > doGetList(Object source)
{
final EObject eObject = (EObject)source;
if (FeatureMapUtil.isMany(eObject, eStructuralFeature))
{
return (List< ? >)eObject.eGet(eStructuralFeature);
}
else
{
return
new AbstractSequentialList<Object>()
{
@Override
public ListIterator<Object> listIterator(int index)
{
ListIterator<Object> result =
new ListIterator<Object>()
{
protected int position = 0;
protected boolean setOrRemoveAllowed;
public void add(Object o)
{
if (position != 0)
{
throw new IllegalStateException();
}
eObject.eSet(eStructuralFeature, o);
position = 1;
setOrRemoveAllowed = false;
}
public boolean hasNext()
{
return position == 0 && size() == 1;
}
public boolean hasPrevious()
{
return position == 1;
}
public Object next()
{
if (!hasNext())
{
throw new IllegalStateException();
}
++position;
setOrRemoveAllowed = true;
return eObject.eGet(eStructuralFeature);
}
public int nextIndex()
{
return position;
}
public Object previous()
{
if (!hasPrevious())
{
throw new IllegalStateException();
}
else
{
--position;
setOrRemoveAllowed = true;
return eObject.eGet(eStructuralFeature);
}
}
public int previousIndex()
{
return position - 1;
}
public void remove()
{
if (!setOrRemoveAllowed)
{
throw new IllegalStateException();
}
else
{
setOrRemoveAllowed = false;
eObject.eUnset(eStructuralFeature);
}
}
public void set(Object o)
{
if (!setOrRemoveAllowed)
{
throw new IllegalStateException();
}
else
{
setOrRemoveAllowed = false;
eObject.eSet(eStructuralFeature, o);
}
}
};
for (int i = 0; i < index; ++i)
{
result.next();
}
return result;
}
@Override
public int size()
{
return eStructuralFeature.isUnsettable() ? eObject.eIsSet(eStructuralFeature) ? 1 : 0 : eObject.eGet(eStructuralFeature, false) == null ? 0 : 1;
}
};
}
}
@Override
@SuppressWarnings("rawtypes")
protected void doSetList(Object source, List list, ListDiff diff)
{
List< ? > currentList = doGetList(source);
diff.applyTo(currentList);
}
@Override
public INativePropertyListener adaptListener(final ISimplePropertyListener listener)
{
return new EMFPropertyListener.EMFListPropertyListener()
{
@Override
protected EStructuralFeature getFeature()
{
return eStructuralFeature;
}
@Override
protected ISimplePropertyListener getListener()
{
return listener;
}
@Override
protected IProperty getOwner()
{
return EMFListProperty.this;
}
};
}
@Override
public String toString()
{
String s = EMFPropertyHelper.propertyName(eStructuralFeature) + "[]"; //$NON-NLS-1$
s += "<" + EMFPropertyHelper.shortClassName(eStructuralFeature) + ">"; //$NON-NLS-1$//$NON-NLS-2$
return s;
}
}