diff options
Diffstat (limited to 'common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandState.java')
-rw-r--r-- | common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandState.java | 220 |
1 files changed, 0 insertions, 220 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandState.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandState.java deleted file mode 100644 index 20a7463b0b..0000000000 --- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/command/RepeatingCommandState.java +++ /dev/null @@ -1,220 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 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.command; - -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.SynchronizedObject; - -/** - * Provide the state machine to support minimal repeat command executions. - */ -public class RepeatingCommandState { - /** - * The current state. - */ - private final SynchronizedObject<State> state; - - /** - * The initial {@link #state} is {@link #STOPPED}. - * Clients must call {@link #start()} before the command can be - * executed. - */ - private enum State { - STOPPED, - READY, - PRE_EXECUTION, - EXECUTING, - REPEAT, - STOPPING - } - - - // ********** construction ********** - - /** - * Construct a repeating command state. - */ - public RepeatingCommandState() { - super(); - // use the command wrapper as the mutex so it is freed up by the wait in #stop() - this.state = new SynchronizedObject<State>(State.STOPPED, this); - } - - - /** - * Set the {@link #state} to {@link State#READY READY}. - * @exception IllegalStateException if the command wrapper is not - * {@link State#STOPPED STOPPED}. - */ - public synchronized void start() { - switch (this.state.getValue()) { - case STOPPED: - this.state.setValue(State.READY); - break; - case READY: - case PRE_EXECUTION: - case EXECUTING: - case REPEAT: - case STOPPING: - throw this.buildISE(); - } - } - - /** - * A client has requested an execution. - * Return whether we are ready to begin a new execution "cycle". - * If an execution is already under way, return <code>false</code>; - * but set the {@link #state} to {@link State#REPEAT REPEAT} - * so another execution will occur once the current - * execution is complete. - * <p> - * <strong>NB:</strong> This method has possible side-effects: - * The value of {@link #state} may be changed. - */ - public synchronized boolean isReadyToStartExecutionCycle() { - switch (this.state.getValue()) { - case STOPPED: - // execution is not allowed - return false; - case READY: - // start a new execution, possibly asynchronously - this.state.setValue(State.PRE_EXECUTION); - return true; - case PRE_EXECUTION: - // no need to set 'state' to PRE_EXECUTION again, - // the command has not yet begun executing - return false; - case EXECUTING: - // set 'state' to REPEAT so a new execution will occur once the current one is finished - this.state.setValue(State.REPEAT); - return false; - case REPEAT: - // no need to set 'state' to REPEAT again - return false; - case STOPPING: - // no further executions are allowed - return false; - } - throw this.buildISE(); - } - - /** - * An execution "cycle" is ready to begin. - * Make sure a call to {@link #stop()} did not slip in between the - * dispatching of the initial wrapped command execution (when - * {@link #isReadyToStartExecutionCycle()} returns <code>true</code>) and the - * actual execution of the wrapped command. - * This can happen if the wrapped command was dispatched asynchronously. - * <p> - * This method should be called from the actual execution method, before it - * starts looping. - */ - public synchronized boolean wasStoppedBeforeFirstExecutionCouldStart() { - switch (this.state.getValue()) { - case STOPPED: - // a call to stop() slipped in before the command could start - // executing, probably because it was dispatched asynchronously - // by 'startCommandExecutor' (e.g. in a job) - return true; - case PRE_EXECUTION: - this.state.setValue(State.EXECUTING); - return false; - case READY: - case EXECUTING: - case REPEAT: - case STOPPING: - throw this.buildISE(); - } - throw this.buildISE(); - } - - /** - * The current execution has finished. - * Return whether we should begin another execution because a call to - * execute occurred <em>during</em> the just-completed execution. - */ - public synchronized boolean isRepeat() { - switch (this.state.getValue()) { - case STOPPED: - case READY: - case PRE_EXECUTION: - throw this.buildISE(); - case EXECUTING: - // execution has finished and there are no outstanding requests for another; return to READY - this.state.setValue(State.READY); - return false; - case REPEAT: - // set 'state' back to EXECUTING and begin another execution - this.state.setValue(State.EXECUTING); - return true; - case STOPPING: - // a client initiated a "stop" during the previous execution; - // mark the "stop" complete and perform no more executions - this.state.setValue(State.STOPPED); - return false; - } - throw this.buildISE(); - } - - /** - * Return whether the execution "cycle" is "quiesced" (i.e. there are no - * outstanding execution requests). - */ - public boolean isQuiesced() { - return this.state.getValue() != State.REPEAT; - } - - /** - * Set {@link #state} so no further executions occur. - * @exception IllegalStateException if the command wrapper is already - * {@link State#STOPPED STOPPED} or {@link State#STOPPING STOPPING}. - */ - public synchronized void stop() throws InterruptedException { - switch (this.state.getValue()) { - case READY: - case PRE_EXECUTION: - // simply set 'state' to STOPPED and return - this.state.setValue(State.STOPPED); - break; - case EXECUTING: - case REPEAT: - // set 'state' to STOPPING and wait until the current execution has finished - this.state.setValue(State.STOPPING); - this.waitUntilStopped(); - break; - case STOPPED: - case STOPPING: - throw this.buildISE(); - } - } - - /** - * This wait will free up the command wrapper's synchronized methods - * (since the command wrapper is the mutex for {@link #state}). - * <p> - * If the thread that called {@link #stop()} is interrupted while waiting - * for the current command to finish executing on another thread, - * {@link #state} will still be {@link State#STOPPING STOPPING}, so the loop - * begun by the command wrapper will still stop and set {@link #state} to - * {@link State#STOPPED STOPPED}, we just won't wait around for it.... - */ - private void waitUntilStopped() throws InterruptedException { - this.state.waitUntilValueIs(State.STOPPED); - } - - private IllegalStateException buildISE() { - return new IllegalStateException("state: " + this.state); //$NON-NLS-1$ - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.state); - } -} |