Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbvosburgh2009-06-25 15:15:37 +0000
committerbvosburgh2009-06-25 15:15:37 +0000
commit87e44c59bce702324121b6d9a250259a4861b488 (patch)
tree60df41c68ab871d99ada9e811713a6c8318d6637
parent06f6b5a525c1494031a0faa8b38d573c9143aff3 (diff)
downloadwebtools.dali-87e44c59bce702324121b6d9a250259a4861b488.tar.gz
webtools.dali-87e44c59bce702324121b6d9a250259a4861b488.tar.xz
webtools.dali-87e44c59bce702324121b6d9a250259a4861b488.zip
Iterator work
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayIterator.java12
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayListIterator.java12
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java44
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GraphIterator.java8
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SynchronizedIterator.java52
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SynchronizedListIterator.java77
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayIteratorTests.java24
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayListIteratorTests.java21
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneIteratorTests.java6
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneListIteratorTests.java4
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/GraphIteratorTests.java4
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java2
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/SynchronizedIteratorTests.java313
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/SynchronizedListIteratorTests.java500
14 files changed, 1009 insertions, 70 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayIterator.java
index 9e6aa342c4..7fffe95d0f 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayIterator.java
@@ -23,8 +23,8 @@ public class ArrayIterator<E>
implements Iterator<E>
{
final E[] array; // private-protected
- int nextIndex; // private-protected
- private final int maxIndex;
+ int cursor; // private-protected
+ private final int max;
/**
@@ -48,17 +48,17 @@ public class ArrayIterator<E>
throw new IllegalArgumentException("length: " + length); //$NON-NLS-1$
}
this.array = array;
- this.nextIndex = start;
- this.maxIndex = start + length;
+ this.cursor = start;
+ this.max = start + length;
}
public boolean hasNext() {
- return this.nextIndex < this.maxIndex;
+ return this.cursor != this.max;
}
public E next() {
if (this.hasNext()) {
- return this.array[this.nextIndex++];
+ return this.array[this.cursor++];
}
throw new NoSuchElementException();
}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayListIterator.java
index 5ed13629d3..8a38965fcb 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayListIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/ArrayListIterator.java
@@ -24,7 +24,7 @@ public class ArrayListIterator<E>
extends ArrayIterator<E>
implements ListIterator<E>
{
- private final int minIndex;
+ private final int min;
/**
@@ -41,24 +41,24 @@ public class ArrayListIterator<E>
*/
public ArrayListIterator(E[] array, int start, int length) {
super(array, start, length);
- this.minIndex = start;
+ this.min = start;
}
public int nextIndex() {
- return this.nextIndex;
+ return this.cursor;
}
public int previousIndex() {
- return this.nextIndex - 1;
+ return this.cursor - 1;
}
public boolean hasPrevious() {
- return this.nextIndex > this.minIndex;
+ return this.cursor != this.min;
}
public E previous() {
if (this.hasPrevious()) {
- return this.array[--this.nextIndex];
+ return this.array[--this.cursor];
}
throw new NoSuchElementException();
}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java
index 3dfbd73226..81424d7ab1 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java
@@ -24,8 +24,8 @@ import org.eclipse.jpt.utility.internal.StringTools;
* By default, a <code>CloneIterator</code> does not support the
* <code>#remove()</code> operation; this is because it does not have
* access to the original collection. But if the <code>CloneIterator</code>
- * is supplied with an <code>Mutator</code> it will delegate the
- * <code>#remove()</code> operation to the <code>Mutator</code>.
+ * is supplied with an <code>Remover</code> it will delegate the
+ * <code>#remove()</code> operation to the <code>Remover</code>.
* Alternatively, a subclass can override the <code>#remove(Object)</code>
* method.
*/
@@ -34,7 +34,7 @@ public class CloneIterator<E>
{
private final Iterator<Object> iterator;
private E current;
- private final Mutator<E> mutator;
+ private final Remover<E> remover;
private boolean removeAllowed;
@@ -46,7 +46,7 @@ public class CloneIterator<E>
* unless a subclass overrides the <code>#remove(Object)</code>.
*/
public CloneIterator(Collection<? extends E> collection) {
- this(collection, Mutator.ReadOnly.<E>instance());
+ this(collection, Remover.ReadOnly.<E>instance());
}
/**
@@ -55,25 +55,25 @@ public class CloneIterator<E>
* unless a subclass overrides the <code>#remove(Object)</code>.
*/
public CloneIterator(E[] array) {
- this(array, Mutator.ReadOnly.<E>instance());
+ this(array, Remover.ReadOnly.<E>instance());
}
/**
* Construct an iterator on a copy of the specified collection.
- * Use the specified mutator to remove objects from the
+ * Use the specified remover to remove objects from the
* original collection.
*/
- public CloneIterator(Collection<? extends E> collection, Mutator<E> mutator) {
- this(mutator, collection.toArray());
+ public CloneIterator(Collection<? extends E> collection, Remover<E> remover) {
+ this(remover, collection.toArray());
}
/**
* Construct an iterator on a copy of the specified array.
- * Use the specified mutator to remove objects from the
+ * Use the specified remover to remove objects from the
* original array.
*/
- public CloneIterator(E[] array, Mutator<E> mutator) {
- this(mutator, array.clone());
+ public CloneIterator(E[] array, Remover<E> remover) {
+ this(remover, array.clone());
}
/**
@@ -81,11 +81,11 @@ public class CloneIterator<E>
* Swap order of arguments to prevent collision with other constructor.
* The passed in array will *not* be cloned.
*/
- protected CloneIterator(Mutator<E> mutator, Object... array) {
+ protected CloneIterator(Remover<E> remover, Object... array) {
super();
this.iterator = new ArrayIterator<Object>(array);
this.current = null;
- this.mutator = mutator;
+ this.remover = remover;
this.removeAllowed = false;
}
@@ -128,10 +128,10 @@ public class CloneIterator<E>
* Remove the specified element from the original collection.
* <p>
* This method can be overridden by a subclass as an
- * alternative to building an <code>Mutator</code>.
+ * alternative to building a <code>Remover</code>.
*/
protected void remove(E e) {
- this.mutator.remove(e);
+ this.remover.remove(e);
}
@Override
@@ -147,19 +147,19 @@ public class CloneIterator<E>
* elements from the original collection; since the iterator
* does not have direct access to the original collection.
*/
- public interface Mutator<T> {
+ public interface Remover<T> {
/**
* Remove the specified object from the original collection.
*/
- void remove(T current);
+ void remove(T element);
- final class ReadOnly<S> implements Mutator<S> {
+ final class ReadOnly<S> implements Remover<S> {
@SuppressWarnings("unchecked")
- public static final Mutator INSTANCE = new ReadOnly();
+ public static final Remover INSTANCE = new ReadOnly();
@SuppressWarnings("unchecked")
- public static <R> Mutator<R> instance() {
+ public static <R> Remover<R> instance() {
return INSTANCE;
}
// ensure single instance
@@ -167,12 +167,12 @@ public class CloneIterator<E>
super();
}
// remove is not supported
- public void remove(Object current) {
+ public void remove(Object element) {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
- return "CloneIterator.Mutator.ReadOnly"; //$NON-NLS-1$
+ return "CloneIterator.Remover.ReadOnly"; //$NON-NLS-1$
}
}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GraphIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GraphIterator.java
index 9b28f19117..c852b1f847 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GraphIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/GraphIterator.java
@@ -52,8 +52,9 @@ import org.eclipse.jpt.utility.internal.StringTools;
public class GraphIterator<E>
implements Iterator<E>
{
- private final LinkedList<Iterator<? extends E>> iterators;
- private final HashSet<E> visitedNeighbors;
+ // use a LinkedList since we will be pulling off the front and adding to the end
+ private final LinkedList<Iterator<? extends E>> iterators = new LinkedList<Iterator<? extends E>>();
+ private final HashSet<E> visitedNeighbors = new HashSet<E>();
private final MisterRogers<E> misterRogers;
private Iterator<? extends E> currentIterator;
@@ -141,10 +142,7 @@ public class GraphIterator<E>
public GraphIterator(Iterator<? extends E> roots, MisterRogers<E> misterRogers) {
super();
this.currentIterator = roots;
- // use a LinkedList since we will be pulling off the front and adding to the end
- this.iterators = new LinkedList<Iterator<? extends E>>();
this.misterRogers = misterRogers;
- this.visitedNeighbors = new HashSet<E>();
this.loadNextNeighbor();
}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SynchronizedIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SynchronizedIterator.java
new file mode 100644
index 0000000000..8b8721bed4
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SynchronizedIterator.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.iterators;
+
+import java.util.Iterator;
+
+import org.eclipse.jpt.utility.internal.StringTools;
+
+/**
+ * Wrap an iterator and synchronize all its methods so it can be safely shared
+ * among multiple threads.
+ */
+public class SynchronizedIterator<E>
+ implements Iterator<E>
+{
+ private final Iterator<? extends E> iterator;
+
+
+ public SynchronizedIterator(Iterable<? extends E> iterable) {
+ this(iterable.iterator());
+ }
+
+ public SynchronizedIterator(Iterator<? extends E> iterator) {
+ super();
+ this.iterator = iterator;
+ }
+
+ public synchronized boolean hasNext() {
+ return this.iterator.hasNext();
+ }
+
+ public synchronized E next() {
+ return this.iterator.next();
+ }
+
+ public synchronized void remove() {
+ this.iterator.remove();
+ }
+
+ @Override
+ public String toString() {
+ return StringTools.buildToStringFor(this, this.iterator);
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SynchronizedListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SynchronizedListIterator.java
new file mode 100644
index 0000000000..1a52f50617
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/SynchronizedListIterator.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.iterators;
+
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.jpt.utility.internal.StringTools;
+
+/**
+ * Wrap a list iterator and synchronize all its methods so it can be safely shared
+ * among multiple threads.
+ */
+public class SynchronizedListIterator<E>
+ implements ListIterator<E>
+{
+ private final ListIterator<E> listIterator;
+
+
+ public SynchronizedListIterator(List<E> list) {
+ this(list.listIterator());
+ }
+
+ public SynchronizedListIterator(ListIterator<E> listIterator) {
+ super();
+ this.listIterator = listIterator;
+ }
+
+ public synchronized boolean hasNext() {
+ return this.listIterator.hasNext();
+ }
+
+ public synchronized E next() {
+ return this.listIterator.next();
+ }
+
+ public synchronized int nextIndex() {
+ return this.listIterator.nextIndex();
+ }
+
+ public synchronized boolean hasPrevious() {
+ return this.listIterator.hasPrevious();
+ }
+
+ public synchronized E previous() {
+ return this.listIterator.previous();
+ }
+
+ public synchronized int previousIndex() {
+ return this.listIterator.previousIndex();
+ }
+
+ public synchronized void remove() {
+ this.listIterator.remove();
+ }
+
+ public synchronized void add(E e) {
+ this.listIterator.add(e);
+ }
+
+ public synchronized void set(E e) {
+ this.listIterator.set(e);
+ }
+
+ @Override
+ public String toString() {
+ return StringTools.buildToStringFor(this, this.listIterator);
+ }
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayIteratorTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayIteratorTests.java
index 4e2e53d84b..a99d88d3fe 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayIteratorTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayIteratorTests.java
@@ -23,7 +23,7 @@ public class ArrayIteratorTests extends TestCase {
public void testHasNext() {
int i = 0;
- for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
+ for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
stream.next();
i++;
}
@@ -31,9 +31,9 @@ public class ArrayIteratorTests extends TestCase {
}
public void testNext() {
- int i = 0;
- for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
- assertEquals("bogus element", ++i, Integer.parseInt(stream.next()));
+ int i = 1;
+ for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
+ assertEquals("bogus element", i++, Integer.parseInt(stream.next()));
}
}
@@ -54,7 +54,7 @@ public class ArrayIteratorTests extends TestCase {
public void testUnsupportedOperationException() {
boolean exCaught = false;
- for (Iterator<String> stream = this.buildIterator(); stream.hasNext();) {
+ for (Iterator<String> stream = this.buildIterator(); stream.hasNext(); ) {
if (stream.next().equals("3")) {
try {
stream.remove();
@@ -79,21 +79,29 @@ public class ArrayIteratorTests extends TestCase {
integers[1] = new Integer(1);
integers[2] = new Integer(2);
int i = 0;
- for (Iterator<Number> stream = new ArrayIterator<Number>(integers); stream.hasNext();) {
+ for (Iterator<Number> stream = this.buildGenericIterator(integers); stream.hasNext();) {
assertEquals(i++, stream.next().intValue());
}
assertEquals(integers.length, i);
}
+ Iterator<Number> buildGenericIterator(Integer[] integers) {
+ return new ArrayIterator<Number>(integers);
+ }
+
public void testVarargs() {
int i = 0;
- for (Iterator<Number> stream = new ArrayIterator<Number>(new Integer(0), new Integer(1), new Integer(2)); stream.hasNext();) {
+ for (Iterator<Number> stream = this.buildVarArgIterator(); stream.hasNext();) {
assertEquals(i++, stream.next().intValue());
}
assertEquals(3, i);
}
- public void triggerIllegalArgumentException(int start, int length) {
+ Iterator<Number> buildVarArgIterator() {
+ return new ArrayIterator<Number>(new Integer(0), new Integer(1), new Integer(2));
+ }
+
+ void triggerIllegalArgumentException(int start, int length) {
boolean exCaught = false;
Iterator<String> stream = null;
try {
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayListIteratorTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayListIteratorTests.java
index d0a5ad1992..9685b6ff60 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayListIteratorTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/ArrayListIteratorTests.java
@@ -12,6 +12,7 @@ package org.eclipse.jpt.utility.tests.internal.iterators;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
+
import org.eclipse.jpt.utility.internal.iterators.ArrayListIterator;
@SuppressWarnings("nls")
@@ -109,25 +110,13 @@ public class ArrayListIteratorTests extends ArrayIteratorTests {
}
@Override
- public void testGenerics() {
- Integer[] integers = new Integer[3];
- integers[0] = new Integer(0);
- integers[1] = new Integer(1);
- integers[2] = new Integer(2);
- int i = 0;
- for (Iterator<Number> stream = new ArrayListIterator<Number>(integers); stream.hasNext();) {
- assertEquals(i++, stream.next().intValue());
- }
- assertEquals(integers.length, i);
+ Iterator<Number> buildGenericIterator(Integer[] integers) {
+ return new ArrayListIterator<Number>(integers);
}
@Override
- public void testVarargs() {
- int i = 0;
- for (Iterator<Number> stream = new ArrayListIterator<Number>(new Integer(0), new Integer(1), new Integer(2)); stream.hasNext();) {
- assertEquals(i++, stream.next().intValue());
- }
- assertEquals(3, i);
+ Iterator<Number> buildVarArgIterator() {
+ return new ArrayListIterator<Number>(new Integer(0), new Integer(1), new Integer(2));
}
private ListIterator<String> buildListIterator() {
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneIteratorTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneIteratorTests.java
index b35cf0a3a0..952df8b02f 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneIteratorTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneIteratorTests.java
@@ -91,9 +91,9 @@ public class CloneIteratorTests extends TestCase {
}
public void testRemoveEliminator() {
- CloneIterator.Mutator<String> eliminator = new CloneIterator.Mutator<String>() {
- public void remove(String current) {
- CloneIteratorTests.this.originalCollection.remove(current);
+ CloneIterator.Remover<String> eliminator = new CloneIterator.Remover<String>() {
+ public void remove(String element) {
+ CloneIteratorTests.this.originalCollection.remove(element);
}
};
this.verifyRemove(new CloneIterator<String>(this.originalCollection, eliminator));
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneListIteratorTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneListIteratorTests.java
index 0d43074560..44652f3819 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneListIteratorTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/CloneListIteratorTests.java
@@ -250,7 +250,7 @@ public class CloneListIteratorTests extends TestCase {
} catch (IllegalStateException ex) {
exCaught = true;
}
- assertTrue("IllegalStateException not thrown", exCaught);
+ assertTrue(exCaught);
while (iterator.hasNext()) {
String next = iterator.next();
if (next.equals(addedAfter)) {
@@ -265,7 +265,7 @@ public class CloneListIteratorTests extends TestCase {
} catch (IllegalStateException ex) {
exCaught = true;
}
- assertTrue("IllegalStateException not thrown", exCaught);
+ assertTrue(exCaught);
}
if (next.equals(replaced)) {
iterator.set(replacement);
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/GraphIteratorTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/GraphIteratorTests.java
index 4e4c80d0ef..b0e7ebd428 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/GraphIteratorTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/GraphIteratorTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 Oracle. All rights reserved.
+ * Copyright (c) 2005, 2009 Oracle. 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.
@@ -162,7 +162,7 @@ public class GraphIteratorTests extends TestCase {
return ncNode;
}
- private class GraphNode {
+ public class GraphNode {
private String name;
private Collection<GraphNode> neighbors = new ArrayList<GraphNode>();
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java
index 132b2c7d63..8a660b0ff4 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java
@@ -38,6 +38,8 @@ public class JptUtilityIteratorsTests {
suite.addTestSuite(ReadOnlyListIteratorTests.class);
suite.addTestSuite(SingleElementIteratorTests.class);
suite.addTestSuite(SingleElementListIteratorTests.class);
+ suite.addTestSuite(SynchronizedIteratorTests.class);
+ suite.addTestSuite(SynchronizedListIteratorTests.class);
suite.addTestSuite(TransformationIteratorTests.class);
suite.addTestSuite(TransformationListIteratorTests.class);
suite.addTestSuite(TreeIteratorTests.class);
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/SynchronizedIteratorTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/SynchronizedIteratorTests.java
new file mode 100644
index 0000000000..cd527b228e
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/SynchronizedIteratorTests.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.iterators;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import junit.framework.TestCase;
+
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.SynchronizedIterator;
+
+@SuppressWarnings("nls")
+public class SynchronizedIteratorTests extends TestCase {
+
+ public SynchronizedIteratorTests(String name) {
+ super(name);
+ }
+
+ /**
+ * test that an unsynchronized iterator will produce corrupt output;
+ * thread 1 will read the first element from the iterator
+ * and then sleep for a bit, allowing thread 2 to sneak in and
+ * read the same element from the iterator
+ */
+ public void testUnsynchronizedNext() throws Exception {
+ TestIterator<String> iterator = this.buildNestedIterator();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ NextTestThread<String> thread2 = new NextTestThread<String>(iterator);
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // both threads should have read the same element from the iterator :-(
+ assertEquals("foo", thread1.next);
+ assertEquals("foo", thread2.next);
+ }
+
+ /**
+ * test that a synchronized iterator will produce valid output;
+ * thread 1 will read the first element from the iterator
+ * and then sleep for a bit, but thread 2 will be locked out and
+ * wait to read the second element from the iterator
+ */
+ public void testSynchronizedNext() throws Exception {
+ TestIterator<String> nestedIterator = this.buildNestedIterator();
+ Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ NextTestThread<String> thread2 = new NextTestThread<String>(iterator);
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // the threads should have read the correct elements from the iterator :-)
+ assertEquals("foo", thread1.next);
+ assertEquals("bar", thread2.next);
+ }
+
+ public void testUnsynchronizedHasNext() throws Exception {
+ TestIterator<String> iterator = this.buildNestedIterator();
+ iterator.next();
+ iterator.next();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ HasNextTestThread<String> thread2 = new HasNextTestThread<String>(iterator);
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // thread 1 will have the last element,
+ // but thread 2 will think there are more elements on the iterator :-(
+ assertEquals("baz", thread1.next);
+ assertEquals(true, thread2.hasNext);
+ }
+
+ public void testSynchronizedHasNext() throws Exception {
+ TestIterator<String> nestedIterator = this.buildNestedIterator();
+ Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+ iterator.next();
+ iterator.next();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ HasNextTestThread<String> thread2 = new HasNextTestThread<String>(iterator);
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // thread 1 will have the last element,
+ // and thread 2 will think there are no more elements on the iterator :-)
+ assertEquals("baz", thread1.next);
+ assertEquals(false, thread2.hasNext);
+ }
+
+ public void testUnsynchronizedRemove() throws Exception {
+ TestIterator<String> iterator = this.buildNestedIterator();
+ iterator.next();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ RemoveTestThread<String> thread2 = new RemoveTestThread<String>(iterator);
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // the wrong element was removed :-(
+ assertEquals("bar", thread1.next);
+ assertFalse(iterator.list.contains("foo"));
+ assertTrue(iterator.list.contains("bar"));
+ assertTrue(iterator.list.contains("baz"));
+ }
+
+ public void testSynchronizedRemove() throws Exception {
+ TestIterator<String> nestedIterator = this.buildNestedIterator();
+ Iterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+ iterator.next();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ RemoveTestThread<String> thread2 = new RemoveTestThread<String>(iterator);
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // the wrong element was removed :-(
+ assertEquals("bar", thread1.next);
+ assertTrue(nestedIterator.list.contains("foo"));
+ assertFalse(nestedIterator.list.contains("bar"));
+ assertTrue(nestedIterator.list.contains("baz"));
+ }
+
+ TestIterator<String> buildNestedIterator() {
+ return new TestIterator<String>(this.buildArray());
+ }
+
+ String[] buildArray() {
+ return new String[] {"foo", "bar", "baz"};
+ }
+
+ Iterator<String> buildSynchronizedIterator(Iterator<String> nestedIterator) {
+ return new SynchronizedIterator<String>(nestedIterator);
+ }
+
+
+ /**
+ * next thread
+ */
+ class NextTestThread<E> extends Thread {
+ final Iterator<E> iterator;
+ E next;
+
+ NextTestThread(Iterator<E> iterator) {
+ super();
+ this.iterator = iterator;
+ }
+
+ @Override
+ public void run() {
+ this.next = this.iterator.next();
+ }
+
+ }
+
+ /**
+ * has next thread
+ */
+ class HasNextTestThread<E> extends Thread {
+ final Iterator<E> iterator;
+ boolean hasNext;
+
+ HasNextTestThread(Iterator<E> iterator) {
+ super();
+ this.iterator = iterator;
+ }
+
+ @Override
+ public void run() {
+ this.hasNext = this.iterator.hasNext();
+ }
+
+ }
+
+ /**
+ * remove thread
+ */
+ class RemoveTestThread<E> extends Thread {
+ final Iterator<E> iterator;
+
+ RemoveTestThread(Iterator<E> iterator) {
+ super();
+ this.iterator = iterator;
+ }
+
+ @Override
+ public void run() {
+ this.iterator.remove();
+ }
+
+ }
+
+ /**
+ * test iterator
+ */
+ class TestIterator<E> implements Iterator<E> {
+ final ArrayList<E> list;
+ int nextIndex;
+ int lastIndex = -1;
+ Thread slowThread;
+
+ TestIterator(E... array) {
+ super();
+ this.list = new ArrayList<E>();
+ CollectionTools.addAll(this.list, array);
+ this.nextIndex = 0;
+ }
+
+ public boolean hasNext() {
+ return this.nextIndex != this.list.size();
+ }
+
+ public E next() {
+ if (this.hasNext()) {
+ E next = this.list.get(this.nextIndex);
+ this.sleep();
+ this.lastIndex = this.nextIndex++;
+ return next;
+ }
+ throw new NoSuchElementException();
+ }
+
+ public void remove() {
+ if (this.lastIndex == -1) {
+ throw new IllegalStateException();
+ }
+ this.list.remove(this.lastIndex);
+ if (this.lastIndex < this.nextIndex) { // check necessary for ListIterator
+ this.nextIndex--;
+ }
+ this.lastIndex = -1;
+ }
+
+ void sleep() {
+ if (Thread.currentThread() == this.slowThread) {
+ SynchronizedIteratorTests.sleep(200);
+ }
+ }
+
+ }
+
+ static void sleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/SynchronizedListIteratorTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/SynchronizedListIteratorTests.java
new file mode 100644
index 0000000000..de5f53dc8d
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/SynchronizedListIteratorTests.java
@@ -0,0 +1,500 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.iterators;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+import org.eclipse.jpt.utility.internal.iterators.SynchronizedListIterator;
+
+@SuppressWarnings("nls")
+public class SynchronizedListIteratorTests extends SynchronizedIteratorTests {
+
+ public SynchronizedListIteratorTests(String name) {
+ super(name);
+ }
+
+ public void testUnsynchronizedPrevious() throws Exception {
+ TestListIterator<String> iterator = this.buildNestedIterator();
+ iterator.next();
+ iterator.next();
+
+ PreviousTestThread<String> thread1 = new PreviousTestThread<String>(iterator);
+ PreviousTestThread<String> thread2 = new PreviousTestThread<String>(iterator);
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // both threads should have read the same element from the iterator :-(
+ assertEquals("bar", thread1.previous);
+ assertEquals("bar", thread2.previous);
+ }
+
+ public void testSynchronizedPrevious() throws Exception {
+ TestListIterator<String> nestedIterator = this.buildNestedIterator();
+ ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+ iterator.next();
+ iterator.next();
+
+ PreviousTestThread<String> thread1 = new PreviousTestThread<String>(iterator);
+ PreviousTestThread<String> thread2 = new PreviousTestThread<String>(iterator);
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // the threads should have read the correct elements from the iterator :-)
+ assertEquals("bar", thread1.previous);
+ assertEquals("foo", thread2.previous);
+ }
+
+ public void testUnsynchronizedHasPrevious() throws Exception {
+ TestListIterator<String> iterator = this.buildNestedIterator();
+ iterator.next();
+
+ PreviousTestThread<String> thread1 = new PreviousTestThread<String>(iterator);
+ HasPreviousTestThread<String> thread2 = new HasPreviousTestThread<String>(iterator);
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // thread 1 will have the first element,
+ // but thread 2 will think there are more "previous" elements on the iterator :-(
+ assertEquals("foo", thread1.previous);
+ assertEquals(true, thread2.hasPrevious);
+ }
+
+ public void testSynchronizedHasPrevious() throws Exception {
+ TestListIterator<String> nestedIterator = this.buildNestedIterator();
+ ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+ iterator.next();
+
+ PreviousTestThread<String> thread1 = new PreviousTestThread<String>(iterator);
+ HasPreviousTestThread<String> thread2 = new HasPreviousTestThread<String>(iterator);
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // thread 1 will have the first element,
+ // and thread 2 will think there are no more "previous" elements on the iterator :-)
+ assertEquals("foo", thread1.previous);
+ assertEquals(false, thread2.hasPrevious);
+ }
+
+ public void testUnsynchronizedNextIndex() throws Exception {
+ TestListIterator<String> iterator = this.buildNestedIterator();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ NextIndexTestThread<String> thread2 = new NextIndexTestThread<String>(iterator);
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // thread 1 will have the first element,
+ // but thread 2 will think the next index is still 0 :-(
+ assertEquals("foo", thread1.next);
+ assertEquals(0, thread2.nextIndex);
+ }
+
+ public void testSynchronizedNextIndex() throws Exception {
+ TestListIterator<String> nestedIterator = this.buildNestedIterator();
+ ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ NextIndexTestThread<String> thread2 = new NextIndexTestThread<String>(iterator);
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // thread 1 will have the first element,
+ // and thread 2 will think the next index is 1 :-)
+ assertEquals("foo", thread1.next);
+ assertEquals(1, thread2.nextIndex);
+ }
+
+ public void testUnsynchronizedPreviousIndex() throws Exception {
+ TestListIterator<String> iterator = this.buildNestedIterator();
+ iterator.next();
+
+ PreviousTestThread<String> thread1 = new PreviousTestThread<String>(iterator);
+ PreviousIndexTestThread<String> thread2 = new PreviousIndexTestThread<String>(iterator);
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // thread 1 will have the first element,
+ // but thread 2 will think the next index is still 0 :-(
+ assertEquals("foo", thread1.previous);
+ assertEquals(0, thread2.previousIndex);
+ }
+
+ public void testSynchronizedPreviousIndex() throws Exception {
+ TestListIterator<String> nestedIterator = this.buildNestedIterator();
+ ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+ iterator.next();
+
+ PreviousTestThread<String> thread1 = new PreviousTestThread<String>(iterator);
+ PreviousIndexTestThread<String> thread2 = new PreviousIndexTestThread<String>(iterator);
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // thread 1 will have the first element,
+ // and thread 2 will think the next index is -1 :-)
+ assertEquals("foo", thread1.previous);
+ assertEquals(-1, thread2.previousIndex);
+ }
+
+ public void testUnsynchronizedSet() throws Exception {
+ TestListIterator<String> iterator = this.buildNestedIterator();
+ iterator.next();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ SetTestThread<String> thread2 = new SetTestThread<String>(iterator, "xxx");
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // the wrong element was set :-(
+ assertEquals("bar", thread1.next);
+ assertFalse(iterator.list.contains("foo"));
+ assertTrue(iterator.list.contains("xxx"));
+ assertTrue(iterator.list.contains("bar"));
+ assertTrue(iterator.list.contains("baz"));
+ }
+
+ public void testSynchronizedSet() throws Exception {
+ TestListIterator<String> nestedIterator = this.buildNestedIterator();
+ ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+ iterator.next();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ SetTestThread<String> thread2 = new SetTestThread<String>(iterator, "xxx");
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // the right element was set :-)
+ assertEquals("bar", thread1.next);
+ assertTrue(nestedIterator.list.contains("foo"));
+ assertFalse(nestedIterator.list.contains("bar"));
+ assertTrue(nestedIterator.list.contains("xxx"));
+ assertTrue(nestedIterator.list.contains("baz"));
+ }
+
+ public void testUnsynchronizedAdd() throws Exception {
+ TestListIterator<String> iterator = this.buildNestedIterator();
+ iterator.next();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ AddTestThread<String> thread2 = new AddTestThread<String>(iterator, "xxx");
+ iterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // the element was added at the wrong index :-(
+ assertEquals("bar", thread1.next);
+ assertTrue(iterator.list.contains("foo"));
+ assertEquals(0, iterator.list.indexOf("xxx"));
+ assertTrue(iterator.list.contains("xxx"));
+ assertTrue(iterator.list.contains("bar"));
+ assertTrue(iterator.list.contains("baz"));
+ }
+
+ public void testSynchronizedAdd() throws Exception {
+ TestListIterator<String> nestedIterator = this.buildNestedIterator();
+ ListIterator<String> iterator = this.buildSynchronizedIterator(nestedIterator);
+ iterator.next();
+
+ NextTestThread<String> thread1 = new NextTestThread<String>(iterator);
+ AddTestThread<String> thread2 = new AddTestThread<String>(iterator, "xxx");
+ nestedIterator.slowThread = thread1;
+
+ thread1.start();
+
+ // allow thread 1 to read the first element and get bogged down
+ sleep(100);
+ thread2.start();
+
+ // wait for the threads to finish
+ thread1.join();
+ thread2.join();
+
+ // the element was added at the correct index :-)
+ assertEquals("bar", thread1.next);
+ assertTrue(nestedIterator.list.contains("foo"));
+ assertEquals(1, nestedIterator.list.indexOf("xxx"));
+ assertTrue(nestedIterator.list.contains("xxx"));
+ assertTrue(nestedIterator.list.contains("bar"));
+ assertTrue(nestedIterator.list.contains("baz"));
+ }
+
+ @Override
+ ListIterator<String> buildSynchronizedIterator(Iterator<String> nestedIterator) {
+ return new SynchronizedListIterator<String>((ListIterator<String>) nestedIterator);
+ }
+
+ @Override
+ TestListIterator<String> buildNestedIterator() {
+ return new TestListIterator<String>(this.buildArray());
+ }
+
+ /**
+ * previous thread
+ */
+ class PreviousTestThread<E> extends Thread {
+ final ListIterator<E> iterator;
+ E previous;
+
+ PreviousTestThread(ListIterator<E> iterator) {
+ super();
+ this.iterator = iterator;
+ }
+
+ @Override
+ public void run() {
+ this.previous = this.iterator.previous();
+ }
+
+ }
+
+ /**
+ * has previous thread
+ */
+ class HasPreviousTestThread<E> extends Thread {
+ final ListIterator<E> iterator;
+ boolean hasPrevious;
+
+ HasPreviousTestThread(ListIterator<E> iterator) {
+ super();
+ this.iterator = iterator;
+ }
+
+ @Override
+ public void run() {
+ this.hasPrevious = this.iterator.hasPrevious();
+ }
+
+ }
+
+ /**
+ * next index thread
+ */
+ class NextIndexTestThread<E> extends Thread {
+ final ListIterator<E> iterator;
+ int nextIndex;
+
+ NextIndexTestThread(ListIterator<E> iterator) {
+ super();
+ this.iterator = iterator;
+ }
+
+ @Override
+ public void run() {
+ this.nextIndex = this.iterator.nextIndex();
+ }
+
+ }
+
+ /**
+ * previous index thread
+ */
+ class PreviousIndexTestThread<E> extends Thread {
+ final ListIterator<E> iterator;
+ int previousIndex;
+
+ PreviousIndexTestThread(ListIterator<E> iterator) {
+ super();
+ this.iterator = iterator;
+ }
+
+ @Override
+ public void run() {
+ this.previousIndex = this.iterator.previousIndex();
+ }
+
+ }
+
+ /**
+ * set thread
+ */
+ class SetTestThread<E> extends Thread {
+ final ListIterator<E> iterator;
+ final E element;
+
+ SetTestThread(ListIterator<E> iterator, E element) {
+ super();
+ this.iterator = iterator;
+ this.element = element;
+ }
+
+ @Override
+ public void run() {
+ this.iterator.set(this.element);
+ }
+
+ }
+
+ /**
+ * add thread
+ */
+ class AddTestThread<E> extends Thread {
+ final ListIterator<E> iterator;
+ final E element;
+
+ AddTestThread(ListIterator<E> iterator, E element) {
+ super();
+ this.iterator = iterator;
+ this.element = element;
+ }
+
+ @Override
+ public void run() {
+ this.iterator.add(this.element);
+ }
+
+ }
+
+ /**
+ * test list iterator
+ */
+ class TestListIterator<E> extends TestIterator<E> implements ListIterator<E> {
+
+ TestListIterator(E... array) {
+ super(array);
+ }
+
+ public int nextIndex() {
+ return this.nextIndex;
+ }
+
+ public boolean hasPrevious() {
+ return this.nextIndex != 0;
+ }
+
+ public E previous() {
+ if (this.hasPrevious()) {
+ E previous = this.list.get(this.previousIndex());
+ sleep();
+ this.nextIndex--;
+ this.lastIndex = this.nextIndex;
+ return previous;
+ }
+ throw new NoSuchElementException();
+ }
+
+ public int previousIndex() {
+ return this.nextIndex - 1;
+ }
+
+ public void set(E e) {
+ if (this.lastIndex == -1) {
+ throw new IllegalStateException();
+ }
+ this.list.set(this.lastIndex, e);
+ }
+
+ public void add(E e) {
+ this.list.add(this.lastIndex, e);
+ this.lastIndex++;
+ this.lastIndex = -1;
+ }
+
+ }
+
+}

Back to the top