KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > za > co > csir > icomtek > workflow > WorkflowEvaluator


1 package za.co.csir.icomtek.workflow;
2
3 import java.util.HashMap JavaDoc;
4 import java.util.List JavaDoc;
5 import java.util.Enumeration JavaDoc;
6 import java.util.Iterator JavaDoc;
7 import java.util.Collection JavaDoc;
8
9 import java.io.InputStream JavaDoc;
10 import java.io.ByteArrayInputStream JavaDoc;
11 import java.io.InputStreamReader JavaDoc;
12 import java.io.FileReader JavaDoc;
13 import java.io.FileInputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.File JavaDoc;
16
17 import org.apache.commons.beanutils.PropertyUtils;
18
19 import za.co.csir.icomtek.workflow.factories.WorkflowFinderFactory;
20 import za.co.csir.icomtek.workflow.handlers.ActionHandler;
21 import za.co.csir.icomtek.workflow.handlers.ComparatorHandler;
22 import za.co.csir.icomtek.workflow.handlers.RulesHandler;
23 import za.co.csir.icomtek.workflow.interfaces.WorkflowContext;
24 import za.co.csir.icomtek.workflow.model.*;
25
26 public class WorkflowEvaluator {
27
28     private static HashMap JavaDoc workflows = new HashMap JavaDoc();
29     
30     static {
31         try {
32             List JavaDoc flows = WorkflowFinderFactory.instance()
33                 .getWorkflowFinder().getAllWorkflows();
34             for (Iterator JavaDoc it = flows.iterator(); it.hasNext(); ) {
35                 Workflow pw = (Workflow)it.next();
36                 workflows.put(pw.getName(), pw);
37                 try {
38                     ComparatorHandler.registerComparators(pw.getComparatorAsReference());
39                 } catch (Exception JavaDoc e) {
40                     e.printStackTrace();
41                     throw new RuntimeException JavaDoc("The comparator does not exist");
42                 }
43             }
44         } catch (Exception JavaDoc e) {
45             System.err.println("<< constructor, unable to load the xml");
46             e.printStackTrace();
47         }
48     }
49
50     /**
51      * This will return all the workflows that the evaluator knows about
52      */

53     public static Collection JavaDoc getAllRegisteredWorkflows () {
54         return workflows.values();
55     }
56
57     /**
58      * This is a convienience method to get the workflow object model for
59      * a named workflow.
60      *
61      * @param workflowName uniquely identifies a workflow
62      * @return is the Workflow object representing the workflow or null
63      * if the workflow does not exist
64      */

65     public static Workflow getWorkflow (String JavaDoc workflowName) {
66         return (Workflow)workflows.get(workflowName);
67     }
68
69     /**
70      * This is a convience method to find out the initial state on a workflow
71      *
72      * @param workflowName uniquely identifies a workflow
73      * @return is the default/initial state for the workflow or null if the
74      * workflow is not found
75      */

76     public static State getDefaultStateForWorkflow (String JavaDoc workflowName) {
77         State retVal = null;
78         Workflow pw = getWorkflow(workflowName);
79         if (pw != null) {
80             for (Enumeration JavaDoc e = pw.enumerateState(); e.hasMoreElements(); ) {
81                 State state = (State)e.nextElement();
82                 if (state.getStartState()) {
83                     retVal = state;
84                 }
85             }
86         }
87         return retVal;
88     }
89
90     /**
91      * This is a convienience method to get the state object model for
92      * a named workflow and state.
93      *
94      * @param workflowName uniquely identifies a workflow
95      * @param stateName uniquely identifies a state within the workflow
96      * @return is the State object from the workflow or null if either the
97      * workflow or the state does not exist
98      */

99     public static State getState (String JavaDoc workflowName, String JavaDoc stateName)
100         throws Exception JavaDoc
101     {
102         return retrieveStateByName(stateName, workflowName);
103     }
104
105     /**
106      * This method will take a current state and return the state we should
107      * be in after evaluation. This method will set the appropriate current
108      * state into the project as well as perform any actions specified if a
109      * transition is required.
110      *
111      * @param ctx is the context that will be populated and passed to module
112      * invocations.
113      */

114     public static State determineState (WorkflowContext ctx, WorkflowData wd)
115         throws Exception JavaDoc
116     {
117         State currentState = null;
118         State nextState = null;
119         boolean transitioning = false;
120         if (wd != null && wd.getCurrentState() == null
121             && wd.getWorkflowName() != null) {
122             // We are in the start state of a workflow
123
nextState = transition(ctx, null, wd);
124         } else {
125             currentState = retrieveStateByName(wd.getCurrentState(),
126                                                wd.getWorkflowName());
127             if (!currentState.hasStopState()) {
128                 // Evalute the rules in the current state to see if we transition
129
for (Enumeration JavaDoc e = currentState.enumerateStateTransition();
130                      e.hasMoreElements() && !transitioning; ) {
131                     StateTransition st = (StateTransition)e.nextElement();
132                     transitioning = RulesHandler.evaluateRules(st.getRules(),
133                                                                ctx);
134                     if (transitioning) {
135                         nextState = transition(ctx, st, wd);
136                     }
137                 }
138             }
139         }
140         return (nextState == null) ? currentState : nextState;
141     }
142
143     public static boolean isModuleViewableForState (WorkflowContext ctx,
144                                                     WorkflowData wd,
145                                                     String JavaDoc moduleName)
146         throws Exception JavaDoc
147     {
148         boolean retVal = false;
149         Module currentModule = new Module();
150         currentModule.setName(moduleName);
151         if (wd != null) {
152             State state = retrieveStateByName(wd.getCurrentState().trim(),
153                                               wd.getWorkflowName().trim());
154             if (state != null) {
155                 retVal = state.getVisibleModules()
156                     .getModuleAsReference().contains(currentModule);
157             }
158         }
159         return retVal;
160     }
161
162     public static void registerWorkflow (Workflow pw) {
163         workflows.put(pw.getName(), pw);
164     }
165
166     public static void deregisterWorkflow (String JavaDoc workflowName) {
167         workflows.remove(workflowName);
168     }
169
170     private static State retrieveStateByName(String JavaDoc stateName,
171                                              String JavaDoc workflowName)
172     {
173         State retVal = null;
174         System.err.println("<< workflows size: "+workflows.size());
175         Workflow pw =
176             (Workflow)workflows.get(workflowName);
177         if (pw != null) {
178             for (Enumeration JavaDoc e = pw.enumerateState(); e.hasMoreElements(); ) {
179                 State state = (State)e.nextElement();
180                 if (stateName == null && state.hasStartState()) {
181                     retVal = state;
182                     break;
183                 } else if (state.getName().equals(stateName)) {
184                     retVal = state;
185                     break;
186                 }
187             }
188             if (retVal == null) {
189                 throw new RuntimeException JavaDoc("The state, " + stateName
190                                                  + "does not exist for "
191                                                  + "project workflow, "
192                                                  + pw.getName());
193             }
194         } else {
195             throw new RuntimeException JavaDoc("workflow, "
196                                              + workflowName +
197                                              " does not exist");
198         }
199         return retVal;
200     }
201
202     /**
203      * Returns the contents of the file in a byte array
204      * @param file File this method should read
205      * @return byte[] Returns a byte[] array of the contents of the file
206      */

207     private static byte[] getBytesFromFile(File JavaDoc file) throws IOException JavaDoc {
208
209         InputStream JavaDoc is = new FileInputStream JavaDoc(file);
210         System.out.println("\nDEBUG: FileInputStream is " + file);
211
212         // Get the size of the file
213
long length = file.length();
214         System.out.println("DEBUG: Length of " + file + " is " + length + "\n");
215
216         /*
217          * You cannot create an array using a long type. It needs to be an int
218          * type. Before converting to an int type, check to ensure that file is
219          * not loarger than Integer.MAX_VALUE;
220          */

221         if (length > Integer.MAX_VALUE) {
222             System.out.println("File is too large to process");
223             return null;
224         }
225
226         // Create the byte array to hold the data
227
byte[] bytes = new byte[(int)length];
228
229         // Read in the bytes
230
int offset = 0;
231         int numRead = 0;
232         while ( (offset < bytes.length)
233                 &&
234                 ( (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) ) {
235
236             offset += numRead;
237
238         }
239
240         // Ensure all the bytes have been read in
241
if (offset < bytes.length) {
242             throw new IOException JavaDoc("Could not completely read file " + file.getName());
243         }
244
245         is.close();
246         return bytes;
247
248     }
249
250     /**
251      * Use this to perform a manual state transition
252      */

253     public static State transition (WorkflowContext ctx, StateTransition st,
254                                     WorkflowData wd)
255         throws Exception JavaDoc
256     {
257         return transition(ctx, st, wd, true);
258     }
259
260     /**
261      * Use this to perform a manual state transition. You can transtion while
262      * bypassing actions by setting performActions to false
263      */

264     public static State transition (WorkflowContext ctx, StateTransition st,
265                                     WorkflowData wd, boolean performActions)
266         throws Exception JavaDoc
267     {
268         State nextState = null;
269         if (st == null) {
270             nextState = retrieveStateByName(null, wd.getWorkflowName());
271         } else {
272             nextState = retrieveStateByName(st.getDestination(),
273                                             wd.getWorkflowName());
274         }
275         System.err.println("<< transitioning to state: "
276                            + nextState.getName());
277         wd.setCurrentState(nextState.getName());
278         wd.setCurrentStateDescription(nextState.getDescription());
279         
280         if (st != null) {
281             // Perform exit transition actions from current state
282
if (performActions) {
283                 ActionHandler.performActions(ctx, st);
284             }
285         }
286         
287         // Perform entry state actions
288
if (performActions) {
289             ActionHandler.performActions(ctx, nextState);
290         }
291         
292         // Make sure we don't just need to breeze through the next state
293
return determineState(ctx, wd);
294     }
295
296 }
297
Popular Tags