Java tutorial
/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation * yyyymmdd bug Email and other contact information * -------- -------- ----------------------------------------------------------- * 20060223 129232 pmoogk@ca.ibm.com - Peter Moogk * 20070314 176886 pmoogk@ca.ibm.com - Peter Moogk * 20070730 197144 pmoogk@ca.ibm.com - Peter Moogk, Pass progress monitor to undo commands. *******************************************************************************/ package org.eclipse.wst.command.internal.env.ui.widgets; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.wst.command.internal.env.core.data.DataFlowManager; import org.eclipse.wst.command.internal.env.core.fragment.CommandFragment; import org.eclipse.wst.command.internal.env.core.fragment.CommandFragmentEngine; import org.eclipse.wst.command.internal.env.core.fragment.FragmentListener; import org.eclipse.wst.command.internal.env.eclipse.BaseStatusHandler; import org.eclipse.wst.command.internal.env.eclipse.EclipseEnvironment; import org.eclipse.wst.common.environment.ILog; /** * This class manages the execution of Commands in a flow of CommandFragments. * The bulk of this work is done by the CommandFragmentEngine. The main job of * this class is run the fragments in a particular transactional environment. * A fragment has a method called doNotRunInTransaction which is used to determine * if its commands should be run in a transaction or not. If this method returns * true(ie. not in a transaction) the Commands are wrapped in a IRunnableWithProgress. * If false( ie. in a transaction ) the Commands are wrapped in a WorkspaceModifyOperation. * */ public class SimpleCommandEngineManager { protected CommandFragmentEngine engine_; protected DataFlowManager dataManager_; protected EclipseEnvironment environment_; private boolean foundStop_; private boolean doNotRunInTransaction_; public SimpleCommandEngineManager(EclipseEnvironment environment, DataFlowManager dataManager) { environment_ = environment; dataManager_ = dataManager; } /** * Sets the root fragment. The execution engine will start executing commands * at the beginning of this root fragment. * * @param root the root fragment. */ public void setRootFragment(CommandFragment root) { engine_ = new CommandFragmentEngine(root, dataManager_, environment_); environment_.setCommandManager(engine_); engine_.setPeekFragmentListener(new FragmentListener() { public boolean notify(CommandFragment fragment) { return peekFragment(fragment); } }); engine_.setNextFragmentListener(new FragmentListener() { public boolean notify(CommandFragment fragment) { return nextFragment(fragment); } }); engine_.setAfterExecuteFragmentListener(new FragmentListener() { public boolean notify(CommandFragment fragment) { return afterExecuteNextFragment(fragment); } }); engine_.setUndoFragmentListener(new FragmentListener() { public boolean notify(CommandFragment fragment) { return undoFragment(fragment); } }); } protected boolean afterExecuteNextFragment(CommandFragment fragment) { boolean continueExecute = true; BaseStatusHandler statusHandler = (BaseStatusHandler) environment_.getStatusHandler(); IStatus commandStatus = engine_.getLastStatus(); IStatus handlerStatus = statusHandler.getStatus(); if (commandStatus.getSeverity() == IStatus.ERROR && handlerStatus.getSeverity() != IStatus.ERROR) { // The command returned an error status for the engine to stop, // but the status handler did not have report and error. // Therefore, we will report this status returned by the command // if there is a message to display. String errorMessage = commandStatus.getMessage(); if (errorMessage != null && errorMessage.length() > 0) { statusHandler.reportError(commandStatus); } } else if (commandStatus.getSeverity() != IStatus.ERROR && handlerStatus.getSeverity() == IStatus.ERROR) { // The last command didn't return an error, but the status handler // did report and error. Therefore, we should stop. continueExecute = false; } return continueExecute; } /** * The CommandFragmentEngine calls this method when it is peeking forward * in the fragments. When peeking forward the command stack state in the * engine is not changes. * * * @param fragment the fragment that it is peeking at. * @return Indicates whether peeking should stop or not. */ protected boolean peekFragment(CommandFragment fragment) { return true; } /** * The CommandFragmentEngine calls this method when it is moving forward * in the fragments. When moving forward the command stack state is saved * at each fragment is traversed. * * @param fragment the fragment that is being traversed. * @return indicates if the forward traversal should continue. */ protected boolean nextFragment(CommandFragment fragment) { if (fragment.doNotRunInTransaction() != doNotRunInTransaction_) { // The fragment is requesting a different transaction environment than // the one that we are in so we must stop and change environments. doNotRunInTransaction_ = fragment.doNotRunInTransaction(); foundStop_ = false; } return foundStop_; } /** * This method is called for each fragment when the command engine is unwinding * its stack during an undo operation. * * @param fragment the fragment being undone. * @return returns true if the undo process should continue. */ protected boolean undoFragment(CommandFragment fragment) { return true; } /** * This method undoes the commands that were executed in the runForwardToNextStop * method. * @param context the runnable context. * @return returns if all commands have been undone or not. */ public boolean runUndoToNextStop(IRunnableContext context) { final boolean result[] = new boolean[] { true }; IRunnableWithProgress undoOperation = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { result[0] = engine_.undoToLastStop(monitor); } }; try { if (context == null) { // We don't have a container yet so just run the operation. undoOperation.run(null); } else { // We have a container where this operation can run and have // its progress displayed. context.run(false, false, undoOperation); } } catch (Exception exc) { // For now we will ignore all exceptions. } return result[0]; } /** * The method executes the CommandFragment commands in the context provided. * * @param context the context * @return returns the status of executing the commands. */ public IStatus runForwardToNextStop(IRunnableContext context) { IRunnableWithProgress operation = null; doNotRunInTransaction_ = false; do { // We will stop unless we are changing transaction modes. foundStop_ = true; if (doNotRunInTransaction_) { operation = getNoTransactionOperation(); } else { operation = getTransactionOperation(); } try { if (context == null) { // We don't have a container yet so just run the operation. operation.run(null); } else { // We have a container where this operation can run and have // its progress displayed. context.run(false, false, operation); } } catch (InterruptedException exc) { //TODO should log these exceptions. exc.printStackTrace(); } catch (InvocationTargetException exc) { //TODO should log these exceptions. exc.printStackTrace(); } } while (!foundStop_); return engine_.getLastStatus(); } private IRunnableWithProgress getTransactionOperation() { IRunnableWithProgress operation = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { environment_.getLog().log(ILog.INFO, "command", 5002, this, "getTransactionOperation", "Start of transaction"); BaseStatusHandler statusHandler = (BaseStatusHandler) environment_.getStatusHandler(); statusHandler.resetStatus(); engine_.moveForwardToNextStop(monitor); environment_.getLog().log(ILog.INFO, "command", 5003, this, "getTransactionOperation", "End of transaction"); } }; return operation; } private IRunnableWithProgress getNoTransactionOperation() { IRunnableWithProgress operation = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { environment_.getLog().log(ILog.INFO, "command", 5085, this, "getNoTransactionOperation", "Start of NON transaction"); BaseStatusHandler statusHandler = (BaseStatusHandler) environment_.getStatusHandler(); statusHandler.resetStatus(); engine_.moveForwardToNextStop(monitor); environment_.getLog().log(ILog.INFO, "command", 5086, this, "getNoTransactionOperation", "End of NON transaction"); } }; return operation; } }