KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencrx > kernel > layer > application > Workflows


1 /*
2  * ====================================================================
3  * Project: opencrx, http://www.opencrx.org/
4  * Name: $Id: Workflows.java,v 1.19 2006/03/27 23:40:09 wfro Exp $
5  * Description: openCRX SecureObject
6  * Revision: $Revision: 1.19 $
7  * Owner: CRIXP AG, Switzerland, http://www.crixp.com
8  * Date: $Date: 2006/03/27 23:40:09 $
9  * ====================================================================
10  *
11  * This software is published under the BSD license
12  * as listed below.
13  *
14  * Copyright (c) 2004-2005, CRIXP Corp., Switzerland
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  *
21  * * Redistributions of source code must retain the above copyright
22  * notice, this list of conditions and the following disclaimer.
23  *
24  * * Redistributions in binary form must reproduce the above copyright
25  * notice, this list of conditions and the following disclaimer in
26  * the documentation and/or other materials provided with the
27  * distribution.
28  *
29  * * Neither the name of CRIXP Corp. nor the names of the contributors
30  * to openCRX may be used to endorse or promote products derived
31  * from this software without specific prior written permission
32  *
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
35  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
36  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
39  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
41  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
43  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46  * POSSIBILITY OF SUCH DAMAGE.
47  *
48  * ------------------
49  *
50  * This product includes software developed by the Apache Software
51  * Foundation (http://www.apache.org/).
52  *
53  * This product includes software developed by contributors to
54  * openMDX (http://www.openmdx.org/)
55  */

