rework ObjectReferences
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/AbstractModifiableObjectReference.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/AbstractModifiableObjectReference.java
new file mode 100644
index 0000000..22af063
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/AbstractModifiableObjectReference.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2015 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.common.utility.internal.reference;
+
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.reference.ModifiableObjectReference;
+
+/**
+ * Implement some of the methods in {@link ModifiableObjectReference} that can
+ * be defined in terms of the other methods.
+ * Subclasses need only implement<ul>
+ * <li>{@link #getValue()}
+ * <li>{@link #setValue(Object)}
+ * </ul>
+ *
+ * @param <V> the type of the reference's value
+ */
+public abstract class AbstractModifiableObjectReference<V>
+ extends AbstractObjectReference<V>
+ implements ModifiableObjectReference<V>
+{
+ protected AbstractModifiableObjectReference() {
+ super();
+ }
+
+ public V setNull() {
+ return this.setValue(null);
+ }
+
+ public boolean commit(V newValue, V expectedValue) {
+ if (ObjectTools.equals(this.getValue(), expectedValue)) {
+ this.setValue(newValue);
+ return true;
+ }
+ return false;
+ }
+
+ public V swap(ModifiableObjectReference<V> other) {
+ if (other == this) {
+ return this.getValue();
+ }
+ V otherValue = other.getValue();
+ if (ObjectTools.equals(this.getValue(), otherValue)) {
+ return this.getValue();
+ }
+ other.setValue(this.getValue());
+ this.setValue(otherValue);
+ return otherValue;
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/AbstractObjectReference.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/AbstractObjectReference.java
index 5957155..b795f2c 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/AbstractObjectReference.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/AbstractObjectReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Oracle. All rights reserved.
+ * Copyright (c) 2013, 2015 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.
@@ -10,6 +10,7 @@
package org.eclipse.jpt.common.utility.internal.reference;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.predicate.Predicate;
import org.eclipse.jpt.common.utility.reference.ObjectReference;
/**
@@ -36,6 +37,14 @@
return ObjectTools.notEquals(this.getValue(), object);
}
+ public boolean is(Object object) {
+ return this.getValue() == object;
+ }
+
+ public boolean isNot(Object object) {
+ return this.getValue() != object;
+ }
+
public boolean isNull() {
return this.getValue() == null;
}
@@ -44,6 +53,37 @@
return this.getValue() != null;
}
+ public boolean isMemberOf(Predicate<? super V> predicate) {
+ return predicate.evaluate(this.getValue());
+ }
+
+ public boolean isNotMemberOf(Predicate<? super V> predicate) {
+ return ! predicate.evaluate(this.getValue());
+ }
+
+
+ // ********** standard methods **********
+
+ /**
+ * Object identity is critical to object references.
+ * There is no reason for two different object references to be
+ * <em>equal</em>.
+ *
+ * @see #valueEquals(Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+
+ /**
+ * @see #equals(Object)
+ */
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
@Override
public String toString() {
return '[' + String.valueOf(this.getValue()) + ']';
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/SimpleObjectReference.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/SimpleObjectReference.java
index d518978..01d3463 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/SimpleObjectReference.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/SimpleObjectReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2013 Oracle. All rights reserved.
+ * Copyright (c) 2009, 2015 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.
@@ -11,6 +11,7 @@
import java.io.Serializable;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.predicate.Predicate;
import org.eclipse.jpt.common.utility.reference.ModifiableObjectReference;
/**
@@ -47,7 +48,7 @@
}
- // ********** value **********
+ // ********** ObjectReference **********
public V getValue() {
return this.value;
@@ -61,6 +62,14 @@
return ObjectTools.notEquals(this.value, object);
}
+ public boolean is(Object object) {
+ return this.value == object;
+ }
+
+ public boolean isNot(Object object) {
+ return this.value != object;
+ }
+
public boolean isNull() {
return this.value == null;
}
@@ -69,6 +78,17 @@
return this.value != null;
}
+ public boolean isMemberOf(Predicate<? super V> predicate) {
+ return predicate.evaluate(this.value);
+ }
+
+ public boolean isNotMemberOf(Predicate<? super V> predicate) {
+ return ! predicate.evaluate(this.value);
+ }
+
+
+ // ********** ModifiableObjectReference **********
+
public V setValue(V value) {
V old = this.value;
this.value = value;
@@ -79,6 +99,27 @@
return this.setValue(null);
}
+ public boolean commit(V newValue, V expectedValue) {
+ if (ObjectTools.equals(this.value, expectedValue)) {
+ this.value = newValue;
+ return true;
+ }
+ return false;
+ }
+
+ public V swap(ModifiableObjectReference<V> other) {
+ if (other == this) {
+ return this.value;
+ }
+ V otherValue = other.getValue();
+ if (ObjectTools.equals(this.value, otherValue)) {
+ return this.value;
+ }
+ other.setValue(this.value);
+ this.value = otherValue;
+ return otherValue;
+ }
+
// ********** standard methods **********
@@ -93,6 +134,26 @@
}
}
+ /**
+ * Object identity is critical to object references.
+ * There is no reason for two different object references to be
+ * <em>equal</em>.
+ *
+ * @see #valueEquals(Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+
+ /**
+ * @see #equals(Object)
+ */
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
@Override
public String toString() {
return '[' + String.valueOf(this.value) + ']';
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/SynchronizedObject.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/SynchronizedObject.java
index 0db9dff..037cb64 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/SynchronizedObject.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/SynchronizedObject.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2012 Oracle. All rights reserved.
+ * Copyright (c) 2007, 2015 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.
@@ -12,6 +12,8 @@
import java.io.Serializable;
import org.eclipse.jpt.common.utility.command.Command;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.internal.predicate.PredicateTools;
+import org.eclipse.jpt.common.utility.predicate.Predicate;
import org.eclipse.jpt.common.utility.reference.ModifiableObjectReference;
/**
@@ -66,7 +68,7 @@
}
- // ********** accessors **********
+ // ********** ObjectReference **********
public V getValue() {
synchronized (this.mutex) {
@@ -75,11 +77,27 @@
}
public boolean valueEquals(Object object) {
- return ObjectTools.equals(this.getValue(), object);
+ synchronized (this.mutex) {
+ return ObjectTools.equals(this.value, object);
+ }
}
public boolean valueNotEqual(Object object) {
- return ObjectTools.notEquals(this.getValue(), object);
+ synchronized (this.mutex) {
+ return ObjectTools.notEquals(this.value, object);
+ }
+ }
+
+ public boolean is(Object object) {
+ synchronized (this.mutex) {
+ return this.value == object;
+ }
+ }
+
+ public boolean isNot(Object object) {
+ synchronized (this.mutex) {
+ return this.value != object;
+ }
}
public boolean isNull() {
@@ -94,6 +112,21 @@
}
}
+ public boolean isMemberOf(Predicate<? super V> predicate) {
+ synchronized (this.mutex) {
+ return predicate.evaluate(this.value);
+ }
+ }
+
+ public boolean isNotMemberOf(Predicate<? super V> predicate) {
+ synchronized (this.mutex) {
+ return ! predicate.evaluate(this.value);
+ }
+ }
+
+
+ // ********** ModifiableObjectReference **********
+
/**
* Set the value. If the value changes, all waiting
* threads are notified. Return the previous value.
@@ -105,6 +138,7 @@
}
/**
+ * Return the previous value.
* Pre-condition: synchronized
*/
private V setValue_(V v) {
@@ -113,6 +147,7 @@
}
/**
+ * Return the previous value.
* Pre-condition: synchronized and new value is different
*/
private V setChangedValue_(V v) {
@@ -120,6 +155,7 @@
}
/**
+ * Return the previous value.
* Pre-condition: synchronized and new value is different
*/
private V setValue_(V v, V old) {
@@ -137,20 +173,77 @@
}
/**
- * If the current value is the specified expected value, set it to the
+ * If the current value is {@link Object#equals(Object) equal} to
+ * the specified expected value, set it to the
* specified new value. Return the previous value.
*/
- public V compareAndSwap(V expectedValue, V newValue) {
+ public boolean commit(V newValue, V expectedValue) {
synchronized (this.mutex) {
- return this.compareAndSwap_(expectedValue, newValue);
+ return this.commit_(newValue, expectedValue);
}
}
/**
* Pre-condition: synchronized
*/
- private V compareAndSwap_(V expectedValue, V newValue) {
- return ObjectTools.equals(this.value, expectedValue) ? this.setValue_(newValue) : this.value;
+ private boolean commit_(V newValue, V expectedValue) {
+ if (ObjectTools.equals(this.value, expectedValue)) {
+ this.setValue_(newValue);
+ return true;
+ }
+ return false;
+ }
+
+ public V swap(ModifiableObjectReference<V> other) {
+ if (other == this) {
+ return this.getValue();
+ }
+ if (other instanceof SynchronizedObject) {
+ return this.swap_((SynchronizedObject<V>) other);
+ }
+
+ V thisValue = null;
+ V otherValue = other.getValue();
+ synchronized (this.mutex) {
+ thisValue = this.value;
+ if (ObjectTools.notEquals(thisValue, otherValue)) {
+ this.setChangedValue_(otherValue);
+ }
+ }
+ other.setValue(thisValue);
+ return otherValue;
+ }
+
+ /**
+ * Atomically swap the value of this synchronized object with the value of
+ * the specified synchronized object. Make assumptions about the value of
+ * <em>identity hash code</em> to avoid deadlock when two synchronized
+ * objects swap values with each other simultaneously.
+ * If either value changes, the corresponding waiting threads are notified.
+ * Return the new value.
+ */
+ public V swap(SynchronizedObject<V> other) {
+ return (other == this) ? this.getValue() : this.swap_(other);
+ }
+
+ /**
+ * Pre-condition: not same object
+ */
+ private V swap_(SynchronizedObject<V> other) {
+ boolean thisFirst = System.identityHashCode(this) < System.identityHashCode(other);
+ SynchronizedObject<V> first = thisFirst ? this : other;
+ SynchronizedObject<V> second = thisFirst ? other : this;
+ synchronized (first.mutex) {
+ synchronized (second.mutex) {
+ V thisValue = this.value;
+ V otherValue = other.value;
+ if (ObjectTools.equals(thisValue, otherValue)) {
+ return thisValue; // nothing changes
+ }
+ other.setChangedValue_(thisValue);
+ return this.setChangedValue_(otherValue);
+ }
+ }
}
/**
@@ -166,43 +259,67 @@
/**
* Suspend the current thread until the value changes
- * to the specified value. If the value is already the
- * specified value, return immediately.
+ * to belong to the set specified by the specified predicate.
+ * If the value already belongs to the set, return immediately.
*/
- public void waitUntilValueIs(V v) throws InterruptedException {
+ public void waitUntil(Predicate<? super V> predicate) throws InterruptedException {
synchronized (this.mutex) {
- this.waitUntilValueIs_(v);
+ this.waitUntil_(predicate);
}
}
/**
* Pre-condition: synchronized
*/
- private void waitUntilValueIs_(V v) throws InterruptedException {
- while (ObjectTools.notEquals(this.value, v)) {
+ private void waitUntil_(Predicate<? super V> predicate) throws InterruptedException {
+ while ( ! predicate.evaluate(this.value)) {
this.mutex.wait();
}
}
/**
* Suspend the current thread until the value changes
- * to something other than the specified value. If the
- * value is already <em>not</em> the specified value,
- * return immediately.
+ * to no longer belong to the set specified by the specified predicate.
+ * If the value is already outside the set, return immediately.
*/
- public void waitUntilValueIsNot(V v) throws InterruptedException {
- synchronized (this.mutex) {
- this.waitUntilValueIsNot_(v);
- }
+ public void waitUntilNot(Predicate<? super V> predicate) throws InterruptedException {
+ this.waitUntil(PredicateTools.not(predicate));
}
/**
- * Pre-condition: synchronized
+ * Suspend the current thread until the value changes
+ * to be {@link Object#equals(Object) equal} to the specified object.
+ * If the value is already equal to the specified object, return immediately.
*/
- private void waitUntilValueIsNot_(V v) throws InterruptedException {
- while (ObjectTools.equals(this.value, v)) {
- this.mutex.wait();
- }
+ public void waitUntilValueEquals(V object) throws InterruptedException {
+ this.waitUntil(PredicateTools.isEqual(object));
+ }
+
+ /**
+ * Suspend the current thread until the value changes
+ * to be <em>not</em> {@link Object#equals(Object) equal} to the specified object.
+ * If the value is already unequal to the specified object, return immediately.
+ */
+ public void waitUntilValueNotEqual(V object) throws InterruptedException {
+ this.waitUntil(PredicateTools.isNotEqual(object));
+ }
+
+ /**
+ * Suspend the current thread until the value changes
+ * to the specified object. If the value is already the
+ * specified object, return immediately.
+ */
+ public void waitUntilValueIs(V object) throws InterruptedException {
+ this.waitUntil(PredicateTools.isIdentical(object));
+ }
+
+ /**
+ * Suspend the current thread until the value changes
+ * to something other than the specified object. If the value is already
+ * something other than the specified object, return immediately.
+ */
+ public void waitUntilValueIsNot(V object) throws InterruptedException {
+ this.waitUntil(PredicateTools.isNotIdentical(object));
}
/**
@@ -225,15 +342,16 @@
/**
* Suspend the current thread until the value changes to
- * something other than the specified value, then change
+ * something not {@link Object#equals(Object) equal} to
+ * the specified value, then change
* it back to the specified value and continue executing.
- * If the value is already <em>not</em> the specified value, set
+ * If the value is already unequal to the specified value, set
* the value immediately.
* Return the previous value.
*/
public V waitToSetValue(V v) throws InterruptedException {
synchronized (this.mutex) {
- this.waitUntilValueIsNot_(v);
+ this.waitUntil_(PredicateTools.isNotEqual(v));
return this.setChangedValue_(v);
}
}
@@ -252,15 +370,16 @@
/**
* Suspend the current thread until the value changes to
- * the specified expected value, then change it
+ * be {@link Object#equals(Object) equal} to the specified
+ * expected value, then change it
* to the specified new value and continue executing.
- * If the value is already the specified expected value,
+ * If the value is already equal to the specified expected value,
* set the value to the specified new value immediately.
* Return the previous value.
*/
- public V waitToSwap(V expectedValue, V newValue) throws InterruptedException {
+ public V waitToCommit(V newValue, V expectedValue) throws InterruptedException {
synchronized (this.mutex) {
- this.waitUntilValueIs_(expectedValue);
+ this.waitUntil_(PredicateTools.isEqual(expectedValue));
return this.setValue_(newValue);
}
}
@@ -270,75 +389,112 @@
/**
* Suspend the current thread until the value changes
- * to the specified value or the specified time-out occurs.
+ * to belong to the set specified by the specified predicate
+ * or the specified time-out occurs.
* The time-out is specified in milliseconds. Return <code>true</code>
- * if the specified value was achieved; return <code>false</code>
+ * if the value became a member of the set; return <code>false</code>
* if a time-out occurred.
- * If the value is already the specified value, return true immediately.
+ * If the value already belongs to the set, return <code>true</code> immediately.
* If the time-out is zero, wait indefinitely.
*/
- public boolean waitUntilValueIs(V v, long timeout) throws InterruptedException {
+ public boolean waitUntil(Predicate<? super V> predicate, long timeout) throws InterruptedException {
synchronized (this.mutex) {
- return this.waitUntilValueIs_(v, timeout);
+ return this.waitUntil_(predicate, timeout);
}
}
/**
* Pre-condition: synchronized
*/
- private boolean waitUntilValueIs_(V v, long timeout) throws InterruptedException {
+ private boolean waitUntil_(Predicate<? super V> predicate, long timeout) throws InterruptedException {
if (timeout == 0L) {
- this.waitUntilValueIs_(v); // wait indefinitely until notified
+ this.waitUntil_(predicate); // wait indefinitely until notified
return true; // if it ever comes back, the condition was met
}
long stop = System.currentTimeMillis() + timeout;
long remaining = timeout;
- while (ObjectTools.notEquals(this.value, v) && (remaining > 0L)) {
+ while (( ! predicate.evaluate(this.value)) && (remaining > 0L)) {
this.mutex.wait(remaining);
remaining = stop - System.currentTimeMillis();
}
- return ObjectTools.equals(this.value, v);
+ return predicate.evaluate(this.value);
}
/**
- * Suspend the current thread until the value changes to something
- * other than the specified value or the specified time-out occurs.
+ * Suspend the current thread until the value changes
+ * to no longer belong to the set specified by the specified predicate
+ * or the specified time-out occurs.
* The time-out is specified in milliseconds. Return <code>true</code>
- * if the specified value was removed; return <code>false</code> if a
- * time-out occurred. If the value is already <em>not</em> the specified
+ * if the value moved outside of the set; return <code>false</code>
+ * if a time-out occurred.
+ * If the value is already outside the set, return <code>true</code> immediately.
+ * If the time-out is zero, wait indefinitely.
+ */
+ public boolean waitUntilNot(Predicate<? super V> predicate, long timeout) throws InterruptedException {
+ return this.waitUntil(PredicateTools.not(predicate), timeout);
+ }
+
+ /**
+ * Suspend the current thread until the value changes
+ * to be {@link Object#equals(Object) equal} to the specified object
+ * or the specified time-out occurs.
+ * The time-out is specified in milliseconds. Return <code>true</code>
+ * if the specified value was achieved; return <code>false</code> if a
+ * time-out occurred. If the value is already equal to the specified
+ * object, return <code>true</code> immediately.
+ * If the time-out is zero, wait indefinitely.
+ */
+ public boolean waitUntilValueEquals(V object, long timeout) throws InterruptedException {
+ return this.waitUntil(PredicateTools.isEqual(object), timeout);
+ }
+
+ /**
+ * Suspend the current thread until the value changes
+ * to be <em>not</em> {@link Object#equals(Object) equal} to the specified object
+ * or the specified time-out occurs.
+ * The time-out is specified in milliseconds. Return <code>true</code>
+ * if the value changed to be unequal; return <code>false</code> if a
+ * time-out occurred. If the value is already unequal to the specified
+ * object, return <code>true</code> immediately.
+ * If the time-out is zero, wait indefinitely.
+ */
+ public boolean waitUntilValueNotEqual(V object, long timeout) throws InterruptedException {
+ return this.waitUntil(PredicateTools.isNotEqual(object), timeout);
+ }
+
+ /**
+ * Suspend the current thread until the value changes
+ * to be the specified object or the specified time-out occurs.
+ * The time-out is specified in milliseconds. Return <code>true</code>
+ * if the specified value was achieved; return <code>false</code> if a
+ * time-out occurred. If the value is already the specified
+ * object, return <code>true</code> immediately.
+ * If the time-out is zero, wait indefinitely.
+ */
+ public boolean waitUntilValueIs(V object, long timeout) throws InterruptedException {
+ return this.waitUntil(PredicateTools.isIdentical(object), timeout);
+ }
+
+ /**
+ * Suspend the current thread until the value changes
+ * to be <em>not</em> {@link Object#equals(Object) equal} to the specified object
+ * or the specified time-out occurs.
+ * The time-out is specified in milliseconds. Return <code>true</code>
+ * if the value changed to be unequal; return <code>false</code> if a
+ * time-out occurred. If the value is already unequal to the specified
* value, return <code>true</code> immediately.
* If the time-out is zero, wait indefinitely.
*/
- public boolean waitUntilValueIsNot(V v, long timeout) throws InterruptedException {
- synchronized (this.mutex) {
- return this.waitUntilValueIsNot_(v, timeout);
- }
- }
-
- /**
- * Pre-condition: synchronized
- */
- private boolean waitUntilValueIsNot_(V v, long timeout) throws InterruptedException {
- if (timeout == 0L) {
- this.waitUntilValueIsNot_(v); // wait indefinitely until notified
- return true; // if it ever comes back, the condition was met
- }
-
- long stop = System.currentTimeMillis() + timeout;
- long remaining = timeout;
- while (ObjectTools.equals(this.value, v) && (remaining > 0L)) {
- this.mutex.wait(remaining);
- remaining = stop - System.currentTimeMillis();
- }
- return ObjectTools.notEquals(this.value, v);
+ public boolean waitUntilValueIsNot(V object, long timeout) throws InterruptedException {
+ return this.waitUntil(PredicateTools.isNotIdentical(object), timeout);
}
/**
* Suspend the current thread until the value changes
* to <code>null</code> or the specified time-out occurs.
* The time-out is specified in milliseconds. Return <code>true</code>
- * if the specified value was achieved; return <code>false</code>
+ * if the value changes to <code>null</code>; return <code>false</code>
* if a time-out occurred. If the value is already <code>null</code>,
* return <code>true</code> immediately.
* If the time-out is zero, wait indefinitely.
@@ -351,7 +507,7 @@
* Suspend the current thread until the value changes
* to something other than <code>null</code> or the specified time-out occurs.
* The time-out is specified in milliseconds. Return <code>true</code>
- * if the specified value was achieved; return <code>false</code>
+ * if the value changes to something other than <code>null</code>; return <code>false</code>
* if a time-out occurred. If the value is already <em>not</em>
* <code>null</code>, return <code>true</code> immediately.
* If the time-out is zero, wait indefinitely.
@@ -362,21 +518,21 @@
/**
* Suspend the current thread until the value changes to
- * something other than the specified value, then change
+ * something unequal to the specified value, then change
* it back to the specified value and continue executing.
- * If the value does not change to something other than the
+ * If the value does not change to something unequal to the
* specified value before the time-out, simply continue executing
* without changing the value.
* The time-out is specified in milliseconds. Return <code>true</code>
* if the value was set to the specified value; return <code>false</code>
* if a time-out occurred.
- * If the value is already something other than the specified value, set
+ * If the value is already something unequal to the specified value, set
* the value immediately and return <code>true</code>.
* If the time-out is zero, wait indefinitely.
*/
public boolean waitToSetValue(V v, long timeout) throws InterruptedException {
synchronized (this.mutex) {
- boolean success = this.waitUntilValueIsNot_(v, timeout);
+ boolean success = this.waitUntil_(PredicateTools.isNotEqual(v), timeout);
if (success) {
this.setChangedValue_(v);
}
@@ -403,7 +559,8 @@
/**
* Suspend the current thread until the value changes to
- * the specified expected value, then change it
+ * be {@link Object#equals(Object) equal} to the specified
+ * expected value, then change it
* to the specified new value and continue executing.
* If the value does not change to the specified expected value
* before the time-out, simply continue executing without changing
@@ -416,9 +573,9 @@
* Return the previous value.
* If the time-out is zero, wait indefinitely.
*/
- public boolean waitToSwap(V expectedValue, V newValue, long timeout) throws InterruptedException {
+ public boolean waitToSwap(V newValue, V expectedValue, long timeout) throws InterruptedException {
synchronized (this.mutex) {
- boolean success = this.waitUntilValueIs_(expectedValue, timeout);
+ boolean success = this.waitUntil_(PredicateTools.isEqual(expectedValue), timeout);
if (success) {
this.setValue_(newValue);
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/reference/ModifiableObjectReference.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/reference/ModifiableObjectReference.java
index c0fcb5a..5238c6e 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/reference/ModifiableObjectReference.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/reference/ModifiableObjectReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle. All rights reserved.
+ * Copyright (c) 2010, 2015 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.
@@ -9,7 +9,6 @@
******************************************************************************/
package org.eclipse.jpt.common.utility.reference;
-
/**
* Provide a container for passing an object that can be changed by the recipient.
* <p>
@@ -33,4 +32,19 @@
* Return the previous value.
*/
V setNull();
+
+ /**
+ * Set the value to the specified new value if it is
+ * currently {@link Object#equals(Object) equal} to
+ * the specified expected value.
+ * Return whether the set was successful.
+ */
+ boolean commit(V newValue, V expectedValue);
+
+ /**
+ * Swap the value of the object reference with
+ * the value of the specified object reference.
+ * Return the new value.
+ */
+ V swap(ModifiableObjectReference<V> other);
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/reference/ObjectReference.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/reference/ObjectReference.java
index 84256d2..8808e28 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/reference/ObjectReference.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/reference/ObjectReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2013 Oracle. All rights reserved.
+ * Copyright (c) 2010, 2015 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.
@@ -10,6 +10,7 @@
package org.eclipse.jpt.common.utility.reference;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.predicate.Predicate;
import org.eclipse.jpt.common.utility.transformer.Transformer;
@@ -45,16 +46,30 @@
}
/**
- * Return whether the current value is equal to the specified value.
+ * Return whether the current value is
+ * {@link Object#equals(Object) equal} to the specified object.
*/
boolean valueEquals(Object object);
/**
- * Return whether the current value is not equal to the specified value.
+ * Return whether the current value is <em>not</em>
+ * {@link Object#equals(Object) equal} to the specified object.
*/
boolean valueNotEqual(Object object);
/**
+ * Return whether the current value is
+ * identical (<code>==</code>) to the specified object.
+ */
+ boolean is(Object object);
+
+ /**
+ * Return whether the current value is <em>not</em>
+ * identical (<code>==</code>) to the specified object.
+ */
+ boolean isNot(Object object);
+
+ /**
* Return whether the current value is <code>null</code>.
*/
boolean isNull();
@@ -63,4 +78,16 @@
* Return whether the current value is not <code>null</code>.
*/
boolean isNotNull();
+
+ /**
+ * Return whether the current value is a
+ * member of the set specified by the specified predicate.
+ */
+ boolean isMemberOf(Predicate<? super V> predicate);
+
+ /**
+ * Return whether the current value is <em>not</em> a
+ * member of the set specified by the specified predicate.
+ */
+ boolean isNotMemberOf(Predicate<? super V> predicate);
}