KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > shark > ThreadedToolAgentManager


1 /*
2  * $Id: ThreadedToolAgentManager.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  */

5 package org.enhydra.shark;
6
7 import java.util.List JavaDoc;
8 import java.util.ArrayList JavaDoc;
9 import java.util.Properties JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.HashMap JavaDoc;
13 import java.util.Collection JavaDoc;
14
15 import org.enhydra.shark.api.internal.working.ToolAgentManager;
16 import org.enhydra.shark.api.internal.working.WfActivityInternal;
17 import org.enhydra.shark.api.internal.working.CallbackUtilities;
18 import org.enhydra.shark.api.internal.working.WfProcessInternal;
19 import org.enhydra.shark.api.internal.toolagent.AppParameter;
20 import org.enhydra.shark.api.internal.toolagent.SessionHandle;
21 import org.enhydra.shark.api.internal.toolagent.ToolAgent;
22 import org.enhydra.shark.api.internal.toolagent.ConnectFailed;
23 import org.enhydra.shark.api.internal.toolagent.ToolAgentGeneralException;
24 import org.enhydra.shark.api.internal.appmappersistence.ApplicationMap;
25 import org.enhydra.shark.api.internal.appmappersistence.ApplicationMappingManager;
26 import org.enhydra.shark.api.SharkTransaction;
27 import org.enhydra.shark.api.RootException;
28 import org.enhydra.shark.api.TransactionException;
29 import org.enhydra.shark.api.ApplicationMappingTransaction;
30 import org.enhydra.shark.api.client.wfbase.BaseException;
31 import org.enhydra.shark.api.client.wfmodel.InvalidData;
32 import org.enhydra.shark.api.client.wfmodel.UpdateNotAllowed;
33 import org.enhydra.shark.api.client.wfmodel.CannotComplete;
34 import org.enhydra.shark.xpdl.elements.Tool;
35 import org.enhydra.shark.xpdl.elements.WorkflowProcess;
36 import org.enhydra.shark.xpdl.elements.Application;
37 import org.enhydra.shark.xpdl.elements.ActualParameters;
38 import org.enhydra.shark.xpdl.elements.FormalParameters;
39 import org.enhydra.shark.xpdl.elements.FormalParameter;
40 import org.enhydra.shark.xpdl.elements.ActualParameter;
41 import org.enhydra.shark.xpdl.XMLComplexChoice;
42 import org.enhydra.shark.xpdl.XMLComplexElement;
43
44 /**
45  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
46  * @version $Rev: 5462 $
47  * @since 3.2
48  */

