Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbvosburgh2007-09-01 00:16:34 +0000
committerbvosburgh2007-09-01 00:16:34 +0000
commit428159b00fa3b24516470491d21fffe7cf460351 (patch)
treeea7281299bf7865c03bce98aa10e92b9fd5946f9 /jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility
parent600fc0c48e2c2c59480c5843eb0285e053018286 (diff)
downloadwebtools.dali-428159b00fa3b24516470491d21fffe7cf460351.tar.gz
webtools.dali-428159b00fa3b24516470491d21fffe7cf460351.tar.xz
webtools.dali-428159b00fa3b24516470491d21fffe7cf460351.zip
[201159] model rework - added "node" support
Diffstat (limited to 'jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility')
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java6
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java142
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java226
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java293
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java271
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java528
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java31
7 files changed, 1497 insertions, 0 deletions
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
index 436f10e901..7d7a7a0924 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
@@ -12,6 +12,7 @@ package org.eclipse.jpt.utility.tests.internal;
import org.eclipse.jpt.utility.internal.ClassTools;
import org.eclipse.jpt.utility.tests.internal.iterators.JptUtilityIteratorsTests;
import org.eclipse.jpt.utility.tests.internal.model.JptUtilityModelTests;
+import org.eclipse.jpt.utility.tests.internal.node.JptUtilityNodeTests;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -26,6 +27,7 @@ public class JptUtilityTests {
suite.addTest(JptUtilityIteratorsTests.suite());
suite.addTest(JptUtilityModelTests.suite());
+ suite.addTest(JptUtilityNodeTests.suite());
suite.addTestSuite(BitToolsTests.class);
suite.addTestSuite(ClasspathTests.class);
@@ -39,7 +41,11 @@ public class JptUtilityTests {
suite.addTestSuite(JDBCTypeTests.class);
suite.addTestSuite(NameToolsTests.class);
suite.addTestSuite(ReverseComparatorTests.class);
+ suite.addTestSuite(SimpleStackTests.class);
suite.addTestSuite(StringToolsTests.class);
+ suite.addTestSuite(SynchronizedBooleanTests.class);
+ suite.addTestSuite(SynchronizedObjectTests.class);
+ suite.addTestSuite(SynchronizedStackTests.class);
suite.addTestSuite(XMLStringEncoderTests.class);
return suite;
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java
new file mode 100644
index 0000000000..f229797565
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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;
+
+import java.util.EmptyStackException;
+
+import org.eclipse.jpt.utility.internal.SimpleStack;
+import org.eclipse.jpt.utility.internal.Stack;
+
+import junit.framework.TestCase;
+
+public class SimpleStackTests extends TestCase {
+
+ public SimpleStackTests(String name) {
+ super(name);
+ }
+
+ public void testIsEmpty() {
+ Stack<String> stack = new SimpleStack<String>();
+ assertTrue(stack.isEmpty());
+ stack.push("first");
+ assertFalse(stack.isEmpty());
+ stack.push("second");
+ assertFalse(stack.isEmpty());
+ stack.pop();
+ assertFalse(stack.isEmpty());
+ stack.pop();
+ assertTrue(stack.isEmpty());
+ }
+
+ public void testPushAndPop() {
+ Stack<String> stack = new SimpleStack<String>();
+ String first = "first";
+ String second = "second";
+
+ stack.push(first);
+ stack.push(second);
+ assertEquals(second, stack.pop());
+ assertEquals(first, stack.pop());
+ }
+
+ public void testPushAndPeek() {
+ Stack<String> stack = new SimpleStack<String>();
+ String first = "first";
+ String second = "second";
+
+ stack.push(first);
+ stack.push(second);
+ assertEquals(second, stack.peek());
+ assertEquals(second, stack.peek());
+ assertEquals(second, stack.pop());
+ assertEquals(first, stack.peek());
+ assertEquals(first, stack.peek());
+ assertEquals(first, stack.pop());
+ }
+
+ public void testEmptyStackExceptionPeek() {
+ Stack<String> stack = new SimpleStack<String>();
+ String first = "first";
+ String second = "second";
+
+ stack.push(first);
+ stack.push(second);
+ assertEquals(second, stack.peek());
+ assertEquals(second, stack.pop());
+ assertEquals(first, stack.peek());
+ assertEquals(first, stack.pop());
+
+ boolean exCaught = false;
+ try {
+ stack.peek();
+ } catch (EmptyStackException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testEmptyStackExceptionPop() {
+ Stack<String> stack = new SimpleStack<String>();
+ String first = "first";
+ String second = "second";
+
+ stack.push(first);
+ stack.push(second);
+ assertEquals(second, stack.peek());
+ assertEquals(second, stack.pop());
+ assertEquals(first, stack.peek());
+ assertEquals(first, stack.pop());
+
+ boolean exCaught = false;
+ try {
+ stack.pop();
+ } catch (EmptyStackException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testClone() {
+ SimpleStack<String> stack = new SimpleStack<String>();
+ stack.push("first");
+ stack.push("second");
+ stack.push("third");
+
+ this.verifyClone(stack, stack.clone());
+ }
+
+ public void testSerialization() throws Exception {
+ SimpleStack<String> stack = new SimpleStack<String>();
+ stack.push("first");
+ stack.push("second");
+ stack.push("third");
+
+ this.verifyClone(stack, TestTools.serialize(stack));
+ }
+
+ private void verifyClone(Stack<String> original, Stack<String> clone) {
+ assertNotSame(original, clone);
+ assertEquals(original.peek(), clone.peek());
+ assertEquals(original.pop(), clone.pop());
+ assertEquals(original.peek(), clone.peek());
+ assertEquals(original.pop(), clone.pop());
+ assertEquals(original.isEmpty(), clone.isEmpty());
+ assertEquals(original.peek(), clone.peek());
+ assertEquals(original.pop(), clone.pop());
+ assertTrue(original.isEmpty());
+ assertEquals(original.isEmpty(), clone.isEmpty());
+
+ original.push("fourth");
+ assertFalse(original.isEmpty());
+ // clone should still be empty
+ assertTrue(clone.isEmpty());
+ }
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java
new file mode 100644
index 0000000000..4b42839081
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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;
+
+import org.eclipse.jpt.utility.internal.SynchronizedBoolean;
+
+import junit.framework.TestCase;
+
+public class SynchronizedBooleanTests extends TestCase {
+ private volatile SynchronizedBoolean sb;
+ private volatile boolean exCaught;
+ private volatile boolean timeoutOccurred;
+ private volatile long startTime;
+ private volatile long endTime;
+
+
+ public SynchronizedBooleanTests(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.sb = new SynchronizedBoolean();
+ this.exCaught = false;
+ this.timeoutOccurred = false;
+ this.startTime = 0;
+ this.endTime = 0;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ TestTools.clear(this);
+ super.tearDown();
+ }
+
+ public void testAccessors() throws Exception {
+ this.sb.setValue(false);
+ assertFalse(this.sb.value());
+ assertFalse(this.sb.isTrue());
+ assertTrue(this.sb.isFalse());
+
+ this.sb.setValue(true);
+ assertTrue(this.sb.value());
+ assertTrue(this.sb.isTrue());
+ assertFalse(this.sb.isFalse());
+
+ this.sb.setFalse();
+ assertFalse(this.sb.value());
+ assertFalse(this.sb.isTrue());
+ assertTrue(this.sb.isFalse());
+
+ this.sb.setTrue();
+ assertTrue(this.sb.value());
+ assertTrue(this.sb.isTrue());
+ assertFalse(this.sb.isFalse());
+
+ assertSame(this.sb, this.sb.mutex());
+ }
+
+ public void testEquals() throws Exception {
+ this.sb.setValue(false);
+ SynchronizedBoolean sb2 = new SynchronizedBoolean(false);
+ assertEquals(this.sb, sb2);
+
+ this.sb.setValue(true);
+ assertFalse(this.sb.equals(sb2));
+
+ sb2.setValue(true);
+ assertEquals(this.sb, sb2);
+ }
+
+ public void testHashCode() {
+ this.sb.setValue(false);
+ assertEquals(0, this.sb.hashCode());
+
+ this.sb.setValue(true);
+ assertEquals(1, this.sb.hashCode());
+ }
+
+ public void testWaitUntilTrue() throws Exception {
+ this.verifyWaitUntilTrue(0);
+ // no timeout occurs...
+ assertFalse(this.timeoutOccurred);
+ // ...and the value should be set to true by t2
+ assertTrue(this.sb.value());
+ // make a reasonable guess about how long t2 took
+ assertTrue(this.elapsedTime() > 150);
+ }
+
+ public void testWaitUntilTrueTimeout() throws Exception {
+ this.verifyWaitUntilTrue(20);
+ // timeout occurs...
+ assertTrue(this.timeoutOccurred);
+ // ...and the value will eventually be set to true by t1
+ assertTrue(this.sb.value());
+ // make a reasonable guess about how long t2 took
+ assertTrue(this.elapsedTime() < 150);
+ }
+
+ private void verifyWaitUntilTrue(long timeout) throws Exception {
+ this.sb.setFalse();
+ Runnable r1 = this.buildRunnable(this.buildSetTrueCommand(), this.sb, 200);
+ Runnable r2 = this.buildRunnable(this.buildWaitUntilTrueCommand(timeout), this.sb, 0);
+ Thread t1 = new Thread(r1);
+ Thread t2 = new Thread(r2);
+ t1.start();
+ t2.start();
+ while (t1.isAlive() || t2.isAlive()) {
+ Thread.sleep(50);
+ }
+ assertFalse(this.exCaught);
+ }
+
+ public void testWaitToSetFalse() throws Exception {
+ this.verifyWaitToSetFalse(0);
+ // no timeout occurs...
+ assertFalse(this.timeoutOccurred);
+ // ...and the value should be set to false by t2
+ assertFalse(this.sb.value());
+ // make a reasonable guess about how long t2 took
+ assertTrue(this.elapsedTime() > 150);
+ }
+
+ public void testWaitToSetFalseTimeout() throws Exception {
+ this.verifyWaitToSetFalse(20);
+ // timeout occurs...
+ assertTrue(this.timeoutOccurred);
+ // ...and the value will eventually be set to true by t1
+ assertTrue(this.sb.value());
+ // make a reasonable guess about how long t2 took
+ assertTrue(this.elapsedTime() < 150);
+ }
+
+ private void verifyWaitToSetFalse(long timeout) throws Exception {
+ this.sb.setFalse();
+ Runnable r1 = this.buildRunnable(this.buildSetTrueCommand(), this.sb, 200);
+ Runnable r2 = this.buildRunnable(this.buildWaitToSetFalseCommand(timeout), this.sb, 0);
+ Thread t1 = new Thread(r1);
+ Thread t2 = new Thread(r2);
+ t1.start();
+ t2.start();
+ while (t1.isAlive() || t2.isAlive()) {
+ Thread.sleep(50);
+ }
+ assertFalse(this.exCaught);
+ }
+
+ private Command buildSetTrueCommand() {
+ return new Command() {
+ public void execute(SynchronizedBoolean syncBool) {
+ syncBool.setTrue();
+ }
+ };
+ }
+
+ private Command buildWaitUntilTrueCommand(final long timeout) {
+ return new Command() {
+ public void execute(SynchronizedBoolean syncBool) throws Exception {
+ SynchronizedBooleanTests.this.setStartTime(System.currentTimeMillis());
+ SynchronizedBooleanTests.this.setTimeoutOccurred( ! syncBool.waitUntilTrue(timeout));
+ SynchronizedBooleanTests.this.setEndTime(System.currentTimeMillis());
+ }
+ };
+ }
+
+ private Command buildWaitToSetFalseCommand(final long timeout) {
+ return new Command() {
+ public void execute(SynchronizedBoolean syncBool) throws Exception {
+ SynchronizedBooleanTests.this.setStartTime(System.currentTimeMillis());
+ SynchronizedBooleanTests.this.setTimeoutOccurred( ! syncBool.waitToSetFalse(timeout));
+ SynchronizedBooleanTests.this.setEndTime(System.currentTimeMillis());
+ }
+ };
+ }
+
+ private Runnable buildRunnable(final Command command, final SynchronizedBoolean syncBool, final long sleep) {
+ return new Runnable() {
+ public void run() {
+ try {
+ if (sleep != 0) {
+ Thread.sleep(sleep);
+ }
+ command.execute(syncBool);
+ } catch (Exception ex) {
+ SynchronizedBooleanTests.this.setExCaught(true);
+ }
+ }
+ };
+ }
+
+ void setExCaught(boolean exCaught) {
+ this.exCaught = exCaught;
+ }
+
+ void setTimeoutOccurred(boolean timeoutOccurred) {
+ this.timeoutOccurred = timeoutOccurred;
+ }
+
+ void setStartTime(long startTime) {
+ this.startTime = startTime;
+ }
+
+ void setEndTime(long endTime) {
+ this.endTime = endTime;
+ }
+
+ long elapsedTime() {
+ return this.endTime - this.startTime;
+ }
+
+
+ // ********** Command interface **********
+
+ private interface Command {
+ void execute(SynchronizedBoolean syncBool) throws Exception;
+ }
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java
new file mode 100644
index 0000000000..1eba5ba39b
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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;
+
+import org.eclipse.jpt.utility.internal.SynchronizedObject;
+
+import junit.framework.TestCase;
+
+public class SynchronizedObjectTests extends TestCase {
+ private volatile SynchronizedObject<Object> so;
+ private volatile boolean exCaught;
+ private volatile boolean timeoutOccurred;
+ volatile Object value = new Object();
+ private volatile long startTime;
+ private volatile long endTime;
+ private volatile Object soValue;
+
+
+ public SynchronizedObjectTests(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.so = new SynchronizedObject<Object>();
+ this.exCaught = false;
+ this.timeoutOccurred = false;
+ this.startTime = 0;
+ this.endTime = 0;
+ this.soValue = null;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ TestTools.clear(this);
+ super.tearDown();
+ }
+
+ public void testAccessors() throws Exception {
+ this.so.setValue(null);
+ assertNull(this.so.value());
+ assertFalse(this.so.isNotNull());
+ assertTrue(this.so.isNull());
+
+ this.so.setValue(this.value);
+ assertEquals(this.value, this.so.value());
+ assertTrue(this.so.isNotNull());
+ assertFalse(this.so.isNull());
+
+ this.so.setNull();
+ assertNull(this.so.value());
+ assertFalse(this.so.isNotNull());
+ assertTrue(this.so.isNull());
+
+ assertSame(this.so, this.so.mutex());
+ }
+
+ public void testEquals() throws Exception {
+ this.so.setValue(null);
+ SynchronizedObject<Object> so2 = new SynchronizedObject<Object>(null);
+ assertEquals(this.so, so2);
+
+ this.so.setValue(this.value);
+ assertFalse(this.so.equals(so2));
+
+ so2.setValue(this.value);
+ assertEquals(this.so, so2);
+ }
+
+ public void testHashCode() {
+ this.so.setValue(this.value);
+ assertEquals(this.value.hashCode(), this.so.hashCode());
+
+ this.so.setValue(null);
+ assertEquals(0, this.so.hashCode());
+ }
+
+ /**
+ * t2 will wait indefinitely until t1 sets the value to null
+ */
+ public void testWaitUntilNull() throws Exception {
+ this.verifyWaitUntilNull(0);
+ // no timeout occurs...
+ assertFalse(this.timeoutOccurred);
+ // ...and the value should be set to null by t2
+ assertNull(this.so.value());
+ // make a reasonable guess about how long t2 took
+ long time = this.elapsedTime();
+ assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150);
+ }
+
+ /**
+ * t2 will time out waiting for t1 to set the value to null
+ */
+ public void testWaitUntilNullTimeout() throws Exception {
+ this.verifyWaitUntilNull(20);
+ // timeout occurs...
+ assertTrue(this.timeoutOccurred);
+ // ...and the value will eventually be set to null by t1
+ assertNull(this.so.value());
+ // make a reasonable guess about how long t2 took
+ long time = this.elapsedTime();
+ assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150);
+ }
+
+ private void verifyWaitUntilNull(long t2Timeout) throws Exception {
+ this.executeThreads(this.buildSetNullCommand(), this.buildWaitUntilNullCommand(t2Timeout));
+ }
+
+ /**
+ * t2 will wait indefinitely until t1 sets the value to null;
+ * then t2 will set the value to an object
+ */
+ public void testWaitToSetValue() throws Exception {
+ this.verifyWaitToSetValue(0);
+ // no timeout occurs...
+ assertFalse(this.timeoutOccurred);
+ // ...and the value should be set to an object by t2
+ assertTrue(this.so.isNotNull());
+ // make a reasonable guess about how long t2 took
+ long time = this.elapsedTime();
+ assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150);
+ }
+
+ /**
+ * t2 will time out waiting for t1 to set the value to null
+ */
+ public void testWaitToSetValueTimeout() throws Exception {
+ this.verifyWaitToSetValue(20);
+ // timeout occurs...
+ assertTrue(this.timeoutOccurred);
+ // ...and the value will eventually be set to null by t1
+ assertTrue(this.so.isNull());
+ // make a reasonable guess about how long t2 took
+ long time = this.elapsedTime();
+ assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150);
+ }
+
+ private void verifyWaitToSetValue(long t2Timeout) throws Exception {
+ this.executeThreads(this.buildSetNullCommand(), this.buildWaitToSetValueCommand(t2Timeout));
+ }
+
+ /**
+ * t2 will wait until t1 is finished "initializing" the value;
+ * then t2 will get the newly-initialized value ("foo")
+ */
+ public void testExecute() throws Exception {
+ this.so.setValue(null);
+ Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.so, 0);
+ // give t1 a head start of 100 ms
+ Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.so, 100);
+ Thread t1 = new Thread(r1);
+ Thread t2 = new Thread(r2);
+ t1.start();
+ t2.start();
+ while (t1.isAlive() || t2.isAlive()) {
+ Thread.sleep(50);
+ }
+ assertFalse(this.exCaught);
+ assertEquals("foo", this.so.value());
+ assertEquals("foo", this.soValue);
+ // make a reasonable guess about how long t2 took
+ long time = this.elapsedTime();
+ assertTrue("t2 finished a bit early (expected value should be > 100): " + time, time > 300);
+ }
+
+ private void executeThreads(Command t1Command, Command t2Command) throws Exception {
+ this.so.setValue(this.value);
+ Runnable r1 = this.buildRunnable(t1Command, this.so, 200);
+ Runnable r2 = this.buildRunnable(t2Command, this.so, 0);
+ Thread t1 = new Thread(r1);
+ Thread t2 = new Thread(r2);
+ t1.start();
+ t2.start();
+ while (t1.isAlive() || t2.isAlive()) {
+ Thread.sleep(50);
+ }
+ assertFalse(this.exCaught);
+ }
+
+ private Command buildSetNullCommand() {
+ return new Command() {
+ public void execute(SynchronizedObject<Object> sObject) {
+ sObject.setNull();
+ }
+ };
+ }
+
+ private Command buildWaitUntilNullCommand(final long timeout) {
+ return new Command() {
+ public void execute(SynchronizedObject<Object> sObject) throws Exception {
+ SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
+ SynchronizedObjectTests.this.setTimeoutOccurred( ! sObject.waitUntilNull(timeout));
+ SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
+ }
+ };
+ }
+
+ private Command buildWaitToSetValueCommand(final long timeout) {
+ return new Command() {
+ public void execute(SynchronizedObject<Object> sObject) throws Exception {
+ SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
+ SynchronizedObjectTests.this.setTimeoutOccurred( ! sObject.waitToSetValue(SynchronizedObjectTests.this.value, timeout));
+ SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
+ }
+ };
+ }
+
+ private Command buildInitializeValueCommand() {
+ return new Command() {
+ public void execute(final SynchronizedObject<Object> sObject) throws Exception {
+ sObject.execute(
+ new org.eclipse.jpt.utility.internal.Command() {
+ public void execute() {
+ // pretend to perform some long initialization process
+ try {
+ Thread.sleep(500);
+ } catch (Exception ex) {
+ SynchronizedObjectTests.this.setExCaught(true);
+ }
+ sObject.setValue("foo");
+ }
+ }
+ );
+ }
+ };
+ }
+
+ private Command buildGetValueCommand() {
+ return new Command() {
+ public void execute(SynchronizedObject<Object> sObject) throws Exception {
+ SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
+ SynchronizedObjectTests.this.setSOValue(sObject.value());
+ SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
+ }
+ };
+ }
+
+ private Runnable buildRunnable(final Command command, final SynchronizedObject<Object> sObject, final long sleep) {
+ return new Runnable() {
+ public void run() {
+ try {
+ if (sleep != 0) {
+ Thread.sleep(sleep);
+ }
+ command.execute(sObject);
+ } catch (Exception ex) {
+ SynchronizedObjectTests.this.setExCaught(true);
+ }
+ }
+ };
+ }
+
+ void setExCaught(boolean exCaught) {
+ this.exCaught = exCaught;
+ }
+
+ void setTimeoutOccurred(boolean timeoutOccurred) {
+ this.timeoutOccurred = timeoutOccurred;
+ }
+
+ void setStartTime(long startTime) {
+ this.startTime = startTime;
+ }
+
+ void setEndTime(long endTime) {
+ this.endTime = endTime;
+ }
+
+ private long elapsedTime() {
+ return this.endTime - this.startTime;
+ }
+
+ void setSOValue(Object soValue) {
+ this.soValue = soValue;
+ }
+
+
+ // ********** Command interface **********
+
+ private interface Command {
+ void execute(SynchronizedObject<Object> so) throws Exception;
+ }
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java
new file mode 100644
index 0000000000..adb83d9f83
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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;
+
+import java.util.EmptyStackException;
+
+import org.eclipse.jpt.utility.internal.SimpleStack;
+import org.eclipse.jpt.utility.internal.Stack;
+import org.eclipse.jpt.utility.internal.SynchronizedStack;
+
+public class SynchronizedStackTests extends SimpleStackTests {
+ private volatile SynchronizedStack<String> ss;
+ private volatile boolean exCaught;
+ private volatile boolean timeoutOccurred;
+ private volatile long startTime;
+ private volatile long endTime;
+ private volatile Object poppedObject;
+
+ static final String ITEM_1 = new String();
+ static final String ITEM_2 = new String();
+
+ public SynchronizedStackTests(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.ss = new SynchronizedStack<String>();
+ this.exCaught = false;
+ this.timeoutOccurred = false;
+ this.startTime = 0;
+ this.endTime = 0;
+ this.poppedObject = null;
+ }
+
+ /**
+ * test first with an unsynchronized stack,
+ * then with a synchronized stack
+ */
+ public void testConcurrentAccess() throws Exception {
+ this.verifyConcurrentAccess(new SlowSimpleStack<String>(), "second");
+ this.verifyConcurrentAccess(new SlowSynchronizedStack<String>(), "first");
+ }
+
+ private void verifyConcurrentAccess(SlowStack<String> slowStack, String expected) throws Exception {
+ slowStack.push("first");
+ slowStack.push("second");
+
+ new Thread(this.buildRunnable(slowStack)).start();
+ Thread.sleep(200);
+
+ assertEquals(expected, slowStack.pop());
+ }
+
+ private Runnable buildRunnable(final SlowStack<String> slowStack) {
+ return new Runnable() {
+ public void run() {
+ slowStack.slowPop();
+ }
+ };
+ }
+
+
+ private interface SlowStack<E> extends Stack<E> {
+ Object slowPop();
+ }
+
+ private class SlowSimpleStack<E> extends SimpleStack<E> implements SlowStack<E> {
+ SlowSimpleStack() {
+ super();
+ }
+ public Object slowPop() {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
+ return this.pop();
+ }
+
+ }
+
+ private class SlowSynchronizedStack<E> extends SynchronizedStack<E> implements SlowStack<E> {
+ SlowSynchronizedStack() {
+ super();
+ }
+ public synchronized Object slowPop() {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ex) {
+ throw new RuntimeException(ex);
+ }
+ return this.pop();
+ }
+
+ }
+
+
+ // ********** waits **********
+
+ public void testWaitToPop() throws Exception {
+ this.verifyWaitToPop(0);
+ // no timeout occurs...
+ assertFalse(this.timeoutOccurred);
+ // ...and an item should have been popped by t2...
+ assertSame(ITEM_1, this.poppedObject);
+ // ...and the stack should be empty
+ assertTrue(this.ss.isEmpty());
+ // make a reasonable guess about how long t2 took
+ assertTrue(this.elapsedTime() > 150);
+ }
+
+ public void testWaitToPopTimeout() throws Exception {
+ this.verifyWaitToPop(20);
+ // timeout occurs...
+ assertTrue(this.timeoutOccurred);
+ // ...and the stack was never popped...
+ assertNull(this.poppedObject);
+ // ...and it still holds the item
+ assertSame(ITEM_1, this.ss.peek());
+ // make a reasonable guess about how long t2 took
+ assertTrue(this.elapsedTime() < 150);
+ }
+
+ private void verifyWaitToPop(long timeout) throws Exception {
+ Runnable r1 = this.buildRunnable(this.buildPushCommand(), this.ss, 200);
+ Runnable r2 = this.buildRunnable(this.buildWaitToPopCommand(timeout), this.ss, 0);
+ Thread t1 = new Thread(r1);
+ Thread t2 = new Thread(r2);
+ t1.start();
+ t2.start();
+ while (t1.isAlive() || t2.isAlive()) {
+ Thread.sleep(50);
+ }
+ assertFalse(this.exCaught);
+ }
+
+ public void testWaitToPush() throws Exception {
+ this.verifyWaitToPush(0);
+ // no timeout occurs...
+ assertFalse(this.timeoutOccurred);
+ // ...and the stack gets popped by t1...
+ assertSame(ITEM_1, this.poppedObject);
+ // ...and an item is pushed on to the stack by t2
+ assertFalse(this.ss.isEmpty());
+ assertSame(ITEM_2, this.ss.peek());
+ // make a reasonable guess about how long t2 took
+ assertTrue(this.elapsedTime() > 150);
+ }
+
+ public void testWaitToPushTimeout() throws Exception {
+ this.verifyWaitToPush(20);
+ // timeout occurs...
+ assertTrue(this.timeoutOccurred);
+ // ...and the stack is eventually popped by t1...
+ assertSame(ITEM_1, this.poppedObject);
+ // ...but nothing is pushed on to the stack by t2
+ assertTrue(this.ss.isEmpty());
+ // make a reasonable guess about how long t2 took
+ assertTrue(this.elapsedTime() < 150);
+ }
+
+ private void verifyWaitToPush(long timeout) throws Exception {
+ this.ss.push(ITEM_1);
+ Runnable r1 = this.buildRunnable(this.buildPopCommand(), this.ss, 200);
+ Runnable r2 = this.buildRunnable(this.buildWaitToPushCommand(timeout), this.ss, 0);
+ Thread t1 = new Thread(r1);
+ Thread t2 = new Thread(r2);
+ t1.start();
+ t2.start();
+ while (t1.isAlive() || t2.isAlive()) {
+ Thread.sleep(50);
+ }
+ assertFalse(this.exCaught);
+ }
+
+ private Command buildPushCommand() {
+ return new Command() {
+ public void execute(SynchronizedStack<String> synchronizedStack) {
+ synchronizedStack.push(ITEM_1);
+ }
+ };
+ }
+
+ private Command buildWaitToPopCommand(final long timeout) {
+ return new Command() {
+ public void execute(SynchronizedStack<String> synchronizedStack) throws Exception {
+ SynchronizedStackTests.this.setStartTime(System.currentTimeMillis());
+ try {
+ SynchronizedStackTests.this.setPoppedObject(synchronizedStack.waitToPop(timeout));
+ } catch (EmptyStackException ex) {
+ SynchronizedStackTests.this.setTimeoutOccurred(true);
+ }
+ SynchronizedStackTests.this.setEndTime(System.currentTimeMillis());
+ }
+ };
+ }
+
+ private Command buildPopCommand() {
+ return new Command() {
+ public void execute(SynchronizedStack<String> synchronizedStack) {
+ SynchronizedStackTests.this.setPoppedObject(synchronizedStack.pop());
+ }
+ };
+ }
+
+ private Command buildWaitToPushCommand(final long timeout) {
+ return new Command() {
+ public void execute(SynchronizedStack<String> synchronizedStack) throws Exception {
+ SynchronizedStackTests.this.setStartTime(System.currentTimeMillis());
+ SynchronizedStackTests.this.setTimeoutOccurred( ! synchronizedStack.waitToPush(ITEM_2, timeout));
+ SynchronizedStackTests.this.setEndTime(System.currentTimeMillis());
+ }
+ };
+ }
+
+ private Runnable buildRunnable(final Command command, final SynchronizedStack<String> synchronizedStack, final long sleep) {
+ return new Runnable() {
+ public void run() {
+ try {
+ if (sleep != 0) {
+ Thread.sleep(sleep);
+ }
+ command.execute(synchronizedStack);
+ } catch (Exception ex) {
+ SynchronizedStackTests.this.setExCaught(true);
+ }
+ }
+ };
+ }
+
+ void setExCaught(boolean exCaught) {
+ this.exCaught = exCaught;
+ }
+
+ void setTimeoutOccurred(boolean timeoutOccurred) {
+ this.timeoutOccurred = timeoutOccurred;
+ }
+
+ void setStartTime(long startTime) {
+ this.startTime = startTime;
+ }
+
+ void setEndTime(long endTime) {
+ this.endTime = endTime;
+ }
+
+ void setPoppedObject(Object poppedObject) {
+ this.poppedObject = poppedObject;
+ }
+
+ long elapsedTime() {
+ return this.endTime - this.startTime;
+ }
+
+
+ // ********** Command interface **********
+
+ private interface Command {
+ void execute(SynchronizedStack<String> synchronizedStack) throws Exception;
+ }
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java
new file mode 100644
index 0000000000..5af287fcfe
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java
@@ -0,0 +1,528 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.node;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.HashBag;
+import org.eclipse.jpt.utility.internal.Range;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.internal.node.AbstractNodeModel;
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.jpt.utility.internal.node.Problem;
+import org.eclipse.jpt.utility.tests.internal.TestTools;
+
+import junit.framework.TestCase;
+
+public class AbstractNodeModelTests extends TestCase {
+ private TestWorkbenchModel root;
+
+ public AbstractNodeModelTests(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.root = this.buildRoot();
+ }
+
+ private TestWorkbenchModel buildRoot() {
+ TestWorkbenchModel r = new RootTestWorkbenchModel("root");
+ TestWorkbenchModel node1 = r.addTestChildNamed("node 1");
+ TestWorkbenchModel node1_1 = node1.addTestChildNamed("node 1.1");
+ node1_1.addTestChildNamed("node 1.1.1");
+ node1_1.addTestChildNamed("node 1.1.2");
+ node1_1.addTestChildNamed("node 1.1.3");
+ node1.addTestChildNamed("node 1.2");
+ TestWorkbenchModel node2 = r.addTestChildNamed("node 2");
+ node2.addTestChildNamed("node 2.1");
+ node2.addTestChildNamed("node 2.2");
+ r.addTestChildNamed("node 3");
+ r.addTestChildNamed("node 4");
+
+ // mark the entire tree clean
+ r.markEntireBranchClean();
+ return r;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ TestTools.clear(this);
+ super.tearDown();
+ }
+
+ public void testTestWorkbenchModel() {
+ // make sure our test class works OK...
+ assertNull(this.root.testChildNamed(""));
+ assertNotNull(this.root.testChildNamed("node 1"));
+ assertTrue(this.root.testChildNamed("node 1").isClean());
+ assertTrue(this.root.testChildNamed("node 1").isCleanBranch());
+ assertNotNull(this.root.testChildNamed("node 2"));
+ assertTrue(this.root.testChildNamed("node 2").isClean());
+ assertTrue(this.root.testChildNamed("node 2").isCleanBranch());
+ assertNull(this.root.testChildNamed("node 2.1"));
+
+ assertNull(this.root.testDescendantNamed(""));
+ assertNotNull(this.root.testDescendantNamed("node 1"));
+ assertNotNull(this.root.testDescendantNamed("node 2"));
+ assertNotNull(this.root.testDescendantNamed("node 2.1"));
+ assertTrue(this.root.testDescendantNamed("node 2.1").isClean());
+ assertTrue(this.root.testDescendantNamed("node 2.1").isCleanBranch());
+ assertNotNull(this.root.testDescendantNamed("node 1.1.3"));
+ assertTrue(this.root.testDescendantNamed("node 1.1.3").isClean());
+ assertTrue(this.root.testDescendantNamed("node 1.1.3").isCleanBranch());
+ }
+
+ public void testParentAndChildren() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ assertEquals("node 1.1.3", node.getName());
+ assertEquals(0, CollectionTools.size(node.children()));
+
+ node = (TestWorkbenchModel) node.parent();
+ assertEquals("node 1.1", node.getName());
+ assertEquals(3, CollectionTools.size(node.children()));
+
+ node = (TestWorkbenchModel) node.parent();
+ assertEquals("node 1", node.getName());
+ assertEquals(2, CollectionTools.size(node.children()));
+
+ node = (TestWorkbenchModel) node.parent();
+ assertEquals("root", node.getName());
+ assertEquals(4, CollectionTools.size(node.children()));
+
+ node = (TestWorkbenchModel) node.parent();
+ assertNull(node);
+ }
+
+ public void testDirty() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setSize(42);
+ assertTrue(node.isDirty());
+
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+ assertTrue(parent.isClean());
+ assertTrue(this.root.isClean());
+ }
+
+ public void testDirtyUnchangedAttribute() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setSize(42);
+ assertTrue(node.isDirty());
+
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+ assertTrue(parent.isClean());
+ assertTrue(this.root.isClean());
+
+ this.root.markEntireBranchClean();
+ // set size to same number - should stay clean
+ node.setSize(42);
+ assertTrue(node.isClean());
+ assertTrue(parent.isClean());
+ assertTrue(this.root.isClean());
+ }
+
+ public void testDirtyBranch() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setSize(42);
+ assertTrue(node.isDirtyBranch());
+
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+ assertTrue(parent.isDirtyBranch());
+ assertTrue(this.root.isDirtyBranch());
+
+ parent.setSize(77);
+ assertTrue(parent.isDirty());
+ assertTrue(parent.isDirtyBranch());
+
+ node.markEntireBranchClean();
+ assertTrue(parent.isDirty());
+ assertTrue(parent.isDirtyBranch());
+ }
+
+ public void testDirtyBranchCleanChildDirtyParent() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setSize(42);
+
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+ parent.setSize(77);
+ assertTrue(parent.isDirty());
+ assertTrue(parent.isDirtyBranch());
+
+ // now, clean the child, but leave the parent dirty
+ node.markEntireBranchClean();
+ assertTrue(parent.isDirty());
+ assertTrue(parent.isDirtyBranch());
+ }
+
+ public void testDirtyBranchCleanChildDirtyChild() {
+ TestWorkbenchModel node1 = this.root.testDescendantNamed("node 1.1.1");
+ node1.setSize(41);
+ TestWorkbenchModel node2 = this.root.testDescendantNamed("node 1.1.2");
+ node2.setSize(42);
+
+ TestWorkbenchModel parent = (TestWorkbenchModel) node1.parent();
+ assertTrue(parent.isClean());
+ assertTrue(parent.isDirtyBranch());
+
+ // now, clean the first child, but leave the second child dirty
+ node1.markEntireBranchClean();
+ assertTrue(parent.isClean());
+ assertTrue(parent.isDirtyBranch());
+ }
+
+ public void testDirtyBranchForced() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+
+ assertTrue(node.isClean());
+ assertTrue(node.isCleanBranch());
+ assertTrue(parent.isClean());
+ assertTrue(parent.isCleanBranch());
+ assertTrue(this.root.isClean());
+ assertTrue(this.root.isCleanBranch());
+
+ this.root.markEntireBranchDirty();
+
+ assertTrue(node.isDirty());
+ assertTrue(node.isDirtyBranch());
+ assertTrue(parent.isDirty());
+ assertTrue(parent.isDirtyBranch());
+ assertTrue(this.root.isDirty());
+ assertTrue(this.root.isDirtyBranch());
+ }
+
+ public void testDirtyTransientAttribute() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setName("BOGUS");
+ assertTrue(node.isDirty());
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+ assertTrue(parent.isClean());
+ assertTrue(parent.isDirtyBranch());
+ assertTrue(this.root.isClean());
+ assertTrue(this.root.isDirtyBranch());
+
+ this.root.markEntireBranchClean();
+
+ this.root.validateBranch();
+
+ assertTrue(this.root.problemsSize() == 0);
+ assertTrue(node.branchProblems().hasNext());
+ assertTrue(parent.problemsSize() == 0);
+ assertTrue(parent.branchProblems().hasNext());
+ assertTrue(node.problemsSize() > 0);
+
+ // since problems are transient, everything should still be clean
+ assertTrue(node.isClean());
+ assertTrue(node.isCleanBranch());
+ assertTrue(parent.isClean());
+ assertTrue(parent.isCleanBranch());
+ assertTrue(this.root.isClean());
+ assertTrue(this.root.isCleanBranch());
+ }
+
+ public void testProblems() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setName("BOGUS");
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+
+ this.root.validateBranch();
+
+ assertEquals(0, this.root.problemsSize());
+ assertTrue(node.branchProblems().hasNext());
+ assertEquals(0, parent.problemsSize());
+ assertTrue(parent.branchProblems().hasNext());
+ assertEquals(1, node.problemsSize());
+ Problem problem1 = node.problems().next();
+
+ // now create another problem that should remove the old problem
+ node.setName("STILL BOGUS");
+ this.root.validateBranch();
+
+ assertEquals(0, this.root.problemsSize());
+ assertTrue(node.branchProblems().hasNext());
+ assertEquals(0, parent.problemsSize());
+ assertTrue(parent.branchProblems().hasNext());
+ assertEquals(1, node.problemsSize());
+ Problem problem2 = node.problems().next();
+ assertFalse(problem1 == problem2);
+ problem1 = problem2;
+
+ // now create another problem that should replace the old problem
+ node.setName("STILL BOGUS");
+ this.root.validateBranch();
+
+ assertEquals(0, this.root.problemsSize());
+ assertTrue(node.branchProblems().hasNext());
+ assertEquals(0, parent.problemsSize());
+ assertTrue(parent.branchProblems().hasNext());
+ assertEquals(1, node.problemsSize());
+ problem2 = node.problems().next();
+ // the same problem should be there
+ assertTrue(problem1.equals(problem2));
+ }
+
+ public void testBranchProblems() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setName("BOGUS");
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+ parent.setName("BOGUS TOO");
+ this.root.setName("BOGUS TOO TOO");
+
+ this.root.validateBranch();
+
+ assertEquals(1, this.root.problemsSize());
+ assertEquals(3, this.root.branchProblemsSize());
+ assertEquals(1, parent.problemsSize());
+ assertEquals(2, parent.branchProblemsSize());
+ assertEquals(1, node.problemsSize());
+ assertEquals(1, node.branchProblemsSize());
+
+ node.setName("okie-dokie");
+
+ this.root.validateBranch();
+
+ assertEquals(1, this.root.problemsSize());
+ assertEquals(2, this.root.branchProblemsSize());
+ assertEquals(1, parent.problemsSize());
+ assertEquals(1, parent.branchProblemsSize());
+ assertEquals(0, node.problemsSize());
+ assertEquals(0, node.branchProblemsSize());
+ }
+
+ public void testClearAllBranchProblems() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setName("BOGUS");
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+ parent.setName("BOGUS TOO");
+ this.root.setName("BOGUS TOO TOO");
+
+ this.root.validateBranch();
+
+ assertEquals(1, this.root.problemsSize());
+ assertEquals(3, this.root.branchProblemsSize());
+ assertEquals(1, parent.problemsSize());
+ assertEquals(2, parent.branchProblemsSize());
+ assertEquals(1, node.problemsSize());
+ assertEquals(1, node.branchProblemsSize());
+
+ parent.clearAllBranchProblems();
+
+ assertEquals(1, this.root.problemsSize());
+ assertEquals(1, this.root.branchProblemsSize());
+ assertEquals(0, parent.problemsSize());
+ assertEquals(0, parent.branchProblemsSize());
+ assertEquals(0, node.problemsSize());
+ assertEquals(0, CollectionTools.size(node.branchProblems()));
+ }
+
+ public void testRemovedBranchProblems() {
+ TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+ node.setName("BOGUS");
+ TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+ parent.setName("BOGUS TOO");
+ this.root.setName("BOGUS TOO TOO");
+
+ this.root.validateBranch();
+
+ assertEquals(1, this.root.problemsSize());
+ assertEquals(3, CollectionTools.size(this.root.branchProblems()));
+ assertEquals(1, parent.problemsSize());
+ assertEquals(2, parent.branchProblemsSize());
+ assertEquals(1, node.problemsSize());
+ assertEquals(1, CollectionTools.size(node.branchProblems()));
+
+ // completely remove a node that has problems -
+ // the entire tree should recalculate its "branch" problems
+ parent.removeTestChild(node);
+
+ this.root.validateBranch();
+
+ assertEquals(1, this.root.problemsSize());
+ assertEquals(2, CollectionTools.size(this.root.branchProblems()));
+ assertEquals(1, parent.problemsSize());
+ assertEquals(1, parent.branchProblemsSize());
+ }
+
+ public void testSort() {
+ List<TestWorkbenchModel> nodes = this.buildSortedNodes();
+ assertTrue(new Range(0, 1).includes(this.indexOf(nodes, "aaa")));
+ assertTrue(new Range(0, 1).includes(this.indexOf(nodes, "AAA")));
+ assertTrue(new Range(2, 3).includes(this.indexOf(nodes, "bbb")));
+ assertTrue(new Range(2, 3).includes(this.indexOf(nodes, "BBB")));
+ assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "ccc")));
+ assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "CCC")));
+ assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "���")));
+ }
+
+ private int indexOf(List<TestWorkbenchModel> nodes, String nodeName) {
+ for (int i = nodes.size(); i-- > 0; ) {
+ if (nodes.get(i).getName().equals(nodeName)) {
+ return i;
+ }
+ }
+ throw new IllegalArgumentException();
+ }
+
+ private List<TestWorkbenchModel> buildSortedNodes() {
+ List<TestWorkbenchModel> result = new ArrayList<TestWorkbenchModel>();
+ result.add(new RootTestWorkbenchModel("AAA"));
+ result.add(new RootTestWorkbenchModel("BBB"));
+ result.add(new RootTestWorkbenchModel("CCC"));
+ result.add(new RootTestWorkbenchModel("���"));
+ result.add(new RootTestWorkbenchModel("ccc"));
+ result.add(new RootTestWorkbenchModel("bbb"));
+ result.add(new RootTestWorkbenchModel("aaa"));
+ return CollectionTools.sort(result);
+ }
+
+
+ // ********** inner classes **********
+
+ private class TestWorkbenchModel extends AbstractNodeModel {
+ private String name;
+ public static final String NAME_PROPERTY = "name";
+ private int size;
+ public static final String SIZE_PROPERTY = "size";
+ private Collection<TestWorkbenchModel> testChildren;
+ public static final String TEST_CHILDREN_COLLECTION = "children";
+
+ // ********** construction/initialization **********
+ public TestWorkbenchModel(TestWorkbenchModel parent, String name) {
+ super(parent);
+ if (name == null) {
+ throw new NullPointerException();
+ }
+ this.name = name;
+ }
+ @Override
+ protected void initialize() {
+ super.initialize();
+ this.size = 0;
+ this.testChildren = new HashBag<TestWorkbenchModel>();
+ }
+
+ @Override
+ protected void checkParent(Node parent) {
+ // do nothing
+ }
+
+
+ // ********** accessors **********
+ public String getName() {
+ return this.name;
+ }
+ public void setName(String name) {
+ Object old = this.name;
+ this.name = name;
+ this.firePropertyChanged(NAME_PROPERTY, old, name);
+ }
+
+ public int getSize() {
+ return this.size;
+ }
+ public void setSize(int size) {
+ int old = this.size;
+ this.size = size;
+ this.firePropertyChanged(SIZE_PROPERTY, old, size);
+ }
+
+ public Iterator<TestWorkbenchModel> testChildren() {
+ return new CloneIterator<TestWorkbenchModel>(this.testChildren) {
+ @Override
+ protected void remove(TestWorkbenchModel current) {
+ TestWorkbenchModel.this.removeTestChild(current);
+ }
+ };
+ }
+ public int testChildrenSize() {
+ return this.testChildren.size();
+ }
+ private TestWorkbenchModel addTestChild(TestWorkbenchModel testChild) {
+ this.addItemToCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION);
+ return testChild;
+ }
+ public TestWorkbenchModel addTestChildNamed(String childName) {
+ if (this.testChildNamed(childName) != null) {
+ throw new IllegalArgumentException(childName);
+ }
+ return this.addTestChild(new TestWorkbenchModel(this, childName));
+ }
+ public void removeTestChild(TestWorkbenchModel testChild) {
+ this.removeItemFromCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION);
+ }
+
+ // ********** queries **********
+ public String displayString() {
+ return this.name;
+ }
+ public TestWorkbenchModel testChildNamed(String childName) {
+ for (TestWorkbenchModel testChild : this.testChildren) {
+ if (testChild.getName().equals(childName)) {
+ return testChild;
+ }
+ }
+ return null;
+ }
+ public TestWorkbenchModel testDescendantNamed(String descendantName) {
+ for (TestWorkbenchModel testDescendant : this.testChildren) {
+ if (testDescendant.getName().equals(descendantName)) {
+ return testDescendant;
+ }
+ // recurse...
+ testDescendant = testDescendant.testDescendantNamed(descendantName);
+ if (testDescendant != null) {
+ return testDescendant;
+ }
+ }
+ return null;
+ }
+
+ // ********** behavior **********
+ @Override
+ protected void addChildrenTo(List<Node> children) {
+ super.addChildrenTo(children);
+ children.addAll(this.testChildren);
+ }
+ @Override
+ protected void addProblemsTo(List<Problem> currentProblems) {
+ super.addProblemsTo(currentProblems);
+ // names must be all lowercase...
+ for (int i = this.name.length(); i-- > 0; ) {
+ char c = this.name.charAt(i);
+ if (Character.isLetter(c) && ! Character.isLowerCase(c)) {
+ currentProblems.add(this.buildProblem("NAME_MUST_BE_LOWERCASE", this.name));
+ return;
+ }
+ }
+ }
+ @Override
+ public void toString(StringBuffer sb) {
+ sb.append(this.name);
+ }
+ }
+
+
+ private class RootTestWorkbenchModel extends TestWorkbenchModel {
+ public RootTestWorkbenchModel(String name) {
+ super(null, name);
+ }
+ @Override
+ public Validator validator() {
+ return Node.NULL_VALIDATOR;
+ }
+ }
+
+}
+
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java
new file mode 100644
index 0000000000..e16c3baecd
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.node;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class JptUtilityNodeTests {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(ClassTools.packageNameFor(JptUtilityNodeTests.class));
+
+ suite.addTestSuite(AbstractNodeModelTests.class);
+
+ return suite;
+ }
+
+ private JptUtilityNodeTests() {
+ super();
+ }
+
+}

Back to the top