001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001-2007 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki.workflow;
021:
022: import java.security.Principal;
023:
024: /**
025: * AbstractStep subclass that executes instructions, uninterrupted, and results
026: * in an Outcome. Concrete classes only need to implement {@link Task#execute()}.
027: * When the execution step completes, <code>execute</code> must return
028: * {@link Outcome#STEP_COMPLETE}, {@link Outcome#STEP_CONTINUE} or
029: * {@link Outcome#STEP_ABORT}. Subclasses can add any errors by calling the
030: * helper method {@link AbstractStep#addError(String)}. The execute method should
031: * <em>generally</em> capture and add errors to the error list instead of
032: * throwing a WikiException.
033: * <p>
034: *
035: * @author Andrew Jaquith
036: * @since 2.5
037: */
038: public abstract class Task extends AbstractStep {
039: private Step m_successor = null;
040:
041: /**
042: * Protected constructor that creates a new Task with a specified message key.
043: * After construction, the protected method {@link #setWorkflow(Workflow)} should be
044: * called.
045: *
046: * @param messageKey
047: * the Step's message key, such as
048: * <code>decision.editPageApproval</code>. By convention, the
049: * message prefix should be a lower-case version of the Step's
050: * type, plus a period (<em>e.g.</em>, <code>task.</code>
051: * and <code>decision.</code>).
052: */
053: public Task(String messageKey) {
054: super (messageKey);
055: super .addSuccessor(Outcome.STEP_COMPLETE, null);
056: super .addSuccessor(Outcome.STEP_ABORT, null);
057: }
058:
059: /**
060: * Constructs a new instance of a Task, with an associated Workflow and
061: * message key.
062: *
063: * @param workflow
064: * the associated workflow
065: * @param messageKey
066: * the i18n message key
067: */
068: public Task(Workflow workflow, String messageKey) {
069: this (messageKey);
070: setWorkflow(workflow);
071: }
072:
073: /**
074: * Returns {@link SystemPrincipal#SYSTEM_USER}.
075: * @return the system principal
076: */
077: public final Principal getActor() {
078: return SystemPrincipal.SYSTEM_USER;
079: }
080:
081: /**
082: * Sets the successor Step to this one, which will be triggered if the Task
083: * completes successfully (that is, {@link Step#getOutcome()} returns
084: * {@link Outcome#STEP_COMPLETE}. This method is really a convenient
085: * shortcut for {@link Step#addSuccessor(Outcome, Step)}, where the first
086: * parameter is {@link Outcome#STEP_COMPLETE}.
087: *
088: * @param step
089: * the successor
090: */
091: public final synchronized void setSuccessor(Step step) {
092: m_successor = step;
093: }
094:
095: /**
096: * Identifies the next Step after this Task finishes successfully. This
097: * method will always return the value set in method
098: * {@link #setSuccessor(Step)}, regardless of the current completion state.
099: *
100: * @return the next step
101: */
102: public final synchronized Step getSuccessor() {
103: return m_successor;
104: }
105:
106: }
|