KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > workflow > spi > ojb > OJBWorkflowStore


1 /*
2  * Copyright (c) 2002-2003 by OpenSymphony
3  * All rights reserved.
4  */

5 package com.opensymphony.workflow.spi.ojb;
6
7 import com.opensymphony.module.propertyset.PropertySet;
8 import com.opensymphony.module.propertyset.PropertySetManager;
9
10 import com.opensymphony.workflow.QueryNotSupportedException;
11 import com.opensymphony.workflow.StoreException;
12 import com.opensymphony.workflow.query.WorkflowExpressionQuery;
13 import com.opensymphony.workflow.query.WorkflowQuery;
14 import com.opensymphony.workflow.spi.Step;
15 import com.opensymphony.workflow.spi.WorkflowEntry;
16 import com.opensymphony.workflow.spi.WorkflowStore;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20
21 import org.apache.ojb.broker.PBFactoryException;
22 import org.apache.ojb.broker.PersistenceBroker;
23 import org.apache.ojb.broker.PersistenceBrokerFactory;
24 import org.apache.ojb.broker.query.*;
25
26 import java.math.BigDecimal JavaDoc;
27
28 import java.util.*;
29
30
31 /**
32  * @author picard
33  * Created on 9 sept. 2003
34  */

35 public class OJBWorkflowStore implements WorkflowStore {
36     //~ Static fields/initializers /////////////////////////////////////////////
37

38     private static final Log log = LogFactory.getLog(OJBWorkflowStore.class);
39
40     //~ Constructors ///////////////////////////////////////////////////////////
41

42     public OJBWorkflowStore() {
43         super();
44     }
45
46     //~ Methods ////////////////////////////////////////////////////////////////
47

48     public void setEntryState(long entryId, int state) throws StoreException {
49         PersistenceBroker broker = null;
50
51         try {
52             broker = this.getBroker();
53
54             Criteria criteria = new Criteria();
55             criteria.addEqualTo("id", new Long JavaDoc(entryId));
56
57             Query query = new QueryByCriteria(OJBWorkflowEntry.class, criteria);
58             OJBWorkflowEntry entry = (OJBWorkflowEntry) broker.getObjectByQuery(query);
59             entry.setState(state);
60             broker.store(entry);
61         } catch (Throwable JavaDoc e) {
62             throw new StoreException("Error to retrieve entry", new Exception JavaDoc(e));
63         } finally {
64             if (broker != null) {
65                 broker.close();
66             }
67         }
68     }
69
70     public PropertySet getPropertySet(long entryId) throws StoreException {
71         HashMap args = new HashMap();
72         args.put("globalKey", "osff_" + entryId);
73
74         return PropertySetManager.getInstance("ojb", args);
75     }
76
77     public Step createCurrentStep(long entryId, int stepId, String JavaDoc owner, Date startDate, Date dueDate, String JavaDoc status, long[] previousIds) throws StoreException {
78         PersistenceBroker broker = null;
79         OJBCurrentStep step = new OJBCurrentStep();
80         OJBWorkflowEntry entry;
81
82         try {
83             broker = this.getBroker();
84
85             Criteria criteria = new Criteria();
86             criteria.addEqualTo("id", new Long JavaDoc(entryId));
87
88             Query requete = new QueryByCriteria(OJBWorkflowEntry.class, criteria);
89
90             entry = (OJBWorkflowEntry) broker.getObjectByQuery(requete);
91
92             step.setEntry(entry);
93             step.setStepId(stepId);
94             step.setOwner(owner);
95             step.setStartDate(startDate);
96             step.setDueDate(dueDate);
97             step.setStatus(status);
98
99             List stepIdList = new ArrayList(previousIds.length);
100
101             for (int i = 0; i < previousIds.length; i++) {
102                 long previousId = previousIds[i];
103                 stepIdList.add(new Long JavaDoc(previousId));
104             }
105
106             if (!stepIdList.isEmpty()) {
107                 criteria = new Criteria();
108                 criteria.addIn("id", stepIdList);
109
110                 requete = new QueryByCriteria(OJBCurrentStep.class, criteria);
111
112                 Collection clPreviousStep = broker.getCollectionByQuery(requete);
113
114                 step.setPreviousSteps(new ArrayList(clPreviousStep));
115             } else {
116                 step.setPreviousSteps(Collections.EMPTY_LIST);
117             }
118
119             if (entry.getCurrentSteps() == null) {
120                 ArrayList cSteps = new ArrayList(1);
121                 cSteps.add(step);
122                 entry.setCurrentSteps(cSteps);
123             } else {
124                 entry.getCurrentSteps().add(step);
125             }
126
127             broker.store(entry);
128         } catch (Exception JavaDoc e) {
129             step = null;
130             throw new StoreException("Error creating new workflow entry", e);
131         } finally {
132             if (broker != null) {
133                 broker.close();
134             }
135         }
136
137         return step;
138     }
139
140     public WorkflowEntry createEntry(String JavaDoc workflowName) throws StoreException {
141         PersistenceBroker broker = null;
142
143         OJBWorkflowEntry entry = new OJBWorkflowEntry();
144         entry.setState(WorkflowEntry.CREATED);
145         entry.setWorkflowName(workflowName);
146
147         try {
148             broker = this.getBroker();
149
150             broker.store(entry);
151         } catch (Exception JavaDoc e) {
152             throw new StoreException("Error creating new workflow entry", e);
153         } finally {
154             if (broker != null) {
155                 broker.close();
156             }
157         }
158
159         return entry;
160     }
161
162     /* (non-Javadoc)
163      * @see com.opensymphony.workflow.spi.WorkflowStore#findCurrentSteps(long)
164      */

165     public List findCurrentSteps(long entryId) throws StoreException {
166         PersistenceBroker broker = null;
167
168         Collection clStep = Collections.EMPTY_LIST;
169
170         try {
171             broker = this.getBroker();
172
173             Criteria critere = new Criteria();
174             critere.addEqualTo("entry.id", new Long JavaDoc(entryId));
175
176             Query requete = new QueryByCriteria(OJBCurrentStep.class, critere);
177
178             clStep = broker.getCollectionByQuery(requete);
179         } catch (Exception JavaDoc e) {
180             throw new StoreException("Error to retrieve current steps", e);
181         } finally {
182             if (broker != null) {
183                 broker.close();
184             }
185         }
186
187         return new ArrayList(clStep);
188     }
189
190     /* (non-Javadoc)
191      * @see com.opensymphony.workflow.spi.WorkflowStore#findEntry(long)
192      */

193     public WorkflowEntry findEntry(long entryId) throws StoreException {
194         PersistenceBroker broker = null;
195
196         WorkflowEntry entry = null;
197
198         try {
199             broker = this.getBroker();
200
201             Criteria criteria = new Criteria();
202             criteria.addEqualTo("id", new Long JavaDoc(entryId));
203
204             Query query = new QueryByCriteria(OJBWorkflowEntry.class, criteria);
205
206             entry = (OJBWorkflowEntry) broker.getObjectByQuery(query);
207         } catch (Throwable JavaDoc e) {
208             throw new StoreException("Error to retrieve entry", new Exception JavaDoc(e));
209         } finally {
210             if (broker != null) {
211                 broker.close();
212             }
213         }
214
215         return entry;
216     }
217
218     public List findHistorySteps(long entryId) throws StoreException {
219         PersistenceBroker broker = null;
220
221         Collection clStep = Collections.EMPTY_LIST;
222
223         try {
224             broker = this.getBroker();
225
226             Criteria critere = new Criteria();
227             critere.addEqualTo("entry.id", new Long JavaDoc(entryId));
228
229             Query requete = new QueryByCriteria(OJBHistoryStep.class, critere);
230
231             clStep = broker.getCollectionByQuery(requete);
232         } catch (Exception JavaDoc e) {
233             throw new StoreException("Error to retrieve history steps", e);
234         } finally {
235             if (broker != null) {
236                 broker.close();
237             }
238         }
239
240         return new ArrayList(clStep);
241     }
242
243     public void init(Map props) throws StoreException {
244     }
245
246     public Step markFinished(Step step, int actionId, Date finishDate, String JavaDoc status, String JavaDoc caller) throws StoreException {
247         PersistenceBroker broker = null;
248
249         OJBCurrentStep currentStep = (OJBCurrentStep) step;
250
251         try {
252             broker = this.getBroker();
253
254             currentStep.setActionId(actionId);
255             currentStep.setFinishDate(finishDate);
256             currentStep.setStatus(status);
257             currentStep.setCaller(caller);
258
259             broker.store(currentStep);
260         } catch (Exception JavaDoc e) {
261             log.error("An exception occured", e);
262
263             throw new StoreException("Error to store current step", e);
264         } finally {
265             if (broker != null) {
266                 broker.close();
267             }
268         }
269
270         return step;
271     }
272
273     public void moveToHistory(Step step) throws StoreException {
274         PersistenceBroker broker = null;
275
276         try {
277             broker = this.getBroker();
278
279             Criteria criteria = new Criteria();
280             criteria.addEqualTo("id", new Long JavaDoc(step.getEntryId()));
281
282             Query query = new QueryByCriteria(OJBWorkflowEntry.class, criteria);
283
284             OJBWorkflowEntry entry = (OJBWorkflowEntry) broker.getObjectByQuery(query);
285
286             if (entry != null) {
287                 OJBHistoryStep hstep = new OJBHistoryStep((OJBStep) step);
288
289                 entry.getCurrentSteps().remove(step);
290
291                 if (entry.getHistorySteps() == null) {
292                     ArrayList hSteps = new ArrayList(1);
293                     hSteps.add(hstep);
294                     entry.setHistorySteps(hSteps);
295                 } else {
296                     entry.getHistorySteps().add(hstep);
297                 }
298
299                 broker.delete(new OJBCurrentStep((OJBStep) step));
300
301                 broker.store(entry);
302             }
303         } catch (Exception JavaDoc e) {
304             throw new StoreException("Error to move current step to history", e);
305         } finally {
306             if (broker != null) {
307                 broker.close();
308             }
309         }
310     }
311
312     public List query(WorkflowExpressionQuery query) throws StoreException {
313         throw new QueryNotSupportedException("OJB Store does not support WorkflowExpressionQuery");
314     }
315
316     public List query(WorkflowQuery query) throws StoreException {
317         PersistenceBroker broker = null;
318
319         List results = new ArrayList();
320
321         try {
322             broker = this.getBroker();
323
324             int qtype = query.getType();
325
326             if (qtype == 0) { // then not set, so look in sub queries
327
// todo: not sure if you would have a query that would look in both old and new, if so, i'll have to change this - TR
328
// but then again, why are there redundant tables in the first place? the data model should probably change
329

330                 if (query.getLeft() != null) {
331                     qtype = query.getLeft().getType();
332                 }
333             }
334
335             String JavaDoc sel = queryWhere(query);
336
337             if (log.isDebugEnabled()) {
338                 log.debug(sel);
339             }
340
341             Criteria critere = new Criteria();
342             critere.addSql(sel);
343
344             ReportQueryByCriteria report;
345
346             if (qtype == WorkflowQuery.CURRENT) {
347                 report = new ReportQueryByCriteria(OJBCurrentStep.class, critere, true); // true = Select distinct
348
} else {
349                 report = new ReportQueryByCriteria(OJBHistoryStep.class, critere, true); // true = Select distinct
350
}
351
352             report.setColumns(new String JavaDoc[] {"entryId"});
353
354             Iterator iter = broker.getReportQueryIteratorByQuery(report);
355
356             while (iter.hasNext()) {
357                 Object JavaDoc[] obj = (Object JavaDoc[]) iter.next();
358                 BigDecimal JavaDoc entryId = (BigDecimal JavaDoc) obj[0];
359
360                 results.add(new Long JavaDoc(entryId.longValue()));
361             }
362         } catch (Exception JavaDoc e) {
363             throw new StoreException("SQL Exception in query: " + e.getMessage());
364         } finally {
365             if (broker != null) {
366                 broker.close();
367             }
368         }
369
370         return results;
371     }
372
373     private PersistenceBroker getBroker() throws PBFactoryException {
374         PersistenceBroker broker = PersistenceBrokerFactory.defaultPersistenceBroker();
375
376         return broker;
377     }
378
379     private static String JavaDoc escape(String JavaDoc s) {
380         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(s);
381
382         char c;
383         char[] chars = s.toCharArray();
384
385         for (int i = 0; i < chars.length; i++) {
386             c = chars[i];
387
388             switch (c) {
389             case '\'':
390                 sb.insert(i, '\'');
391                 i++;
392
393                 break;
394
395             case '\\':
396                 sb.insert(i, '\\');
397                 i++;
398             }
399         }
400
401         return sb.toString();
402     }
403
404     private String JavaDoc queryComparison(WorkflowQuery query) {
405         Object JavaDoc value = query.getValue();
406         int operator = query.getOperator();
407         int field = query.getField();
408
409         //int type = query.getType();
410
String JavaDoc oper;
411
412         switch (operator) {
413         case WorkflowQuery.EQUALS:
414             oper = " = ";
415
416             break;
417
418         case WorkflowQuery.NOT_EQUALS:
419             oper = " <> ";
420
421             break;
422
423         case WorkflowQuery.GT:
424             oper = " > ";
425
426             break;
427
428         case WorkflowQuery.LT:
429             oper = " < ";
430
431             break;
432
433         default:
434             oper = " = ";
435         }
436
437         String JavaDoc left;
438         String JavaDoc right;
439
440         switch (field) {
441         case WorkflowQuery.ACTION: // actionId
442
left = "ACTION_ID";
443
444             break;
445
446         case WorkflowQuery.CALLER:
447             left = "CALLER";
448
449             break;
450
451         case WorkflowQuery.FINISH_DATE:
452             left = "FINISH_DATE";
453
454             break;
455
456         case WorkflowQuery.OWNER:
457             left = "OWNER";
458
459             break;
460
461         case WorkflowQuery.START_DATE:
462             left = "START_DATE";
463
464             break;
465
466         case WorkflowQuery.STEP: // stepId
467
left = "STEP_ID";
468
469             break;
470
471         case WorkflowQuery.STATUS:
472             left = "STATUS";
473
474             break;
475
476         default:
477             left = "1";
478         }
479
480         if (value != null) {
481             right = "'" + escape(value.toString()) + "'";
482         } else {
483             right = "null";
484         }
485
486         return left + oper + right;
487     }
488
489     private String JavaDoc queryWhere(WorkflowQuery query) {
490         if (query.getLeft() == null) {
491             // leaf node
492
return queryComparison(query);
493         } else {
494             int operator = query.getOperator();
495             WorkflowQuery left = query.getLeft();
496             WorkflowQuery right = query.getRight();
497
498             switch (operator) {
499             case WorkflowQuery.AND:
500                 return "(" + queryWhere(left) + " AND " + queryWhere(right) + ")";
501
502             case WorkflowQuery.OR:
503                 return "(" + queryWhere(left) + " OR " + queryWhere(right) + ")";
504
505             case WorkflowQuery.XOR:
506                 return "(" + queryWhere(left) + " XOR " + queryWhere(right) + ")";
507             }
508         }
509
510         return ""; // not sure if we should throw an exception or how this should be handled
511
}
512 }
513
Popular Tags