001 /*******************************************************************************
002 * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian
003 * Thomschke.
004 *
005 * All Rights Reserved. This program and the accompanying materials
006 * are made available under the terms of the Eclipse Public License v1.0
007 * which accompanies this distribution, and is available at
008 * http://www.eclipse.org/legal/epl-v10.html
009 *
010 * Contributors:
011 * Sebastian Thomschke - initial implementation.
012 *******************************************************************************/
013 package net.sf.oval.internal.util;
014
015 import static net.sf.oval.Validator.*;
016
017 import java.util.Collection;
018 import java.util.Iterator;
019 import java.util.List;
020 import java.util.ListIterator;
021 import java.util.Set;
022
023 /**
024 * @author Sebastian Thomschke
025 */
026 public final class LinkedSet<E> implements Cloneable, Set<E>, List<E>
027 {
028 private final List<E> list;
029
030 /**
031 * Constructs a new, empty collection with an initial capacity (16).
032 */
033 public LinkedSet()
034 {
035 list = getCollectionFactory().createList(16);
036 }
037
038 /**
039 * Constructs a new, empty collection with the given initial capacity.
040 *
041 * @param initialCapacity the initial capacity
042 */
043 public LinkedSet(final int initialCapacity)
044 {
045 list = getCollectionFactory().createList(initialCapacity);
046 }
047
048 /**
049 * {@inheritDoc}
050 */
051 public boolean add(final E e)
052 {
053 return list.add(e);
054 }
055
056 /**
057 * {@inheritDoc}
058 */
059 public void add(final int index, final E e)
060 {
061 if (!list.contains(e)) list.add(index, e);
062 }
063
064 /**
065 * {@inheritDoc}
066 */
067 public boolean addAll(final Collection< ? extends E> c)
068 {
069 boolean itemAdded = false;
070 for (final E o : c)
071 if (!list.contains(o))
072 {
073 add(o);
074 itemAdded = true;
075 }
076 return itemAdded;
077 }
078
079 /**
080 * {@inheritDoc}
081 */
082 public boolean addAll(final int index, final Collection< ? extends E> c)
083 {
084 final List<E> tmp = getCollectionFactory().createList(c.size());
085 for (final E o : c)
086 if (!list.contains(o)) tmp.add(o);
087 return list.addAll(index, tmp);
088 }
089
090 /**
091 * {@inheritDoc}
092 */
093 public void clear()
094 {
095 list.clear();
096 }
097
098 /**
099 * {@inheritDoc}
100 */
101 @Override
102 public Object clone() throws CloneNotSupportedException
103 {
104 @SuppressWarnings("unchecked")
105 final LinkedSet<E> os = (LinkedSet<E>) super.clone();
106 os.list.addAll(list);
107 return os;
108 }
109
110 /**
111 * {@inheritDoc}
112 */
113 public boolean contains(final Object o)
114 {
115 return list.contains(o);
116 }
117
118 /**
119 * {@inheritDoc}
120 */
121 public boolean containsAll(final Collection< ? > c)
122 {
123 return list.containsAll(c);
124 }
125
126 /**
127 * {@inheritDoc}
128 */
129 @Override
130 public boolean equals(final Object obj)
131 {
132 if (this == obj) return true;
133 if (obj == null) return false;
134 if (getClass() != obj.getClass()) return false;
135 @SuppressWarnings({"rawtypes"})
136 final LinkedSet other = (LinkedSet) obj;
137 if (list == null)
138 {
139 if (other.list != null) return false;
140 }
141 else if (!list.equals(other.list)) return false;
142 return true;
143 }
144
145 /**
146 * {@inheritDoc}
147 */
148 public E get(final int index)
149 {
150 return list.get(index);
151 }
152
153 /**
154 * {@inheritDoc}
155 */
156 @Override
157 public int hashCode()
158 {
159 final int prime = 31;
160 int result = 1;
161 result = prime * result + (list == null ? 0 : list.hashCode());
162 return result;
163 }
164
165 /**
166 * {@inheritDoc}
167 */
168 public int indexOf(final Object o)
169 {
170 return list.indexOf(o);
171 }
172
173 /**
174 * {@inheritDoc}
175 */
176 public boolean isEmpty()
177 {
178 return list.isEmpty();
179 }
180
181 /**
182 * {@inheritDoc}
183 */
184 public Iterator<E> iterator()
185 {
186 return list.iterator();
187 }
188
189 /**
190 * {@inheritDoc}
191 */
192 public int lastIndexOf(final Object o)
193 {
194 return list.lastIndexOf(o);
195 }
196
197 /**
198 * {@inheritDoc}
199 */
200 public ListIterator<E> listIterator()
201 {
202 return list.listIterator();
203 }
204
205 /**
206 * {@inheritDoc}
207 */
208 public ListIterator<E> listIterator(final int index)
209 {
210 return list.listIterator(index);
211 }
212
213 /**
214 * {@inheritDoc}
215 */
216 public E remove(final int index)
217 {
218 return list.remove(index);
219 }
220
221 /**
222 * {@inheritDoc}
223 */
224 public boolean remove(final Object o)
225 {
226 return list.remove(o);
227 }
228
229 /**
230 * {@inheritDoc}
231 */
232 public boolean removeAll(final Collection< ? > c)
233 {
234 return list.removeAll(c);
235 }
236
237 /**
238 * {@inheritDoc}
239 */
240 public boolean retainAll(final Collection< ? > c)
241 {
242 return list.retainAll(c);
243 }
244
245 /**
246 * {@inheritDoc}
247 */
248 public E set(final int index, final E element)
249 {
250 final int elementIndex = list.indexOf(element);
251
252 if (elementIndex == index) return element;
253
254 if (elementIndex == -1) return list.set(index, element);
255 if (elementIndex > index)
256 {
257 list.remove(element);
258 return list.set(index, element);
259 }
260
261 // if (elementIndex < index)
262 list.remove(element);
263 return list.set(index - 1, element);
264 }
265
266 /**
267 * {@inheritDoc}
268 */
269 public int size()
270 {
271 return list.size();
272 }
273
274 /**
275 * {@inheritDoc}
276 */
277 public List<E> subList(final int fromIndex, final int toIndex)
278 {
279 return list.subList(fromIndex, toIndex);
280 }
281
282 /**
283 * {@inheritDoc}
284 */
285 public Object[] toArray()
286 {
287 return list.toArray();
288 }
289
290 /**
291 * {@inheritDoc}
292 */
293 public <T> T[] toArray(final T[] a)
294 {
295 return list.toArray(a);
296 }
297
298 /**
299 * {@inheritDoc}
300 */
301 @Override
302 public String toString()
303 {
304 return list.toString();
305 }
306 }