KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > module > workflow > jcr > JCRExpressionStore


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 2006 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.module.workflow.jcr;
14
15 import info.magnolia.cms.beans.config.ContentRepository;
16 import info.magnolia.cms.core.Content;
17 import info.magnolia.cms.core.HierarchyManager;
18 import info.magnolia.cms.core.ItemType;
19 import info.magnolia.cms.core.search.Query;
20 import info.magnolia.cms.core.search.QueryManager;
21 import info.magnolia.cms.core.search.QueryResult;
22 import info.magnolia.cms.util.ContentUtil;
23 import info.magnolia.context.MgnlContext;
24 import info.magnolia.module.workflow.WorkflowConstants;
25 import openwfe.org.ApplicationContext;
26 import openwfe.org.ServiceException;
27 import openwfe.org.engine.expool.PoolException;
28 import openwfe.org.engine.expressions.FlowExpression;
29 import openwfe.org.engine.expressions.FlowExpressionId;
30 import openwfe.org.engine.impl.expool.AbstractExpressionStore;
31 import openwfe.org.engine.impl.expool.ExpoolUtils;
32 import openwfe.org.util.beancoder.XmlBeanCoder;
33 import openwfe.org.xml.XmlUtils;
34 import org.jdom.Document;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import javax.jcr.ValueFactory;
39 import java.io.InputStream JavaDoc;
40 import java.util.Iterator JavaDoc;
41
42
43 /**
44  * The JCR implementation of the expression store.
45  *
46  * @author Jackie Ju
47  * @author Nicolas Modrzyk
48  * @author John Mettraux
49  */

