KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lenya > workflow > impl > WorkflowInstanceImpl


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17
18 /* $Id: WorkflowInstanceImpl.java 42837 2004-04-13 22:04:35Z joerg $ */
19
20 package org.apache.lenya.workflow.impl;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30
31 import org.apache.lenya.workflow.Action;
32 import org.apache.lenya.workflow.BooleanVariable;
33 import org.apache.lenya.workflow.BooleanVariableInstance;
34 import org.apache.lenya.workflow.Event;
35 import org.apache.lenya.workflow.Situation;
36 import org.apache.lenya.workflow.State;
37 import org.apache.lenya.workflow.Transition;
38 import org.apache.lenya.workflow.Workflow;
39 import org.apache.lenya.workflow.WorkflowException;
40 import org.apache.lenya.workflow.WorkflowInstance;
41 import org.apache.lenya.workflow.WorkflowListener;
42 import org.apache.log4j.Category;
43
44
45 /**
46  * Implementation of a workflow instance.
47  */

48 public abstract class WorkflowInstanceImpl implements WorkflowInstance {
49     
50     private static final Category log = Category.getInstance(WorkflowInstanceImpl.class);
51     
52     /**
53      * Creates a new instance of WorkflowInstanceImpl.
54      */

55     protected WorkflowInstanceImpl() {
56     }
57
58     private WorkflowImpl workflow;
59
60     /**
61      * Returns the workflow object of this instance.
62      * @return A workflow object.
63      */

64     public Workflow getWorkflow() {
65         return getWorkflowImpl();
66     }
67
68     /**
69      * Returns the workflow object of this instance.
70      * @return A workflow object.
71      */

72     protected WorkflowImpl getWorkflowImpl() {
73         return workflow;
74     }
75
76     /** Returns the events that can be invoked in a certain situation.
77      * @param situation The situation to check.
78      * @return The events that can be invoked.
79      * @throws WorkflowException when something went wrong.
80      */

81     public Event[] getExecutableEvents(Situation situation) throws WorkflowException {
82         
83         if (log.isDebugEnabled()) {
84             log.debug("Resolving executable events");
85         }
86         
87         Transition[] transitions = getWorkflow().getLeavingTransitions(getCurrentState());
88         Set JavaDoc executableEvents = new HashSet JavaDoc();
89
90         for (int i = 0; i < transitions.length; i++) {
91             if (transitions[i].canFire(situation, this)) {
92                 executableEvents.add(transitions[i].getEvent());
93                 if (log.isDebugEnabled()) {
94                     log.debug(" [" + transitions[i].getEvent() + "] can fire.");
95                 }
96             }
97             else {
98                 if (log.isDebugEnabled()) {
99                     log.debug(" [" + transitions[i].getEvent() + "] can not fire.");
100                 }
101             }
102         }
103
104         if (log.isDebugEnabled()) {
105             log.debug(" Resolving executable events completed.");
106         }
107         
108         return (Event[]) executableEvents.toArray(new Event[executableEvents.size()]);
109     }
110
111     /** Invoke an event on this workflow instance.
112      * @param situation The situation when the event was invoked.
113      * @param event The event that was invoked.
114      * @throws WorkflowException when the event may not be invoked.
115      */

116     public void invoke(Situation situation, Event event)
117         throws WorkflowException {
118         if (!Arrays.asList(getExecutableEvents(situation)).contains(event)) {
119             throw new WorkflowException("The event '" + event +
120                 "' cannot be invoked in the situation '" + situation + "'.");
121         }
122
123         fire(getNextTransition(event));
124
125         for (Iterator JavaDoc iter = listeners.iterator(); iter.hasNext();) {
126             WorkflowListener listener = (WorkflowListener) iter.next();
127             listener.transitionFired(this, situation, event);
128         }
129     }
130
131     /**
132      * Returns the transition that would fire for a given event.
133      * @param event The event.
134      * @return A transition.
135      * @throws WorkflowException if no single transition would fire.
136      */

137     protected TransitionImpl getNextTransition(Event event) throws WorkflowException {
138         TransitionImpl nextTransition = null;
139         Transition[] transitions = getWorkflow().getLeavingTransitions(getCurrentState());
140
141         for (int i = 0; i < transitions.length; i++) {
142             if (transitions[i].getEvent().equals(event)) {
143                 
144                 if (nextTransition != null) {
145                     throw new WorkflowException("More than one transition found for event [" + event + "]!");
146                 }
147                 
148                 nextTransition = (TransitionImpl) transitions[i];
149             }
150         }
151         
152         if (nextTransition == null) {
153             throw new WorkflowException("No transition found for event [" + event + "]!");
154         }
155         
156         return nextTransition;
157     }
158
159     /**
160      * Invokes a transition.
161      * @param transition The transition to invoke.
162      * @throws WorkflowException if something goes wrong.
163      */

164     protected void fire(TransitionImpl transition) throws WorkflowException {
165         Action[] actions = transition.getActions();
166
167         for (int i = 0; i < actions.length; i++) {
168             actions[i].execute(this);
169         }
170
171         setCurrentState(transition.getDestination());
172     }
173
174     private State currentState;
175
176     /**
177      * Sets the current state of this instance.
178      * @param state The state to set.
179      */

180     protected void setCurrentState(State state) {
181         this.currentState = state;
182     }
183
184     /** Returns the current state of this WorkflowInstance.
185      * @return A state object.
186      */

187     public State getCurrentState() {
188         return currentState;
189     }
190
191     /**
192      * Sets the workflow of this instance.
193      * @param workflow A workflow object.
194      */

195     protected void setWorkflow(WorkflowImpl workflow) {
196         this.workflow = workflow;
197         setCurrentState(getWorkflow().getInitialState());
198         initVariableInstances();
199     }
200
201     /**
202      * Sets the workflow of this instance.
203      * @param workflowName The identifier of the workflow.
204      * @throws WorkflowException if something goes wrong.
205      */

206     protected void setWorkflow(String JavaDoc workflowName) throws WorkflowException {
207         setWorkflow(getWorkflow(workflowName));
208     }
209
210     /**
211      * Factory method to create a workflow object for a given identifier.
212      * @param workflowName The workflow identifier.
213      * @return A workflow object.
214      * @throws WorkflowException when the workflow could not be created.
215      */

216     protected abstract WorkflowImpl getWorkflow(String JavaDoc workflowName)
217         throws WorkflowException;
218
219     /**
220      * Returns a workflow state for a given name.
221      * @param id The state id.
222      * @return A workflow object.
223      * @throws WorkflowException when the state was not found.
224      */

225     protected State getState(String JavaDoc id) throws WorkflowException {
226         return getWorkflowImpl().getState(id);
227     }
228
229     private Map JavaDoc variableInstances = new HashMap JavaDoc();
230
231     /**
232      * Initializes the variable instances in the initial state.
233      */

234     protected void initVariableInstances() {
235         variableInstances.clear();
236
237         BooleanVariable[] variables = getWorkflowImpl().getVariables();
238
239         for (int i = 0; i < variables.length; i++) {
240             BooleanVariableInstance instance = new BooleanVariableInstanceImpl();
241             instance.setValue(variables[i].getInitialValue());
242             variableInstances.put(variables[i], instance);
243         }
244     }
245
246     /**
247      * Returns the corresponding instance of a workflow variable.
248      * @param variable A variable of the corresponding workflow.
249      * @return A variable instance object.
250      * @throws WorkflowException when the variable instance was not found.
251      */

252     protected BooleanVariableInstance getVariableInstance(BooleanVariable variable)
253         throws WorkflowException {
254         if (!variableInstances.containsKey(variable)) {
255             throw new WorkflowException("No instance for variable '" + variable.getName() + "'!");
256         }
257
258         return (BooleanVariableInstance) variableInstances.get(variable);
259     }
260
261     /**
262      * @see org.apache.lenya.workflow.WorkflowInstance#getValue(java.lang.String)
263      */

264     public boolean getValue(String JavaDoc variableName) throws WorkflowException {
265         BooleanVariable variable = getWorkflowImpl().getVariable(variableName);
266         BooleanVariableInstance instance = getVariableInstance(variable);
267
268         return instance.getValue();
269     }
270
271     /**
272      * Sets the value of a state variable.
273      * @param variableName The variable name.
274      * @param value The value to set.
275      * @throws WorkflowException when the variable was not found.
276      */

277     protected void setValue(String JavaDoc variableName, boolean value)
278         throws WorkflowException {
279         BooleanVariable variable = getWorkflowImpl().getVariable(variableName);
280         BooleanVariableInstance instance = getVariableInstance(variable);
281         instance.setValue(value);
282     }
283
284     private List JavaDoc listeners = new ArrayList JavaDoc();
285
286     /**
287      * @see org.apache.lenya.workflow.WorkflowInstance#addWorkflowListener(org.apache.lenya.workflow.WorkflowListener)
288      */

289     public void addWorkflowListener(WorkflowListener listener) {
290         if (!listeners.contains(listener)) {
291             listeners.add(listener);
292         }
293     }
294
295     /**
296      * @see org.apache.lenya.workflow.WorkflowInstance#removeWorkflowListener(org.apache.lenya.workflow.WorkflowListener)
297      */

298     public void removeWorkflowListener(WorkflowListener listener) {
299         listeners.remove(listener);
300     }
301
302     /**
303      * @see org.apache.lenya.workflow.WorkflowInstance#isSynchronized(org.apache.lenya.workflow.Event)
304      */

305     public boolean isSynchronized(Event event) throws WorkflowException {
306         Transition nextTransition = getNextTransition(event);
307         return nextTransition.isSynchronized();
308     }
309
310 }
311
Popular Tags