001    /*
002     * Copyright (c) 2005, 2010 IBM Corporation and others.
003     * All rights reserved.   This program and the accompanying materials
004     * are made available under the terms of the Eclipse Public License v1.0
005     * which accompanies this distribution, and is available at
006     * http://www.eclipse.org/legal/epl-v10.html
007     *
008     * Contributors:
009     *   IBM - initial API and implementation
010     *   Kenn Hussey - 286329
011     *
012     * $Id: UnionEObjectEList.java,v 1.7 2010/03/02 03:10:40 khussey Exp $
013     */
014    package org.eclipse.uml2.common.util;
015    
016    import java.util.Iterator;
017    import java.util.ListIterator;
018    
019    import org.eclipse.emf.ecore.EObject;
020    import org.eclipse.emf.ecore.EStructuralFeature;
021    import org.eclipse.emf.ecore.InternalEObject;
022    import org.eclipse.emf.ecore.util.EcoreEList;
023    
024    /**
025     * An unmodifiable list that represents a union of elements. This list is ideal
026     * for implementing derived features whose values are obtained from the values
027     * of other features in a non-trivial way.
028     */
029    public class UnionEObjectEList<E>
030                    extends EcoreEList.UnmodifiableEList<E> {
031    
032            private static final long serialVersionUID = 1L;
033    
034            public UnionEObjectEList(InternalEObject owner,
035                            EStructuralFeature eStructuralFeature, int size, Object[] data) {
036                    super(owner, eStructuralFeature, size, data);
037            }
038    
039            protected EObject resolveProxy(EObject eObject) {
040                    return eObject.eIsProxy()
041                            ? owner.eResolveProxy((InternalEObject) eObject)
042                            : eObject;
043            }
044    
045            @SuppressWarnings("unchecked")
046            @Override
047            protected E resolve(int index, E object) {
048                    E resolved = (E) resolveProxy((EObject) object);
049    
050                    if (resolved != object) {
051                            E oldObject = (E) data[index];
052                            assign(index, validate(index, resolved));
053                            didSet(index, resolved, oldObject);
054    
055                            return resolved;
056                    } else {
057                            return object;
058                    }
059            }
060    
061            @Override
062            protected boolean canContainNull() {
063                    return false;
064            }
065    
066            @Override
067            protected boolean isUnique() {
068                    return true;
069            }
070    
071            @Override
072            protected boolean useEquals() {
073                    return false;
074            }
075    
076            @Override
077            public boolean contains(Object object) {
078                    boolean result = super.contains(object);
079    
080                    if (!result) {
081    
082                            for (int i = 0; i < size; i++) {
083    
084                                    if (resolveProxy((EObject) data[i]) == object) {
085                                            return true;
086                                    }
087                            }
088                    }
089    
090                    return result;
091            }
092    
093            @Override
094            public int indexOf(Object object) {
095                    int result = super.indexOf(object);
096    
097                    if (result == -1) {
098    
099                            for (int i = 0; i < size; i++) {
100    
101                                    if (resolveProxy((EObject) data[i]) == object) {
102                                            return i;
103                                    }
104                            }
105                    }
106    
107                    return result;
108            }
109    
110            @Override
111            public int lastIndexOf(Object object) {
112                    int result = super.lastIndexOf(object);
113    
114                    if (result == -1) {
115    
116                            for (int i = size - 1; i >= 0; i--) {
117    
118                                    if (resolveProxy((EObject) data[i]) == object) {
119                                            return i;
120                                    }
121                            }
122                    }
123    
124                    return result;
125            }
126    
127            @Override
128            public Iterator<E> iterator() {
129                    return listIterator();
130            }
131    
132        @SuppressWarnings("deprecation")
133            @Override
134            public ListIterator<E> listIterator() {
135                    return new EListIterator<E>();
136            }
137    
138            @SuppressWarnings("deprecation")
139            @Override
140            public ListIterator<E> listIterator(int index) {
141    
142                    if (index < 0 || index > size()) {
143                            throw new BasicIndexOutOfBoundsException(index, size);
144                    }
145    
146                    return new EListIterator<E>(index);
147            }
148    
149    }