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    }