diff options
author | bvosburgh | 2011-07-08 15:54:29 +0000 |
---|---|---|
committer | bvosburgh | 2011-07-08 15:54:29 +0000 |
commit | c6d10fa4fb5972c7f1ef033725794df95577324a (patch) | |
tree | 87b42cb76ce0bc99f1a861881adf4aa1307a7401 /common | |
parent | a2c57da22b9d0c9a16843981e2ebc4ff7dcab26d (diff) | |
download | webtools.dali-c6d10fa4fb5972c7f1ef033725794df95577324a.tar.gz webtools.dali-c6d10fa4fb5972c7f1ef033725794df95577324a.tar.xz webtools.dali-c6d10fa4fb5972c7f1ef033725794df95577324a.zip |
add InterruptibleCommand/Executor
Diffstat (limited to 'common')
5 files changed, 303 insertions, 31 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/Command.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/Command.java index f152ba5fa6..59d35fbc1a 100644 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/Command.java +++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/Command.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. + * Copyright (c) 2007, 2011 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; import java.io.Serializable; +import org.eclipse.jpt.common.utility.internal.StringTools; /** * Simple interface for implementing the GOF Command design pattern, @@ -21,19 +22,23 @@ import java.io.Serializable; * pioneering adopters on the understanding that any code that uses this API * will almost certainly be broken (repeatedly) as the API evolves. */ -public interface Command { - +public interface Command + extends InterruptibleCommand +{ /** * Execute the command. The semantics of the command * is determined by the contract between the client and server. */ void execute(); + /** * Singleton implementation of the command interface that will do nothing * when executed. */ - final class Null implements Command, Serializable { + final class Null + implements Command, Serializable + { public static final Command INSTANCE = new Null(); public static Command instance() { return INSTANCE; @@ -47,7 +52,7 @@ public interface Command { } @Override public String toString() { - return "Command.Null"; //$NON-NLS-1$ + return StringTools.buildSingletonToString(this); } private static final long serialVersionUID = 1L; private Object readResolve() { @@ -60,7 +65,9 @@ public interface Command { * Singleton implementation of the command interface that will throw an * exception when executed. */ - final class Disabled implements Command, Serializable { + final class Disabled + implements Command, Serializable + { public static final Command INSTANCE = new Disabled(); public static Command instance() { return INSTANCE; @@ -75,7 +82,7 @@ public interface Command { } @Override public String toString() { - return "Command.Disabled"; //$NON-NLS-1$ + return StringTools.buildSingletonToString(this); } private static final long serialVersionUID = 1L; private Object readResolve() { @@ -83,5 +90,4 @@ public interface Command { return INSTANCE; } } - } diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/CommandExecutor.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/CommandExecutor.java index 461ab8615d..07a8ea41a4 100644 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/CommandExecutor.java +++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/CommandExecutor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Oracle. All rights reserved. + * Copyright (c) 2007, 2011 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; import java.io.Serializable; +import org.eclipse.jpt.common.utility.internal.StringTools; /** * This interface allows clients to control how a command is executed. @@ -35,7 +36,9 @@ public interface CommandExecutor { * Singleton implementation of the command executor interface * that simply executes the command without any sort of enhancement. */ - final class Default implements CommandExecutor, Serializable { + final class Default + implements CommandExecutor, Serializable + { public static final CommandExecutor INSTANCE = new Default(); public static CommandExecutor instance() { return INSTANCE; @@ -49,7 +52,7 @@ public interface CommandExecutor { } @Override public String toString() { - return "CommandExecutor.Default"; //$NON-NLS-1$ + return StringTools.buildSingletonToString(this); } private static final long serialVersionUID = 1L; private Object readResolve() { @@ -57,5 +60,4 @@ public interface CommandExecutor { return INSTANCE; } } - } diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/InterruptibleCommand.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/InterruptibleCommand.java new file mode 100644 index 0000000000..685350045b --- /dev/null +++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/InterruptibleCommand.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2011 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; + +import java.io.Serializable; +import org.eclipse.jpt.common.utility.internal.StringTools; + +/** + * Simple interface for implementing the GOF Command design pattern + * and allows for the command to throw an {@link InterruptedException}. + * <p> + * Provisional API: This interface is part of an interim API that is still + * under development and expected to change significantly before reaching + * stability. It is available at this early stage to solicit feedback from + * pioneering adopters on the understanding that any code that uses this API + * will almost certainly be broken (repeatedly) as the API evolves. + * + * @see org.eclipse.jpt.common.utility.Command + */ +public interface InterruptibleCommand { + + /** + * Execute the command. The semantics of the command + * is determined by the contract between the client and server. + */ + void execute() throws InterruptedException; + + + /** + * Singleton implementation of the interruptible command interface that + * will throw an interrupted exception when executed. + */ + final class Interrupted + implements InterruptibleCommand, Serializable + { + public static final InterruptibleCommand INSTANCE = new Interrupted(); + public static InterruptibleCommand instance() { + return INSTANCE; + } + // ensure single instance + private Interrupted() { + super(); + } + // throw an exception + public void execute() throws InterruptedException { + throw new InterruptedException(); + } + @Override + public String toString() { + return StringTools.buildSingletonToString(this); + } + private static final long serialVersionUID = 1L; + private Object readResolve() { + // replace this object with the singleton + return INSTANCE; + } + } +} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/InterruptibleCommandExecutor.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/InterruptibleCommandExecutor.java new file mode 100644 index 0000000000..651164bc23 --- /dev/null +++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/InterruptibleCommandExecutor.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2011 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; + +import java.io.Serializable; +import org.eclipse.jpt.common.utility.internal.StringTools; + +/** + * This interface allows clients to control how an interruptible command is executed. + * This is useful when the server provides the command but the client provides + * the context (e.g. the client would like to dispatch the command to the UI + * thread). + * <p> + * Provisional API: This interface is part of an interim API that is still + * under development and expected to change significantly before reaching + * stability. It is available at this early stage to solicit feedback from + * pioneering adopters on the understanding that any code that uses this API + * will almost certainly be broken (repeatedly) as the API evolves. + * + * @see org.eclipse.jpt.common.utility.CommandExecutor + */ +public interface InterruptibleCommandExecutor { + + /** + * Execute the specified command. + */ + void execute(InterruptibleCommand command) throws InterruptedException; + + + /** + * Singleton implementation of the interruptible command executor interface + * that simply executes the command without any sort of enhancement. + */ + final class Default + implements InterruptibleCommandExecutor, Serializable + { + public static final InterruptibleCommandExecutor INSTANCE = new Default(); + public static InterruptibleCommandExecutor instance() { + return INSTANCE; + } + // ensure single instance + private Default() { + super(); + } + public void execute(InterruptibleCommand command) throws InterruptedException { + command.execute(); + } + @Override + public String toString() { + return StringTools.buildSingletonToString(this); + } + private static final long serialVersionUID = 1L; + private Object readResolve() { + // replace this object with the singleton + return INSTANCE; + } + } +} diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/SynchronizedBoolean.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/SynchronizedBoolean.java index 90e594419b..79c368b364 100644 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/SynchronizedBoolean.java +++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/SynchronizedBoolean.java @@ -10,7 +10,8 @@ package org.eclipse.jpt.common.utility.internal; import java.io.Serializable; -import org.eclipse.jpt.common.utility.Command; +import org.eclipse.jpt.common.utility.InterruptibleCommand; +import org.eclipse.jpt.common.utility.InterruptibleCommandExecutor; /** * This class provides synchronized access to a <code>boolean</code> value. @@ -21,7 +22,7 @@ import org.eclipse.jpt.common.utility.Command; * @see SimpleBooleanReference */ public class SynchronizedBoolean - implements BooleanReference, Cloneable, Serializable + implements InterruptibleCommandExecutor, BooleanReference, Cloneable, Serializable { /** Backing <code>boolean</code>. */ private boolean value; @@ -303,9 +304,9 @@ public class SynchronizedBoolean /** * Suspend the current thread until the <code>boolean</code> value changes to - * <em>not</em> the specified value, then change it back to the specified + * the NOT of the specified value, then change it back to the specified * value and continue executing. If the <code>boolean</code> value is already - * <em>not</em> the specified value, set the value to the specified value + * the NOT of the specified value, set the value to the specified value * immediately. */ public void waitToSetValue(boolean b) throws InterruptedException { @@ -337,6 +338,53 @@ public class SynchronizedBoolean this.waitToSetValue(false); } + /** + * Suspend the current thread until the <code>boolean</code> value + * changes to the specified value, + * then execute the specified command. + * If the <code>boolean</code> value is already equal to the specified + * value, execute the specified command immediately. + */ + public void whenEqual(boolean b, InterruptibleCommand command) throws InterruptedException { + synchronized (this.mutex) { + this.waitUntilValueIs_(b); + command.execute(); + } + } + + /** + * Suspend the current thread until the <code>boolean</code> value + * changes to the NOT of the specified value, + * then execute the specified command. + * If the <code>boolean</code> value is already the NOT of the specified + * value, execute the specified command immediately. + */ + public void whenNotEqual(boolean b, InterruptibleCommand command) throws InterruptedException { + this.whenEqual( ! b, command); + } + + /** + * Suspend the current thread until the <code>boolean</code> value + * changes to <code>true</code>, + * then execute the specified command. + * If the <code>boolean</code> value is already <code>true</code>, + * execute the specified command immediately. + */ + public void whenTrue(InterruptibleCommand command) throws InterruptedException { + this.whenEqual(true, command); + } + + /** + * Suspend the current thread until the <code>boolean</code> value + * changes to <code>false</code>, + * then execute the specified command. + * If the <code>boolean</code> value is already <code>false</code>, + * execute the specified command immediately. + */ + public void whenFalse(InterruptibleCommand command) throws InterruptedException { + this.whenEqual(false, command); + } + // ********** timed waits ********** @@ -381,11 +429,11 @@ public class SynchronizedBoolean * the NOT of the specified value was achieved; * return <code>false</code> if a time-out occurred. * If the <code>boolean</code> value is already the NOT of the specified - * value, return immediately. + * value, return <code>true</code> immediately. * If the time-out is zero, wait indefinitely. */ - public void waitUntilValueIsNot(boolean b, long timeout) throws InterruptedException { - this.waitUntilValueIs( ! b, timeout); + public boolean waitUntilValueIsNot(boolean b, long timeout) throws InterruptedException { + return this.waitUntilValueIs( ! b, timeout); } /** @@ -408,7 +456,7 @@ public class SynchronizedBoolean * The time-out is specified in milliseconds. Return <code>true</code> if * <code>false</code> was achieved; * return <code>false</code> if a time-out occurred. - * If the <code>boolean</code> value is already <code>true</code>, + * If the <code>boolean</code> value is already <code>false</code>, * return <code>true</code> immediately. * If the time-out is zero, wait indefinitely. */ @@ -418,14 +466,15 @@ public class SynchronizedBoolean /** * Suspend the current thread until the <code>boolean</code> value changes - * to <em>not</em> the specified value, then change it back to the specified + * to the NOT of the specified value, then change it back to the specified * value and continue executing. If the <code>boolean</code> value does not * change to <code>false</code> 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 <code>boolean</code> value is already - * <em>not</em> the specified value, set the value to the specified value + * if a time-out occurred. + * If the <code>boolean</code> value is already + * the NOT of the specified value, set the value to the specified value * immediately and return <code>true</code>. * If the time-out is zero, wait indefinitely. */ @@ -444,10 +493,11 @@ public class SynchronizedBoolean * to <code>false</code>, then change it back to <code>true</code> and * continue executing. If the <code>boolean</code> value does not change to * <code>false</code> before the time-out, simply continue executing without - * changing the value. The time-out is specified in milliseconds. Return + * changing the value. + * The time-out is specified in milliseconds. Return * <code>true</code> if the value was set to <code>true</code>; - * return <code>false</code> if a time-out occurred. If the - * <code>boolean</code> value is already <code>false</code>, set the + * return <code>false</code> if a time-out occurred. + * If the <code>boolean</code> value is already <code>false</code>, set the * value to <code>true</code> immediately and return <code>true</code>. * If the time-out is zero, wait indefinitely. */ @@ -460,10 +510,11 @@ public class SynchronizedBoolean * to <code>true</code>, then change it back to <code>false</code> and * continue executing. If the <code>boolean</code> value does not change to * <code>true</code> before the time-out, simply continue executing without - * changing the value. The time-out is specified in milliseconds. Return + * changing the value. + * The time-out is specified in milliseconds. Return * <code>true</code> if the value was set to <code>false</code>; - * return <code>false</code> if a time-out occurred. If the - * <code>boolean</code> value is already <code>true</code>, set the + * return <code>false</code> if a time-out occurred. + * If the <code>boolean</code> value is already <code>true</code>, set the * value to <code>false</code> immediately and return <code>true</code>. * If the time-out is zero, wait indefinitely. */ @@ -471,6 +522,72 @@ public class SynchronizedBoolean return this.waitToSetValue(false, timeout); } + /** + * Suspend the current thread until the <code>boolean</code> value changes + * to the specified value or the specified time-out occurs; + * then, if a time-out did not occur, execute the specified command. + * The time-out is specified in milliseconds. Return <code>true</code> if + * the command was executed; + * return <code>false</code> if a time-out occurred. + * If the <code>boolean</code> value is already the specified value, + * execute the specified command immediately and return <code>true</code>. + * If the time-out is zero, wait indefinitely. + */ + public boolean whenEqual(boolean b, InterruptibleCommand command, long timeout) throws InterruptedException { + synchronized (this.mutex) { + boolean success = this.waitUntilValueIs_(b, timeout); + if (success) { + command.execute(); + } + return success; + } + } + + /** + * Suspend the current thread until the <code>boolean</code> value changes + * to the NOT of the specified value or the specified time-out occurs; + * then, if a time-out did not occur, execute the specified command. + * The time-out is specified in milliseconds. Return <code>true</code> if + * the command was executed; + * return <code>false</code> if a time-out occurred. + * If the <code>boolean</code> value is already the NOT of the specified value, + * execute the specified command immediately and return <code>true</code>. + * If the time-out is zero, wait indefinitely. + */ + public boolean whenNotEqual(boolean b, InterruptibleCommand command, long timeout) throws InterruptedException { + return this.whenEqual( ! b, command, timeout); + } + + /** + * Suspend the current thread until the <code>boolean</code> value changes + * to <code>true</code> or the specified time-out occurs; + * then, if a time-out did not occur, execute the specified command. + * The time-out is specified in milliseconds. Return <code>true</code> if + * the command was executed; + * return <code>false</code> if a time-out occurred. + * If the <code>boolean</code> value is already <code>true</code>, + * execute the specified command immediately and return <code>true</code>. + * If the time-out is zero, wait indefinitely. + */ + public boolean whenTrue(InterruptibleCommand command, long timeout) throws InterruptedException { + return this.whenEqual(true, command, timeout); + } + + /** + * Suspend the current thread until the <code>boolean</code> value changes + * to <code>false</code> or the specified time-out occurs; + * then, if a time-out did not occur, execute the specified command. + * The time-out is specified in milliseconds. Return <code>true</code> if + * the command was executed; + * return <code>false</code> if a time-out occurred. + * If the <code>boolean</code> value is already <code>false</code>, + * execute the specified command immediately and return <code>true</code>. + * If the time-out is zero, wait indefinitely. + */ + public boolean whenFalse(InterruptibleCommand command, long timeout) throws InterruptedException { + return this.whenEqual(false, command, timeout); + } + // ********** synchronized behavior ********** @@ -479,7 +596,7 @@ public class SynchronizedBoolean * with the mutex locked. This is useful for initializing the value from another * thread. */ - public void execute(Command command) throws InterruptedException { + public void execute(InterruptibleCommand command) throws InterruptedException { if (Thread.interrupted()) { throw new InterruptedException(); } @@ -502,6 +619,24 @@ public class SynchronizedBoolean } } + /** + * Object identity is critical to synchronized booleans. + * There is no reason for two different synchronized booleans to be + * <em>equal</em>. + */ + @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()) + ']'; @@ -512,5 +647,4 @@ public class SynchronizedBoolean s.defaultWriteObject(); } } - } |