KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > workflow > spi > hibernate > SpringHibernateWorkflowStore


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

5 package com.opensymphony.workflow.spi.hibernate;
6
7 import com.opensymphony.module.propertyset.PropertySet;
8 import com.opensymphony.module.propertyset.PropertySetManager;
9 import com.opensymphony.module.propertyset.hibernate.DefaultHibernateConfigurationProvider;
10
11 import com.opensymphony.util.TextUtils;
12
13 import com.opensymphony.workflow.StoreException;
14 import com.opensymphony.workflow.query.FieldExpression;
15 import com.opensymphony.workflow.query.NestedExpression;
16 import com.opensymphony.workflow.query.WorkflowExpressionQuery;
17 import com.opensymphony.workflow.query.WorkflowQuery;
18 import com.opensymphony.workflow.spi.Step;
19 import com.opensymphony.workflow.spi.WorkflowEntry;
20 import com.opensymphony.workflow.spi.WorkflowStore;
21
22 import net.sf.hibernate.Criteria;
23 import net.sf.hibernate.HibernateException;
24 import net.sf.hibernate.expression.Criterion;
25 import net.sf.hibernate.expression.Expression;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 import org.springframework.orm.hibernate.support.HibernateDaoSupport;
31
32 import java.util.ArrayList JavaDoc;
33 import java.util.Collection JavaDoc;
34 import java.util.Collections JavaDoc;
35 import java.util.Date JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.HashSet JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.List JavaDoc;
40 import java.util.Map JavaDoc;
41 import java.util.Set JavaDoc;
42
43
44 /**
45  * @author Quake Wang
46  * @since 2004-5-2
47  * @version $Revision: 1.1 $
48  *
49  **/

