001: /*--
002:
003: Copyright (C) 2002-2005 Adrian Price.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: adrianprice@sourceforge.net.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Adrian Price (adrianprice@users.sourceforge.net).
027:
028: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
029: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
030: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
032: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
034: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
036: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
037: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
038: POSSIBILITY OF SUCH DAMAGE.
039:
040: For more information on OBE, please see
041: <http://obe.sourceforge.net/>.
042:
043: */
044:
045: package org.obe.xpdl.model.workflow;
046:
047: import org.obe.xpdl.PackageVisitor;
048: import org.obe.xpdl.model.XPDLProperties;
049: import org.obe.xpdl.model.activity.Activity;
050: import org.obe.xpdl.model.activity.ActivitySet;
051: import org.obe.xpdl.model.activity.BlockActivity;
052: import org.obe.xpdl.model.data.FormalParameter;
053: import org.obe.xpdl.model.ext.Trigger;
054: import org.obe.xpdl.model.misc.AccessLevel;
055: import org.obe.xpdl.model.misc.Graph;
056: import org.obe.xpdl.model.misc.Invokable;
057: import org.obe.xpdl.model.misc.ResourceContainer;
058: import org.obe.xpdl.model.pkg.XPDLPackage;
059: import org.obe.xpdl.model.transition.Transition;
060:
061: import java.beans.PropertyVetoException;
062: import java.util.Map;
063:
064: public final class WorkflowProcess extends ResourceContainer implements
065: Graph, Invokable {
066:
067: private static final long serialVersionUID = -2304468508983567539L;
068: public static final String ACCESS_LEVEL = XPDLProperties.ACCESS_LEVEL;
069: public static final String ACTIVITY = XPDLProperties.ACTIVITY;
070: public static final String ACTIVITY_SET = XPDLProperties.ACTIVITY_SET;
071: public static final String COMPLETION_STRATEGY = XPDLProperties.COMPLETION_STRATEGY;
072: public static final String FORMAL_PARAMETER = XPDLProperties.FORMAL_PARAMETER;
073: public static final String PACKAGE = XPDLProperties.PACKAGE;
074: public static final String PACKAGE_ID = XPDLProperties.PACKAGE_ID;
075: public static final String PROCESS_DEFINITION_ID = XPDLProperties.PROCESS_DEFINITION_ID;
076: public static final String PROCESS_HEADER = XPDLProperties.PROCESS_HEADER;
077: public static final String STATE = XPDLProperties.STATE;
078: public static final String TRANSITION = XPDLProperties.TRANSITION;
079: public static final String TRIGGER = XPDLProperties.TRIGGER;
080: private static final Activity[] EMPTY_ACTIVITY = {};
081: private static final ActivitySet[] EMPTY_ACTIVITY_SET = {};
082: private static final FormalParameter[] EMPTY_FORMAL_PARM = {};
083: private static final Transition[] EMPTY_TRANSITION = {};
084: private static final String[] _indexedPropertyNames = {
085: APPLICATION, DATA_FIELD, PARTICIPANT, ACTIVITY,
086: ACTIVITY_SET, FORMAL_PARAMETER, TRANSITION };
087: private static final Object[] _indexedPropertyValues = {
088: EMPTY_APPLICATION, EMPTY_DATA_FIELD, EMPTY_PARTICIPANT,
089: EMPTY_ACTIVITY, EMPTY_ACTIVITY_SET, EMPTY_FORMAL_PARM,
090: EMPTY_TRANSITION };
091: private static final int ACTIVITY_IDX = 3;
092: private static final int ACTIVITY_SET_IDX = 4;
093: private static final int FORMAL_PARAMETER_IDX = 5;
094: private static final int TRANSITION_IDX = 6;
095:
096: private XPDLPackage _pkg;
097: private ProcessHeader _processHeader;
098: private FormalParameter[] _formalParameter = EMPTY_FORMAL_PARM;
099: private ActivitySet[] _activitySet = EMPTY_ACTIVITY_SET;
100: private Activity[] _activity = EMPTY_ACTIVITY;
101: private Transition[] _transition = EMPTY_TRANSITION;
102: private AccessLevel _accessLevel;
103: private String _completionStrategy;
104: private Trigger _trigger;
105: private int _state = 1; // (WMProcessDefinitionState.ENABLED_INT)
106:
107: // 'Connects up' each BlockActivity to its ActivitySet.
108: private static void resolveActivitySets(ActivitySet[] activitySets,
109: Activity[] activities, boolean recursive) {
110:
111: // Resolve ActivitySet references from the activities collection.
112: for (int i = 0, m = activities.length; i < m; i++) {
113: Activity activity = activities[i];
114: BlockActivity ba = activity.getBlockActivity();
115: if (ba != null) {
116: for (int j = 0, n = activitySets.length; j < n; j++) {
117: ActivitySet activitySet = activitySets[j];
118: if (activitySet.getId().equals(ba.getBlockId())) {
119: ba.setActivitySet(activitySet);
120: break;
121: }
122: }
123: if (ba.getActivitySet() == null) {
124: throw new IllegalStateException(
125: "ActivitySet not found: " + ba.getBlockId());
126: }
127: }
128: }
129:
130: if (recursive) {
131: // Resolve ActivitySet references from each of the ActivitySets.
132: for (int i = 0, n = activitySets.length; i < n; i++) {
133: ActivitySet activitySet = activitySets[i];
134: resolveActivitySets(activitySets, activitySet
135: .getActivity(), false);
136: }
137: }
138: }
139:
140: // 'Connects up' each activity to its transitions.
141: private static void resolveTransitions(ActivitySet[] activitySets,
142: Activity[] activities, Transition[] transitions) {
143:
144: for (int i = 0, m = activities.length; i < m; i++) {
145: Activity activity = activities[i];
146: String activityId = activity.getId();
147: Map afferentTransitions = activity.getAfferentTransitions();
148: Map efferentTransitions = activity.getEfferentTransitions();
149: afferentTransitions.clear();
150: efferentTransitions.clear();
151: for (int j = 0, n = transitions.length; j < n; j++) {
152: Transition transition = transitions[j];
153: if (transition.getFrom().equals(activityId)) {
154: transition.setFromActivity(activity);
155: efferentTransitions.put(transition.getId(),
156: transition);
157: }
158: if (transition.getTo().equals(activityId)) {
159: transition.setToActivity(activity);
160: afferentTransitions.put(transition.getId(),
161: transition);
162: }
163: }
164: }
165:
166: if (activitySets != null) {
167: // Resolve ActivitySet references from each of the ActivitySets.
168: for (int i = 0, n = activitySets.length; i < n; i++) {
169: ActivitySet activitySet = activitySets[i];
170: resolveTransitions(null, activitySet.getActivity(),
171: activitySet.getTransition());
172: }
173: }
174: }
175:
176: public WorkflowProcess() {
177: super (_indexedPropertyNames, _indexedPropertyValues);
178: _processHeader = new ProcessHeader();
179: }
180:
181: /**
182: * Construct a new WorkflowProcess.
183: *
184: * @param id The id
185: * @param name The name
186: * @param processHeader The Workflow process header
187: */
188: public WorkflowProcess(String id, String name, XPDLPackage pkg,
189: ProcessHeader processHeader) {
190:
191: super (_indexedPropertyNames, _indexedPropertyValues, id, name);
192: setProcessHeader(processHeader);
193: _pkg = pkg;
194: }
195:
196: public void accept(PackageVisitor visitor) {
197: visitor.visit(this );
198: super .accept(visitor);
199: for (int i = 0; i < _formalParameter.length; i++)
200: _formalParameter[i].accept(visitor);
201: for (int i = 0; i < _activitySet.length; i++)
202: _activitySet[i].accept(visitor);
203: for (int i = 0; i < _activity.length; i++)
204: _activity[i].accept(visitor);
205: for (int i = 0; i < _transition.length; i++)
206: _transition[i].accept(visitor);
207: }
208:
209: public Trigger getTrigger() {
210: return _trigger;
211: }
212:
213: public void setTrigger(Trigger trigger) {
214: _trigger = trigger;
215: }
216:
217: /**
218: * Get the workflow process access level.
219: *
220: * @return The access level
221: */
222:
223: public AccessLevel getAccessLevel() {
224: return _accessLevel;
225: }
226:
227: /**
228: * Set the workflow process access level.
229: *
230: * @param accessLevel The access level
231: */
232: public void setAccessLevel(AccessLevel accessLevel) {
233: _accessLevel = accessLevel;
234: }
235:
236: public void add(Activity activity) throws PropertyVetoException {
237: _activity = (Activity[]) add(ACTIVITY_IDX, activity);
238: }
239:
240: public void remove(Activity activity) throws PropertyVetoException {
241: _activity = (Activity[]) remove(ACTIVITY_IDX, activity);
242: }
243:
244: public Activity[] getActivity() {
245: return (Activity[]) get(ACTIVITY_IDX);
246: }
247:
248: public Activity getActivity(int i) {
249: return _activity[i];
250: }
251:
252: public Activity getActivity(String id) {
253: if (_activity != null) {
254: for (int i = 0; i < _activity.length; i++) {
255: Activity activity = _activity[i];
256: if (activity.getId().equals(id))
257: return activity;
258: }
259: }
260: return null;
261: }
262:
263: public void setActivity(Activity[] activities)
264: throws PropertyVetoException {
265:
266: set(ACTIVITY_IDX,
267: _activity = activities == null ? EMPTY_ACTIVITY
268: : activities);
269: }
270:
271: public void setActivity(int i, Activity activity)
272: throws PropertyVetoException {
273:
274: set(ACTIVITY_IDX, i, activity);
275: }
276:
277: public void add(ActivitySet activitySet)
278: throws PropertyVetoException {
279: _activitySet = (ActivitySet[]) add(ACTIVITY_SET_IDX,
280: activitySet);
281: }
282:
283: public void remove(ActivitySet activitySet)
284: throws PropertyVetoException {
285: _activitySet = (ActivitySet[]) remove(ACTIVITY_SET_IDX,
286: activitySet);
287: }
288:
289: public ActivitySet[] getActivitySet() {
290: return (ActivitySet[]) get(ACTIVITY_SET_IDX);
291: }
292:
293: public ActivitySet getActivitySet(int i) {
294: return _activitySet[i];
295: }
296:
297: public ActivitySet getActivitySet(String id) {
298: if (_activitySet != null) {
299: for (int i = 0; i < _activitySet.length; i++) {
300: ActivitySet as = _activitySet[i];
301: if (as.getId().equals(id))
302: return as;
303: }
304: }
305: return null;
306: }
307:
308: public void setActivitySet(ActivitySet[] activitySet)
309: throws PropertyVetoException {
310:
311: set(ACTIVITY_SET_IDX,
312: _activitySet = activitySet == null ? EMPTY_ACTIVITY_SET
313: : activitySet);
314: }
315:
316: public void setActivitySet(int i, ActivitySet activitySet)
317: throws PropertyVetoException {
318:
319: set(ACTIVITY_SET_IDX, i, activitySet);
320: }
321:
322: public String getCompletionStrategy() {
323: return _completionStrategy;
324: }
325:
326: public void setCompletionStrategy(String completionStrategy) {
327: _completionStrategy = completionStrategy;
328: }
329:
330: public void add(FormalParameter formalParameter)
331: throws PropertyVetoException {
332:
333: _formalParameter = (FormalParameter[]) add(
334: FORMAL_PARAMETER_IDX, formalParameter);
335: }
336:
337: public void remove(FormalParameter formalParameter)
338: throws PropertyVetoException {
339:
340: _formalParameter = (FormalParameter[]) remove(
341: FORMAL_PARAMETER_IDX, formalParameter);
342: }
343:
344: public FormalParameter[] getFormalParameter() {
345: return (FormalParameter[]) get(FORMAL_PARAMETER_IDX);
346: }
347:
348: public FormalParameter getFormalParameter(int i) {
349: return _formalParameter[i];
350: }
351:
352: public FormalParameter getFormalParameter(String id) {
353: if (_formalParameter != null) {
354: for (int i = 0; i < _formalParameter.length; i++) {
355: FormalParameter fp = _formalParameter[i];
356: if (fp.getId().equals(id))
357: return fp;
358: }
359: }
360: return null;
361: }
362:
363: public void setFormalParameter(FormalParameter[] formalParameters)
364: throws PropertyVetoException {
365:
366: set(
367: FORMAL_PARAMETER_IDX,
368: _formalParameter = formalParameters == null ? EMPTY_FORMAL_PARM
369: : formalParameters);
370: }
371:
372: public void setFormalParameter(int i,
373: FormalParameter formalParameter)
374: throws PropertyVetoException {
375:
376: set(FORMAL_PARAMETER_IDX, i, formalParameter);
377: }
378:
379: public XPDLPackage getPackage() {
380: return _pkg;
381: }
382:
383: public void setPackage(XPDLPackage pkg) {
384: _pkg = pkg;
385: }
386:
387: public String getPackageId() {
388: return _pkg == null ? null : _pkg.getId();
389: }
390:
391: public String getProcessDefinitionId() {
392: return getId();
393: }
394:
395: public ProcessHeader getProcessHeader() {
396: return _processHeader;
397: }
398:
399: public void setProcessHeader(ProcessHeader processHeader) {
400: if (processHeader == null) {
401: throw new IllegalArgumentException(
402: "ProcessHeader must not be null");
403: }
404:
405: _processHeader = processHeader;
406: }
407:
408: public int getState() {
409: return _state;
410: }
411:
412: public void setState(int state) {
413: _state = state;
414: }
415:
416: public void add(Transition transition) throws PropertyVetoException {
417: _transition = (Transition[]) add(TRANSITION_IDX, transition);
418: }
419:
420: public void remove(Transition transition)
421: throws PropertyVetoException {
422: _transition = (Transition[]) remove(TRANSITION_IDX, transition);
423: }
424:
425: public Transition[] getTransition() {
426: return (Transition[]) get(TRANSITION_IDX);
427: }
428:
429: public Transition getTransition(int i) {
430: return _transition[i];
431: }
432:
433: public Transition getTransition(String id) {
434: if (_transition != null) {
435: for (int i = 0; i < _transition.length; i++) {
436: Transition t = _transition[i];
437: if (t.getId().equals(id))
438: return t;
439: }
440: }
441: return null;
442: }
443:
444: public void setTransition(Transition[] transitions)
445: throws PropertyVetoException {
446:
447: set(TRANSITION_IDX,
448: _transition = transitions == null ? EMPTY_TRANSITION
449: : transitions);
450: }
451:
452: public void setTransition(int i, Transition transition)
453: throws PropertyVetoException {
454:
455: set(TRANSITION_IDX, i, transition);
456: }
457:
458: public void setPkg(XPDLPackage pkg) {
459: _pkg = pkg;
460: }
461:
462: public void resolveReferences() {
463: resolveActivitySets(getActivitySet(), getActivity(), true);
464: resolveTransitions(getActivitySet(), getActivity(),
465: getTransition());
466: }
467:
468: public String toString() {
469: return "WorkflowProcess[id=" + getId() + ", name=" + getName()
470: + ']';
471: }
472: }
|