001: /*--
002:
003: Copyright (C) 2002-2005 Adrian Price.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: adrianprice@sourceforge.net.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Adrian Price (adrianprice@users.sourceforge.net).
027:
028: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
029: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
030: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
031: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
032: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
033: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
034: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
035: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
036: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
037: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
038: POSSIBILITY OF SUCH DAMAGE.
039:
040: For more information on OBE, please see
041: <http://obe.sourceforge.net/>.
042:
043: */
044:
045: package org.obe.server.j2ee.repository;
046:
047: import org.apache.commons.logging.Log;
048: import org.apache.commons.logging.LogFactory;
049: import org.obe.client.api.repository.ObjectNotFoundException;
050: import org.obe.client.api.repository.RepositoryException;
051: import org.obe.client.api.model.ProcessInstanceAttributes;
052: import org.obe.engine.repository.AbstractRepository;
053: import org.obe.server.j2ee.ejb.EJBHelper;
054: import org.obe.server.j2ee.ejb.Sequence;
055: import org.obe.spi.model.*;
056: import org.obe.spi.service.ApplicationEventBroker;
057: import org.obe.spi.service.InstanceRepository;
058: import org.obe.spi.service.ServiceManager;
059: import org.wfmc.audit.WMAAuditEntry;
060: import org.wfmc.wapi.WMFilter;
061:
062: import javax.ejb.CreateException;
063: import javax.ejb.EJBLocalObject;
064: import javax.ejb.FinderException;
065: import javax.ejb.RemoveException;
066: import java.util.Arrays;
067: import java.util.Collection;
068: import java.util.Date;
069: import java.util.Iterator;
070:
071: /**
072: * Provides instance persistence services using EJBs.
073: *
074: * @author Adrian Price
075: */
076: public final class EJBInstanceRepository extends AbstractRepository
077: implements InstanceRepository {
078:
079: private static final Log _logger = LogFactory
080: .getLog(EJBInstanceRepository.class);
081:
082: private static boolean isSystemAttribute(String[] attrs, String attr) {
083: return Arrays.binarySearch(attrs, attr) >= 0;
084: }
085:
086: private static AttributeInstance findAttribute(String ownerId,
087: int ownerType, String attributeName)
088: throws RepositoryException {
089:
090: try {
091: return EJBLocalHelper.getAttributeInstanceHome()
092: .findByPrimaryKey(
093: new AttributeInstancePK(ownerId,
094: attributeName, ownerType));
095: } catch (javax.ejb.ObjectNotFoundException e) {
096: throw new ObjectNotFoundException(attributeName);
097: } catch (FinderException e) {
098: throw new RepositoryException(e);
099: }
100: }
101:
102: private static AttributeInstance[] findAttributes(
103: String processDefinitionId, String processInstanceId,
104: String activityDefinitionId, String ownerId, int ownerType,
105: WMFilter filter, String attrName, boolean countFlag)
106: throws RepositoryException {
107:
108: try {
109: AttributeInstanceLocalHome home = EJBLocalHelper
110: .getAttributeInstanceHome();
111: if (countFlag) {
112: int count;
113: if (processDefinitionId == null
114: && activityDefinitionId == null
115: && processInstanceId == null && ownerId != null
116: && filter == null && attrName == null) {
117:
118: // Also, this is the only case where we can include
119: // system attributes in the returned list, and the only
120: // case where we can obtain the attributes directly from
121: // their owner.
122: AttributedEntity owner;
123: switch (ownerType) {
124: case AttributedEntity.PROCESS_INSTANCE_TYPE:
125: ProcessInstanceLocalHome piHome = EJBLocalHelper
126: .getProcessInstanceHome();
127: owner = piHome.findByPrimaryKey(ownerId);
128: break;
129: case AttributedEntity.ACTIVITY_INSTANCE_TYPE:
130: ActivityInstanceLocalHome aiHome = EJBLocalHelper
131: .getActivityInstanceHome();
132: owner = aiHome.findByPrimaryKey(ownerId);
133: break;
134: case AttributedEntity.WORKITEM_TYPE:
135: WorkItemLocalHome wiHome = EJBLocalHelper
136: .getWorkItemHome();
137: owner = wiHome.findByPrimaryKey(ownerId);
138: break;
139: default:
140: throw new IllegalArgumentException(String
141: .valueOf(ownerType));
142: }
143: count = owner.getAttributeInstances().values()
144: .size();
145: } else {
146: count = home.count(processDefinitionId,
147: processInstanceId, activityDefinitionId,
148: ownerId, ownerType, filter, attrName);
149: }
150: return new AttributeInstance[count];
151: } else {
152: // Select the matching attributes.
153: Collection attributes;
154: if (filter == null) {
155: if (processDefinitionId == null
156: && processInstanceId == null
157: && activityDefinitionId == null
158: && ownerId == null && attrName == null) {
159:
160: attributes = home.findAll();
161: } else if (processDefinitionId != null
162: && processInstanceId == null
163: && activityDefinitionId == null
164: && attrName != null) {
165:
166: attributes = home.findByName(
167: processDefinitionId, ownerType,
168: attrName);
169: } else if (processDefinitionId == null
170: && activityDefinitionId == null
171: && processInstanceId == null
172: && ownerId != null && attrName == null) {
173:
174: // Also, this is the only case where we can include
175: // system attributes in the returned list, and the only
176: // case where we can obtain the attributes directly from
177: // their owner.
178: AttributedEntity owner;
179: switch (ownerType) {
180: case AttributedEntity.PROCESS_INSTANCE_TYPE:
181: ProcessInstanceLocalHome piHome = EJBLocalHelper
182: .getProcessInstanceHome();
183: owner = piHome.findByPrimaryKey(ownerId);
184: break;
185: case AttributedEntity.ACTIVITY_INSTANCE_TYPE:
186: ActivityInstanceLocalHome aiHome = EJBLocalHelper
187: .getActivityInstanceHome();
188: owner = aiHome.findByPrimaryKey(ownerId);
189: break;
190: case AttributedEntity.WORKITEM_TYPE:
191: WorkItemLocalHome wiHome = EJBLocalHelper
192: .getWorkItemHome();
193: owner = wiHome.findByPrimaryKey(ownerId);
194: break;
195: default:
196: throw new IllegalArgumentException(String
197: .valueOf(ownerType));
198: }
199: attributes = owner.getAttributeInstances()
200: .values();
201: } else {
202: attributes = home.xfindByFilter(
203: processDefinitionId, processInstanceId,
204: activityDefinitionId, ownerId,
205: ownerType, attrName, filter);
206: }
207: } else {
208: attributes = home.xfindByFilter(
209: processDefinitionId, processInstanceId,
210: activityDefinitionId, ownerId, ownerType,
211: attrName, filter);
212: }
213: return (AttributeInstance[]) attributes
214: .toArray(new AttributeInstance[attributes
215: .size()]);
216: }
217: } catch (FinderException e) {
218: throw new RepositoryException(e);
219: }
220: }
221:
222: public EJBInstanceRepository(ServiceManager svcMgr) {
223: super (svcMgr, null);
224: }
225:
226: public void init() {
227: }
228:
229: public void exit() {
230: }
231:
232: public void purge() throws RepositoryException {
233: // DAOs can't do database updates, because this bypasses JBoss' caching
234: // and can result in false duplicate key exceptions.
235: // try {
236: // EJBRepositoryDAO.getInstance().executeSQLScript(PURGE_SCRIPT);
237: // } catch (SQLException e) {
238: // throw new RepositoryException(e);
239: // }
240: try {
241: // Delete all process instances: CMP will cascade delete activity
242: // instances and work items; attributes cascade delete is done
243: // explicitly by our own code.
244: ApplicationEventBroker eventBroker = _svcMgr
245: .getApplicationEventBroker();
246: String[] keys = new String[2];
247: Collection coll = EJBLocalHelper.getProcessInstanceHome()
248: .findAll();
249: for (Iterator iter = coll.iterator(); iter.hasNext();) {
250: ProcessInstanceLocal processInstance = (ProcessInstanceLocal) iter
251: .next();
252: keys[0] = processInstance.getProcessDefinitionId();
253: keys[1] = processInstance.getProcessInstanceId();
254: eventBroker.unsubscribe(keys, false);
255: processInstance.remove();
256: }
257: coll = EJBHelper.getSequenceHome().findAll();
258: for (Iterator iter = coll.iterator(); iter.hasNext();)
259: ((EJBLocalObject) iter.next()).remove();
260: Sequence.resetAll();
261:
262: // Delete all audit entries.
263: EJBLocalHelper.getAuditEntryHome().deleteByFilter(null);
264: } catch (FinderException e) {
265: throw new RepositoryException(e);
266: } catch (RemoveException e) {
267: throw new RepositoryException(e);
268: }
269: }
270:
271: public ProcessInstance createProcessInstance(
272: String processDefinitionId,
273: String parentActivityInstanceId,
274: String processInstanceName, int priority, int state,
275: Date createdDate, Date startedDate, String[] participants)
276: throws RepositoryException {
277:
278: try {
279: ProcessInstance processInstance;
280: if (parentActivityInstanceId != null) {
281: ActivityInstanceLocal activityInstance = EJBLocalHelper
282: .getActivityInstanceHome().findByPrimaryKey(
283: parentActivityInstanceId);
284: processInstance = activityInstance
285: .addChildProcessInstance(processDefinitionId,
286: processInstanceName, priority, state,
287: createdDate, startedDate, participants);
288: } else {
289: processInstance = EJBLocalHelper
290: .getProcessInstanceHome().create(
291: processDefinitionId,
292: processInstanceName, priority, state,
293: createdDate, startedDate, participants);
294: }
295: return processInstance;
296: } catch (javax.ejb.ObjectNotFoundException e) {
297: throw new ObjectNotFoundException(parentActivityInstanceId);
298: } catch (FinderException e) {
299: throw new RepositoryException(e);
300: } catch (CreateException e) {
301: throw new RepositoryException(e);
302: }
303: }
304:
305: public ProcessInstance findProcessInstance(String processInstanceId)
306: throws RepositoryException {
307:
308: try {
309: return EJBLocalHelper.getProcessInstanceHome()
310: .findByPrimaryKey(processInstanceId);
311: } catch (javax.ejb.ObjectNotFoundException e) {
312: throw new ObjectNotFoundException(processInstanceId);
313: } catch (FinderException e) {
314: throw new RepositoryException(e);
315: }
316: }
317:
318: public ProcessInstance[] findProcessInstances(
319: String processDefinitionId, WMFilter filter,
320: boolean countFlag) throws RepositoryException {
321:
322: try {
323: ProcessInstanceLocalHome home = EJBLocalHelper
324: .getProcessInstanceHome();
325: if (countFlag) {
326: int count = home.count(processDefinitionId, filter);
327: return new ProcessInstance[count];
328: } else {
329: // Select the matching process instances.
330: Collection instances;
331: if (filter == null) {
332: if (processDefinitionId == null) {
333: instances = home.findAll();
334: } else {
335: instances = home
336: .findByProcessDefinitionId(processDefinitionId);
337: }
338: } else {
339: instances = home.xfindByFilter(processDefinitionId,
340: filter);
341: }
342: return (ProcessInstance[]) instances
343: .toArray(new ProcessInstance[instances.size()]);
344: }
345: } catch (FinderException e) {
346: throw new RepositoryException(e);
347: }
348: }
349:
350: public void deleteProcessInstance(String processInstanceId)
351: throws RepositoryException {
352:
353: try {
354: EJBLocalHelper.getProcessInstanceHome().remove(
355: processInstanceId);
356: } catch (RemoveException e) {
357: throw new RepositoryException(e);
358: }
359: }
360:
361: public AttributeInstance createProcessInstanceAttribute(
362: String processInstanceId, String attributeName,
363: int attributeType, Object attributeValue)
364: throws RepositoryException {
365:
366: try {
367: ProcessInstanceLocal procInst = EJBLocalHelper
368: .getProcessInstanceHome().findByPrimaryKey(
369: processInstanceId);
370: return procInst.addAttributeInstance(attributeName,
371: attributeType, attributeValue);
372: } catch (javax.ejb.ObjectNotFoundException e) {
373: throw new ObjectNotFoundException(processInstanceId);
374: } catch (FinderException e) {
375: throw new RepositoryException(e);
376: }
377: }
378:
379: public AttributeInstance findProcessInstanceAttribute(
380: String processInstanceId, String attributeName)
381: throws RepositoryException {
382:
383: if (isSystemAttribute(
384: ProcessInstanceAttributes.SYSTEM_ATTRIBUTES,
385: attributeName)) {
386: try {
387: return EJBLocalHelper.getProcessInstanceHome()
388: .findByPrimaryKey(processInstanceId)
389: .getAttributeInstance(attributeName);
390: } catch (javax.ejb.ObjectNotFoundException e) {
391: throw new ObjectNotFoundException(processInstanceId);
392: } catch (FinderException e) {
393: throw new RepositoryException(e);
394: }
395: }
396: return findAttribute(processInstanceId,
397: AttributedEntity.PROCESS_INSTANCE_TYPE, attributeName);
398: }
399:
400: public AttributeInstance[] findProcessInstanceAttributes(
401: String processDefinitionId, String processInstanceId,
402: WMFilter filter, String attrName, boolean countFlag)
403: throws RepositoryException {
404:
405: return findAttributes(processDefinitionId, null, null,
406: processInstanceId,
407: AttributedEntity.PROCESS_INSTANCE_TYPE, filter,
408: attrName, countFlag);
409: }
410:
411: public ActivityInstance createActivityInstance(
412: String processDefinitionId, String processInstanceId,
413: String activityDefinitionId, String activityName,
414: JoinInstance join, String blockActivityInstanceId,
415: PersistentIterator blockActivityIterator, int priority,
416: int state, String[] participants)
417: throws RepositoryException {
418:
419: try {
420: ProcessInstanceLocal procInst = EJBLocalHelper
421: .getProcessInstanceHome().findByPrimaryKey(
422: processInstanceId);
423: return procInst.addActivityInstance(activityDefinitionId,
424: activityName, join, blockActivityInstanceId,
425: blockActivityIterator, priority, state,
426: participants);
427: } catch (javax.ejb.ObjectNotFoundException e) {
428: throw new ObjectNotFoundException(processInstanceId);
429: } catch (FinderException e) {
430: throw new RepositoryException(e);
431: }
432: }
433:
434: public ActivityInstance findActivityInstance(
435: String activityInstanceId) throws RepositoryException {
436:
437: try {
438: ActivityInstanceLocalHome home = EJBLocalHelper
439: .getActivityInstanceHome();
440: return home.findByPrimaryKey(activityInstanceId);
441: } catch (javax.ejb.ObjectNotFoundException e) {
442: throw new ObjectNotFoundException(activityInstanceId);
443: } catch (FinderException e) {
444: throw new RepositoryException(e);
445: }
446: }
447:
448: public ActivityInstance findActivityInstance(
449: String processInstanceId, String activityDefinitionId,
450: String blockActivityInstanceId) throws RepositoryException {
451:
452: try {
453: ActivityInstanceLocalHome home = EJBLocalHelper
454: .getActivityInstanceHome();
455: return home.findByActivityDefinitionId(processInstanceId,
456: activityDefinitionId, blockActivityInstanceId);
457: } catch (javax.ejb.ObjectNotFoundException e) {
458: throw new ObjectNotFoundException(activityDefinitionId);
459: } catch (FinderException e) {
460: throw new RepositoryException(e);
461: }
462: }
463:
464: public ActivityInstance[] findActivityInstances(
465: String processDefinitionId, String activityDefinitionId,
466: WMFilter filter, boolean countFlag)
467: throws RepositoryException {
468:
469: try {
470: ActivityInstanceLocalHome home = EJBLocalHelper
471: .getActivityInstanceHome();
472: if (countFlag) {
473: int count = home.count(filter);
474: return new ActivityInstance[count];
475: } else {
476: Collection activities;
477: if (processDefinitionId == null
478: && activityDefinitionId == null
479: && filter == null) {
480:
481: activities = home.findAll();
482: } else if (processDefinitionId != null
483: && activityDefinitionId == null
484: && filter == null) {
485:
486: activities = home
487: .findByProcessDefinitionId(processDefinitionId);
488: } else if (processDefinitionId != null
489: && activityDefinitionId != null
490: && filter == null) {
491:
492: activities = home
493: .findByProcessActivityDefinitionId(
494: processDefinitionId,
495: activityDefinitionId);
496: } else {
497: activities = home.xfindByFilter(
498: processDefinitionId, activityDefinitionId,
499: filter);
500: }
501: return (ActivityInstance[]) activities
502: .toArray(new ActivityInstance[activities.size()]);
503: }
504: } catch (FinderException e) {
505: throw new RepositoryException(e);
506: }
507: }
508:
509: public AttributeInstance createActivityInstanceAttribute(
510: String processInstanceId, String activityInstanceId,
511: String attributeName, int attributeType,
512: Object attributeValue) throws RepositoryException {
513:
514: try {
515: ActivityInstanceLocal activity = EJBLocalHelper
516: .getActivityInstanceHome().findByPrimaryKey(
517: activityInstanceId);
518: return activity.addAttributeInstance(attributeName,
519: attributeType, attributeValue);
520: } catch (javax.ejb.ObjectNotFoundException e) {
521: throw new ObjectNotFoundException(activityInstanceId);
522: } catch (FinderException e) {
523: throw new RepositoryException(e);
524: }
525: }
526:
527: public AttributeInstance findActivityInstanceAttribute(
528: String processInstanceId, String activityInstanceId,
529: String attributeName) throws RepositoryException {
530:
531: if (isSystemAttribute(ActivityInstance.attributes,
532: attributeName)) {
533: try {
534: return EJBLocalHelper.getActivityInstanceHome()
535: .findByPrimaryKey(activityInstanceId)
536: .getAttributeInstance(attributeName);
537: } catch (javax.ejb.ObjectNotFoundException e) {
538: throw new ObjectNotFoundException(activityInstanceId);
539: } catch (FinderException e) {
540: throw new RepositoryException(e);
541: }
542: }
543: return findAttribute(activityInstanceId,
544: AttributedEntity.ACTIVITY_INSTANCE_TYPE, attributeName);
545: }
546:
547: public AttributeInstance[] findActivityInstanceAttributes(
548: String processDefinitionId, String processInstanceId,
549: String activityDefinitionId, String activityInstanceId,
550: WMFilter filter, String attributeName, boolean countFlag)
551: throws RepositoryException {
552:
553: return findAttributes(processDefinitionId, null,
554: activityDefinitionId, activityInstanceId,
555: AttributedEntity.ACTIVITY_INSTANCE_TYPE, filter,
556: attributeName, countFlag);
557: }
558:
559: public WorkItem createWorkItem(String processDefinitionId,
560: String processInstanceId, String activityInstanceId,
561: int toolIndex, int state, String performer,
562: String participant) throws RepositoryException {
563:
564: try {
565: ActivityInstanceLocalHome home = EJBLocalHelper
566: .getActivityInstanceHome();
567: ActivityInstanceLocal activity = home
568: .findByPrimaryKey(activityInstanceId);
569: return activity.addWorkItem(toolIndex, state, performer,
570: participant);
571: } catch (javax.ejb.ObjectNotFoundException e) {
572: throw new ObjectNotFoundException(activityInstanceId);
573: } catch (FinderException e) {
574: throw new RepositoryException(e);
575: }
576: }
577:
578: public WorkItem findWorkItem(String processInstanceId,
579: String workItemId) throws RepositoryException {
580:
581: try {
582: return EJBLocalHelper.getWorkItemHome().findByPrimaryKey(
583: workItemId);
584: } catch (javax.ejb.ObjectNotFoundException e) {
585: throw new ObjectNotFoundException(workItemId);
586: } catch (FinderException e) {
587: throw new RepositoryException(e);
588: }
589: }
590:
591: public WorkItem[] findWorkItems(WMFilter filter, boolean countFlag)
592: throws RepositoryException {
593:
594: try {
595: WorkItemLocalHome home = EJBLocalHelper.getWorkItemHome();
596: if (countFlag) {
597: int count = home.count(filter);
598: return new WorkItem[count];
599: } else {
600: Collection workItems;
601: if (filter == null) {
602: workItems = home.findAll();
603: } else {
604: workItems = home.xfindByFilter(filter);
605: }
606: return (WorkItem[]) workItems
607: .toArray(new WorkItem[workItems.size()]);
608: }
609: } catch (FinderException e) {
610: throw new RepositoryException(e);
611: }
612: }
613:
614: public AttributeInstance createWorkItemAttribute(
615: String processInstanceId, String workItemId,
616: String attributeName, int attributeType,
617: Object attributeValue) throws RepositoryException {
618:
619: try {
620: WorkItemLocal workItem = EJBLocalHelper.getWorkItemHome()
621: .findByPrimaryKey(workItemId);
622: return workItem.addAttributeInstance(attributeName,
623: attributeType, attributeValue);
624: } catch (javax.ejb.ObjectNotFoundException e) {
625: throw new ObjectNotFoundException(workItemId);
626: } catch (FinderException e) {
627: throw new RepositoryException(e);
628: }
629: }
630:
631: public AttributeInstance findWorkItemAttribute(
632: String processInstanceId, String workItemId,
633: String attributeName) throws RepositoryException {
634:
635: if (isSystemAttribute(WorkItem.attributes, attributeName)) {
636: try {
637: return EJBLocalHelper.getWorkItemHome()
638: .findByPrimaryKey(workItemId)
639: .getAttributeInstance(attributeName);
640: } catch (javax.ejb.ObjectNotFoundException e) {
641: throw new ObjectNotFoundException(workItemId);
642: } catch (FinderException e) {
643: throw new RepositoryException(e);
644: }
645: }
646: return findAttribute(workItemId,
647: AttributedEntity.WORKITEM_TYPE, attributeName);
648: }
649:
650: public AttributeInstance[] findWorkItemAttributes(
651: String processInstanceId, String workItemId,
652: WMFilter filter, boolean countFlag)
653: throws RepositoryException {
654:
655: return findAttributes(null, null, null, workItemId,
656: AttributedEntity.WORKITEM_TYPE, filter, null, countFlag);
657: }
658:
659: public WMAAuditEntry[] findAuditEntries(WMFilter filter)
660: throws RepositoryException {
661:
662: return EJBLocalHelper.getAuditEntryHome().xfindByFilter(filter);
663: }
664:
665: public int deleteAuditEntries(WMFilter filter)
666: throws RepositoryException {
667: return EJBLocalHelper.getAuditEntryHome()
668: .deleteByFilter(filter);
669: }
670:
671: protected Log getLogger() {
672: return _logger;
673: }
674:
675: public String getServiceName() {
676: return SERVICE_NAME;
677: }
678: }
|