50 public class SpringHibernateWorkflowStore extends HibernateDaoSupport implements WorkflowStore {
51     //~ Static fields/initializers /////////////////////////////////////////////
52

53     private static final Log log = LogFactory.getLog(SpringHibernateWorkflowStore.class);
54
55     //~ Methods ////////////////////////////////////////////////////////////////
56

57     public void setEntryState(long entryId, int state) throws StoreException {
58         HibernateWorkflowEntry entry = loadEntry(entryId);
59         entry.setState(state);
60         getHibernateTemplate().update(entry);
61     }
62
63     public PropertySet getPropertySet(long entryId) throws StoreException {
64         HashMap JavaDoc args = new HashMap JavaDoc();
65         args.put("entityName", "OSWorkflowEntry");
66         args.put("entityId", new Long JavaDoc(entryId));
67
68         DefaultHibernateConfigurationProvider configurationProvider = new DefaultHibernateConfigurationProvider();
69         configurationProvider.setSessionFactory(getSessionFactory());
70
71         args.put("configurationProvider", configurationProvider);
72
73         return PropertySetManager.getInstance("hibernate", args);
74     }
75
76     public Step createCurrentStep(long entryId, int stepId, String JavaDoc owner, Date JavaDoc startDate, Date JavaDoc dueDate, String JavaDoc status, long[] previousIds) throws StoreException {
77         HibernateCurrentStep step = new HibernateCurrentStep();
78         HibernateWorkflowEntry entry = loadEntry(entryId);
79
80         step.setEntry(entry);
81         step.setStepId(stepId);
82         step.setOwner(owner);
83         step.setStartDate(startDate);
84         step.setDueDate(dueDate);
85         step.setStatus(status);
86
87         List JavaDoc stepIdList = new ArrayList JavaDoc(previousIds.length);
88
89         for (int i = 0; i < previousIds.length; i++) {
90             long previousId = previousIds[i];
91             stepIdList.add(new Long JavaDoc(previousId));
92         }
93
94         if (!stepIdList.isEmpty()) {
95             String JavaDoc stepIds = TextUtils.join(", ", stepIdList);
96             step.setPreviousSteps(getHibernateTemplate().find("FROM " + HibernateCurrentStep.class.getName() + " step WHERE step.id IN (" + stepIds + ")"));
97         } else {
98             step.setPreviousSteps(Collections.EMPTY_LIST);
99         }
100
101         getHibernateTemplate().save(step);
102
103         return step;
104     }
105
106     public WorkflowEntry createEntry(String JavaDoc workflowName) throws StoreException {
107         HibernateWorkflowEntry entry = new HibernateWorkflowEntry();
108         entry.setState(WorkflowEntry.CREATED);
109         entry.setWorkflowName(workflowName);
110         getHibernateTemplate().save(entry);
111
112         return entry;
113     }
114
115     public List JavaDoc findCurrentSteps(long entryId) throws StoreException {
116         return getHibernateTemplate().find("FROM " + HibernateCurrentStep.class.getName() + " step WHERE step.entry.id = ?", new Long JavaDoc(entryId));
117     }
118
119     public WorkflowEntry findEntry(long entryId) throws StoreException {
120         return loadEntry(entryId);
121     }
122
123     public List JavaDoc findHistorySteps(long entryId) throws StoreException {
124         return getHibernateTemplate().find("FROM " + HibernateHistoryStep.class.getName() + " step WHERE step.entry.id = ?", new Long JavaDoc(entryId));
125     }
126
127     public void init(Map JavaDoc props) throws StoreException {
128         // TODO Auto-generated method stub
129
}
130
131     public Step markFinished(Step step, int actionId, Date JavaDoc finishDate, String JavaDoc status, String JavaDoc caller) throws StoreException {
132         HibernateCurrentStep currentStep = (HibernateCurrentStep) step;
133
134         currentStep.setActionId(actionId);
135         currentStep.setFinishDate(finishDate);
136         currentStep.setStatus(status);
137         currentStep.setCaller(caller);
138         getHibernateTemplate().update(currentStep);
139
140         return currentStep;
141     }
142
143     public void moveToHistory(Step step) throws StoreException {
144         HibernateHistoryStep hStep = new HibernateHistoryStep((HibernateStep) step);
145         getHibernateTemplate().delete(step);
146         getHibernateTemplate().save(hStep);
147     }
148
149     public List JavaDoc query(WorkflowQuery query) throws StoreException {
150         Class JavaDoc entityClass;
151
152         int qtype = query.getType();
153
154         if (qtype == 0) { // then not set, so look in sub queries
155

156             if (query.getLeft() != null) {
157                 qtype = query.getLeft().getType();
158             }
159         }
160
161         if (qtype == WorkflowQuery.CURRENT) {
162             entityClass = HibernateCurrentStep.class;
163         } else {
164             entityClass = HibernateHistoryStep.class;
165         }
166
167         Criteria criteria = getSession().createCriteria(entityClass);
168         Criterion expression = buildExpression(query);
169         criteria.add(expression);
170
171         //get results and send them back
172
try {
173             Set results = new HashSet JavaDoc();
174             Iterator JavaDoc iter = criteria.list().iterator();
175
176             while (iter.hasNext()) {
177                 HibernateStep step = (HibernateStep) iter.next();
178                 results.add(new Long JavaDoc(step.getEntryId()));
179             }
180
181             return new ArrayList JavaDoc(results);
182         } catch (HibernateException e) {
183             throw new StoreException("Error executing query " + expression, e);
184         }
185     }
186
187     /* (non-Javadoc)
188      * @see com.opensymphony.workflow.spi.WorkflowStore#query(com.opensymphony.workflow.query.WorkflowExpressionQuery)
189      */

190     public List JavaDoc query(WorkflowExpressionQuery query) throws StoreException {
191         com.opensymphony.workflow.query.Expression expression = query.getExpression();
192
193         Criterion expr;
194
195         Class JavaDoc entityClass = getQueryClass(expression, null);
196
197         if (expression.isNested()) {
198             expr = buildNested((NestedExpression) expression);
199         } else {
200             expr = queryComparison((FieldExpression) expression);
201         }
202
203         Criteria criteria = getSession().createCriteria(entityClass);
204         criteria.add(expr);
205
206         try {
207             Set results = new HashSet JavaDoc();
208
209             Iterator JavaDoc iter = criteria.list().iterator();
210
211             while (iter.hasNext()) {
212                 Object JavaDoc next = iter.next();
213                 Object JavaDoc item;
214
215                 if (next instanceof HibernateStep) {
216                     HibernateStep step = (HibernateStep) next;
217                     item = new Long JavaDoc(step.getEntryId());
218                 } else {
219                     WorkflowEntry entry = (WorkflowEntry) next;
220                     item = new Long JavaDoc(entry.getId());
221                 }
222
223                 results.add(item);
224             }
225
226             return new ArrayList JavaDoc(results);
227         } catch (HibernateException e) {
228             throw new StoreException("Error executing query " + expression, e);
229         }
230     }
231
232     private Criterion getExpression(WorkflowQuery query) {
233         int operator = query.getOperator();
234
235         switch (operator) {
236         case WorkflowQuery.EQUALS:
237             return Expression.eq(getFieldName(query.getField()), query.getValue());
238
239         case WorkflowQuery.NOT_EQUALS:
240             return Expression.not(Expression.like(getFieldName(query.getField()), query.getValue()));
241
242         case WorkflowQuery.GT:
243             return Expression.gt(getFieldName(query.getField()), query.getValue());
244
245         case WorkflowQuery.LT:
246             return Expression.lt(getFieldName(query.getField()), query.getValue());
247
248         default:
249             return Expression.eq(getFieldName(query.getField()), query.getValue());
250         }
251     }
252
253     private String JavaDoc getFieldName(int field) {
254         switch (field) {
255         case FieldExpression.ACTION: // actionId
256
return "actionId";
257
258         case FieldExpression.CALLER:
259             return "caller";
260
261         case FieldExpression.FINISH_DATE:
262             return "finishDate";
263
264         case FieldExpression.OWNER:
265             return "owner";
266
267         case FieldExpression.START_DATE:
268             return "startDate";
269
270         case FieldExpression.STEP: // stepId
271
return "stepId";
272
273         case FieldExpression.STATUS:
274             return "status";
275
276         case FieldExpression.STATE:
277             return "state";
278
279         case FieldExpression.NAME:
280             return "workflowName";
281
282         default:
283             return "1";
284         }
285     }
286
287     private Class JavaDoc getQueryClass(com.opensymphony.workflow.query.Expression expr, Collection JavaDoc classesCache) throws StoreException {
288         if (classesCache == null) {
289             classesCache = new HashSet JavaDoc();
290         }
291
292         if (expr instanceof FieldExpression) {
293             FieldExpression fieldExpression = (FieldExpression) expr;
294
295             switch (fieldExpression.getContext()) {
296             case FieldExpression.CURRENT_STEPS:
297                 classesCache.add(HibernateCurrentStep.class);
298
299                 break;
300
301             case FieldExpression.HISTORY_STEPS:
302                 classesCache.add(HibernateHistoryStep.class);
303
304                 break;
305
306             case FieldExpression.ENTRY:
307                 classesCache.add(HibernateWorkflowEntry.class);
308
309                 break;
310
311             default:
312                 throw new StoreException("Query for unsupported context " + fieldExpression.getContext());
313             }
314         } else {
315             NestedExpression nestedExpression = (NestedExpression) expr;
316
317             for (int i = 0; i < nestedExpression.getExpressionCount(); i++) {
318                 com.opensymphony.workflow.query.Expression expression = nestedExpression.getExpression(i);
319
320                 if (expression.isNested()) {
321                     classesCache.add(getQueryClass(nestedExpression.getExpression(i), classesCache));
322                 } else {
323                     classesCache.add(getQueryClass(expression, classesCache));
324                 }
325             }
326         }
327
328         if (classesCache.size() > 1) {
329             throw new StoreException("Store does not support nested queries of different types (types found:" + classesCache + ")");
330         }
331
332         return (Class JavaDoc) classesCache.iterator().next();
333     }
334
335     private Criterion buildExpression(WorkflowQuery query) throws StoreException {
336         if (query.getLeft() == null) {
337             if (query.getRight() == null) {
338                 return getExpression(query); //leaf node
339
} else {
340                 throw new StoreException("Invalid WorkflowQuery object. QueryLeft is null but QueryRight is not.");
341             }
342         } else {
343             if (query.getRight() == null) {
344                 throw new StoreException("Invalid WorkflowQuery object. QueryLeft is not null but QueryRight is.");
345             }
346
347             int operator = query.getOperator();
348             WorkflowQuery left = query.getLeft();
349             WorkflowQuery right = query.getRight();
350
351             switch (operator) {
352             case WorkflowQuery.AND:
353                 return Expression.and(buildExpression(left), buildExpression(right));
354
355             case WorkflowQuery.OR:
356                 return Expression.or(buildExpression(left), buildExpression(right));
357
358             case WorkflowQuery.XOR:
359                 throw new StoreException("XOR Operator in Queries not supported by " + this.getClass().getName());
360
361             default:
362                 throw new StoreException("Operator '" + operator + "' is not supported by " + this.getClass().getName());
363             }
364         }
365     }
366
367     private Criterion buildNested(NestedExpression nestedExpression) throws StoreException {
368         Criterion full = null;
369
370         for (int i = 0; i < nestedExpression.getExpressionCount(); i++) {
371             Criterion expr;
372             com.opensymphony.workflow.query.Expression expression = nestedExpression.getExpression(i);
373
374             if (expression.isNested()) {
375                 expr = buildNested((NestedExpression) nestedExpression.getExpression(i));
376             } else {
377                 FieldExpression sub = (FieldExpression) nestedExpression.getExpression(i);
378                 expr = queryComparison(sub);
379
380                 if (sub.isNegate()) {
381                     expr = Expression.not(expr);
382                 }
383             }
384
385             if (full == null) {
386                 full = expr;
387             } else {
388                 switch (nestedExpression.getExpressionOperator()) {
389                 case NestedExpression.AND:
390                     full = Expression.and(full, expr);
391
392                     break;
393
394                 case NestedExpression.OR:
395                     full = Expression.or(full, expr);
396                 }
397             }
398         }
399
400         return full;
401     }
402
403     private HibernateWorkflowEntry loadEntry(long entryId) {
404         return (HibernateWorkflowEntry) getHibernateTemplate().load(HibernateWorkflowEntry.class, new Long JavaDoc(entryId));
405     }
406
407     private Criterion queryComparison(FieldExpression expression) {
408         int operator = expression.getOperator();
409
410         switch (operator) {
411         case FieldExpression.EQUALS:
412             return Expression.eq(getFieldName(expression.getField()), expression.getValue());
413
414         case FieldExpression.NOT_EQUALS:
415             return Expression.not(Expression.like(getFieldName(expression.getField()), expression.getValue()));
416
417         case FieldExpression.GT:
418             return Expression.gt(getFieldName(expression.getField()), expression.getValue());
419
420         case FieldExpression.LT:
421             return Expression.lt(getFieldName(expression.getField()), expression.getValue());
422
423         default:
424             return Expression.eq(getFieldName(expression.getField()), expression.getValue());
425         }
426     }
427 }
428
Popular Tags