From c2516c02cc1bd79ce11638488acc088d25cf6748 Mon Sep 17 00:00:00 2001 From: Brian Vosburgh Date: Wed, 21 Oct 2015 11:42:00 -0400 Subject: rework ObjectReferences --- .../AbstractModifiableObjectReference.java | 57 ++++ .../reference/AbstractObjectReference.java | 42 ++- .../internal/reference/SimpleObjectReference.java | 65 ++++- .../internal/reference/SynchronizedObject.java | 305 ++++++++++++++++----- .../reference/ModifiableObjectReference.java | 18 +- .../common/utility/reference/ObjectReference.java | 33 ++- 6 files changed, 438 insertions(+), 82 deletions(-) create mode 100644 common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/reference/AbstractModifiableObjectReference.java 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 0000000000..22af0639b6 --- /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 + * + * @param the type of the reference's value + */ +public abstract class AbstractModifiableObjectReference + extends AbstractObjectReference + implements ModifiableObjectReference +{ + 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 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 5957155841..b795f2cebd 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 @@ public abstract class AbstractObjectReference 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 @@ public abstract class AbstractObjectReference return this.getValue() != null; } + public boolean isMemberOf(Predicate predicate) { + return predicate.evaluate(this.getValue()); + } + + public boolean isNotMemberOf(Predicate 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 + * equal. + * + * @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 d518978819..01d346330c 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 @@ package org.eclipse.jpt.common.utility.internal.reference; 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 @@ public class SimpleObjectReference } - // ********** value ********** + // ********** ObjectReference ********** public V getValue() { return this.value; @@ -61,6 +62,14 @@ public class SimpleObjectReference 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 @@ public class SimpleObjectReference return this.value != null; } + public boolean isMemberOf(Predicate predicate) { + return predicate.evaluate(this.value); + } + + public boolean isNotMemberOf(Predicate predicate) { + return ! predicate.evaluate(this.value); + } + + + // ********** ModifiableObjectReference ********** + public V setValue(V value) { V old = this.value; this.value = value; @@ -79,6 +99,27 @@ public class SimpleObjectReference 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 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 @@ public class SimpleObjectReference } } + /** + * Object identity is critical to object references. + * There is no reason for two different object references to be + * equal. + * + * @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 0db9dff232..037cb64482 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 @@ package org.eclipse.jpt.common.utility.internal.reference; 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 @@ public class SynchronizedObject } - // ********** accessors ********** + // ********** ObjectReference ********** public V getValue() { synchronized (this.mutex) { @@ -75,11 +77,27 @@ public class SynchronizedObject } 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 class SynchronizedObject } } + public boolean isMemberOf(Predicate predicate) { + synchronized (this.mutex) { + return predicate.evaluate(this.value); + } + } + + public boolean isNotMemberOf(Predicate 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 @@ public class SynchronizedObject } /** + * Return the previous value. * Pre-condition: synchronized */ private V setValue_(V v) { @@ -113,6 +147,7 @@ public class SynchronizedObject } /** + * Return the previous value. * Pre-condition: synchronized and new value is different */ private V setChangedValue_(V v) { @@ -120,6 +155,7 @@ public class SynchronizedObject } /** + * Return the previous value. * Pre-condition: synchronized and new value is different */ private V setValue_(V v, V old) { @@ -137,20 +173,77 @@ public class SynchronizedObject } /** - * 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 other) { + if (other == this) { + return this.getValue(); + } + if (other instanceof SynchronizedObject) { + return this.swap_((SynchronizedObject) 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 + * identity hash code 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 other) { + return (other == this) ? this.getValue() : this.swap_(other); + } + + /** + * Pre-condition: not same object + */ + private V swap_(SynchronizedObject other) { + boolean thisFirst = System.identityHashCode(this) < System.identityHashCode(other); + SynchronizedObject first = thisFirst ? this : other; + SynchronizedObject 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 @@ public class SynchronizedObject /** * 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 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 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 not 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 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 not {@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 @@ public class SynchronizedObject /** * 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 not 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 @@ public class SynchronizedObject /** * 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 @@ public class SynchronizedObject /** * 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 true - * if the specified value was achieved; return false + * if the value became a member of the set; return false * 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 true immediately. * If the time-out is zero, wait indefinitely. */ - public boolean waitUntilValueIs(V v, long timeout) throws InterruptedException { + public boolean waitUntil(Predicate 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 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 true - * if the specified value was removed; return false if a - * time-out occurred. If the value is already not the specified - * value, return true immediately. + * if the value moved outside of the set; return false + * if a time-out occurred. + * If the value is already outside the set, return true 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); - } + public boolean waitUntilNot(Predicate predicate, long timeout) throws InterruptedException { + return this.waitUntil(PredicateTools.not(predicate), timeout); } /** - * Pre-condition: synchronized + * 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 true + * if the specified value was achieved; return false if a + * time-out occurred. If the value is already equal to the specified + * object, return true immediately. + * If the time-out is zero, wait indefinitely. */ - 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 - } + public boolean waitUntilValueEquals(V object, long timeout) throws InterruptedException { + return this.waitUntil(PredicateTools.isEqual(object), timeout); + } - 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); + /** + * Suspend the current thread until the value changes + * to be not {@link Object#equals(Object) equal} to the specified object + * or the specified time-out occurs. + * The time-out is specified in milliseconds. Return true + * if the value changed to be unequal; return false if a + * time-out occurred. If the value is already unequal to the specified + * object, return true 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 true + * if the specified value was achieved; return false if a + * time-out occurred. If the value is already the specified + * object, return true 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 not {@link Object#equals(Object) equal} to the specified object + * or the specified time-out occurs. + * The time-out is specified in milliseconds. Return true + * if the value changed to be unequal; return false if a + * time-out occurred. If the value is already unequal to the specified + * value, return true immediately. + * If the time-out is zero, wait indefinitely. + */ + 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 null or the specified time-out occurs. * The time-out is specified in milliseconds. Return true - * if the specified value was achieved; return false + * if the value changes to null; return false * if a time-out occurred. If the value is already null, * return true immediately. * If the time-out is zero, wait indefinitely. @@ -351,7 +507,7 @@ public class SynchronizedObject * Suspend the current thread until the value changes * to something other than null or the specified time-out occurs. * The time-out is specified in milliseconds. Return true - * if the specified value was achieved; return false + * if the value changes to something other than null; return false * if a time-out occurred. If the value is already not * null, return true immediately. * If the time-out is zero, wait indefinitely. @@ -362,21 +518,21 @@ public class SynchronizedObject /** * 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 true * if the value was set to the specified value; return false * 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 true. * 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 @@ public class SynchronizedObject /** * 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 @@ public class SynchronizedObject * 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 c0fcb5a084..5238c6e156 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. *

@@ -33,4 +32,19 @@ public interface ModifiableObjectReference * 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 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 84256d2cfe..8808e28810 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,15 +46,29 @@ public interface ObjectReference { } /** - * 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 not + * {@link Object#equals(Object) equal} to the specified object. */ boolean valueNotEqual(Object object); + /** + * Return whether the current value is + * identical (==) to the specified object. + */ + boolean is(Object object); + + /** + * Return whether the current value is not + * identical (==) to the specified object. + */ + boolean isNot(Object object); + /** * Return whether the current value is null. */ @@ -63,4 +78,16 @@ public interface ObjectReference { * Return whether the current value is not null. */ boolean isNotNull(); + + /** + * Return whether the current value is a + * member of the set specified by the specified predicate. + */ + boolean isMemberOf(Predicate predicate); + + /** + * Return whether the current value is not a + * member of the set specified by the specified predicate. + */ + boolean isNotMemberOf(Predicate predicate); } -- cgit v1.2.3