56 package org.opencrx.kernel.layer.application;
57
58 import java.lang.reflect.Constructor JavaDoc;
59 import java.lang.reflect.InvocationTargetException JavaDoc;
60 import java.util.Date JavaDoc;
61 import java.util.HashMap JavaDoc;
62 import java.util.Iterator JavaDoc;
63 import java.util.List JavaDoc;
64 import java.util.Map JavaDoc;
65
66 import org.opencrx.kernel.generic.OpenCrxException;
67 import org.openmdx.base.accessor.jmi.cci.RefPackage_1_0;
68 import org.openmdx.base.exception.ServiceException;
69 import org.openmdx.base.text.format.DateFormat;
70 import org.openmdx.compatibility.base.dataprovider.cci.AttributeSelectors;
71 import org.openmdx.compatibility.base.dataprovider.cci.AttributeSpecifier;
72 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject;
73 import org.openmdx.compatibility.base.dataprovider.cci.DataproviderObject_1_0;
74 import org.openmdx.compatibility.base.dataprovider.cci.Dataprovider_1_0;
75 import org.openmdx.compatibility.base.dataprovider.cci.Orders;
76 import org.openmdx.compatibility.base.dataprovider.cci.RequestCollection;
77 import org.openmdx.compatibility.base.dataprovider.cci.ServiceHeader;
78 import org.openmdx.compatibility.base.dataprovider.cci.SystemAttributes;
79 import org.openmdx.compatibility.base.naming.Path;
80 import org.openmdx.compatibility.kernel.application.cci.Classes;
81 import org.openmdx.kernel.exception.BasicException;
82 import org.openmdx.model1.accessor.basic.cci.Model_1_0;
83
84 public class Workflows {
85
86     //-----------------------------------------------------------------------
87
public Workflows(
88         Model_1_0 model,
89         ServiceHeader header,
90         OpenCrxKernel_1 plugin,
91         Dataprovider_1_0 dataprovider,
92         RefPackage_1_0 rootPkg
93     ) throws ServiceException {
94         this.header = header;
95         this.delegation = new RequestCollection(
96             header,
97             dataprovider
98         );
99         this.plugin = plugin;
100         this.rootPkg = rootPkg;
101     }
102                 
103     //-------------------------------------------------------------------------
104
public DataproviderObject executeWorkflow(
105         DataproviderObject_1_0 userHome,
106         Path wfProcessIdentity,
107         Path targetObject,
108         String JavaDoc targetObjectXri,
109         String JavaDoc triggeredByEventId,
110         Path triggeredBySubscription,
111         Number JavaDoc triggeredByEventType
112     ) throws ServiceException {
113
114         // Workflow
115
if(wfProcessIdentity == null) {
116             throw new ServiceException(
117                 OpenCrxException.DOMAIN,
118                 OpenCrxException.WORKFLOW_MISSING_WORKFLOW,
119                 null,
120                 "Missing workflow"
121             );
122         }
123         DataproviderObject_1_0 wfProcess = this.delegation.addGetRequest(
124             wfProcessIdentity,
125             AttributeSelectors.ALL_ATTRIBUTES,
126             new AttributeSpecifier[]{}
127         );
128         String JavaDoc workflowName = (String JavaDoc)wfProcess.values("name").get(0);
129         boolean isSynchronous =
130             (wfProcess.values("isSynchronous").get(0) != null) &&
131             ((Boolean JavaDoc)wfProcess.values("isSynchronous").get(0)).booleanValue();
132
133         // Target
134
if((targetObject == null) && (targetObjectXri == null)) {
135             throw new ServiceException(
136                 OpenCrxException.DOMAIN,
137                 OpenCrxException.WORKFLOW_MISSING_TARGET,
138                 null,
139                 "Missing target object"
140             );
141         }
142         Path targetObjectIdentity = targetObject != null
143             ? targetObject
144             : new Path(targetObjectXri);
145         
146         // Create workflow process instance
147
DataproviderObject wfProcessInstance = new DataproviderObject(
148             userHome.path().getDescendant(
149                 new String JavaDoc[]{
150                     "wfProcessInstance",
151                     this.plugin.getUidAsString()
152                 }
153             )
154         );
155         wfProcessInstance.values(SystemAttributes.OBJECT_CLASS).add("org:opencrx:kernel:home1:WfProcessInstance");
156         wfProcessInstance.values("stepCounter").add(new Integer JavaDoc(1));
157         wfProcessInstance.values("process").add(wfProcess.path());
158         wfProcessInstance.values("targetObject").add(targetObjectIdentity.toXri());
159         // Start synchronous workflows immediately. Asynchronous workflows must be
160
// executed by external workflow engine
161
if(isSynchronous) {
162             wfProcessInstance.values("startedOn").add(DateFormat.getInstance().format(new Date JavaDoc()));
163             wfProcessInstance.values("lastActivityOn").add(DateFormat.getInstance().format(new Date JavaDoc()));
164         }
165         // Assert that a workflow instance is created at most once for a given eventId
166
try {
167             try {
168                 // Return wfProcessInstance if it exists, i.e. has same eventId
169
return new DataproviderObject(
170                     this.plugin.retrieveObjectFromDelegation(
171                         wfProcessInstance.path()
172                     )
173                 );
174             }
175             catch(ServiceException e) {
176                 this.delegation.addCreateRequest(
177                     wfProcessInstance
178                 );
179             }
180         }
181         catch(ServiceException e) {
182             new ServiceException(e).log();
183             throw new ServiceException(
184                 OpenCrxException.DOMAIN,
185                 OpenCrxException.WORKFLOW_CAN_NOT_CREATE_PROCESS_INSTANCE,
186                 new BasicException.Parameter[]{
187                     new BasicException.Parameter("param0", workflowName),
188                     new BasicException.Parameter("param1", e.getMessage())
189                 },
190                 "Can not create process instance"
191             );
192         }
193         
194         // Add parameters of executeWorkflow() operation to property set of WfProcessInstance
195
if(triggeredBySubscription != null) {
196             DataproviderObject property = new DataproviderObject(
197                 wfProcessInstance.path().getDescendant(new String JavaDoc[]{"property", this.plugin.getUidAsString()})
198             );
199             property.values(SystemAttributes.OBJECT_CLASS).add(
200                 "org:opencrx:kernel:base:UriProperty"
201             );
202             property.values("name").add(
203                 "triggeredBySubscription"
204             );
205             property.values("uriValue").add(
206                 triggeredBySubscription.toXri()
207             );
208             this.delegation.addCreateRequest(
209                 property
210             );
211         }
212         if(triggeredByEventType != null) {
213             DataproviderObject property = new DataproviderObject(
214                 wfProcessInstance.path().getDescendant(new String JavaDoc[]{"property", this.plugin.getUidAsString()})
215             );
216             property.values(SystemAttributes.OBJECT_CLASS).add(
217                 "org:opencrx:kernel:base:IntegerProperty"
218             );
219             property.values("name").add(
220                 "triggeredByEventType"
221             );
222             property.values("integerValue").add(
223                 triggeredByEventType
224             );
225             this.delegation.addCreateRequest(
226                 property
227             );
228         }
229         
230         // Execute workflow if synchronous
231
if(isSynchronous) {
232             // Execute (synchronous) workflow
233
SynchWorkflow_1_0 workflow = null;
234             Class JavaDoc workflowClass = null;
235             try {
236                 workflowClass = Classes.getApplicationClass(
237                     workflowName
238                 );
239             }
240             catch(ClassNotFoundException JavaDoc e) {
241                 new ServiceException(e).log();
242                 throw new ServiceException(
243                     OpenCrxException.DOMAIN,
244                     OpenCrxException.WORKFLOW_NO_IMPLEMENTATION,
245                     new BasicException.Parameter[]{
246                         new BasicException.Parameter("param0", workflowName),
247                         new BasicException.Parameter("param1", e.getMessage())
248                     },
249                     "implementation not found"
250                 );
251             }
252             // Look up constructor
253
Constructor JavaDoc workflowConstructor = null;
254             try {
255                 workflowConstructor = workflowClass.getConstructor(new Class JavaDoc[]{});
256             }
257             catch(NoSuchMethodException JavaDoc e) {
258                 new ServiceException(e).log();
259                 throw new ServiceException(
260                     OpenCrxException.DOMAIN,
261                     OpenCrxException.WORKFLOW_MISSING_CONSTRUCTOR,
262                     new BasicException.Parameter[]{
263                         new BasicException.Parameter("param0", workflowName),
264                         new BasicException.Parameter("param1", e.getMessage())
265                     },
266                     "missing constructor"
267                 );
268             }
269             // Instantiate workflow
270
try {
271                 workflow = (SynchWorkflow_1_0)workflowConstructor.newInstance(new Object JavaDoc[]{});
272             }
273             catch(InstantiationException JavaDoc e) {
274                 new ServiceException(e).log();
275                 throw new ServiceException(
276                     OpenCrxException.DOMAIN,
277                     OpenCrxException.WORKFLOW_CAN_NOT_INSTANTIATE,
278                     new BasicException.Parameter[]{
279                         new BasicException.Parameter("param0", workflowName),
280                         new BasicException.Parameter("param1", e.getMessage())
281                     },
282                     "can not instantiate"
283                 );
284             }
285             catch(IllegalAccessException JavaDoc e) {
286                 new ServiceException(e).log();
287                 throw new ServiceException(
288                     OpenCrxException.DOMAIN,
289                     OpenCrxException.WORKFLOW_ILLEGAL_ACCESS,
290                     new BasicException.Parameter[]{
291                         new BasicException.Parameter("param0", workflowName),
292                         new BasicException.Parameter("param1", e.getMessage())
293                     },
294                     "illegal access"
295                 );
296             }
297             catch(IllegalArgumentException JavaDoc e) {
298                 new ServiceException(e).log();
299                 throw new ServiceException(
300                     OpenCrxException.DOMAIN,
301                     OpenCrxException.WORKFLOW_ILLEGAL_ARGUMENT,
302                     new BasicException.Parameter[]{
303                         new BasicException.Parameter("param0", workflowName),
304                         new BasicException.Parameter("param1", e.getMessage())
305                     },
306                     "illegal argument"
307                 );
308             }
309             catch(InvocationTargetException JavaDoc e) {
310 // new ServiceException(e.getTargetException()).log();
311
throw new ServiceException(
312                     OpenCrxException.DOMAIN,
313                     OpenCrxException.WORKFLOW_CAN_NOT_INVOKE,
314                     new BasicException.Parameter[]{
315                         new BasicException.Parameter("param0", workflowName),
316                         new BasicException.Parameter("param1", e.getTargetException().getMessage())
317                     },
318                     "can not invoke"
319                 );
320             }
321             // Get workflow parameters
322
List JavaDoc parameters = this.delegation.addFindRequest(
323                 wfProcess.path().getChild("property"),
324                 null,
325                 AttributeSelectors.ALL_ATTRIBUTES,
326                 null,
327                 0,
328                 Integer.MAX_VALUE,
329                 Orders.ASCENDING
330             );
331             Map JavaDoc params = new HashMap JavaDoc();
332             // Add parameters of executeWorkflow operation to params
333
if(triggeredBySubscription != null) {
334                 params.put("triggeredBySubscription", triggeredBySubscription);
335             }
336             if(triggeredByEventType != null) {
337                 params.put("triggeredByEventType", triggeredByEventType);
338             }
339             for(
340                 Iterator JavaDoc i = parameters.iterator();
341                 i.hasNext();
342             ) {
343                 DataproviderObject_1_0 parameter = (DataproviderObject_1_0)i.next();
344                 String JavaDoc parameterType = (String JavaDoc)parameter.values(SystemAttributes.OBJECT_CLASS).get(0);
345                 Object JavaDoc val = null;
346                 if("org:opencrx:kernel:base:BooleanProperty".equals(parameterType)) {
347                     val = parameter.values("booleanValue");
348                 }
349                 else if("org:opencrx:kernel:base:IntegerProperty".equals(parameterType)) {
350                     val = parameter.values("integerValue");
351                 }
352                 else if("org:opencrx:kernel:base:DecimalProperty".equals(parameterType)) {
353                     val = parameter.values("decimalValue");
354                 }
355                 else if("org:opencrx:kernel:base:UriProperty".equals(parameterType)) {
356                     val = parameter.values("uriValue");
357                 }
358                 else {
359                     val = parameter.values("stringValue");
360                 }
361                 params.put(
362                     parameter.values("name").get(0),
363                     val
364                 );
365             }
366             // Execute workflow
367
try {
368                 workflow.execute(
369                     userHome,
370                     targetObjectIdentity,
371                     params,
372                     wfProcessInstance.path(),
373                     this.header,
374                     this.delegation,
375                     this.plugin
376                 );
377             }
378             catch(ServiceException e) {
379                 e.log();
380                 throw e;
381             }
382             catch(Exception JavaDoc e) {
383                 ServiceException e0 = new ServiceException(e);
384                 e0.log();
385                 throw e0;
386             }
387         }
388         return wfProcessInstance;
389     }
390     
391     //-------------------------------------------------------------------------
392
// Members
393
//-------------------------------------------------------------------------
394
public static final short STATUS_OK = 0;
395     public static final short STATUS_FAILED = 1;
396
397     private final ServiceHeader header;
398     private final RequestCollection delegation;
399     private final OpenCrxKernel_1 plugin;
400     private final RefPackage_1_0 rootPkg;
401     
402 }
403
404 //--- End of File -----------------------------------------------------------
405
Popular Tags