0001: /*
0002: * This file is part of the WfMOpen project.
0003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
0004: * All rights reserved.
0005: *
0006: * This program is free software; you can redistribute it and/or modify
0007: * it under the terms of the GNU General Public License as published by
0008: * the Free Software Foundation; either version 2 of the License, or
0009: * (at your option) any later version.
0010: *
0011: * This program is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0014: * GNU General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU General Public License
0017: * along with this program; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0019: *
0020: * $Id: ProcessDefinitionDirectoryEJB.java,v 1.14 2007/07/04 21:32:22 mlipp Exp $
0021: *
0022: * $Log: ProcessDefinitionDirectoryEJB.java,v $
0023: * Revision 1.14 2007/07/04 21:32:22 mlipp
0024: * Using local interface whereever possible.
0025: *
0026: * Revision 1.13 2007/05/03 21:58:25 mlipp
0027: * Internal refactoring for making better use of local EJBs.
0028: *
0029: * Revision 1.12 2007/03/01 12:34:09 schnelle
0030: * Typo.
0031: *
0032: * Revision 1.11 2006/10/11 09:06:08 drmlipp
0033: * Fixed EJB naming.
0034: *
0035: * Revision 1.10 2006/10/07 20:41:34 mlipp
0036: * Merged J2EE 1.4 adaptions from test branch.
0037: *
0038: * Revision 1.9 2006/10/01 10:03:19 mlipp
0039: * Removed "hidden" process initialization.
0040: *
0041: * Revision 1.8 2006/09/29 12:32:10 drmlipp
0042: * Consistently using WfMOpen as projct name now.
0043: *
0044: * Revision 1.7 2006/09/28 09:50:13 drmlipp
0045: * Moved parsing methods to better place.
0046: *
0047: * Revision 1.6 2006/09/25 20:08:28 mlipp
0048: * Merged changes from 1.3.4p1.
0049: *
0050: * Revision 1.5 2005/04/22 15:11:03 drmlipp
0051: * Merged changes from 1.3 branch up to 1.3p15.
0052: *
0053: * Revision 1.3.4.12 2005/04/21 12:37:04 drmlipp
0054: * Moved warning about non-standard behaviour to proper place.
0055: *
0056: * Revision 1.3.4.11 2005/04/16 21:18:30 drmlipp
0057: * Made audit event filtering more flexible and added possibility to turn
0058: * off audit log.
0059: *
0060: * Revision 1.3.4.10 2005/04/15 21:07:40 drmlipp
0061: * Added "storeAuditEvents" flag.
0062: *
0063: * Revision 1.3.4.9 2005/04/14 15:08:52 drmlipp
0064: * Added "filterable" event auditing.
0065: *
0066: * Revision 1.3.4.8 2005/04/13 16:14:07 drmlipp
0067: * Optimized db access.
0068: *
0069: * Revision 1.4 2005/04/08 11:28:04 drmlipp
0070: * Merged changes from 1.3 branch up to 1.3p6.
0071: *
0072: * Revision 1.3.4.7 2005/04/07 15:54:22 drmlipp
0073: * Fixed problem with process not being started. Removed fix that handled
0074: * special case of subprocess only.
0075: *
0076: * Revision 1.3.4.6 2005/04/05 07:03:56 drmlipp
0077: * Re-activated fix for race condition.
0078: *
0079: * Revision 1.3.4.5 2005/04/04 20:09:07 drmlipp
0080: * Changed WLS transaction isolation.
0081: *
0082: * Revision 1.3.4.4 2005/04/04 12:41:17 drmlipp
0083: * Tentatively removed fix for race condition, caused different problems.
0084: *
0085: * Revision 1.3.4.3 2005/03/18 15:02:01 drmlipp
0086: * Optimized (reduced number of DB accesses).
0087: *
0088: * Revision 1.3.4.2 2005/03/17 12:57:25 drmlipp
0089: * Improved transaction handling ehile importing process definitions.
0090: *
0091: * Revision 1.3.4.1 2005/03/16 14:36:53 drmlipp
0092: * Fixed race condition during creation and start of subprocesses.
0093: *
0094: * Revision 1.3 2004/10/20 15:11:29 drmlipp
0095: * Simplified proces import.
0096: *
0097: * Revision 1.2 2004/09/10 12:44:29 drmlipp
0098: * Enabled call by reference for weblogic by default.
0099: *
0100: * Revision 1.1.1.4 2004/08/18 15:17:38 drmlipp
0101: * Update to 1.2
0102: *
0103: * Revision 1.28 2004/07/07 11:34:00 lipp
0104: * Clarified transaction attributes.
0105: *
0106: * Revision 1.27 2004/07/04 17:36:03 lipp
0107: * Added JOnAS support.
0108: *
0109: * Revision 1.26 2004/02/21 21:52:11 lipp
0110: * Moved ActivityFinder and ProcessMgrStub back to admin package.
0111: *
0112: * Revision 1.25 2004/02/21 21:31:00 lipp
0113: * Some more refactoring to resolve cyclic dependencies.
0114: *
0115: * Revision 1.24 2004/01/14 07:59:44 lipp
0116: * Added transaction isolation attribute for WLS.
0117: *
0118: * Revision 1.23 2003/11/11 15:44:25 lipp
0119: * Changed transaction attribute.
0120: *
0121: * Revision 1.22 2003/10/29 20:12:25 lipp
0122: * Fixed process definition copy bug.
0123: *
0124: * Revision 1.21 2003/10/06 15:32:57 lipp
0125: * More WebLogic adaptations.
0126: *
0127: * Revision 1.20 2003/09/26 12:52:01 lipp
0128: * Changed role names.
0129: *
0130: * Revision 1.19 2003/06/29 19:50:07 lipp
0131: * Moved primary key generator fropm JDBCUtil to EJBUtil and made some
0132: * fixes.
0133: *
0134: * Revision 1.18 2003/06/27 08:51:45 lipp
0135: * Fixed copyright/license information.
0136: *
0137: * Revision 1.17 2003/06/04 13:15:50 lipp
0138: * Optimized resource allocation/caching.
0139: *
0140: * Revision 1.16 2003/05/23 15:09:48 huaiyang
0141: * clean up the methods and variable for caching home interface.
0142: *
0143: * Revision 1.15 2003/05/22 09:20:53 lipp
0144: * Improved KeyGen referencing.
0145: *
0146: * Revision 1.14 2003/05/14 08:30:07 lipp
0147: * Package import behaviour changed.
0148: *
0149: * Revision 1.13 2003/04/26 16:11:14 lipp
0150: * Moved some classes to reduce package dependencies.
0151: *
0152: * Revision 1.12 2003/04/09 14:51:47 lipp
0153: * Improved caching.
0154: *
0155: * Revision 1.11 2003/03/31 16:50:28 huaiyang
0156: * Logging using common-logging.
0157: *
0158: * Revision 1.10 2003/03/03 12:18:23 lipp
0159: * Comment fixes.
0160: *
0161: * Revision 1.9 2003/02/28 15:30:53 huaiyang
0162: * use the method of setLargeString to set xpdl in prepareStatement.
0163: *
0164: * Revision 1.8 2003/02/21 16:38:51 lipp
0165: * Introduced UniversalPrepStmt.
0166: *
0167: * Revision 1.7 2003/02/18 15:09:35 lipp
0168: * Using JDBCUtil.getString now.
0169: *
0170: * Revision 1.6 2003/02/14 16:48:07 lipp
0171: * New primary key generator.
0172: *
0173: * Revision 1.5 2003/01/21 12:12:10 ott
0174: * next step weblogic 7.0
0175: *
0176: * Revision 1.4 2002/12/03 13:49:38 huaiyang
0177: * importProcessDefinitions method return list of prioritized message.
0178: *
0179: * Revision 1.3 2002/12/02 15:55:31 huaiyang
0180: * Replace ParseException with ImportException.
0181: *
0182: * Revision 1.2 2002/11/21 14:58:08 lipp
0183: * Improved debug output.
0184: *
0185: * Revision 1.1 2002/11/21 12:09:12 montag
0186: * Moved *Bean to *EJB for workflow.
0187: *
0188: * Revision 1.46 2002/11/21 11:37:11 montag
0189: * xdoclet for wfcore finished.
0190: *
0191: * Revision 1.45 2002/11/20 14:32:41 montag
0192: * begin generation of home and remote interfaces.
0193: *
0194: * Revision 1.44 2002/11/19 11:29:39 montag
0195: * begin generation of deployment descriptors.
0196: *
0197: * Revision 1.43 2002/11/06 13:29:43 huaiyang
0198: * constructor of processMgrStub changed.
0199: *
0200: * Revision 1.42 2002/11/05 14:07:09 huaiyang
0201: * patched the method of deleteProcessDefinition with
0202: * copyProcessDefinitionToProcess.
0203: *
0204: * Revision 1.41 2002/10/15 13:22:32 huaiyang
0205: * Remove system.out.println and printStackTrace.
0206: *
0207: * Revision 1.40 2002/09/27 15:24:01 barzik
0208: * optimized caching of process definitions
0209: *
0210: * Revision 1.39 2002/09/27 12:44:55 lipp
0211: * Moved validation to a separate class.
0212: *
0213: * Revision 1.38 2002/09/20 10:06:21 barzik
0214: * ...
0215: *
0216: * Revision 1.37 2002/09/20 09:56:26 barzik
0217: * process definition cache implementation (v0.1)
0218: *
0219: * Revision 1.36 2002/09/19 15:22:46 huaiyang
0220: * Use parseProcessDefinitions which returns a collection of process definition.
0221: *
0222: * Revision 1.35 2002/09/19 08:44:15 huaiyang
0223: * Moved validate staff from AbstractProcessDefinitionDirectory to
0224: * DefaultProcessDefinition.
0225: *
0226: * Revision 1.34 2002/09/18 11:10:32 barzik
0227: * extended to rollback transactions in case of application exceptions
0228: *
0229: * Revision 1.33 2002/09/08 18:49:18 lipp
0230: * Proper use of packageId and processId.
0231: *
0232: * Revision 1.32 2002/09/04 15:14:33 lipp
0233: * Removed dubious use of id as process definition identifier.
0234: *
0235: * Revision 1.31 2002/08/30 13:37:05 lipp
0236: * Using Workflow engine facade now.
0237: *
0238: * Revision 1.30 2002/08/27 11:36:37 lipp
0239: * Better use of ProcessDefinition.
0240: *
0241: * Revision 1.29 2002/08/26 20:23:13 lipp
0242: * Lots of method renames.
0243: *
0244: * Revision 1.28 2002/08/26 14:17:07 lipp
0245: * JavaDoc fixes.
0246: *
0247: * Revision 1.27 2002/08/22 08:47:29 lipp
0248: * Some minor optimizations.
0249: *
0250: * Revision 1.26 2002/08/21 22:06:47 lipp
0251: * Finished transition to ProcessMgrStub.
0252: *
0253: * Revision 1.25 2002/08/21 15:08:25 lipp
0254: * Replaced WfProcessMgrBean with an intelligent stub.
0255: *
0256: * Revision 1.24 2002/08/20 11:54:32 lipp
0257: * Cleaned up usage of XPDL and JDOM representation of processes and
0258: * process definitions.
0259: *
0260: * Revision 1.23 2002/08/01 10:13:17 huaiyang
0261: * Use JDOM instead of DOM now.
0262: *
0263: * Revision 1.22 2002/07/24 08:04:42 huaiyang
0264: * doccheck.
0265: *
0266: * Revision 1.21 2002/07/08 19:37:59 lipp
0267: * New import process definition method.
0268: *
0269: * Revision 1.20 2002/02/06 18:28:29 huaiyang
0270: * Add the methods of isEnabled/setEnabled.
0271: *
0272: * Revision 1.19 2002/02/01 15:06:50 lipp
0273: * Modified error handling for initial load.
0274: *
0275: * Revision 1.18 2002/02/01 14:30:36 lipp
0276: * Added error handling for process definition parsing.
0277: *
0278: * Revision 1.17 2002/01/23 22:28:05 lipp
0279: * Improved exception message.
0280: *
0281: * Revision 1.16 2002/01/17 16:45:06 lipp
0282: * ProcessDefinition moved to workflow.api.
0283: *
0284: * Revision 1.15 2002/01/16 14:21:54 robert
0285: * replace ProcessDefinitionDirectoryHome interface
0286: * from workflow/ejbs/admin to workflow/api/ejbhomes
0287: *
0288: * Revision 1.14 2002/01/16 09:21:34 robert
0289: * replace ConfigurationHome interface
0290: * from workflow/ejbs/admin to workflow/api/ejbhomes
0291: *
0292: * Revision 1.13 2002/01/15 12:21:25 robert
0293: * add getProcessTypes
0294: *
0295: * Revision 1.12 2002/01/14 12:02:48 robert
0296: * replace parameter DataSource with Connection (JDBCUtil.getFreePrimaryKey)
0297: *
0298: * Revision 1.11 2002/01/11 18:28:44 robert
0299: * replace getFree...PK methods with JDBCUtil.getFreePrimaryKey
0300: *
0301: * Revision 1.10 2002/01/11 14:42:35 robert
0302: * add IllegalArgumentException to getProcessDefinition
0303: *
0304: * Revision 1.9 2001/12/15 16:42:08 lipp
0305: * Cleand up exception declaration for finder methods in home interfaces.
0306: *
0307: * Revision 1.8 2001/12/14 13:28:25 lipp
0308: * Cleaned up implementation structure of ProcessDefinitionDirectory,
0309: * renamed Package to ProcessDirectoryPackage and restored initial load
0310: * of process definitions.
0311: *
0312: * Revision 1.7 2001/12/13 22:13:09 lipp
0313: * New method to check if a process definition exists.
0314: *
0315: * Revision 1.6 2001/12/10 09:53:58 robert
0316: * changed Vector to ArrayList
0317: *
0318: * Revision 1.5 2001/12/04 09:54:05 robert
0319: * modifyied error handlig for validating parser
0320: *
0321: * Revision 1.4 2001/12/03 16:15:29 robert
0322: * now will parsing validate
0323: *
0324: * Revision 1.3 2001/11/30 18:53:49 robert
0325: * Added removeProcessDefinition method.
0326: *
0327: * Revision 1.2 2001/11/26 10:54:53 robert
0328: * modify the package name for ProsessDefinition beans from definitions to admin
0329: *
0330: * Revision 1.1 2001/11/26 10:42:46 robert
0331: * replace the ProsessDefinition beans from ../definitions to admin
0332: *
0333: * Revision 1.25 2001/11/23 20:03:20 lipp
0334: * Update to hsql 1.6 (from JBoss-2.4.3) / trying to fix
0335: * ProcessDefinitionDirectory problem (not successful yet)
0336: *
0337: * Revision 1.24 2001/11/23 16:48:16 robert
0338: * storeProcessDefinitions method call ctx.setRollbackOnly on sql error
0339: *
0340: * Revision 1.23 2001/11/22 13:18:18 robert
0341: * finished persistence handling for ProcessDefinition
0342: *
0343: * Revision 1.22 2001/11/22 09:42:08 robert
0344: * move the persistence handling of ProcessDefinition
0345: * to the ProcessDefinitionDirectoryBean
0346: *
0347: * Revision 1.21 2001/11/21 17:50:48 robert
0348: * modify sql-statement
0349: *
0350: * Revision 1.20 2001/11/21 17:03:03 robert
0351: * header infos of ProcessDefinition will stored as blob
0352: *
0353: * Revision 1.19 2001/11/20 14:00:00 robert
0354: * temporary status of ProcessDefinition implementation
0355: *
0356: * Revision 1.18 2001/11/16 15:57:57 robert
0357: * rename column description to xpdl (table processdefinition)
0358: *
0359: * Revision 1.17 2001/11/16 15:38:59 robert
0360: * getProcessDefinition returns now an ProcesDefinition
0361: *
0362: * Revision 1.16 2001/11/16 10:01:21 lipp
0363: * Prepared cleanup of ProcessDefintion handling.
0364: *
0365: * Revision 1.15 2001/11/13 15:20:19 montag
0366: * changed type of header parameter from string to byte[]
0367: *
0368: * Revision 1.14 2001/11/09 10:11:52 montag
0369: * different jndi names for jdbc resource of workflow and staffmgmt
0370: *
0371: * Revision 1.13 2001/10/25 07:49:33 lipp
0372: * Moved W3CDomUtil to de.danet.an.util.web
0373: *
0374: * Revision 1.12 2001/10/25 07:38:05 lipp
0375: * Moved JDBCUtil to de.danet.an.util
0376: *
0377: * Revision 1.11 2001/10/19 15:34:05 montag
0378: * Automatic reading of process definitions.
0379: *
0380: * Revision 1.10 2001/10/19 09:56:45 montag
0381: * process types now from the process definition directory.
0382: * creation of activities due to process definition.
0383: *
0384: * Revision 1.9 2001/10/17 15:02:53 montag
0385: * ProcessDefinitionInfo now inner class of ProcessDefinition
0386: *
0387: * Revision 1.8 2001/10/17 14:50:14 montag
0388: * New class ProcessDefinitionInfo
0389: *
0390: * Revision 1.7 2001/10/17 14:23:13 montag
0391: * changed return type for importProcessDefinitions
0392: *
0393: * Revision 1.6 2001/10/17 14:06:29 montag
0394: * no ProcessDefinitionInfo
0395: *
0396: * Revision 1.5 2001/10/17 12:32:45 montag
0397: * javadoc
0398: *
0399: * Revision 1.4 2001/10/17 12:16:12 montag
0400: * importProcessDefinitions working
0401: *
0402: * Revision 1.3 2001/10/17 12:12:38 montag
0403: * importProcessDefinitions working
0404: *
0405: * Revision 1.2 2001/10/16 09:55:21 montag
0406: * javadoc
0407: *
0408: * Revision 1.1 2001/10/16 09:43:15 montag
0409: * new session bean ProcessDefinitionDirectory
0410: *
0411: *
0412: */
0413: package de.danet.an.workflow.ejbs.admin;
0414:
0415: import java.io.ByteArrayInputStream;
0416: import java.io.IOException;
0417: import java.io.OptionalDataException;
0418: import java.io.Serializable;
0419: import java.io.StringReader;
0420:
0421: import java.util.ArrayList;
0422: import java.util.Collection;
0423: import java.util.Collections;
0424: import java.util.HashMap;
0425: import java.util.Iterator;
0426: import java.util.List;
0427: import java.util.Map;
0428:
0429: import java.sql.Connection;
0430: import java.sql.PreparedStatement;
0431: import java.sql.ResultSet;
0432: import java.sql.SQLException;
0433:
0434: import javax.ejb.CreateException;
0435: import javax.ejb.EJBException;
0436: import javax.ejb.FinderException;
0437: import javax.ejb.NoSuchEntityException;
0438: import javax.ejb.SessionBean;
0439: import javax.ejb.SessionContext;
0440: import javax.naming.NamingException;
0441: import javax.sql.DataSource;
0442:
0443: import org.xml.sax.InputSource;
0444:
0445: import de.danet.an.util.EJBUtil;
0446: import de.danet.an.util.JDBCUtil;
0447: import de.danet.an.util.ResourceNotAvailableException;
0448: import de.danet.an.util.UniversalPrepStmt;
0449:
0450: import de.danet.an.workflow.internalapi.ExtProcessLocal;
0451: import de.danet.an.workflow.localcoreapi.WfProcessLocal;
0452: import de.danet.an.workflow.omgcore.InvalidRequesterException;
0453: import de.danet.an.workflow.omgcore.NotEnabledException;
0454: import de.danet.an.workflow.omgcore.RequesterRequiredException;
0455: import de.danet.an.workflow.omgcore.WfRequester;
0456:
0457: import de.danet.an.workflow.api.ImportException;
0458: import de.danet.an.workflow.api.InvalidKeyException;
0459: import de.danet.an.workflow.api.ProcessDefinition;
0460: import de.danet.an.workflow.api.ProcessMgr;
0461:
0462: import de.danet.an.workflow.domain.AbstractProcessDefinitionDirectory;
0463: import de.danet.an.workflow.domain.DefaultProcessDefinition;
0464:
0465: import de.danet.an.workflow.ejbs.core.WfProcessHome;
0466: import de.danet.an.workflow.ejbs.core.WfProcessLocalHome;
0467:
0468: /**
0469: * The session bean <code>ProcessDefinitionDirectoryEJB</code> manage the
0470: * process definitions.<P>
0471: *
0472: * Setting log level to <code>DEBUG</code> outputs messages about
0473: * process definition caching.
0474: *
0475: * @ejb.bean name="ProcessDefinitionDirectory"
0476: * display-name="ProcessDefinitionDirectory"
0477: * jndi-name="ejb/@@@_JNDI_Name_Prefix_@@@ProcessDefinitionDirectory"
0478: * local-jndi-name="ejb/@@@_JNDI_Name_Prefix_@@@ProcessDefinitionDirectoryLocal"
0479: * type="Stateless" transaction-type="Container" view-type="both"
0480: * @jonas.bean ejb-name="ProcessDefinitionDirectory"
0481: * @ejb.home
0482: * remote-class="de.danet.an.workflow.ejbs.admin.ProcessDefinitionDirectoryHome"
0483: * @ejb.interface
0484: * extends="javax.ejb.EJBObject, de.danet.an.workflow.api.ProcessDefinitionDirectory"
0485: * remote-class="de.danet.an.workflow.ejbs.admin.ProcessDefinitionDirectory"
0486: * local-extends="javax.ejb.EJBLocalObject, de.danet.an.workflow.localapi.ProcessDefinitionDirectoryLocal"
0487: * local-class="de.danet.an.workflow.ejbs.admin.ProcessDefinitionDirectoryLocal"
0488: * @ejb.ejb-ref ejb-name="ConfigurationBean" view-type="remote"
0489: * ref-name="ejb/Configuration"
0490: * @ejb.ejb-ref ejb-name="ProcessBean" view-type="remote"
0491: * @ejb.ejb-ref ejb-name="ProcessBean" view-type="local"
0492: * @ejb.ejb-external-ref ref-name="ejb/JdbcKeyGenLocal" link="KeyGen"
0493: * type="Session" view-type="local" home="de.danet.an.util.KeyGenLocalHome"
0494: * business="de.danet.an.util.KeyGenLocal"
0495: * @ejb.resource-ref res-ref-name="jdbc/WfEngine"
0496: * res-type="javax.sql.DataSource" res-auth="Container"
0497: * @jonas.resource res-ref-name="jdbc/WfEngine" jndi-name="jdbc_1"
0498: * @weblogic.enable-call-by-reference True
0499: * @weblogic.resource-description
0500: * res-ref-name="jdbc/WfEngine" jndi-name="DefaultDS"
0501: * @ejb.transaction type="Required"
0502: * @ejb.permission role-name="WfMOpenAdmin"
0503: * @weblogic.transaction-isolation TRANSACTION_READ_COMMITTED
0504: */
0505: public class ProcessDefinitionDirectoryEJB extends
0506: AbstractProcessDefinitionDirectory implements SessionBean {
0507:
0508: /**
0509: * logger of this class.
0510: */
0511: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
0512: .getLog(ProcessDefinitionDirectoryEJB.class);
0513:
0514: /**
0515: * A cache for for process definitions as found in the database
0516: */
0517: private static Map processDefinitionCache = Collections
0518: .synchronizedMap(new HashMap());
0519:
0520: /**
0521: * An index on the cache using pacjageId/processId as key.
0522: */
0523: private static Map processDefinitionDBIds = Collections
0524: .synchronizedMap(new HashMap());
0525:
0526: /**
0527: * The SessionContext interface of the instance.
0528: */
0529: private SessionContext ctx;
0530:
0531: /**
0532: * The data source of the database.
0533: * @see javax.sql.DataSource
0534: */
0535: private DataSource ds = null;
0536:
0537: /** Database name */
0538: private static final String DB_NAME = "java:comp/env/jdbc/WfEngine";
0539:
0540: private static boolean fullyInitialized = false;
0541:
0542: /** The cached home interface of the process EJB. */
0543: private WfProcessHome processHomeCache = null;
0544: private WfProcessLocalHome processLocalHomeCache = null;
0545:
0546: /** The cached home interface of the configuration EJB. */
0547: private ConfigurationHome configurationHomeCache = null;
0548:
0549: /**
0550: * This operation method delivers a WfProcessHome interface.
0551: * @return home interface of WfProcessBean
0552: * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfProcess</code>}
0553: */
0554: private WfProcessHome processHome()
0555: throws ResourceNotAvailableException {
0556: if (processHomeCache == null) {
0557: processHomeCache = (WfProcessHome) EJBUtil.retrieveEJBHome(
0558: WfProcessHome.class,
0559: "java:comp/env/ejb/ProcessBean");
0560: }
0561: return processHomeCache;
0562: }
0563:
0564: /**
0565: * This operation method delivers a WfProcessLocalHome interface.
0566: * @return home interface of WfProcessBean
0567: * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfProcess</code>}
0568: */
0569: private WfProcessLocalHome processLocalHome() {
0570: if (processLocalHomeCache == null) {
0571: try {
0572: processLocalHomeCache = (WfProcessLocalHome) EJBUtil
0573: .retrieveEJBLocalHome(WfProcessLocalHome.class,
0574: "java:comp/env/ejb/ProcessBeanLocal");
0575: } catch (ResourceNotAvailableException e) {
0576: throw new EJBException(e);
0577: }
0578: }
0579: return processLocalHomeCache;
0580: }
0581:
0582: /**
0583: * This operation method delivers a ConfigurationHome interface.
0584: * @return home interface of ConfigurationBean
0585: */
0586: private ConfigurationHome configurationHome()
0587: throws ResourceNotAvailableException {
0588: if (configurationHomeCache == null) {
0589: configurationHomeCache = (ConfigurationHome) EJBUtil
0590: .retrieveEJBHome(ConfigurationHome.class,
0591: "java:comp/env/ejb/Configuration");
0592: }
0593: return configurationHomeCache;
0594: }
0595:
0596: /**
0597: * set the session context and get new data source.
0598: * @param context the given session context.
0599: * @throws EJBException if problem encountered with getting the data source.
0600: */
0601: public void setSessionContext(SessionContext context)
0602: throws EJBException {
0603: ctx = context;
0604: processHomeCache = null;
0605: configurationHomeCache = null;
0606: try {
0607: // getting new data source
0608: ds = JDBCUtil.refreshDS(null, DB_NAME);
0609: } catch (NamingException ne) {
0610: throw new EJBException(ne);
0611: }
0612: }
0613:
0614: /**
0615: * Not called for stateless session bean.
0616: */
0617: public void ejbActivate() {
0618: }
0619:
0620: /**
0621: * Not called for stateless session bean.
0622: */
0623: public void ejbPassivate() {
0624: }
0625:
0626: /**
0627: * A container invokes this method before it ends the life of the session
0628: * object. This happens as a result of a client's invoking a remove
0629: * operation, or when a container decides to terminate the session object
0630: * after a timeout.
0631: * @see javax.ejb.SessionBean
0632: */
0633: public void ejbRemove() {
0634: ds = null;
0635: processHomeCache = null;
0636: configurationHomeCache = null;
0637: ctx = null;
0638: }
0639:
0640: /**
0641: * Create an new instance of ProcessDefinitonDirectoryBean.
0642: * @throws CreateException Throws if the ProcessDefinitionDirectoryBean
0643: * can not be created.
0644: */
0645: public void ejbCreate() throws CreateException {
0646: init();
0647: }
0648:
0649: private void init() {
0650: }
0651:
0652: /**
0653: * This operation method delivers a collection of all
0654: * defined process definitions or an empty collection if no process
0655: * definition are found.
0656: *
0657: * @return collection
0658: * @ejb.interface-method view-type="remote"
0659: */
0660: public Collection processDefinitions() {
0661: Collection definitions = new ArrayList();
0662: Connection con = null;
0663: PreparedStatement prepStmt = null;
0664: ResultSet rs = null;
0665: try {
0666: try {
0667: con = ds.getConnection();
0668: prepStmt = con
0669: .prepareStatement("SELECT PackageId, ProcessId FROM ProcessDefinition ");
0670: rs = prepStmt.executeQuery();
0671: while (rs.next()) {
0672: String pkgId = JDBCUtil.getString(ds, rs, 1);
0673: String prcId = JDBCUtil.getString(ds, rs, 2);
0674: try {
0675: definitions.add(lookupProcessDefinition(pkgId,
0676: prcId));
0677: } catch (InvalidKeyException e) {
0678: logger
0679: .debug("Couldn't find definition, propably"
0680: + " deleted since key lookup.");
0681: }
0682: }
0683: } finally {
0684: JDBCUtil.closeAll(rs, prepStmt, con);
0685: }
0686: } catch (SQLException se) {
0687: throw new EJBException(se);
0688: } catch (OptionalDataException ode) {
0689: throw new EJBException(ode);
0690: } catch (IOException ioe) {
0691: throw new EJBException(ioe);
0692: }
0693: return definitions;
0694: }
0695:
0696: /**
0697: * This method delivers the process manager for the given process.
0698: *
0699: * @param packageId Id attribute of the process package.
0700: * @param processId Id attribute of the process.
0701: * @return the process manager for the process type.
0702: * @throws InvalidKeyException if no process definition with
0703: * the given ids exists.
0704: * @ejb.interface-method view-type="remote"
0705: */
0706: public ProcessMgr processMgr(String packageId, String processId)
0707: throws InvalidKeyException {
0708: try {
0709: ProcessDefinition procDef = lookupProcessDefinition(
0710: packageId, processId);
0711: return new ProcessMgrStub(packageId, processId, procDef
0712: .mgrName(), null,
0713: (ProcessDefinitionDirectoryHome) ctx.getEJBHome(),
0714: processHome());
0715: } catch (ResourceNotAvailableException re) {
0716: throw new EJBException(re);
0717: } catch (InvalidKeyException ikex) {
0718: ctx.setRollbackOnly();
0719: throw ikex;
0720: }
0721: }
0722:
0723: /**
0724: * This method checks if a process definiton with the given ids
0725: * exists in the database.
0726: *
0727: * @param packageId Id attribute of the process package.
0728: * @param processId Id attribute of the process.
0729: * @return <code>true</code> if a process definition with the given
0730: * <code>id</code> exists, otherwise <code>false</code>.
0731: * @ejb.interface-method view-type="remote"
0732: */
0733: public boolean processDefinitionExists(String packageId,
0734: String processId) {
0735: ProcessDefinition processDefinition = null;
0736: Connection con = null;
0737: PreparedStatement prepStmt = null;
0738: ResultSet rs = null;
0739: String definition = null;
0740: try {
0741: try {
0742: con = ds.getConnection();
0743: prepStmt = con
0744: .prepareStatement("SELECT DBId FROM ProcessDefinition "
0745: + "WHERE PackageId = ? AND ProcessId = ?");
0746: prepStmt.setString(1, packageId);
0747: prepStmt.setString(2, processId);
0748: rs = prepStmt.executeQuery();
0749: if (rs.next()) {
0750: return true;
0751: }
0752: } finally {
0753: JDBCUtil.closeAll(rs, prepStmt, con);
0754: }
0755: } catch (SQLException se) {
0756: throw new EJBException(se);
0757: }
0758: return false;
0759: }
0760:
0761: /**
0762: * This operation method import new process definitions from an
0763: * XPDL description.
0764: *
0765: * @param processDefinitions document describing the process definitions.
0766: * @return list of prioritized message
0767: * {@link de.danet.an.workflow.api.PrioritizedMessage
0768: * <code>PrioritizedMessage</code>}
0769: * @throws ImportException if the input is not a correct.
0770: * @ejb.interface-method view-type="remote"
0771: */
0772: public List importProcessDefinitions(String processDefinitions)
0773: throws ImportException {
0774: return importProcessDefinitions(new InputSource(
0775: new StringReader(processDefinitions)));
0776: }
0777:
0778: /**
0779: * This operation method import new process definitions from an
0780: * XPDL description.
0781: *
0782: * @param processDefinitions byte array resulting from an
0783: * InputStream that describes the process definitions.
0784: * @return list of prioritized message
0785: * {@link de.danet.an.workflow.api.PrioritizedMessage
0786: * <code>PrioritizedMessage</code>}
0787: * @throws ImportException if the input is not a correct.
0788: * @ejb.interface-method view-type="remote"
0789: */
0790: public List importProcessDefinitions(byte[] processDefinitions)
0791: throws ImportException {
0792: return importProcessDefinitions(new InputSource(
0793: new ByteArrayInputStream(processDefinitions)));
0794: }
0795:
0796: /**
0797: * This operation method import new process definitions from an
0798: * XPDL description.
0799: *
0800: * @param inSrc the input that describes the package as XPDL.
0801: * @return list of prioritized message
0802: * {@link de.danet.an.workflow.api.PrioritizedMessage
0803: * <code>PrioritizedMessage</code>}
0804: * @throws ImportException if the input is not a correct.
0805: */
0806: private List importProcessDefinitions(InputSource inSrc)
0807: throws ImportException {
0808: try {
0809: List l = AbstractProcessDefinitionDirectory
0810: .parseProcessDefinitions(inSrc);
0811: if (l.size() > 1) {
0812: // Remove all defintions with the imported package id
0813: String pkgId = ((ProcessDefinition) l.get(1))
0814: .packageId();
0815: List tbr = new ArrayList();
0816: try {
0817: Connection con = null;
0818: PreparedStatement prepStmt = null;
0819: ResultSet rs = null;
0820: try {
0821: con = ds.getConnection();
0822: prepStmt = con
0823: .prepareStatement("SELECT ProcessId FROM ProcessDefinition "
0824: + "WHERE PackageId = ?");
0825: prepStmt.setString(1, pkgId);
0826: rs = prepStmt.executeQuery();
0827: while (rs.next()) {
0828: tbr.add(rs.getString(1));
0829: }
0830: rs.close();
0831: rs = null;
0832: prepStmt.close();
0833: prepStmt = null;
0834: for (Iterator i = tbr.iterator(); i.hasNext();) {
0835: String processId = (String) i.next();
0836: try {
0837: ProcessDefinition procDef = lookupProcessDefinition(
0838: pkgId, processId);
0839: copyProcessDefinitionToProcesses(procDef);
0840: } catch (InvalidKeyException e) {
0841: logger
0842: .debug("Process definition has disappeared: "
0843: + pkgId
0844: + "/"
0845: + processId);
0846: }
0847: uncacheDefinition(pkgId + "/" + processId);
0848: }
0849: Iterator it = l.subList(1, l.size()).iterator();
0850: prepStmt = con
0851: .prepareStatement("DELETE FROM ProcessDefinition "
0852: + "WHERE PackageId = ?");
0853: prepStmt.setString(1, pkgId);
0854: prepStmt.executeUpdate();
0855: prepStmt.close();
0856: prepStmt = null;
0857: while (it.hasNext()) {
0858: ProcessDefinition pd = (ProcessDefinition) it
0859: .next();
0860: insertProcessDefinition(ds, con, pd);
0861: }
0862: } finally {
0863: JDBCUtil.closeAll(rs, prepStmt, con);
0864: }
0865: } catch (SQLException e) {
0866: throw new EJBException(e);
0867: }
0868: }
0869: return (List) l.get(0);
0870: } catch (ImportException pex) {
0871: ctx.setRollbackOnly();
0872: throw pex;
0873: }
0874: }
0875:
0876: /**
0877: * Insert the process definition into the database.
0878: * @throws SQLException, if another process with the
0879: * same id already exist in the database.
0880: */
0881: private void insertProcessDefinition(DataSource ds, Connection con,
0882: ProcessDefinition processDefiniton) throws SQLException {
0883: UniversalPrepStmt prepStmt = null;
0884: try {
0885: prepStmt = new UniversalPrepStmt(
0886: ds,
0887: con,
0888: "INSERT INTO ProcessDefinition ("
0889: + "DBId, PackageId, ProcessId, Xpdl, Enabled) "
0890: + "VALUES (?, ?, ?, ?, 'T')");
0891: int offset = 1;
0892: prepStmt.setLong(offset++, EJBUtil
0893: .newPrimaryKey("processdefinition"));
0894: prepStmt.setString(offset++, processDefiniton.packageId());
0895: prepStmt.setString(offset++, processDefiniton.processId());
0896: prepStmt
0897: .setLargeString(offset++, processDefiniton.toXPDL());
0898: prepStmt.executeUpdate();
0899: } catch (ResourceNotAvailableException e) {
0900: throw new SQLException("Cannot get primary key"
0901: + e.getMessage());
0902: } catch (IOException e) {
0903: throw new EJBException(e);
0904: } finally {
0905: JDBCUtil.closeAll(null, prepStmt, null);
0906: }
0907: }
0908:
0909: /**
0910: * This operation method removes a process definition with the
0911: * given ids from the database. If called for a definition that
0912: * does not exist, it does nothing.
0913: *
0914: * @param packageId Id attribute of the process package.
0915: * @param processId Id attribute of the process.
0916: * @throws InvalidKeyException if packageId or processId are
0917: * (formally) invalid ids.
0918: * @ejb.interface-method view-type="remote"
0919: */
0920: public void removeProcessDefinition(String packageId,
0921: String processId) throws InvalidKeyException {
0922: try {
0923: ProcessDefinition procDef = lookupProcessDefinition(
0924: packageId, processId);
0925: copyProcessDefinitionToProcesses(procDef);
0926: PreparedStatement prepStmt = null;
0927: Connection con = null;
0928: try {
0929: uncacheDefinition(packageId + "/" + processId);
0930: // remove process definition from the database
0931: con = ds.getConnection();
0932: prepStmt = con
0933: .prepareStatement("DELETE FROM ProcessDefinition "
0934: + "WHERE PackageId = ? AND ProcessId = ?");
0935: prepStmt.setString(1, packageId);
0936: prepStmt.setString(2, processId);
0937: prepStmt.executeUpdate();
0938: } finally {
0939: JDBCUtil.closeAll(null, prepStmt, con);
0940: }
0941: } catch (InvalidKeyException e) {
0942: // do nothing, as specified
0943: } catch (SQLException e) {
0944: throw new EJBException(e);
0945: }
0946: }
0947:
0948: /**
0949: * This method delivers the process definition for the
0950: * given ids. If no process definition with the ids exist, it
0951: * throws an <code>IllegalArgumentException</code>.
0952: *
0953: * @param packageId the package id
0954: * @param processId the process definition id
0955: * @return the found ProcessDefinition object
0956: * @throws InvalidKeyException if no process definition with
0957: * the given ids exists.
0958: * @ejb.interface-method view-type="remote"
0959: */
0960: public ProcessDefinition lookupProcessDefinition(String packageId,
0961: String processId) throws InvalidKeyException {
0962: return lookupProcessDefinitionInfo(packageId, processId).processDefinition;
0963: }
0964:
0965: /**
0966: * Result type for {@link #lookupProcessDefinitionInfo
0967: * <code>lookupProcessDefinitionInfo</code>.
0968: */
0969: public class ProcessDefinitionInfo implements Serializable {
0970: /** The process definition. */
0971: public ProcessDefinition processDefinition;
0972: /** The enabled state. */
0973: public boolean enabled;
0974:
0975: /**
0976: * Create a new object with attributes initialized to the
0977: * given values.
0978: * @param pd the process definition
0979: * @param enabState the enabled state
0980: */
0981: public ProcessDefinitionInfo(ProcessDefinition pd,
0982: boolean enabState) {
0983: processDefinition = pd;
0984: enabled = enabState;
0985: }
0986: }
0987:
0988: /**
0989: * This method delivers the process definition for the
0990: * given ids. If no process definition with the ids exist, it
0991: * throws an <code>IllegalArgumentException</code>.
0992: *
0993: * @param packageId the package id
0994: * @param processId the process definition id
0995: * @return the found ProcessDefinition object
0996: * @throws InvalidKeyException if no process definition with
0997: * the given ids exists.
0998: * @ejb.interface-method view-type="local"
0999: * @ejb.transaction type="RequiresNew"
1000: */
1001: public ProcessDefinitionInfo lookupProcessDefinitionInfo(
1002: String packageId, String processId)
1003: throws InvalidKeyException {
1004: ProcessDefinition processDefinition = null;
1005: try {
1006: Connection con = null;
1007: PreparedStatement prepStmt = null;
1008: ResultSet rs = null;
1009: try {
1010: String processType = packageId + "/" + processId;
1011: synchronized (processDefinitionCache) {
1012: Long ck = (Long) processDefinitionDBIds
1013: .get(processType);
1014: if (ck != null) {
1015: processDefinition = (ProcessDefinition) processDefinitionCache
1016: .get(ck);
1017: }
1018: }
1019: // if we have a cached definition, only get enabled
1020: // state, else get everything
1021: con = ds.getConnection();
1022: prepStmt = con.prepareStatement("SELECT Enabled"
1023: + (processDefinition == null ? ", DBId, Xpdl"
1024: : "") + " FROM ProcessDefinition "
1025: + "WHERE PackageId = ? AND ProcessId = ?");
1026: prepStmt.setString(1, packageId);
1027: prepStmt.setString(2, processId);
1028: rs = prepStmt.executeQuery();
1029: if (!rs.next()) {
1030: // cleanup cache as a side effect
1031: uncacheDefinition(processType);
1032: throw new InvalidKeyException(
1033: "No process with packageId/processId = "
1034: + processType);
1035: }
1036: boolean enabled = (rs.getString(1).charAt(0) == 'T');
1037: if (processDefinition != null) {
1038: if (logger.isDebugEnabled()) {
1039: logger.debug("found ("
1040: + processDefinition.packageId() + "/"
1041: + processDefinition.processId() + ") "
1042: + "in cache");
1043: }
1044: return new ProcessDefinitionInfo(processDefinition,
1045: enabled);
1046: }
1047: long dbid = rs.getLong(2);
1048: String xpdl = JDBCUtil.getString(ds, rs, 3);
1049: processDefinition = new DefaultProcessDefinition(xpdl);
1050: Long ck = new Long(dbid);
1051: synchronized (processDefinitionCache) {
1052: processDefinitionCache.put(ck, processDefinition);
1053: processDefinitionDBIds.put(processDefinition
1054: .packageId()
1055: + "/" + processDefinition.processId(), ck);
1056: }
1057: if (logger.isDebugEnabled()) {
1058: logger.debug("put ("
1059: + processDefinition.packageId() + "/"
1060: + processDefinition.processId()
1061: + ") in cache");
1062: }
1063: return new ProcessDefinitionInfo(processDefinition,
1064: enabled);
1065: } finally {
1066: JDBCUtil.closeAll(rs, prepStmt, con);
1067: }
1068: } catch (SQLException se) {
1069: throw new EJBException(se);
1070: } catch (IOException ioe) {
1071: throw new EJBException(ioe);
1072: } catch (ImportException pe) {
1073: throw new EJBException(pe);
1074: }
1075: }
1076:
1077: /**
1078: * Returns the dbid associated to the process definition as stored in the
1079: * database.
1080: * @param packageId Id attribute of the process package.
1081: * @param processId Id attribute of the process.
1082: * @return the associated dbid. If not found, -1 is returned.
1083: */
1084: private long getAssociatedDbId(String packageId, String processId) {
1085: long dbId = -1;
1086: try {
1087: Connection con = null;
1088: PreparedStatement prepStmt = null;
1089: ResultSet rs = null;
1090: try {
1091: con = ds.getConnection();
1092: prepStmt = con
1093: .prepareStatement("SELECT DBId FROM ProcessDefinition "
1094: + "WHERE PackageId = ? AND ProcessId = ?");
1095: prepStmt.setString(1, packageId);
1096: prepStmt.setString(2, processId);
1097: rs = prepStmt.executeQuery();
1098: if (rs.next()) {
1099: dbId = rs.getLong(1);
1100: }
1101: } finally {
1102: JDBCUtil.closeAll(rs, prepStmt, con);
1103: }
1104: } catch (SQLException se) {
1105: throw new EJBException(se);
1106: }
1107: return dbId;
1108: }
1109:
1110: /**
1111: * This operation method returns true if the process definition
1112: * with the given ids is enabled.
1113: *
1114: * @param packageId Id attribute of the process package.
1115: * @param processId Id attribute of the process.
1116: * @return <code>true</code> if the process definition is enabled.
1117: * @throws InvalidKeyException if no process definition with
1118: * the given ids exists.
1119: * @ejb.interface-method view-type="remote"
1120: */
1121: public boolean isEnabled(String packageId, String processId)
1122: throws InvalidKeyException {
1123: boolean enabled = false;
1124: Connection con = null;
1125: ResultSet rs = null;
1126: PreparedStatement prepStmt = null;
1127: try {
1128: con = ds.getConnection();
1129: prepStmt = con
1130: .prepareStatement("SELECT Enabled FROM ProcessDefinition "
1131: + "WHERE PackageId = ? AND ProcessId = ?");
1132: prepStmt.setString(1, packageId);
1133: prepStmt.setString(2, processId);
1134: rs = prepStmt.executeQuery();
1135: if (!rs.next()) {
1136: ctx.setRollbackOnly();
1137: throw new InvalidKeyException(
1138: "No process with packageId/processId = "
1139: + packageId + "/" + processId);
1140: }
1141: if (rs.getString(1).charAt(0) == 'T') {
1142: enabled = true;
1143: }
1144: return enabled;
1145: } catch (SQLException se) {
1146: throw new EJBException(se);
1147: } finally {
1148: try {
1149: JDBCUtil.closeAll(rs, prepStmt, con);
1150: } catch (SQLException e) {
1151: throw new EJBException(e);
1152: }
1153: }
1154: }
1155:
1156: /**
1157: * This operation method set the process definition with the given
1158: * ids as enabled or disabled.
1159: *
1160: * @param packageId Id attribute of the process package.
1161: * @param processId Id attribute of the process.
1162: * @param enabled enable the process definition or not.
1163: * @throws InvalidKeyException if no process definition with
1164: * the given ids exists.
1165: * @ejb.interface-method view-type="remote"
1166: */
1167: public void setEnabled(String packageId, String processId,
1168: boolean enabled) throws InvalidKeyException {
1169: Connection con = null;
1170: PreparedStatement prepStmt = null;
1171: String updateStatement = null;
1172: try {
1173: con = ds.getConnection();
1174: prepStmt = con
1175: .prepareStatement("UPDATE processDefinition SET Enabled = ? "
1176: + "WHERE PackageId = ? AND ProcessId = ?");
1177: if (enabled) {
1178: prepStmt.setString(1, "T");
1179: } else {
1180: prepStmt.setString(1, "F");
1181: }
1182: prepStmt.setString(2, packageId);
1183: prepStmt.setString(3, processId);
1184: int rowCount = prepStmt.executeUpdate();
1185: if (rowCount == 0) {
1186: ctx.setRollbackOnly();
1187: throw new InvalidKeyException(
1188: "No process with packageId/processId = "
1189: + packageId + "/" + processId);
1190: }
1191:
1192: } catch (SQLException se) {
1193: throw new EJBException(se);
1194: } finally {
1195: try {
1196: JDBCUtil.closeAll(null, prepStmt, con);
1197: } catch (SQLException e) {
1198: throw new EJBException(e);
1199: }
1200: }
1201: }
1202:
1203: /**
1204: * Create a process of the given type with the given requester.
1205: *
1206: * @param packageId Id attribute of the process package.
1207: * @param processId Id attribute of the process.
1208: * @param requester the requester.
1209: * @return the new process.
1210: * @throws NotEnabledException if processes of this type may not be
1211: * created.
1212: * @throws InvalidRequesterException if the requester is not valid.
1213: * @throws RequesterRequiredException if no requester is passed (i.e.
1214: * parameter is <code>null</code>.
1215: * @throws InvalidKeyException if no process definition with
1216: * the given ids exists.
1217: * @ejb.interface-method view-type="remote"
1218: */
1219: public de.danet.an.workflow.omgcore.WfProcess createProcess(
1220: String packageId, String processId, WfRequester requester)
1221: throws NotEnabledException, InvalidRequesterException,
1222: RequesterRequiredException, InvalidKeyException {
1223: return ((ExtProcessLocal) createProcessLocal(packageId,
1224: processId, requester)).toProcess();
1225: }
1226:
1227: /**
1228: * Create a process of the given type with the given requester.
1229: *
1230: * @param packageId Id attribute of the process package.
1231: * @param processId Id attribute of the process.
1232: * @param requester the requester.
1233: * @return the new process.
1234: * @throws NotEnabledException if processes of this type may not be
1235: * created.
1236: * @throws InvalidRequesterException if the requester is not valid.
1237: * @throws RequesterRequiredException if no requester is passed (i.e.
1238: * parameter is <code>null</code>.
1239: * @throws InvalidKeyException if no process definition with
1240: * the given ids exists.
1241: * @ejb.interface-method view-type="remote"
1242: */
1243: public WfProcessLocal createProcessLocal(String packageId,
1244: String processId, WfRequester requester)
1245: throws NotEnabledException, InvalidRequesterException,
1246: RequesterRequiredException, InvalidKeyException {
1247: try {
1248: if (requester == null) {
1249: ctx.setRollbackOnly();
1250: throw new RequesterRequiredException();
1251: }
1252: ProcessDefinitionInfo pdi = ((ProcessDefinitionDirectoryLocal) ctx
1253: .getEJBLocalObject()).lookupProcessDefinitionInfo(
1254: packageId, processId);
1255: if (!pdi.enabled) {
1256: ctx.setRollbackOnly();
1257: throw new NotEnabledException(
1258: "Process definition disabled.");
1259: }
1260: return processLocalHome().create(pdi.processDefinition,
1261: requester);
1262: } catch (CreateException ce) {
1263: throw new EJBException(ce);
1264: }
1265:
1266: }
1267:
1268: /**
1269: * Copy the given process definition to all processes created
1270: * using the given process definition.
1271: * @param procDef the process definition
1272: */
1273: private void copyProcessDefinitionToProcesses(
1274: ProcessDefinition procDef) {
1275: String procMgr = procDef.mgrName();
1276: String procXpdl = procDef.toXPDL();
1277:
1278: while (((ProcessDefinitionDirectoryLocal) ctx
1279: .getEJBLocalObject()).copyProcessDefinitionToProcess(
1280: procMgr, procXpdl)) {
1281: }
1282: }
1283:
1284: /**
1285: * Copy the given process definition to the first process created
1286: * using the given process definition that does not have a copy.
1287: * @param procDef the process definition
1288: * @ejb.interface-method view-type="local"
1289: * @ejb.transaction type="RequiresNew"
1290: * @return <code>true</code> if a process was found.
1291: */
1292: public boolean copyProcessDefinitionToProcess(String procMgr,
1293: String procXpdl) {
1294: String procKey = null;
1295: try {
1296: Collection processes = processLocalHome()
1297: .findWithoutDefinitionByProcessMgrName(procMgr);
1298: Iterator iterator = processes.iterator();
1299: if (!iterator.hasNext()) {
1300: return false;
1301: }
1302: ExtProcessLocal process = (ExtProcessLocal) iterator.next();
1303: procKey = process.key();
1304: process.copyProcessDefinition(procXpdl);
1305: } catch (NoSuchEntityException e) {
1306: logger
1307: .info("Process "
1308: + procKey
1309: + " has vanished when trying to update "
1310: + "process definition. Probably removed by other thread.");
1311: } catch (FinderException onf) {
1312: throw new EJBException(onf);
1313: }
1314: return true;
1315: }
1316:
1317: /**
1318: * Remove given process definition from cache.
1319: */
1320: private void uncacheDefinition(String key) {
1321: synchronized (processDefinitionCache) {
1322: Long ck = (Long) processDefinitionDBIds.get(key);
1323: if (ck != null) {
1324: processDefinitionDBIds.remove(key);
1325: processDefinitionCache.remove(ck);
1326: if (logger.isDebugEnabled()) {
1327: logger.debug("removed (" + key + ") from cache");
1328: }
1329: }
1330: }
1331: }
1332: }
|