50 public class JCRExpressionStore extends AbstractExpressionStore {
51
52     //
53
// CONSTANTS & co
54

55     private static final String JavaDoc ENGINE_ID = "ee";
56
57     protected static Logger log = LoggerFactory.getLogger(JCRExpressionStore.class.getName());
58
59     //private static final Object HM_LOCK = new Object();
60

61     //
62
// FIELDS
63

64     private HierarchyManager hierarchyManager = null;
65
66     //
67
// CONSTRUCTORS
68

69     public void init(final String JavaDoc serviceName, final ApplicationContext context, final java.util.Map JavaDoc serviceParams) throws ServiceException {
70
71         super.init(serviceName, context, serviceParams);
72         this.hierarchyManager = ContentRepository.getHierarchyManager(WorkflowConstants.WORKSPACE_EXPRESSION);
73
74         if (this.hierarchyManager == null) {
75             throw new ServiceException("Can't access HierarchyManager for workitems");
76         }
77     }
78
79     //
80
// METHODS from ExpressionStore
81

82     //
83
// METHODS
84

85     /**
86      * Stores one expresion
87      */

88     public void storeExpression(final FlowExpression fe) throws PoolException {
89
90         try {
91             synchronized (this.hierarchyManager) {
92
93                 Content cExpression = findExpression(fe);
94
95                 if (log.isDebugEnabled()) {
96
97                     log.debug
98                         ("storeExpression() handle is "+
99                          cExpression.getHandle());
100                 }
101
102                 // set expressionId as attribte id
103

104                 ValueFactory vf = cExpression.getJCRNode().getSession().getValueFactory();
105                 String JavaDoc value = fe.getId().toParseableString();
106
107                 cExpression.createNodeData
108                     (WorkflowConstants.NODEDATA_ID, vf.createValue(value));
109
110                 //serializeExpressionWithBeanCoder(ct, fe);
111

112                 serializeExpressionAsXml(cExpression, fe);
113
114                 this.hierarchyManager.save();
115             }
116         }
117         catch (final Exception JavaDoc e) {
118
119             log.error
120                 ("storeExpression() store exception failed", e);
121
122             throw new PoolException
123                 ("storeExpression() store exception failed", e);
124         }
125     }
126
127     /**
128      * Removes the expression from the JCR storage.
129      */

130     public void unstoreExpression(final FlowExpression fe) throws PoolException {
131
132         try {
133             Content cExpression = findExpression(fe);
134
135             if (cExpression != null) {
136
137                 synchronized (this.hierarchyManager) {
138
139                     cExpression.delete();
140
141                     this.hierarchyManager.save();
142                 }
143             }
144             else {
145                 log.info
146                     ("unstoreExpression() "+
147                      "didn't find content node for fe "+
148                      fe.getId().toParseableString());
149             }
150         }
151         catch (final Exception JavaDoc e) {
152
153             log.error
154                 ("unstoreExpression() unstore exception failed", e);
155
156             throw new PoolException
157                 ("unstoreExpression() unstore exception failed", e);
158         }
159     }
160
161     /**
162      * Returns an iterator on the content of that expression store.
163      */

164     public synchronized Iterator JavaDoc contentIterator(final Class JavaDoc assignClass) {
165
166         try {
167             return new StoreIterator(assignClass);
168         }
169         catch (final Throwable JavaDoc t) {
170             log.error("contentIterator() failed to set up an iterator", t);
171         }
172
173         //return null;
174
return new java.util.ArrayList JavaDoc(0).iterator();
175     }
176
177     /**
178      * Loads an expression given its id.
179      */

180     public FlowExpression loadExpression(final FlowExpressionId fei) throws PoolException {
181
182         try {
183
184             Content cExpression = findExpression(fei);
185
186             if (cExpression != null) {
187
188                 final FlowExpression expression =
189                     deserializeExpressionAsXml(cExpression);
190
191                 expression.setApplicationContext(getContext());
192
193                 return expression;
194             }
195         }
196         catch (final Exception JavaDoc e) {
197
198             log.debug
199                 ("loadExpression() failed for "+fei.asStringId(), e);
200
201             throw new PoolException
202                 ("loadExpression() failed for "+fei.asStringId(), e);
203         }
204
205         if (log.isDebugEnabled()) {
206
207             log.debug
208                 ("loadExpression() "+
209                  "didn't find expression "+fei.asStringId()+
210                  " in the repository");
211         }
212
213         throw new PoolException
214             ("loadExpression() "+
215              "didn't find expression "+fei.asStringId()+" in the repository");
216
217     }
218
219     /**
220      * Returns the number of expressions currently stored in that store.
221      */

222     public int size() {
223
224         try {
225
226             QueryManager qm = MgnlContext.getSystemContext().getQueryManager(WorkflowConstants.WORKSPACE_EXPRESSION);
227
228             Query q = qm.createQuery(WorkflowConstants.STORE_ITERATOR_QUERY, Query.SQL);
229             QueryResult qr = q.execute();
230
231             return qr.getContent().size();
232         }
233         catch (final Exception JavaDoc e) {
234
235             log.error("size() failed", e);
236
237             return -1;
238         }
239     }
240
241     //
242
// METHODS
243

244     private void serializeExpressionAsXml(Content c, FlowExpression fe) throws Exception JavaDoc {
245
246         final org.jdom.Document doc = XmlBeanCoder.xmlEncode(fe);
247         String JavaDoc s = XmlUtils.toString(doc, null);
248         ValueFactory vf = c.getJCRNode().getSession().getValueFactory();
249         c.createNodeData(WorkflowConstants.NODEDATA_VALUE, vf.createValue(s));
250     }
251
252     /*
253     private void serializeExpressionWithBeanCoder(Content c,FlowExpression fr) throws Exception {
254
255         OwfeJcrBeanCoder coder = new OwfeJcrBeanCoder(null,new MgnlNode(c),WorkflowConstants.NODEDATA_VALUE);
256         coder.encode(fr);
257     }
258     */

259
260     public final String JavaDoc toXPathFriendlyString(final FlowExpressionId fei) {
261
262         final StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
263         final String JavaDoc engineId = fei.getEngineId();
264
265         buffer.append(WorkflowConstants.SLASH);
266         buffer.append(engineId);
267
268         // engine storage
269
if (engineId.equals(ENGINE_ID)) {
270             return buffer.toString();
271         }
272
273         buffer.append(WorkflowConstants.SLASH);
274         buffer.append(fei.getWorkflowDefinitionName());
275
276         buffer.append(WorkflowConstants.SLASH);
277         buffer.append(fei.getWorkflowInstanceId());
278
279         buffer
280             .append(WorkflowConstants.SLASH);
281         buffer
282             .append(fei.getExpressionId())
283             .append("__")
284             .append(fei.getExpressionName());
285
286         return buffer.toString();
287     }
288
289     private Content findExpression(final FlowExpression fe) throws Exception JavaDoc {
290
291         return findExpression(fe.getId());
292     }
293
294     private Content findExpression(final FlowExpressionId fei) throws Exception JavaDoc {
295
296         if (log.isDebugEnabled()) {
297             log.debug("findExpression() looking for "+fei.toParseableString());
298         }
299
300         final String JavaDoc path = toXPathFriendlyString(fei);
301
302         if (this.hierarchyManager.isExist(path)) {
303             return this.hierarchyManager.getContent(path);
304         }
305         else {
306             return ContentUtil.createPath
307                 (this.hierarchyManager, path, ItemType.EXPRESSION);
308         }
309     }
310
311     private FlowExpression deserializeExpressionAsXml(final Content c) throws Exception JavaDoc {
312
313         final InputStream JavaDoc is = c
314             .getNodeData(WorkflowConstants.NODEDATA_VALUE)
315             .getStream();
316
317         if (is == null) return null;
318             //
319
// not an expression
320

321         final org.jdom.input.SAXBuilder builder =
322             new org.jdom.input.SAXBuilder();
323
324         final Document doc = builder.build(is);
325
326         return (FlowExpression)XmlBeanCoder.xmlDecode(doc);
327     }
328
329     /*
330      * could be useful once again later...
331      *
332     private void debugNodeData(final Content c) throws Exception {
333
334         final InputStream is = c
335             .getNodeData(WorkflowConstants.NODEDATA_VALUE)
336             .getStream();
337
338         if (is == null) return;
339
340         final java.io.ByteArrayOutputStream baos =
341             new java.io.ByteArrayOutputStream();
342
343         final byte[] buffer = new byte[70];
344         final int i = is.read(buffer);
345
346         if (i > -1) {
347             baos.write(buffer);
348             baos.flush();
349         }
350
351         log.warn
352             ("deserializeExpressionAsXml() nodeData is >"+baos.toString()+"<");
353     }
354     */

355
356     /*
357     protected FlowExpression deserializeExpressionWithBeanCoder(Content ret) throws Exception {
358         OwfeJcrBeanCoder coder = new OwfeJcrBeanCoder(null, new MgnlNode(ret.getContent(WorkflowConstants.NODEDATA_VALUE)));
359         return (FlowExpression)coder.decode();
360     }
361     */

362
363     /**
364      * 'lightweight' storeIterator. The previous version were stuffing all
365      * the expression within a collection and
366      * returning an iterator on it.
367      * <p>
368      * The remaining question is : what's behind
369      * Magnolia's Content.iterator() method ?
370      */

371     protected final class StoreIterator implements Iterator JavaDoc {
372
373         //
374
// FIELDS
375

376         private Class JavaDoc assignClass;
377
378         private Iterator JavaDoc rootIterator = null;
379
380         private FlowExpression next = null;
381
382         //
383
// CONSTRUCTORS
384

385         public StoreIterator(final Class JavaDoc assignClass) throws Exception JavaDoc {
386
387             super();
388
389             this.assignClass = assignClass;
390
391             final QueryManager qm = MgnlContext
392                 .getSystemContext()
393                 .getQueryManager(WorkflowConstants.WORKSPACE_EXPRESSION);
394
395             final Query query = qm.createQuery
396                 (WorkflowConstants.STORE_ITERATOR_QUERY, Query.SQL);
397
398             final QueryResult qr = query.execute();
399
400             if (log.isDebugEnabled()) {
401                 log.debug
402                     ("() query found "+
403                      qr.getContent("expression").size()+" elements");
404             }
405
406             this.rootIterator = qr.getContent("expression").iterator();
407
408             this.next = fetchNext();
409         }
410
411         //
412
// METHODS
413

414         public boolean hasNext() {
415
416             return (this.next != null);
417         }
418
419         public FlowExpression fetchNext() {
420
421             if ( ! this.rootIterator.hasNext()) {
422                 return null;
423             }
424
425             final Content content = (Content) this.rootIterator.next();
426             try {
427
428                 final FlowExpression fe = deserializeExpressionAsXml(content);
429
430                 if (fe == null) {
431                     return fetchNext();
432                 }
433
434                 fe.setApplicationContext(JCRExpressionStore.this.getContext());
435
436                 if ( ! ExpoolUtils.isAssignableFromClass(fe, this.assignClass)) {
437                     return fetchNext();
438                 }
439
440                 return fe;
441             }
442             catch (final Exception JavaDoc e) {
443
444                 log.error("fetchNext() problem", e);
445                 return null;
446             }
447         }
448
449         public Object JavaDoc next() throws java.util.NoSuchElementException JavaDoc {
450
451             final FlowExpression current = this.next;
452
453             if (current == null) {
454                 throw new java.util.NoSuchElementException JavaDoc();
455             }
456
457             this.next = fetchNext();
458
459             if (log.isDebugEnabled()) {
460
461                 if (this.next == null) {
462                     log.debug("next() is 'null'");
463                 }
464                 else {
465                     log.debug("next() is "+this.next.getId());
466                 }
467             }
468
469             return current;
470         }
471
472         public void remove() {
473             // not necessary
474
}
475     }
476
477 }
478
Popular Tags