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: WorkflowService.java,v 1.7 2007/02/27 14:34:21 drmlipp Exp $
021: *
022: * $Log: WorkflowService.java,v $
023: * Revision 1.7 2007/02/27 14:34:21 drmlipp
024: * Some refactoring to reduce cyclic dependencies.
025: *
026: * Revision 1.6 2007/02/16 21:43:23 mlipp
027: * Improved.
028: *
029: * Revision 1.5 2006/09/29 12:32:07 drmlipp
030: * Consistently using WfMOpen as projct name now.
031: *
032: * Revision 1.4 2006/09/21 14:20:42 drmlipp
033: * New method for retrieving current user.
034: *
035: * Revision 1.3 2005/08/17 21:15:31 mlipp
036: * Synchronized with 1.3.1p3.
037: *
038: * Revision 1.2 2005/04/08 11:28:03 drmlipp
039: * Merged changes from 1.3 branch up to 1.3p6.
040: *
041: * Revision 1.1.1.3.6.2 2005/04/07 12:12:54 drmlipp
042: * Added event subscriber with filter.
043: *
044: * Revision 1.1.1.3.6.1 2005/04/06 15:42:06 drmlipp
045: * Added additional support for accessing the event queue to
046: * WorkflowService.
047: *
048: * Revision 1.1.1.3 2004/08/18 15:17:36 drmlipp
049: * Update to 1.2
050: *
051: * Revision 1.24 2004/06/14 19:37:19 lipp
052: * Fixed assignment functions and cleaned up assignment related
053: * interfaces.
054: *
055: * Revision 1.23 2004/02/12 13:10:38 lipp
056: * Renamed openChannel to getChannel (channels have no open state).
057: *
058: * Revision 1.22 2004/01/28 16:11:38 lipp
059: * Re-implementation of chabacc, Sender working.
060: *
061: * Revision 1.21 2004/01/23 12:49:26 lipp
062: * Fixes to WorkflowService[Factory] implementation/documentation.
063: *
064: * Revision 1.20 2004/01/22 15:06:09 lipp
065: * Clarified serializability of workflow service.
066: *
067: * Revision 1.19 2003/10/06 15:20:27 lipp
068: * Made doFinish available in WorkflowService.
069: *
070: * Revision 1.18 2003/06/27 08:51:46 lipp
071: * Fixed copyright/license information.
072: *
073: * Revision 1.17 2003/06/01 20:58:50 lipp
074: * Moved toSAX to batch.
075: *
076: * Revision 1.16 2003/04/25 14:50:59 lipp
077: * Fixed javadoc errors and warnings.
078: *
079: * Revision 1.15 2003/04/24 20:50:13 lipp
080: * Fixed some warnings.
081: *
082: * Revision 1.14 2003/04/22 16:35:25 lipp
083: * Made SAXEventBuffer outer class.
084: *
085: * Revision 1.13 2003/02/25 17:08:05 lipp
086: * Reorganized requester implementation.
087: *
088: * Revision 1.12 2003/02/07 15:56:19 lipp
089: * Implemented Requester notifications.
090: *
091: * Revision 1.11 2003/02/06 12:47:14 lipp
092: * Implemented Requester (no event handling yet).
093: *
094: * Revision 1.10 2003/02/05 15:57:06 lipp
095: * Replaced DummyRequester with DefaultRequester.
096: *
097: * Revision 1.9 2002/12/19 21:37:43 lipp
098: * Reorganized interfaces.
099: *
100: * Revision 1.8 2002/12/19 16:23:46 lipp
101: * Resolved illegal dependency between apis and danet.an.util.
102: *
103: * Revision 1.7 2002/12/10 11:21:05 lipp
104: * Added batch processing as "generic DTO".
105: *
106: * Revision 1.6 2002/11/26 11:23:30 lipp
107: * Modified RemoteException comment.
108: *
109: * Revision 1.5 2002/11/22 09:56:15 lipp
110: * Clarified usage of the danet utility bean for user preferences.
111: *
112: * Revision 1.4 2002/09/19 14:37:37 lipp
113: * Using WorkflowService.release now and optimized process definition
114: * storage.
115: *
116: * Revision 1.3 2002/09/18 21:26:51 lipp
117: * Removed SAXFacade (integrated with WorkflowEngine).
118: *
119: * Revision 1.2 2002/09/18 14:22:28 lipp
120: * Javadoc improved.
121: *
122: * Revision 1.1 2002/09/18 13:00:26 lipp
123: * Renamed WorkflowEngine to WorkflowService and introduced
124: * WorkflowServiceFactory.
125: *
126: * Revision 1.3 2002/08/30 21:32:07 lipp
127: * Finished transition to WorkflowEngine.
128: *
129: * Revision 1.2 2002/08/30 13:37:05 lipp
130: * Using Workflow engine facade now.
131: *
132: * Revision 1.1 2002/08/30 11:39:42 lipp
133: * Added workflow engine EJB.
134: *
135: */
136: package de.danet.an.workflow.api;
137:
138: import java.io.IOException;
139:
140: import java.util.Collection;
141: import java.util.Map;
142:
143: import java.lang.reflect.InvocationTargetException;
144: import java.rmi.RemoteException;
145: import java.security.Principal;
146:
147: import de.danet.an.workflow.omgcore.CannotCompleteException;
148: import de.danet.an.workflow.omgcore.InvalidDataException;
149: import de.danet.an.workflow.omgcore.ProcessData;
150: import de.danet.an.workflow.omgcore.WfActivity;
151: import de.danet.an.workflow.omgcore.WfAuditHandler;
152: import de.danet.an.workflow.omgcore.WfObject;
153: import de.danet.an.workflow.omgcore.WfProcess;
154: import de.danet.an.workflow.omgcore.WfRequester;
155: import de.danet.an.workflow.omgcore.WfResource;
156:
157: /**
158: * This interface defines the methods provided by the workflow engine.
159: *
160: * @author <a href="mailto:lipp@danet.de"></a>
161: * @version $Revision: 1.7 $
162: */
163:
164: public interface WorkflowService extends WfObject {
165:
166: /**
167: * Returns the properties that uniquely decribe the workflow
168: * service in the current environment. <P>
169: *
170: * <code>WorkflowService</code> does not implement
171: * <code>Serializable</code> because implementations of this class
172: * may have attributes that e.g. include network connections to
173: * the server and may thus not be serializable. Nevertheless it
174: * should be possible to obtain some unique reference to a
175: * workflow service and to restore this service without having to
176: * "manually" collect the (implementation dependant!) properties
177: * set for <code>WorkflowServiceFactory</code> before the call to
178: * <code>newInstance</code>.<P>
179: *
180: * This methods therefore returns a set of relevant properties
181: * that will restore this workflow service when set as properties
182: * of <code>WorkflowServiceFactory</code> in the same or an
183: * equivalent environment before <code>newInstance</code> is
184: * called. The properties returned by this method are, of course,
185: * based on the properties in effect when the
186: * <code>WorkflowService</code> was initially created.<P>
187: *
188: * Note the restriction "same or equivalent environment" in the
189: * previous paragraph. One of the explicitly mentioned properties
190: * of the <code>WorkflowServiceFactory</code> (in a J2EE based
191: * implementation) is the <code>InitialContext</code> used. If not
192: * set explicitly, the default initial context may be specified by
193: * something like "<code>localhost:1099</code>". While the
194: * properties returned by <code>serviceProperties</code> will
195: * include this property of the connection to the JNDI provider,
196: * using the properties in a different JVM on a different machine
197: * may result in a different workflow service (or no workflow
198: * service at all) because a different JNDI server is accessed.
199: *
200: * The impossibility to transfer all relevant information between
201: * JVM's under all circumstances (<code>InitialContext</code> is
202: * not serializable as may be some other crucial information in an
203: * implementation based on some other technology than J2EE) has
204: * prevented us from demanding serializability for
205: * <code>WorkflowService</code>. The requirement to obtain the
206: * service information explicitly and to create a new instance
207: * should result in some awareness of the problems.
208: *
209: * @return the service properties
210: * @throws RemoteException if a system-level error occurs
211: */
212: Map serviceProperties() throws RemoteException;
213:
214: /**
215: * Return the workflow engine configuration.
216: *
217: * @return the configuration.
218: * @throws RemoteException if a system-level error occurs.
219: */
220: Configuration configuration() throws RemoteException;
221:
222: /**
223: * Return the process definition directory of the workflow service.
224: *
225: * @return the process definition directory.
226: * @throws RemoteException if a system-level error occurs.
227: */
228: ProcessDefinitionDirectory processDefinitionDirectory()
229: throws RemoteException;
230:
231: /**
232: * Return the process directory of the workflow service.
233: *
234: * @return the process directory.
235: * @throws RemoteException if a system-level error occurs.
236: */
237: ProcessDirectory processDirectory() throws RemoteException;
238:
239: /**
240: * Given a {@link java.security.Principal principal}, return the
241: * workflow resource associated with this principal. This method
242: * is usually used to get a <code>WfResource</code> object
243: * corresponding to the current user. The <code>WfResource</code>
244: * object can subsequently be used to e.g. determine the current
245: * user's worklist.<P>
246: *
247: * Calls to this method are typically delegated to {@link
248: * de.danet.an.workflow.spis.ras.ResourceAssignmentService#asResource
249: * <code>ResourceAssignmentService.asResource</code>}. Note that
250: * since implementation of this method by the resource assignment
251: * service is optional, calling this method may result in an
252: * <code>UnsupportedOperationException</code>.
253: *
254: * @param principal the principal.
255: * @return a <code>WfResource</code> object corresponding to the
256: * given principal.
257: * @throws InvalidKeyException if a resource with the given principal
258: * can't be found.
259: * @throws RemoteException if a system-level error occurs.
260: * @since 1.2
261: */
262: WfResource asResource(Principal principal) throws RemoteException,
263: InvalidKeyException;
264:
265: /**
266: * Given the <code>key</code> of a <code>WfResource</code>
267: * (obtained with {@link WfResource#resourceKey
268: * <code>resourceKey()</code>}), return the workflow resource
269: * associated with this key.<P>
270: *
271: * Calls to this method are typically delegated to {@link
272: * de.danet.an.workflow.spis.ras.ResourceAssignmentService#resourceByKey
273: * <code>ResourceAssignmentService.resourceByKey</code>}. Note
274: * that since implementation of this method by the resource
275: * assignment service is optional, calling this method may result
276: * in an <code>UnsupportedOperationException</code>.
277: *
278: * @param key the key.
279: * @return a <code>WfResource</code> object corresponding to the
280: * given key.
281: * @throws InvalidKeyException if the resource with the given
282: * key can't be found. As the environment is a concurrent multi
283: * user environment, <code>WfResource</code> objects (and keys obtained
284: * from <code>WfResource</code> objects) may become invalid.
285: * @throws RemoteException if a system-level error occurs.
286: * @since 1.2
287: * @see ResourceAssignmentService#resourceByKey
288: */
289: WfResource resourceByKey(String key) throws InvalidKeyException,
290: RemoteException;
291:
292: /**
293: * Returns at least the collection of all the workflow resources
294: * that have been assigned work items, but optionally it can
295: * return the additional workflow resources that are known to the
296: * resource assignment service.
297: *
298: * Calls to this method are typically delegated to {@link
299: * de.danet.an.workflow.spis.ras.ResourceAssignmentService#knownResources
300: * <code>ResourceAssignmentService.knownResources</code>}. Note
301: * that since implementation of this method by the resource
302: * assignment service is optional, calling this method may result
303: * in an <code>UnsupportedOperationException</code>.
304: *
305: * @return the collection of the known resources to the ras (instances of
306: * {@link de.danet.an.workflow.omgcore.WfResource
307: * <code>WfResource</code>}).
308: * @throws RemoteException if a system-level error occurs.
309: * @since 1.2
310: * @see ResourceAssignmentService#knownResources
311: */
312: Collection knownResources() throws RemoteException;
313:
314: /**
315: * Given a {@link de.danet.an.workflow.omgcore.WfResource
316: * <code>WfResource</code> object}, return the collection of
317: * resources this resource is authorized for.<P>
318: *
319: * This method usually returns all groups the resource is a
320: * member of and all roles assigned to the resource.<P>
321: *
322: * Calls to this method are typically delegated to {@link
323: * de.danet.an.workflow.spis.ras.ResourceAssignmentService#authorizers
324: * <code>ResourceAssignmentService.authorizers</code>}. Note that
325: * since implementation of this method by the resource assignment
326: * service is optional, calling this method may result in an
327: * <code>UnsupportedOperationException</code>.
328: *
329: * @param resource the resource.
330: * @return a collection of <code>WfResource</code> objects, not
331: * including <code>resource</code>
332: * @throws RemoteException if a system-level error occurs.
333: * @since 1.2
334: */
335: Collection authorizers(WfResource resource) throws RemoteException;
336:
337: /**
338: * Returns an event receiver. The events received will be handled
339: * by the given handler. Event receivers should be released using
340: * {@link #release <code>release</code>} when no longer needed as
341: * they may consume considerable resources.
342: * @param handler the handler for received events.
343: * @return the receiver.
344: * @throws RemoteException if a system-level error occurs.
345: * @deprecated since version 1.3.2. Use {@link
346: * #createEventSubscriber <code>createEventSubscriber</code>}
347: * instead and set a handler for the object thus obtained
348: */
349: WfObject eventReceiver(WfAuditHandler handler)
350: throws RemoteException;
351:
352: /**
353: * Returns an event subscriber. Event subscriber should be
354: * released using {@link #release <code>release</code>} when no
355: * longer needed as they may consume considerable resources.
356: * @return the subscriber
357: * @throws IOException if an error occurs.
358: */
359: EventSubscriber createEventSubscriber() throws IOException;
360:
361: /**
362: * Returns an event subscriber that receives events as specified
363: * by the parameters. Event subscriber should be released using
364: * {@link #release <code>release</code>} when no longer needed as
365: * they may consume considerable resources.
366: * @param processKey if not <code>null</code>, receive events for
367: * the given process only
368: * @param eventTypes if not <code>null</code>, receive events of
369: * the given types only. Types are specified as a whitespace,
370: * comma or semicolon separated list of event names. See {@link
371: * de.danet.an.workflow.omgcore.WfAuditEvent
372: * <code>WfAuditEvent</code>} for a list of valid event names.
373: * @return the subscriber
374: * @throws IOException if an error occurs.
375: */
376: EventSubscriber createEventSubscriber(String processKey,
377: String eventTypes) throws IOException;
378:
379: /**
380: * Register a <code>WfRequester</code>. Registered requesters'
381: * <code>receiveEvent</code> methods will be called for their
382: * performers. Note that a requester must be registered before
383: * it is used for process creation. Else events may be lost.
384: * @param requester the requester to be registered.
385: * @throws RemoteException if a system-level error occurs.
386: */
387: void registerRequester(WfRequester requester)
388: throws RemoteException;
389:
390: /**
391: * Return the processes requested by the given requester. This is
392: * a helper method intended to be used when implementing a
393: * <code>WfRequester</code>. Applications should use {@link
394: * WfRequester#performers <code>WfRequester.performers()</code>}
395: * instead.
396: * @param req the requester.
397: * @return the processes created with the given requester.
398: * @throws RemoteException if a system-level error occurs.
399: */
400: Collection requestedBy(WfRequester req) throws RemoteException;
401:
402: /**
403: * Set a result and complete an activity in a new transaction.
404: * This is usually required to implement tools with reasonable
405: * behaviour since a failure when calling <code>setResult</code>
406: * or <code>complete</code> on an activity may not cause the tool
407: * invocation to be repeated (as would be the case when simply
408: * calling <code>setResult</code> or <code>complete</code> due to
409: * the transaction rollback associated with an exception). <P>
410: *
411: * As an example consider an
412: * <code>InvalidDataException</code>. This usually occurs when the
413: * result contains an item that is not a declared process data
414: * field. Ususally, repeating the tool invocation will not solve
415: * this problem.
416: *
417: * @param act the <code>Activity</code>.
418: * @param result the tool's result data. If <code>null</code> do
419: * not call <code>setResult</code>.
420: * @throws InvalidDataException see {@link
421: * de.danet.an.workflow.omgcore.WfActivity#setResult
422: * <code>WfActivity.setResult(...)</code>}
423: * @throws CannotCompleteException see {@link
424: * de.danet.an.workflow.omgcore.WfActivity#complete
425: * <code>WfActivity.complete()</code>}
426: * @throws RemoteException if a system-level error occurs.
427: * @since 1.1
428: */
429: void doFinish(WfActivity act, ProcessData result)
430: throws InvalidDataException, CannotCompleteException,
431: RemoteException;
432:
433: /**
434: * Release an object obtained from the workflow service
435: * immediately instead of waiting for it to be automatically
436: * released. This may be called to optimize resource
437: * utilization.<P>
438: *
439: * We do not want to define a specific mechanism for implementing
440: * the remote invocation mechanism used with the workflow
441: * API. Therefore, we cannot demand that each object defines a
442: * method to release resources (like e.g. CORBA's release). This
443: * method knows about the implementation specifics and acts
444: * appropriately.
445: *
446: * @param obj the object which is no longer used.
447: */
448: void release(WfObject obj);
449:
450: /**
451: * Execute a batch in the context of the workflow service i.e. on
452: * the server.<P>
453: *
454: * We do not want to define a specific mechanism for implementing
455: * the remote invocation mechanism used with the workflow API. Yet
456: * it is obvious that any implementation can profit from the
457: * possibility to execute several actions as one call to the
458: * server.
459: *
460: * @param batch the batch to be executed.
461: * @return the result returned by {@link Batch#execute
462: * <code>Batch.execute</code>}.
463: * @throws RemoteException if a system-level error occurs.
464: * @throws InvocationTargetException if thrown by {@link
465: * Batch#execute <code>Batch.execute</code>}
466: */
467: Object executeBatch(Batch batch) throws RemoteException,
468: InvocationTargetException;
469:
470: /**
471: * Return a named communication channel to the given process. The
472: * channel may be used to send messages to the receiver tool and
473: * receive messages from the sender tool.<P>
474: *
475: * Channels should be {@link #release released} when no longer
476: * needed to free resources.
477: *
478: * @param process the process to communicate with
479: * @param channelName the channel name
480: * @return the channel
481: * @throws RemoteException if a system-level error occurs.
482: */
483: Channel getChannel(WfProcess process, String channelName)
484: throws RemoteException;
485:
486: /**
487: * Return a named communication channel to the given process. The
488: * channel may be used to send messages to the receiver tool and
489: * optionally receive messages from the sender tool.<P>
490: *
491: * Channels should be {@link #release released} when no longer
492: * needed to free resources.
493: *
494: * @param process the process to communicate with
495: * @param channelName the channel name
496: * @param sendOnly if set, returns a channel that may only be used
497: * for sending messages. This may save some resources.
498: * @return the channel
499: * @throws RemoteException if a system-level error occurs.
500: */
501: Channel getChannel(WfProcess process, String channelName,
502: boolean sendOnly) throws RemoteException;
503:
504: /**
505: * Returns the currently (i.e. for this call) authenticated user
506: * as a <code>Principal</code>.<P>
507: *
508: * In an environment where authentication is performed by the container,
509: * it may not be easy to discover this information. Although most
510: * container environments provide a possibility to access the current
511: * principal, there may be a mapping between the client's representation
512: * of the currently authenticated user and the workflow engine's
513: * (i.e. server's) representation.
514: *
515: * @return the caller principal.
516: * @see #asResource
517: * @ejb.interface-method view-type="remote"
518: * @ejb.transaction type="Supports"
519: */
520: public Principal caller() throws RemoteException;
521:
522: }
|