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 }