/** * Copyright (c) 2015 committers of YAKINDU 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: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.sct.model.sgraph.util; import java.util.ConcurrentModificationException; import java.util.List; import java.util.ListIterator; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.util.FeatureMapUtil; import org.eclipse.emf.ecore.util.InternalEList; /** * A modifiable derived list whose values are obtained from a single multivalued * source feature. This list is ideal for implementing derived subset features. * * @since . */ public class DerivedSubsetEObjectEList<E> extends DerivedEObjectEList<E> { protected class DerivedSubsetListIterator extends DerivedListIterator { protected int expectedModCount = modCount; @Override public void remove() { checkModCount(); if (valuesIterator == null) { throw new IllegalStateException(); } switch (prepared) { case 3: case 1: preparePrevious(); break; case -1: case -3: prepareNext(); break; } prepared = 0; valuesIterator.remove(); modCount++; expectedModCount++; } @Override public void set(Object element) { checkModCount(); if (valuesIterator == null) { throw new IllegalStateException(); } switch (prepared) { case 3: case 1: preparePrevious(); break; case -1: case -3: prepareNext(); break; } prepared = 0; valuesIterator.set(element); modCount++; expectedModCount++; } @Override public void add(Object element) { checkModCount(); if (valuesIterator == null) { @SuppressWarnings("unchecked") List<Object> valuesList = resolve() ? (List<Object>) owner .eGet(sourceFeatureIDs[featureIndex], resolve(), true) : ((InternalEList<Object>) owner .eGet(sourceFeatureIDs[featureIndex], resolve(), true)).basicList(); valuesList.listIterator(valuesList.size()).add(element); } else { switch (prepared) { case 3: preparePrevious(); break; case -3: prepareNext(); break; } valuesIterator.add(element); } prepared = 0; modCount++; expectedModCount++; index++; } protected void checkModCount() { if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } } } protected class ResolvingDerivedSubsetListIterator extends DerivedSubsetListIterator { @Override protected boolean resolve() { return true; } } protected class EmptyDerivedSubsetListIterator extends EmptyDerivedListIterator { @Override public void remove() { throw new IllegalStateException(); } @Override public void set(Object element) { throw new IllegalStateException(); } @Override public void add(Object element) { throw new IllegalStateException(); } } public DerivedSubsetEObjectEList(Class<?> dataClass, InternalEObject owner, int featureID, int[] sourceFeatureIDs) { super(dataClass, owner, featureID, sourceFeatureIDs); EStructuralFeature feature = sourceFeatureIDs.length == 1 ? getEStructuralFeature(sourceFeatureIDs[0]) : null; if (feature == null || !feature.isMany() || FeatureMapUtil.isFeatureMap(feature)) { throw new IllegalArgumentException(String.valueOf(sourceFeatureIDs)); } } public DerivedSubsetEObjectEList(Class<?> dataClass, InternalEObject owner, int featureID, int sourceFeatureID) { this(dataClass, owner, featureID, new int[] { sourceFeatureID }); } @Override public List<E> basicList() { return new DerivedSubsetEObjectEList<E>(dataClass, owner, featureID, sourceFeatureIDs) { @Override public ListIterator<E> listIterator(int index) { return basicListIterator(index); } }; } @Override protected ListIterator<E> newListIterator() { return new DerivedSubsetListIterator(); } @Override protected ListIterator<E> newResolvingListIterator() { return new ResolvingDerivedSubsetListIterator(); } @Override protected ListIterator<E> newEmptyListIterator() { return new EmptyDerivedSubsetListIterator(); } @Override protected boolean isNotificationRequired() { return owner.eNotificationRequired(); } }