001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 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 General Public License for more details.
015: *
016: * You should have received a copy of the GNU 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: * $Id: ExtActivityLocal.java,v 1.1.2.1 2007/11/02 16:00:33 drmlipp Exp $
021: *
022: * $Log: ExtActivityLocal.java,v $
023: * Revision 1.1.2.1 2007/11/02 16:00:33 drmlipp
024: * Merged bug fixes from HEAD.
025: *
026: * Revision 1.2 2007/09/20 21:18:43 mlipp
027: * Removed superfluous import.
028: *
029: * Revision 1.1 2007/05/03 21:58:20 mlipp
030: * Internal refactoring for making better use of local EJBs.
031: *
032: */
033: package de.danet.an.workflow.internalapi;
034:
035: import java.io.Serializable;
036:
037: import java.util.Collection;
038: import java.util.Date;
039: import java.util.Map;
040:
041: import de.danet.an.workflow.api.Activity;
042: import de.danet.an.workflow.api.Activity.JoinAndSplitMode;
043: import de.danet.an.workflow.localapi.ActivityLocal;
044: import de.danet.an.workflow.omgcore.AlreadyRunningException;
045: import de.danet.an.workflow.omgcore.InvalidStateException;
046: import de.danet.an.workflow.omgcore.NotRunningException;
047: import de.danet.an.workflow.omgcore.TransitionNotAllowedException;
048: import de.danet.an.workflow.omgcore.WfAuditEvent;
049: import de.danet.an.workflow.omgcore.WfExecutionObject.NotRunningState;
050: import de.danet.an.workflow.omgcore.WfExecutionObject.State;
051:
052: import de.danet.an.workflow.spis.aii.ResultProvider.ExceptionResult;
053: import de.danet.an.workflow.spis.ras.ActivityFinder;
054:
055: /**
056: * This interface defines some additional methods of <code>Activity</code>s
057: * that are only available within the implementation (not part of the API).
058: *
059: * @author <a href="mailto:lipp@danet.de"></a>
060: * @version $Revision: 1.1.2.1 $
061: */
062:
063: public interface ExtActivityLocal extends ExtExecutionObjectLocal,
064: ActivityLocal {
065:
066: /**
067: * This class defines the sub-states of NotRunningState.NOT_STARTED of a
068: * {@link de.danet.an.workflow.localcoreapi.WfExecutionObjectLocal
069: * <code>WfExecutionObject</code>}. These substates are an extention of
070: * the predefined omg states.
071: */
072: public static class NotStartedState extends NotRunningState
073: implements Serializable {
074: /**
075: * Provides a state indicating that start conditions have not been
076: * evaluated yet.
077: */
078: public static final NotStartedState UNKNOWN = new NotStartedState(
079: "unknown");
080:
081: /**
082: * Provides a state indicating that the activity is startable.
083: */
084: public static final NotStartedState STARTABLE = new NotStartedState(
085: "startable");
086: static {
087: registerState(UNKNOWN);
088: registerState(STARTABLE);
089: }
090:
091: /**
092: * Default constructor.
093: *
094: * @param text
095: * Textual representation of the state
096: */
097: protected NotStartedState(String text) {
098: super (text);
099: }
100:
101: /**
102: * Returns the parent in the state hierachy if all states defined in
103: * this class or <code>null</code>, if this states are at the top
104: * level of the hierachy.
105: *
106: * @return parent in the state hierachy
107: */
108: public State getParent() {
109: // parent is OpenState.RUNNING
110: return NotRunningState.NOT_STARTED;
111: }
112:
113: /**
114: * Returns the workflow state, i.e. the great-grandparent.
115: *
116: * @return the workflow state.
117: */
118: public State workflowState() {
119: return getParent().getParent().getParent();
120: }
121:
122: /**
123: * Returns the workflow substate for open execution objects.
124: *
125: * @return the open state.
126: */
127: public State whileOpenState() {
128: return getParent().getParent();
129: }
130:
131: /**
132: * Returns the workflow substate for open, not running execution
133: * objects.
134: *
135: * @return the why not running state.
136: */
137: public State whyNotRunningState() {
138: return getParent();
139: }
140:
141: /**
142: * Returns the workflow substate for closed execution objects.
143: *
144: * @return the closed state.
145: */
146: public State howClosedState() {
147: throw new IllegalStateException();
148: }
149:
150: /**
151: * Perform instance substitution during serialization.
152: */
153: private Object readResolve() {
154: String repr = textRepresentation();
155: if (repr == null) {
156: throw new IllegalArgumentException(
157: "Unexpected error in deserialization");
158: }
159: if (repr.equals(UNKNOWN.textRepresentation())) {
160: return UNKNOWN;
161: }
162: if (repr.equals(STARTABLE.textRepresentation())) {
163: return STARTABLE;
164: }
165: throw new IllegalArgumentException(
166: "Unexpected error in serialization");
167: }
168: }
169:
170: /**
171: * Initiate enactment of a WfActivity.
172: * @throws AlreadyRunningException
173: * when the process has already been started.
174: */
175: void start() throws AlreadyRunningException;
176:
177: /**
178: * Return the start time of the activity.
179: * @return result
180: * @throws NotRunningException if the activity has not been started yet
181: */
182: Date startTime() throws NotRunningException;
183:
184: /**
185: * Close the activity which assumes the given state. This method has no side
186: * effects and is intended to be used by the containing process during
187: * processing of
188: * {@link ExtProcessLocal#closeActivity <code>closeActivity</code>}.
189: *
190: * @param closedState
191: * the state to assume
192: */
193: void doCloseActivity(State closedState);
194:
195: /**
196: * Set the join mode of the activity.
197: *
198: * @param joinMode
199: * the new join mode
200: */
201: void setJoinMode(JoinAndSplitMode joinMode);
202:
203: /**
204: * Set the join mode of the activity.
205: *
206: * @param splitMode
207: * the new split mode
208: */
209: void setSplitMode(JoinAndSplitMode splitMode);
210:
211: /**
212: * Update the sub-state of an activity in state
213: * <code>NotRunningState.NOT_STARTED</code> to
214: * <code>NotStartedState.STARTABLE</code>. This update reflects internal
215: * evaluation progression only and does neither update last state change
216: * time nor fire an event.
217: *
218: * @param triggers
219: * the activities that caused the activity to be startable (one
220: * or more activities depending on the join mode).
221: * @param preliminaryElected
222: * if the activity is triggered due to a deferred choice
223: */
224: void setStartable(Collection triggers, boolean preliminaryElected);
225:
226: /**
227: * Reset an activity to <code>NotStartedState.UNKNOWN</code>, i.e. have
228: * it assume exactly the same state as it has when newly created. An
229: * exception is the thread info which can (optionally) be preserved in
230: * certain cases.
231: *
232: * @param preserveThreadInfo
233: * preserve the thread info, i.e. the information about the
234: * activity's predecessors.
235: * @param publishChange
236: * publish the state change, i.e. create a corresponding audit
237: * event
238: */
239: void reset(boolean preserveThreadInfo, boolean publishChange);
240:
241: /**
242: * Return the activity's thread info.
243: *
244: * @return the thread info.
245: */
246: ThreadInfo threadInfo();
247:
248: /**
249: * Returns a <code>WfAuditEvent</code> containing information about the
250: * activity and its container, only.
251: *
252: * @return the event containing the required information.
253: */
254: WfAuditEvent auditEventBase();
255:
256: /**
257: * Updates the process name (which is cached by the activity EJB) if the
258: * process name changes.
259: *
260: * @param newName
261: * the new process name.
262: */
263: void updateProcessName(String newName);
264:
265: /**
266: * Returns an {@link de.danet.an.workflow.spis.ras.ActivityFinder
267: * <code>ActivityFinder</code>} that identifies this activity against a
268: * resource assignment service as defined by
269: * {@link de.danet.an.workflow.spis.ras the ras package}.
270: *
271: * @return the activity finder.
272: */
273: ActivityFinder activityFinder();
274:
275: /**
276: * Invoke a tool for this activity.
277: *
278: * @param appl
279: * the application description of the tool.
280: * @param params
281: * the invocation parameters.
282: */
283: void invokeTool(ExtApplication appl, Map params);
284:
285: /**
286: * Abort a requesting activity. Called by subprocesses to abort their
287: * invoker.
288: */
289: void abortRequester();
290:
291: /**
292: * Returns the performer as string.
293: *
294: * @return performer as string
295: */
296: String performer();
297:
298: /**
299: * Like {@link Activity.abandon(String) <code>abandon(String)</code>} but
300: * may also suspend the activity.
301: *
302: * @param result
303: * exception information
304: * @throws TransitionNotAllowedException
305: * if the activity is not executing a tool
306: */
307: void abandon(ExceptionResult result)
308: throws TransitionNotAllowedException;
309:
310: /**
311: * Force the completion of this activity, leaving it in state
312: * "closed.completed.abandoned" if it is currently running or
313: * "open.not_running.suspended.abandoning" if currently suspended. Does
314: * nothing if the activity is in state "closed" already or has not been
315: * started ("open.not_running.not_started").
316: * <P>
317: *
318: * The state transition will be signaled to event listeners but will not be
319: * forwarded to the process.
320: *
321: * @param blockException
322: * indicates that the exception occurred on the block activity
323: * this activity is a member of
324: * @param exceptionName
325: * the related exception. If <code>null</code> it is an
326: * asynchronous exception
327: * @return <code>true</code> if state has changed to closed in this method
328: */
329: boolean initiateAbandoning(boolean blockException,
330: String exceptionName);
331:
332: /**
333: * Enable or disable debugging of the activity.
334: *
335: * @param debug
336: * if the activity is to be debugged
337: * @throws InvalidStateException TODO
338: */
339: void setDebugEnabled(boolean debug) throws InvalidStateException;
340:
341: /**
342: * Returns if the activity's split is to be executed as deferred choice.
343: *
344: * @return <code>true</code> if the activity has been elected
345: */
346: boolean deferChoiceOnSplit();
347:
348: /**
349: * Returns if the activity has been preliminarily chosen in a deferred
350: * choice.
351: *
352: * @return <code>true</code> if the activity has been elected
353: */
354: boolean preliminarilyChosen();
355:
356: /**
357: * Terminates and resets an activity that was started preliminarily as part
358: * of a deferred choice.
359: *
360: * @param reset
361: * if the activity's state is to be reset
362: * @throws TransitionNotAllowedException
363: * if the activity has not been preliminarily chosen
364: */
365: void withdrawPreliminaryChoice(boolean reset)
366: throws TransitionNotAllowedException;
367:
368: /**
369: * Return the remote version of this object.
370: *
371: * @return the client side object.
372: */
373: Activity toActivity();
374: }
|