49 public class ThreadedToolAgentManager implements ToolAgentManager {
50
51     private final static String JavaDoc TOOL_AGENT_PREFIX = "ToolAgent.";
52     private final static String JavaDoc DEFAULT_TOOL_AGENT = "DefaultToolAgent";
53     private final static long APP_STATUS_INVALID = -1;
54     private static List JavaDoc toolMonitors = new ArrayList JavaDoc();
55
56     private String JavaDoc defaultToolAgentClassName = null;
57     private List JavaDoc toolAgents = null;
58     private CallbackUtilities cus = null;
59
60     ThreadedToolAgentManager() {
61         this.cus = SharkEngineManager.getInstance().getCallbackUtilities();
62         createToolAgentList();
63     }
64
65     public void executeActivity(SharkTransaction t, WfActivityInternal act) throws BaseException, ToolAgentGeneralException {
66         ThreadedToolAgentManager.toolMonitors.add(new ToolRunnerManager(t, act));
67     }
68
69     /**
70      * Returns all tool agents registered at nameserver.
71      */

72     public String JavaDoc[] getDefinedToolAgents() {
73         String JavaDoc[] ata = new String JavaDoc[toolAgents.size()];
74         toolAgents.toArray(ata);
75         return ata;
76     }
77
78     private void createToolAgentList() {
79         this.toolAgents = new ArrayList JavaDoc();
80         String JavaDoc taName = null;
81         String JavaDoc className = null;
82         Properties JavaDoc props = cus.getProperties();
83
84         Iterator JavaDoc it = props.entrySet().iterator();
85         while (it.hasNext()) {
86             try {
87                 Map.Entry JavaDoc me = (Map.Entry JavaDoc) it.next();
88                 taName = me.getKey().toString();
89                 if (taName.startsWith(TOOL_AGENT_PREFIX)) {
90                     taName = taName.substring(TOOL_AGENT_PREFIX.length());
91                     className = me.getValue().toString();
92                     toolAgents.add(className);
93                 }
94             } catch (Throwable JavaDoc ex) {
95                 //ex.printStackTrace();
96
cus.error("ToolAgentManager -> Creation of Tool Agent " + taName + " from clas " + className + " failed !!!");
97             }
98         }
99
100         // setting default tool agent
101
try {
102             defaultToolAgentClassName = (String JavaDoc) props.get(DEFAULT_TOOL_AGENT);
103
104         } catch (Throwable JavaDoc ex) {
105             cus.error("ToolAgentManager -> Creation of Default Tool Agent failed !!!");
106         }
107     }
108
109     public static int howManyActivitiesRunning() {
110         return ThreadedToolAgentManager.toolMonitors.size();
111     }
112
113     private synchronized static void removeToolMonitor(ToolRunnerManager monitor) {
114         ThreadedToolAgentManager.toolMonitors.remove(monitor);
115     }
116
117     class ToolContext {
118
119         private Tool tool;
120         private Application app;
121         private ApplicationMap appMap;
122         private String JavaDoc packageId;
123         private String JavaDoc processId;
124         private String JavaDoc activityId;
125         private String JavaDoc resource;
126         private AppParameter[] params;
127
128         public ToolContext(Tool tool, Application app, ApplicationMap appMap, String JavaDoc pkgId,
129                 String JavaDoc procId, String JavaDoc actId, String JavaDoc resource, AppParameter[] params) {
130             this.tool = tool;
131             this.app = app;
132             this.appMap = appMap;
133             this.packageId = pkgId;
134             this.processId = procId;
135             this.activityId = actId;
136             this.resource = resource;
137             this.params = params;
138         }
139
140         public Tool getTool() {
141             return tool;
142         }
143
144         public Application getApplication() {
145             return app;
146         }
147
148         public ApplicationMap getApplicationMap() {
149             return appMap;
150         }
151
152         public String JavaDoc getPackageId() {
153             return packageId;
154         }
155
156         public String JavaDoc getProcessId() {
157             return processId;
158         }
159
160         public String JavaDoc getActivityId() {
161             return activityId;
162         }
163
164         public String JavaDoc getActivityResource() {
165             return resource;
166         }
167
168         public AppParameter[] getParameters() {
169             return params;
170         }
171     }
172
173     class ToolRunnerManager implements Runnable JavaDoc {
174
175         private String JavaDoc packageKey;
176         private String JavaDoc packageVer;
177         private String JavaDoc processKey;
178         private String JavaDoc activityKey;
179         private String JavaDoc resource;
180         private List JavaDoc tools;
181         private Map JavaDoc context;
182
183         private Map JavaDoc toolResults;
184         private List JavaDoc runners;
185         private Thread JavaDoc thread;
186         private boolean isRunning = false;
187
188         public ToolRunnerManager(SharkTransaction trans, WfActivityInternal activity) throws BaseException {
189             this.packageKey = activity.container(trans).package_id(trans);
190             this.packageVer = activity.container(trans).manager_version(trans);
191             this.processKey = activity.container(trans).key(trans);
192             this.packageKey = activity.container(trans).package_id(trans);
193             this.activityKey = activity.key(trans);
194             this.resource = activity.getResourceUsername(trans);
195             this.context = activity.process_context(trans);
196             this.tools = this.getTools(trans, activity);
197             this.toolResults = new HashMap JavaDoc();
198             this.runners = new ArrayList JavaDoc();
199
200             // start the thread
201
thread = new Thread JavaDoc(this);
202             thread.setDaemon(false);
203             thread.setName(this.getClass().getName());
204             thread.start();
205         }
206
207         private Collection JavaDoc getToolObjs(SharkTransaction trans, WfActivityInternal activity) throws BaseException {
208             WfProcessInternal pr = activity.container(trans);
209             WorkflowProcess wp = SharkUtilities.getWorkflowProcess(pr.manager(trans).package_id(trans),
210                     pr.manager_version(trans), pr.manager(trans).process_definition_id(trans));
211
212             return SharkUtilities.getActivityDefinition(trans, activity, wp,
213                     activity.block_activity(trans)).getTools().toCollection();
214         }
215
216         private List JavaDoc getTools(SharkTransaction trans, WfActivityInternal activity) throws BaseException {
217             Collection JavaDoc tools = getToolObjs(trans, activity);
218
219             List JavaDoc toolList = null;
220             if (tools != null) {
221                 toolList = new ArrayList JavaDoc();
222                 Iterator JavaDoc i = tools.iterator();
223                 while (i.hasNext()) {
224                     Tool tool = (Tool) i.next();
225                     String JavaDoc toolId = tool.getID();
226
227                     Application app = (Application) ((XMLComplexChoice) tool.get("Application")).getChoosen();
228                     ApplicationMap appMap = null;
229                     try {
230                         appMap = getApplicationMap(app, toolId);
231                     } catch (Exception JavaDoc e) {
232                         throw new BaseException(e);
233                     }
234
235                     AppParameter[] params = null;
236                     try {
237                         params = makeParameters(trans, tool, app);
238                     } catch (Exception JavaDoc e) {
239                         throw new BaseException(e);
240                     }
241                     ToolContext ctx = new ToolContext(tool, app, appMap, packageKey, processKey, activityKey, resource, params);
242                     toolList.add(ctx);
243                 }
244             }
245             return toolList;
246         }
247
248         private AppParameter[] makeParameters(SharkTransaction transaction, Tool tool, Application app) throws Exception JavaDoc {
249             // build up the parameters
250
List JavaDoc parameters = new ArrayList JavaDoc();
251
252             // the extended attributes are always the first parameter passed to tool agent
253
String JavaDoc appPStr = app.getExtendedAttributesString();
254             AppParameter param = new AppParameter("ExtendedAttributes", "ExtendedAttributes", AppParameter.MODE_IN, appPStr, String JavaDoc.class);
255             parameters.add(param);
256
257             ActualParameters aps = (ActualParameters) tool.get("ActualParameters");
258             FormalParameters fps = (FormalParameters) ((XMLComplexChoice) app.get("Choice")).getChoosen();
259             Map JavaDoc ctxMap = SharkUtilities.createContextMap(transaction, context, aps, fps, packageKey, packageVer);
260
261             Iterator JavaDoc itFps = fps.toCollection().iterator();
262             Iterator JavaDoc itAps = aps.toCollection().iterator();
263             while (itFps.hasNext() && itAps.hasNext()) {
264                 FormalParameter fp = (FormalParameter) itFps.next();
265                 ActualParameter ap = (ActualParameter) itAps.next();
266                 String JavaDoc fpMode = fp.get("Mode").toValue().toString();
267                 String JavaDoc fpId = fp.getID();
268                 Object JavaDoc paramVal = ctxMap.get(fpId);
269
270                 // JAWE's CLASSES DataField and FormalParameter RETURNS ITs
271
// Id ATTRIBUTE WHEN METHOD toString() is CALLED (when calling
272
// ap.toValue().toString(), it can be called toString() method of
273
// these two classes)
274
param = new AppParameter(ap.toValue().toString(), fpId, fpMode, paramVal, SharkUtilities.getJavaClass(fp));
275                 parameters.add(param);
276             }
277
278             return (AppParameter[]) parameters.toArray(new AppParameter[parameters.size()]);
279         }
280
281         private ApplicationMap getApplicationMap(Application app, String JavaDoc applicationId) throws Exception JavaDoc {
282             // find mapped procedure - but we can also live without mapping
283
// manager (but we can't without ToolAgentFactory
284
ApplicationMappingManager mm = SharkEngineManager.getInstance().getApplicationMapPersistenceManager();
285             ApplicationMap tad = null;
286             if (mm != null) {
287                 XMLComplexElement cOwn = app.getCollection().getOwner();
288                 boolean isProcessApp = (cOwn instanceof WorkflowProcess);
289                 ApplicationMappingTransaction t = null;
290                 try {
291                     t = SharkUtilities.createApplicationMappingTransaction();
292                     tad = SharkEngineManager.getInstance().getApplicationMapPersistenceManager().
293                             getApplicationMap(t, app.getPackage().get("Id").toString(),
294                                     ((isProcessApp) ? cOwn.get("Id").toString() : null), applicationId);
295                 } catch (RootException e) {
296                     throw e;
297                 } finally {
298                     SharkUtilities.releaseMappingTransaction(t);
299                 }
300             }
301
302             return tad;
303         }
304
305         public void run() {
306             this.isRunning = true;
307
308             // start the tools
309
Iterator JavaDoc ti = tools.iterator();
310             while (ti.hasNext()) {
311                 ToolContext tool = (ToolContext) ti.next();
312                 runners.add(new ToolRunner(tool));
313             }
314
315             // monitor the tools
316
while (isRunning) {
317                 // check tool status
318
Iterator JavaDoc ri = runners.iterator();
319                 while (ri.hasNext()) {
320                     ToolRunner runner = (ToolRunner) ri.next();
321                     if (!runner.isRunning()) {
322                         // check for errors
323
Throwable JavaDoc toolError = runner.getError();
324                         if (toolError != null) {
325                             // handle tool error
326
} else {
327                             // get the results
328
Map JavaDoc thisResult = runner.getResults();
329                             if (thisResult != null) {
330                                 toolResults.putAll(thisResult);
331                             }
332                         }
333                         // remove the runner from the waiting list
334
ri.remove();
335                     }
336                 }
337
338                 // sleep for a while then run again
339
try {
340                     Thread.sleep(5000);
341                 } catch (InterruptedException JavaDoc e) {
342                 }
343             }
344
345             // all tools finished - need a transaction and internal activity object
346
SharkTransaction trans = null;
347             WfActivityInternal act = null;
348
349             try {
350                 trans = SharkUtilities.createTransaction();
351                 act = SharkUtilities.getActivity(trans, processKey, activityKey);
352                 act.set_process_context(trans, toolResults);
353                 act.finish(trans);
354             } catch (TransactionException e) {
355                 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
356
} catch (BaseException e) {
357                 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
358
} catch (UpdateNotAllowed e) {
359                 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
360
} catch (InvalidData e) {
361                 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
362
} catch (CannotComplete e) {
363                 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
364
}
365
366             // clear out the reference in parent class
367
ThreadedToolAgentManager.removeToolMonitor(this);
368         }
369
370         class ToolRunner implements Runnable JavaDoc {
371
372             private Thread JavaDoc thread;
373             private ToolContext tool;
374
375             private boolean isRunning = false;
376             private Throwable JavaDoc error = null;
377             private Map JavaDoc results = null;
378
379             ToolRunner(ToolContext tool) {
380                 this.tool = tool;
381
382                 // run the tool
383
thread = new Thread JavaDoc(this);
384                 thread.setDaemon(false);
385                 thread.setName(this.getClass().getName());
386                 thread.start();
387             }
388
389             public void run() {
390                 this.isRunning = true;
391                 try {
392                     this.results = this.runTool(null);
393                 } catch (Exception JavaDoc e) {
394                     this.error = e;
395                 }
396                 this.isRunning = false;
397             }
398
399             public boolean isRunning() {
400                 return this.isRunning;
401             }
402
403             public Throwable JavaDoc getError() {
404                 return this.error;
405             }
406
407             public Map JavaDoc getResults() {
408                 return this.results;
409             }
410
411             private Map JavaDoc runTool(SharkTransaction transaction) throws Exception JavaDoc {
412                 // get the application to run
413
ApplicationMap tad = tool.getApplicationMap();
414
415                 // connect to the tool
416
String JavaDoc tacn = (tad != null) ? tad.getToolAgentClassName() : defaultToolAgentClassName;
417                 String JavaDoc uname = (tad != null) ? tad.getUsername() : "";
418                 String JavaDoc pwd = (tad != null) ? tad.getPassword() : "";
419                 String JavaDoc appN = (tad != null) ? tad.getApplicationName() : "";
420                 Integer JavaDoc appM = (tad != null) ? tad.getApplicationMode() : null;
421                 ToolAgent ta = SharkEngineManager.getInstance().getToolAgentFactory().createToolAgent(transaction, tacn);
422
423                 SessionHandle shandle = null;
424                 // try to connect to the tool agent
425
try {
426                     shandle = ta.connect(transaction, uname, pwd, cus.getProperty("enginename", "imaobihostrezube"), "");
427                 } catch (ConnectFailed cf) {
428                     cus.error("Activity[" + tool.getActivityId() + "] - connection to Tool agent " + tacn + " failed !");
429                     throw cf;
430                 }
431
432                 String JavaDoc assId = SharkUtilities.createAssignmentKey(tool.getActivityId(), resource);
433
434                 // invoke the application
435
ta.invokeApplication(transaction, shandle.getHandle(), appN, tool.getProcessId(), assId, tool.getParameters(), appM);
436
437                 // check the status
438
long appStatus = ta.requestAppStatus(transaction, shandle.getHandle(), tool.getProcessId(), assId, tool.getParameters());
439                 if (appStatus == APP_STATUS_INVALID) {
440                     ta.disconnect(transaction, shandle);
441                     throw new Exception JavaDoc();
442                 }
443                 ta.disconnect(transaction, shandle);
444
445                 // return the result parameters
446
AppParameter[] returnValues = tool.getParameters();
447                 Map JavaDoc newData = new HashMap JavaDoc();
448                 for (int i = 0; i < returnValues.length; i++) {
449                     if (returnValues[i].the_mode.equals(AppParameter.MODE_OUT) ||
450                             returnValues[i].the_mode.equals(AppParameter.MODE_INOUT)) {
451                         String JavaDoc name = returnValues[i].the_actual_name;
452                         Object JavaDoc value = returnValues[i].the_value;
453                         newData.put(name, value);
454                     }
455                 }
456
457                 return newData;
458             }
459         }
460     }
461 }
462
Popular Tags