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.engine.repository.AbstractRepository;
052: import org.obe.spi.service.ApplicationEventBroker;
053: import org.obe.spi.service.ProcessRepository;
054: import org.obe.spi.service.ServiceManager;
055: import org.obe.xpdl.model.pkg.XPDLPackage;
056: import org.obe.xpdl.model.workflow.WorkflowProcess;
057: import org.wfmc.wapi.WMFilter;
058: import org.wfmc.wapi.WMProcessDefinitionState;
059: import org.wfmc.wapi.WMWorkflowException;
060:
061: import javax.ejb.CreateException;
062: import javax.ejb.FinderException;
063: import javax.ejb.RemoveException;
064: import java.util.*;
065:
066: /**
067: * An EJB implementation of the ProcessRepository. N.B. This class is designed
068: * to be called from within an EJB container (i.e., it calls entity EJBs whose
069: * transactional requirement is MANDATORY).
070: *
071: * @author Adrian Price
072: */
073: public class EJBProcessRepository extends AbstractRepository implements
074: ProcessRepository {
075:
076: private static final Log _logger = LogFactory
077: .getLog(EJBProcessRepository.class);
078:
079: public EJBProcessRepository(ServiceManager svcMgr) {
080: super (svcMgr, null);
081: }
082:
083: public void init() {
084: }
085:
086: public void exit() {
087: }
088:
089: public void purge() throws RepositoryException {
090: try {
091: // Delete all packages: CMP will cascade delete process definitions.
092: ApplicationEventBroker eventBroker = _svcMgr
093: .getApplicationEventBroker();
094: String[] keys = new String[1];
095: Collection c = EJBLocalHelper.getPackageHome().findAll();
096: for (Iterator i = c.iterator(); i.hasNext();) {
097: PackageLocal pkgLocal = (PackageLocal) i.next();
098: XPDLPackage pkg = pkgLocal.getXPDLPackageBean();
099: WorkflowProcess[] workflows = pkg.getWorkflowProcess();
100: for (int j = 0; j < workflows.length; j++) {
101: keys[0] = workflows[j].getProcessDefinitionId();
102: eventBroker.unsubscribe(keys, false);
103: }
104: pkgLocal.remove();
105: }
106: } catch (RemoveException e) {
107: throw new RepositoryException(e);
108: } catch (FinderException e) {
109: throw new RepositoryException(e);
110: }
111: }
112:
113: public void createPackage(XPDLPackage pkg)
114: throws RepositoryException {
115: try {
116: EJBLocalHelper.getPackageHome().create(pkg);
117: ProcessDefinitionLocalHome pdHome = EJBLocalHelper
118: .getProcessDefinitionHome();
119: WorkflowProcess[] workflows = pkg.getWorkflowProcess();
120: for (int i = 0, n = workflows.length; i < n; i++) {
121: WorkflowProcess workflow = workflows[i];
122: ProcessDefinitionLocal procDef = pdHome
123: .findByPrimaryKey(workflow.getId());
124: procDef.setState(WMProcessDefinitionState.ENABLED_INT);
125: }
126:
127: _svcMgr.getEngine().createTriggers(pkg);
128: } catch (CreateException e) {
129: throw new RepositoryException(e);
130: } catch (FinderException e) {
131: throw new RepositoryException(e);
132: } catch (WMWorkflowException e) {
133: throw new RepositoryException(e);
134: }
135: }
136:
137: public void deletePackage(String packageId)
138: throws RepositoryException {
139: try {
140: PackageLocal pkgBean = EJBLocalHelper.getPackageHome()
141: .findByPrimaryKey(packageId);
142: XPDLPackage pkg = pkgBean.getXPDLPackageBean();
143: pkgBean.remove();
144:
145: _svcMgr.getEngine().deleteTriggers(pkg, false);
146: } catch (FinderException e) {
147: throw new RepositoryException(e);
148: } catch (RemoveException e) {
149: throw new RepositoryException(e);
150: } catch (WMWorkflowException e) {
151: throw new RepositoryException(e);
152: }
153: }
154:
155: public XPDLPackage[] findPackages(WMFilter filter, boolean countFlag)
156: throws RepositoryException {
157:
158: try {
159: // The RO entity cannot be used in the current transaction after
160: // the RW version has been enlisted (the two will deadlock each
161: // other if used with the same PK value).
162: PackageROHome home = TransactionUtil
163: .isReadWrite(EJBLocalHelper.PACKAGE) ? (PackageROHome) EJBLocalHelper
164: .getPackageHome()
165: : EJBLocalHelper.getPackageROHome();
166:
167: if (countFlag) {
168: int count = home.count(filter);
169: return new XPDLPackage[count];
170: } else {
171: Collection pkgBeans = filter == null ? home.findAll()
172: : home.xfindByFilter(filter);
173:
174: XPDLPackage[] packages = new XPDLPackage[pkgBeans
175: .size()];
176: int j = 0;
177: for (Iterator i = pkgBeans.iterator(); i.hasNext();) {
178: PackageRO pkg = (PackageRO) i.next();
179: packages[j++] = pkg.getXPDLPackageBean();
180: }
181: return packages;
182: }
183: } catch (FinderException e) {
184: throw new RepositoryException(e);
185: }
186: }
187:
188: public XPDLPackage findPackage(String packageId)
189: throws RepositoryException {
190: try {
191: // The RO entity cannot be used in the current transaction after
192: // the RW version has been enlisted (the two will deadlock each
193: // other if used with the same PK value).
194: return TransactionUtil.isReadWrite(EJBLocalHelper.PACKAGE) ? EJBLocalHelper
195: .getPackageHome().findByPrimaryKey(packageId)
196: .getXPDLPackageBean()
197: : EJBLocalHelper.getPackageROHome()
198: .findByPrimaryKey(packageId)
199: .getXPDLPackageBean();
200: } catch (javax.ejb.ObjectNotFoundException e) {
201: throw new ObjectNotFoundException(packageId);
202: } catch (FinderException e) {
203: throw new RepositoryException(e);
204: }
205: }
206:
207: public void updatePackage(XPDLPackage pkg)
208: throws RepositoryException {
209: try {
210: PackageLocal pkgBean = EJBLocalHelper.getPackageHome()
211: .findByPrimaryKey(pkg.getId());
212: pkgBean.setXPDLPackageBean(pkg);
213:
214: _svcMgr.getEngine().updateTriggers(pkg);
215: } catch (javax.ejb.ObjectNotFoundException e) {
216: throw new ObjectNotFoundException(pkg.getId());
217: } catch (FinderException e) {
218: throw new RepositoryException(e);
219: } catch (WMWorkflowException e) {
220: throw new RepositoryException(e);
221: }
222: }
223:
224: public WorkflowProcess findWorkflowProcess(String procDefId)
225: throws RepositoryException {
226:
227: try {
228: // The RO entity cannot be used in the current transaction after
229: // the RW version has been enlisted (the two will deadlock each
230: // other if used with the same PK value).
231: XPDLPackage pkg = TransactionUtil
232: .isReadWrite(EJBLocalHelper.PROCESS_DEFINITION) ? EJBLocalHelper
233: .getProcessDefinitionHome().findByPrimaryKey(
234: procDefId).getXpdlPackage()
235: .getXPDLPackageBean()
236: : EJBLocalHelper.getProcessDefinitionROHome()
237: .findByPrimaryKey(procDefId)
238: .getXpdlPackage().getXPDLPackageBean();
239:
240: // Extract the workflow we're looking for.
241: WorkflowProcess workflow = pkg
242: .getWorkflowProcess(procDefId);
243: if (workflow == null)
244: throw new ObjectNotFoundException(procDefId);
245: return workflow;
246: } catch (javax.ejb.ObjectNotFoundException e) {
247: throw new ObjectNotFoundException(procDefId);
248: } catch (FinderException e) {
249: throw new RepositoryException(e);
250: }
251: }
252:
253: public WorkflowProcess[] findWorkflowProcesses(String name,
254: boolean validOnly) throws RepositoryException {
255:
256: try {
257: // The RO entity cannot be used in the current transaction after
258: // the RW version has been enlisted (the two will deadlock each
259: // other if used with the same PK value).
260: ProcessDefinitionROHome home = TransactionUtil
261: .isReadWrite(EJBLocalHelper.PROCESS_DEFINITION) ? (ProcessDefinitionROHome) EJBLocalHelper
262: .getProcessDefinitionHome()
263: : EJBLocalHelper.getProcessDefinitionROHome();
264:
265: // Select the matching process definitions.
266: Collection procDefs = validOnly ? home.findByName(name,
267: new Date()) : home.findByName(name);
268: return toWorkflowProcesses(procDefs);
269: } catch (FinderException e) {
270: throw new RepositoryException(e);
271: }
272: }
273:
274: public WorkflowProcess[] findWorkflowProcesses(WMFilter filter,
275: boolean countFlag) throws RepositoryException {
276:
277: try {
278: // The RO entity cannot be used in the current transaction after
279: // the RW version has been enlisted (the two will deadlock each
280: // other if used with the same PK value).
281: ProcessDefinitionROHome home = TransactionUtil
282: .isReadWrite(EJBLocalHelper.PROCESS_DEFINITION) ? (ProcessDefinitionROHome) EJBLocalHelper
283: .getProcessDefinitionHome()
284: : EJBLocalHelper.getProcessDefinitionROHome();
285:
286: WorkflowProcess[] workflows;
287: if (countFlag) {
288: int count = home.count(filter);
289: workflows = new WorkflowProcess[count];
290: } else {
291: // Select the matching process definitions.
292: Collection procDefs = filter == null ? home.findAll()
293: : home.xfindByFilter(filter);
294: workflows = toWorkflowProcesses(procDefs);
295: }
296: return workflows;
297: } catch (FinderException e) {
298: throw new RepositoryException(e);
299: }
300: }
301:
302: private static WorkflowProcess[] toWorkflowProcesses(
303: Collection procDefs) {
304: WorkflowProcess[] workflows = new WorkflowProcess[procDefs
305: .size()];
306: int k = 0;
307: Map pkgMap = new HashMap();
308: for (Iterator i = procDefs.iterator(); i.hasNext();) {
309: ProcessDefinitionRO procDef = (ProcessDefinitionRO) i
310: .next();
311: String pkgId = procDef.getPackageId();
312: String procDefId = procDef.getProcessDefinitionId();
313:
314: // Get the XPDL package containing this process definition.
315: XPDLPackage pkg = (XPDLPackage) pkgMap.get(pkgId);
316: if (pkg == null) {
317: pkg = procDef.getXPDLPackageRO().getXPDLPackageBean();
318: pkgMap.put(pkgId, pkg);
319: }
320:
321: // Find the WorkflowProcess corresponding to this process
322: // definition and add it to the array.
323: workflows[k++] = pkg.getWorkflowProcess(procDefId);
324: }
325: return workflows;
326: }
327:
328: public int findProcessDefinitionState(String processDefinitionId)
329: throws RepositoryException {
330:
331: try {
332: return TransactionUtil
333: .isReadWrite(EJBLocalHelper.PROCESS_DEFINITION) ? EJBLocalHelper
334: .getProcessDefinitionHome().findByPrimaryKey(
335: processDefinitionId).getState()
336: : EJBLocalHelper.getProcessDefinitionROHome()
337: .findByPrimaryKey(processDefinitionId)
338: .getState();
339: } catch (javax.ejb.ObjectNotFoundException e) {
340: throw new ObjectNotFoundException(processDefinitionId);
341: } catch (FinderException e) {
342: throw new RepositoryException(e);
343: }
344: }
345:
346: protected Log getLogger() {
347: return _logger;
348: }
349:
350: public void updateProcessDefinitionState(
351: String processDefinitionId, int newState)
352: throws RepositoryException {
353:
354: try {
355: ProcessDefinitionLocal procDef = EJBLocalHelper
356: .getProcessDefinitionHome().findByPrimaryKey(
357: processDefinitionId);
358: procDef.setState(newState);
359: String pkgId = procDef.getPackageId();
360: PackageLocal pkg = EJBLocalHelper.getPackageHome()
361: .findByPrimaryKey(pkgId);
362: pkg
363: .setProcessDefinitionState(processDefinitionId,
364: newState);
365: } catch (javax.ejb.ObjectNotFoundException e) {
366: throw new ObjectNotFoundException(processDefinitionId);
367: } catch (FinderException e) {
368: throw new RepositoryException(e);
369: }
370: }
371:
372: public String getServiceName() {
373: return SERVICE_NAME;
374: }
375: }
|