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: WfActivityEJB.java,v 1.22.2.1 2007/11/02 16:00:33 drmlipp Exp $
0021: *
0022: * $Log: WfActivityEJB.java,v $
0023: * Revision 1.22.2.1 2007/11/02 16:00:33 drmlipp
0024: * Merged bug fixes from HEAD.
0025: *
0026: * Revision 1.23 2007/09/21 06:19:35 mlipp
0027: * Fixed problem with NamingException during process deletion.
0028: *
0029: * Revision 1.22 2007/07/08 20:35:01 mlipp
0030: * Even more usage of local EJB interfaces.
0031: *
0032: * Revision 1.21 2007/06/10 05:55:30 drmlipp
0033: * Using local interface for optimization.
0034: *
0035: * Revision 1.20 2007/05/03 21:58:16 mlipp
0036: * Internal refactoring for making better use of local EJBs.
0037: *
0038: */
0039: package de.danet.an.workflow.ejbs.core;
0040:
0041: import java.io.IOException;
0042: import java.io.Serializable;
0043:
0044: import java.util.ArrayList;
0045: import java.util.Collection;
0046: import java.util.Date;
0047: import java.util.Iterator;
0048: import java.util.List;
0049:
0050: import java.rmi.RemoteException;
0051: import java.sql.Connection;
0052: import java.sql.PreparedStatement;
0053: import java.sql.ResultSet;
0054: import java.sql.SQLException;
0055: import java.sql.Timestamp;
0056:
0057: import javax.ejb.CreateException;
0058: import javax.ejb.EJBException;
0059: import javax.ejb.EntityBean;
0060: import javax.ejb.EntityContext;
0061: import javax.ejb.FinderException;
0062: import javax.ejb.NoSuchEntityException;
0063: import javax.ejb.NoSuchObjectLocalException;
0064: import javax.ejb.ObjectNotFoundException;
0065: import javax.ejb.RemoveException;
0066: import javax.ejb.TimedObject;
0067: import javax.ejb.Timer;
0068: import javax.naming.NamingException;
0069: import javax.sql.DataSource;
0070:
0071: import de.danet.an.util.EJBUtil;
0072: import de.danet.an.util.JDBCUtil;
0073: import de.danet.an.util.ResourceNotAvailableException;
0074: import de.danet.an.util.UniversalPrepStmt;
0075:
0076: import de.danet.an.workflow.internalapi.ExtActivityLocal;
0077: import de.danet.an.workflow.internalapi.ExtExecutionObjectLocal;
0078: import de.danet.an.workflow.internalapi.ExtProcessLocal;
0079: import de.danet.an.workflow.internalapi.ThreadInfo;
0080: import de.danet.an.workflow.localapi.ProcessLocal;
0081: import de.danet.an.workflow.localapi.TransitionLocal;
0082: import de.danet.an.workflow.localcoreapi.WfActivityLocal;
0083: import de.danet.an.workflow.localcoreapi.WfProcessLocal;
0084: import de.danet.an.workflow.omgcore.HistoryNotAvailableException;
0085: import de.danet.an.workflow.omgcore.InvalidPriorityException;
0086: import de.danet.an.workflow.omgcore.InvalidStateException;
0087: import de.danet.an.workflow.omgcore.WfAssignment;
0088: import de.danet.an.workflow.omgcore.WfAuditEvent;
0089: import de.danet.an.workflow.omgcore.WfProcess;
0090: import de.danet.an.workflow.omgcore.WfExecutionObject.NotRunningState;
0091: import de.danet.an.workflow.omgcore.WfExecutionObject.State;
0092:
0093: import de.danet.an.workflow.api.Activity;
0094: import de.danet.an.workflow.api.InvalidKeyException;
0095: import de.danet.an.workflow.api.Activity.Implementation;
0096: import de.danet.an.workflow.api.Activity.JoinAndSplitMode;
0097: import de.danet.an.workflow.api.Activity.StartFinishMode;
0098: import de.danet.an.workflow.apix.ExtActivity;
0099:
0100: import de.danet.an.workflow.domain.AbstractActivity;
0101: import de.danet.an.workflow.domain.DefaultAuditEvent;
0102: import de.danet.an.workflow.domain.RASInvocationHandler;
0103: import de.danet.an.workflow.domain.ToolInvocationHandler;
0104:
0105: import de.danet.an.workflow.ejbs.WorkflowEngine;
0106: import de.danet.an.workflow.ejbs.WorkflowEngineHome;
0107: import de.danet.an.workflow.ejbs.admin.WorkflowEngineLocal;
0108: import de.danet.an.workflow.ejbs.admin.WorkflowEngineLocalHome;
0109: import de.danet.an.workflow.ejbs.util.QueuerLocal;
0110: import de.danet.an.workflow.ejbs.util.QueuerLocalHome;
0111: import de.danet.an.workflow.spis.aii.ApplicationNotStoppedException;
0112: import de.danet.an.workflow.spis.ras.ActivityFinder;
0113: import de.danet.an.workflow.spis.ras.ResourceAssignmentService;
0114:
0115: /**
0116: * The entity bean <code>WfActivityEJB</code> represent a activity.
0117: * <code>AbstractActivity</code> represents a simple implementation
0118: * of the interface {@link ActivityLocal <code>Activity</code>}.
0119: * It has the following additional features:
0120: * <ul>
0121: * <li>Support for transition restrictions of type SPLIT or JOIN.</li>
0122: * </ul>
0123: *
0124: * @ejb.bean name="ActivityBean" display-name="ActivityBean"
0125: * jndi-name="ejb/@@@_JNDI_Name_Prefix_@@@ActivityBean"
0126: * type="BMP" reentrant="true" view-type="both"
0127: * @jonas.bean ejb-name="ActivityBean"
0128: * @ejb.pk class="java.lang.Long" generate="false"
0129: * @ejb.home remote-class="de.danet.an.workflow.ejbs.core.WfActivityHome"
0130: * local-class="de.danet.an.workflow.ejbs.core.WfActivityLocalHome"
0131: * @ejb.interface
0132: * extends="javax.ejb.EJBObject, de.danet.an.workflow.apix.ExtActivity"
0133: * remote-class="de.danet.an.workflow.ejbs.core.WfActivity"
0134: * local-extends="javax.ejb.EJBLocalObject,
0135: * de.danet.an.workflow.internalapi.ExtActivityLocal"
0136: * local-class="de.danet.an.workflow.ejbs.core.WfActivityLocal"
0137: * @ejb.transaction type="Required"
0138: * @ejb.security-identity run-as="WfMOpenAdmin"
0139: * sunone-principal="WfMCorePrincipalForAdmin"
0140: * @weblogic.run-as-identity-principal WfMCorePrincipalForAdmin
0141: * @ejb.ejb-ref ejb-name="WorkflowEngine" view-type="remote"
0142: * @ejb.ejb-ref ejb-name="WorkflowEngine" view-type="local"
0143: * @ejb.ejb-ref ejb-name="Queuer" view-type="local"
0144: * @ejb.ejb-ref ejb-name="ProcessBean" view-type="remote"
0145: * @ejb.ejb-ref ejb-name="ProcessBean" view-type="local"
0146: * @ejb.ejb-ref ejb-name="ConfigurationBean" view-type="remote"
0147: * ref-name="ejb/Configuration"
0148: * @ejb.ejb-external-ref ref-name="ejb/JdbcKeyGenLocal" link="KeyGen"
0149: * type="Session" view-type="local" home="de.danet.an.util.KeyGenLocalHome"
0150: * business="de.danet.an.util.KeyGenLocal"
0151: * @ejb.resource-ref res-ref-name="jdbc/WfEngine"
0152: * res-type="javax.sql.DataSource" res-auth="Container"
0153: * @jonas.resource res-ref-name="jdbc/WfEngine" jndi-name="jdbc_1"
0154: * @weblogic.enable-call-by-reference True
0155: * @weblogic.resource-description
0156: * res-ref-name="jdbc/WfEngine" jndi-name="DefaultDS"
0157: * @ejb.permission role-name="WfMOpenAdmin"
0158: * @weblogic.transaction-isolation TRANSACTION_READ_COMMITTED
0159: * @weblogic.cache concurrency-strategy="Exclusive"
0160: */
0161: public class WfActivityEJB extends AbstractActivity implements
0162: EntityBean, TimedObject {
0163:
0164: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
0165: .getLog(WfActivityEJB.class);
0166:
0167: private EntityContext ctx;
0168:
0169: /** The primary key of the process. */
0170: private Long processPk = null;
0171:
0172: /** The name of the process. */
0173: private String processName = null;
0174:
0175: /** The manager of the process. */
0176: private String processMgr = null;
0177:
0178: /** The version of the process (manager). */
0179: private String processMgrVers = null;
0180:
0181: /**
0182: * The data source of the database.
0183: * @see javax.sql.DataSource
0184: */
0185: private DataSource ds = null;
0186:
0187: /** Indicates if the database supports select for update. */
0188: private Boolean haveSelForUp = null;
0189:
0190: /** Database name. */
0191: private static final String DB_NAME = "java:comp/env/jdbc/WfEngine";
0192:
0193: /** The cached home interface of WfProcess. */
0194: private WfProcessHome processHomeCache = null;
0195: private WfProcessLocalHome processLocalHomeCache = null;
0196:
0197: /** The owning process of this activity. */
0198: private WfProcess containerCache = null;
0199: private WfProcessLocal containerLocalCache = null;
0200:
0201: /**
0202: * The list of activities that may follow this activity,
0203: * i.e. to which transitions exist.
0204: */
0205: private List nextActivitiesCache = null;
0206:
0207: /**
0208: * The activity finder used in {@link #activityFinderAndKey
0209: * <code>activityFinderAndKey</code>}.
0210: */
0211: private ActivityFinder activityFinderCache = null;
0212:
0213: private QueuerLocal queuerCache = null;
0214:
0215: /** The resource assignment service. */
0216: private RASInvocationHandler rasCache = null;
0217:
0218: /** The workflow engine. */
0219: private WorkflowEngine engineCache = null;
0220: private WorkflowEngineLocal engineLocalCache = null;
0221:
0222: private ToolInvocationHandler toolInvocationHandlerCache = null;
0223:
0224: /** This, as delivered to a client. */
0225: private Activity this RemoteCache = null;
0226:
0227: //
0228: // Provide the persistent attributes
0229: //
0230:
0231: /** Indicates change of a persistent attribute. */
0232: private boolean persistentAttributeModified = false;
0233:
0234: /** Indicates change of a slowly changing persistent attribute. */
0235: private boolean slowlyChangingPaModified = false;
0236:
0237: /** Indicates change of thread info persistent attribute. */
0238: private boolean threadInfoModified = false;
0239:
0240: /** Indicates change of exec info attributes. */
0241: private boolean execTimesModified = false;
0242:
0243: /** Indicates change of deadline attribute. */
0244: private boolean deadlinesModified = false;
0245:
0246: /** Indicates change of waiting on attribute. */
0247: private boolean waitingOnModified = false;
0248:
0249: /** Persistent attribute <code>name</code>. */
0250: private String paName;
0251:
0252: /** Persistent attribute <code>description</code>. */
0253: private String paDescription;
0254:
0255: /** Persistent attribute <code>priority</code>. */
0256: private Priority paPriority;
0257:
0258: /** Persistent attribute <code>typedState</code>. */
0259: private State paTypedState;
0260:
0261: /** Persistent attribute <code>lastStateTime</code>. */
0262: private Date paLastStateTime;
0263:
0264: /** Persistent attribute <code>startMode</code>. */
0265: private StartFinishMode paStartMode;
0266:
0267: /** Persistent attribute <code>finishMode</code>. */
0268: private StartFinishMode paFinishMode;
0269:
0270: /** Persistent attribute <code>joinMode</code>. */
0271: private JoinAndSplitMode paJoinMode;
0272:
0273: /** Persistent attribute <code>splitMode</code>. */
0274: private JoinAndSplitMode paSplitMode;
0275:
0276: /** Persistent attribute <code>performer</code>. */
0277: private String paPerformer;
0278:
0279: /** Persistent attribute <code>executor</code>. */
0280: private Integer paExecStat;
0281:
0282: /** Persistent attribute <code>actImpl</code>. */
0283: private Implementation[] paActImpl;
0284:
0285: /** Persistent attribute <code>threadInfo</code>. */
0286: private ThreadInfo paThreadInfo;
0287:
0288: /** Persistent attribute <code>Subflow</code>. */
0289: private String paSubflow;
0290:
0291: /** Persistent attribute <code>deadlines</code>. */
0292: private List paDeadlines = null;
0293:
0294: /** Persistent attribute <code>startTime</code>. */
0295: private Date paStartTime;
0296:
0297: /** Persistent attribute <code>suspendStart</code>. */
0298: private Date paSuspendStart;
0299:
0300: /** Persistent attribute <code>suspendAccum</code>. */
0301: private long paSuspendAccum;
0302:
0303: /** Persistent attribute <code>pendingException</code>. */
0304: private String paPendingException;
0305:
0306: /** Persistent attribute <code>waitOnProc</code>. */
0307: private Long paWaitOnProc;
0308:
0309: /** Persistent attribute <code>waitOnChan</code>. */
0310: private String paWaitOnChan;
0311:
0312: /**
0313: * Persistent attribute <code>flags</code>. This attribute is not
0314: * exposed, it serves as space efficient storage for various
0315: * attributes that are exposed.
0316: */
0317: private int paFlags;
0318:
0319: private static final int FLAGS_DEBUG = 1;
0320: private static final int FLAGS_AUDIT_SELECTION_SHIFT = 1;
0321: private static final int FLAGS_AUDIT_SELECTION_MASK = 7 << 1;
0322: private static final int FLAGS_STORE_AUDIT_EVENTS = 16;
0323:
0324: private static final int FLAGS_SUB_STATE_SHIFT = 28;
0325: private static final int FLAGS_SUB_STATE_MASK = 0x7 << FLAGS_SUB_STATE_SHIFT;
0326: private static final int FLAGS_DEFERRED_CHOICE = 1 << 27;
0327: private static final int FLAGS_PRELIMINARILY_CHOSEN = 1 << 26;
0328: private static final int FLAGS_NO_ASSIGNMENTS = 1 << 25;
0329: private static final int FLAGS_PENDING_EXCEPTION_IS_FROM_BLOCK = 1 << 24;
0330:
0331: //
0332: // Accessor methods for cached attributes
0333: //
0334:
0335: /**
0336: * The home interface of the WfProcessBean.
0337: * @return home interface of the WfProcessBean.
0338: */
0339: private WfProcessHome processHome()
0340: throws ResourceNotAvailableException {
0341: if (processHomeCache == null) {
0342: processHomeCache = (WfProcessHome) EJBUtil.retrieveEJBHome(
0343: WfProcessHome.class,
0344: "java:comp/env/ejb/ProcessBean");
0345: }
0346: return processHomeCache;
0347: }
0348:
0349: /**
0350: * The local home interface of the WfProcessBean.
0351: * @return local home interface of the WfProcessBean.
0352: */
0353: private WfProcessLocalHome processLocalHome()
0354: throws ResourceNotAvailableException {
0355: if (processLocalHomeCache == null) {
0356: processLocalHomeCache = (WfProcessLocalHome) EJBUtil
0357: .retrieveEJBLocalHome(WfProcessLocalHome.class,
0358: "java:comp/env/ejb/ProcessBeanLocal");
0359: }
0360: return processLocalHomeCache;
0361: }
0362:
0363: /**
0364: * The workflow engine.
0365: * @return the workflow engine
0366: */
0367: private WorkflowEngine engine()
0368: throws ResourceNotAvailableException {
0369: if (engineCache == null) {
0370: engineCache = (WorkflowEngine) EJBUtil.createSession(
0371: WorkflowEngineHome.class,
0372: "java:comp/env/ejb/WorkflowEngine");
0373: }
0374: return engineCache;
0375: }
0376:
0377: /**
0378: * The workflow engine.
0379: * @return the workflow engine
0380: */
0381: private WorkflowEngineLocal engineLocal()
0382: throws ResourceNotAvailableException {
0383: if (engineLocalCache == null) {
0384: engineLocalCache = (WorkflowEngineLocal) EJBUtil
0385: .createSession(WorkflowEngineLocalHome.class,
0386: "java:comp/env/ejb/WorkflowEngineLocal");
0387: }
0388: return engineLocalCache;
0389: }
0390:
0391: /**
0392: * Get the resource assignment invocation handler.
0393: * @return the configured resource assignment invocation handler.
0394: */
0395: protected RASInvocationHandler rasInvocationHandler() {
0396: if (rasCache == null) {
0397: WorkflowEngine engine = null;
0398: try {
0399: ResourceAssignmentService ras = engineLocal()
0400: .resourceAssignmentService();
0401: if (ras == null) {
0402: return null;
0403: }
0404: rasCache = new DefaultRASInvocationHandler(ras);
0405: } catch (RemoteException rex) {
0406: throw new EJBException(rex);
0407: }
0408: }
0409: return rasCache;
0410: }
0411:
0412: /**
0413: * Access cached event queuer.
0414: * @return the event queuer
0415: */
0416: private QueuerLocal queuer() throws ResourceNotAvailableException {
0417: if (queuerCache == null) {
0418: queuerCache = (QueuerLocal) EJBUtil.createSession(
0419: QueuerLocalHome.class, "java:comp/env/ejb/Queuer");
0420: }
0421: return queuerCache;
0422: }
0423:
0424: //
0425: // EJB container contract
0426: //
0427:
0428: /**
0429: * Set the associated session context. The container calls this method
0430: * after the instance creation.
0431: * @see javax.ejb.EntityBean
0432: * @param context - A SessionContext interface for the instance
0433: */
0434: public void setEntityContext(EntityContext context) {
0435: try {
0436: ctx = context;
0437: // getting new data source
0438: ds = JDBCUtil.refreshDS(null, DB_NAME);
0439: } catch (NamingException ex) {
0440: throw new EJBException(ex);
0441: }
0442: }
0443:
0444: /**
0445: * Unset the associated session context.
0446: * @see javax.ejb.EntityBean
0447: */
0448: public void unsetEntityContext() {
0449: processHomeCache = null;
0450: engineCache = null;
0451: engineLocalCache = null;
0452: activityFinderCache = null;
0453: rasCache = null;
0454: ds = null;
0455: ctx = null;
0456: }
0457:
0458: /**
0459: * The activate method is called when the instance is activated from its
0460: * "passive" state. The instance should acquire any resource that it has
0461: * released earlier in the ejbPassivate() method.
0462: * This method gets the primary key from container.
0463: * @see javax.ejb.EntityBean
0464: */
0465: public void ejbActivate() {
0466: containerCache = null;
0467: containerLocalCache = null;
0468: nextActivitiesCache = null;
0469: this RemoteCache = null;
0470: }
0471:
0472: /**
0473: * The passivate method is called before the instance enters the
0474: * "passive" state. The instance should release any resources that it
0475: * can re-acquire later in the ejbActivate() method.
0476: * @see javax.ejb.EntityBean
0477: */
0478: public void ejbPassivate() {
0479: containerCache = null;
0480: containerLocalCache = null;
0481: nextActivitiesCache = null;
0482: this RemoteCache = null;
0483: paDeadlines = null;
0484: dispose();
0485: }
0486:
0487: /**
0488: * This method checks if the activity exists.
0489: * If it is ok, it returns the activity-primary-key.
0490: * EJBException is thrown on any error except finder exception.
0491: * @param primaryKey The activity primary key.
0492: * @return The activity-key
0493: * @throws FinderException (<code>ObjectNotFoundException</code>)
0494: * if no activity found.
0495: */
0496: public Long ejbFindByPrimaryKey(Long primaryKey)
0497: throws FinderException {
0498: boolean result = false;
0499: try {
0500: result = selectByPrimaryKey(primaryKey);
0501: } catch (SQLException ex) {
0502: throw new EJBException(ex);
0503: }
0504: if (!result) {
0505: throw new ObjectNotFoundException("Row for id "
0506: + primaryKey + " not found.");
0507: }
0508: return primaryKey;
0509: }
0510:
0511: /**
0512: * This method retrieve the activities of a process.
0513: * @param primaryKey The process primary key.
0514: * @return Collection with whe activity-keys
0515: * @throws FinderException will not be thrown.
0516: * If no activities found, return a empty collection.
0517: */
0518: public Collection ejbFindByProcess(Long primaryKey)
0519: throws FinderException {
0520: Collection col = null;
0521: try {
0522: col = selectByProcess(primaryKey);
0523: } catch (SQLException ex) {
0524: throw new EJBException(ex);
0525: }
0526: return col;
0527: }
0528:
0529: /**
0530: * This method looks up an activity by its
0531: * {@link de.danet.an.workflow.localcoreapi.WfActivityLocal#key key}.
0532: * @param key the activity key
0533: * @return the activity EJB's primary key
0534: * @throws FinderException if no activity found
0535: */
0536: public Long ejbFindByActivityKey(String key) throws FinderException {
0537:
0538: Long pk = null;
0539: try {
0540: pk = Long.valueOf(key);
0541: } catch (NumberFormatException nex) {
0542: throw new ObjectNotFoundException(
0543: "Invalid key format for key = " + key);
0544: }
0545: return ejbFindByPrimaryKey(pk);
0546: }
0547:
0548: /**
0549: * This method looks up an activity by its
0550: * its container and waiting on attribute.
0551: * @param processId the containing process' id
0552: * @param channel the channel the activity is waiting on
0553: * @return the activity EJB's primary key
0554: * @throws FinderException if no activity found.
0555: */
0556: public Long ejbFindByWaitingOn(Long processId, String channel)
0557: throws FinderException {
0558: try {
0559: Long res = selectByWaitingOn(processId, channel);
0560: if (res == null) {
0561: throw new ObjectNotFoundException(
0562: "No activity of process " + processId
0563: + " waiting on " + channel);
0564: }
0565: return res;
0566: } catch (SQLException ex) {
0567: throw new EJBException(ex);
0568: }
0569: }
0570:
0571: /**
0572: * Create a new activity and save it into database.
0573: * @param process the containing process
0574: * @param procPk pk of process.
0575: * @param evtBase the base data for an audit event.
0576: * @param blockActId if the activity is part of a block activity,
0577: * else <code>null</code>
0578: * @param priority a <code>Priority</code> value
0579: * @param name the activity's name
0580: * @param description activity description
0581: * @param startMode the start mode
0582: * @param finishMode the finish mode
0583: * @param joinMode the join mode
0584: * @param splitMode the split mode
0585: * @param implementation the implementation description
0586: * @param performer the performer
0587: * @param deadlines the deadlines
0588: * @param deferChoiceOnSplit if the eventual choice of the
0589: * subsequent activity is to be deferred
0590: * @param auditEventSelection the audit event selection
0591: * @param storeAuditEvents if true, audit events are stored in the
0592: * database
0593: * @return primary key of the activity.
0594: * @throws CreateException if the activity can not be create.
0595: * @ejb.create-method view-type="local"
0596: */
0597: public Long ejbCreate(WfProcessLocal process, Long procPk,
0598: WfAuditEvent evtBase, Long blockActId,
0599: ExtExecutionObjectLocal.Priority priority, String name,
0600: String description, StartFinishMode startMode,
0601: StartFinishMode finishMode, JoinAndSplitMode joinMode,
0602: JoinAndSplitMode splitMode,
0603: Implementation[] implementation, String performer,
0604: List deadlines, boolean deferChoiceOnSplit,
0605: int auditEventSelection, boolean storeAuditEvents)
0606: throws CreateException {
0607: Long activityPk = null;
0608: try {
0609: containerLocalCache = process;
0610: nextActivitiesCache = null;
0611: this RemoteCache = null;
0612: // create new activityPk
0613: activityPk = new Long(EJBUtil.newPrimaryKey("activity"));
0614: // Process id etc.
0615: processPk = procPk;
0616: processMgr = evtBase.processMgrName();
0617: processName = evtBase.processName();
0618: processMgrVers = evtBase.processMgrVersion();
0619: // assign default to deadlines to avoid loading on access
0620: paDeadlines = new ArrayList();
0621: // initialize underlying domain object
0622: init(blockActId, priority, name, description, startMode,
0623: finishMode, joinMode, splitMode, implementation,
0624: performer, deadlines, deferChoiceOnSplit,
0625: auditEventSelection, storeAuditEvents);
0626: } catch (RemoteException ex) {
0627: throw new EJBException(ex);
0628: }
0629: return activityPk;
0630: }
0631:
0632: /**
0633: * Create a new activity with activity modes, join modes
0634: * and save it into database.
0635: * @param process the containing process
0636: * @param procPk pk of process
0637: * @param evtBase the base data for an audit event.
0638: * @param blockActId if the activity is part of a block activity,
0639: * else <code>null</code>
0640: * @param priority a <code>Priority</code> value
0641: * @param name the activity's name
0642: * @param description activity description
0643: * @param startMode the start mode
0644: * @param finishMode the finish mode
0645: * @param joinMode the join mode
0646: * @param splitMode the split mode
0647: * @param implementation the implementation description
0648: * @param performer the performer
0649: * @param deadlines the deadlines
0650: * @param deferChoiceOnSplit if the eventual choice of the
0651: * subsequent activity is to be deferred
0652: * @param auditEventSelection the audit event selection
0653: * @param storeAuditEvents if true, audit events are stored in the
0654: * database
0655: * @throws CreateException if the activity can not be create.
0656: */
0657: public void ejbPostCreate(WfProcessLocal process, Long procPk,
0658: WfAuditEvent evtBase, Long blockActId,
0659: ExtExecutionObjectLocal.Priority priority, String name,
0660: String description, StartFinishMode startMode,
0661: StartFinishMode finishMode, JoinAndSplitMode joinMode,
0662: JoinAndSplitMode splitMode,
0663: Implementation[] implementation, String performer,
0664: List deadlines, boolean deferChoiceOnSplit,
0665: int auditEventSelection, boolean storeAuditEvents)
0666: throws CreateException {
0667: try {
0668: // notify underlying domain object now (may throw exceptions)
0669: refresh();
0670: // save the new activity into database
0671: insertActivity();
0672: persistentAttributeModified = false;
0673: slowlyChangingPaModified = false;
0674: threadInfoModified = false;
0675: execTimesModified = false;
0676: deadlinesModified = false;
0677: waitingOnModified = false;
0678: } catch (SQLException e) {
0679: throw new EJBException(e);
0680: }
0681: }
0682:
0683: /**
0684: * A container invokes this method to synchronize the state of the
0685: * entity object in the database with the state of the enterprise bean
0686: * instancee.
0687: * @see javax.ejb.EntityBean
0688: */
0689: public void ejbStore() {
0690: try {
0691: if (persistentAttributeModified) {
0692: storeActivity();
0693: persistentAttributeModified = false;
0694: slowlyChangingPaModified = false;
0695: threadInfoModified = false;
0696: execTimesModified = false;
0697: deadlinesModified = false;
0698: waitingOnModified = false;
0699: }
0700: } catch (SQLException ex) {
0701: throw new EJBException(ex);
0702: }
0703: }
0704:
0705: /**
0706: * A container invokes this method to synchronize the state of an
0707: * enterprise bean instance with the entity object's state in the database.
0708: * @see javax.ejb.EntityBean
0709: */
0710: public void ejbLoad() {
0711: try {
0712: // load activity attributes from persistent store
0713: loadActivity();
0714: // notify underlying domain object
0715: refresh();
0716: } catch (SQLException ex) {
0717: throw new EJBException(ex);
0718: }
0719: }
0720:
0721: /**
0722: * A container invokes this method before it ends the life of the session
0723: * object. This happens as a result of a client's invoking a remove
0724: * operation, or when a container decides to terminate the session object
0725: * after a timeout.
0726: * @throws RemoveException if the activity is not closed.
0727: * @see javax.ejb.EntityBean
0728: */
0729: public void ejbRemove() throws RemoveException {
0730: try {
0731: if (getPaTypedState().workflowState() != State.CLOSED
0732: && (!getPaTypedState().isSameOrSubState(
0733: NotRunningState.NOT_STARTED))) {
0734: throw new RemoveException("Cannot remove " + toString()
0735: + ": still running.");
0736: }
0737: dispose();
0738: removeActivity();
0739: containerCache = null;
0740: containerLocalCache = null;
0741: nextActivitiesCache = null;
0742: this RemoteCache = null;
0743: paDeadlines = null;
0744: } catch (RemoteException ex) {
0745: throw new EJBException(ex);
0746: } catch (SQLException ex) {
0747: throw new EJBException(ex);
0748: }
0749: }
0750:
0751: /**
0752: * This method retrieve the activities of a process.
0753: * @param primaryKey key to looked for
0754: * @return A Collection with primary keys from the found activities.
0755: */
0756: private Collection selectByProcess(Long primaryKey)
0757: throws SQLException {
0758: Connection con = null;
0759: PreparedStatement prepStmt = null;
0760: ResultSet rs = null;
0761: try {
0762: Collection activities = new ArrayList();
0763: con = ds.getConnection();
0764: String selectStatement = "SELECT DBId FROM activity WHERE ProcessDBId = ? "
0765: + " ORDER BY DBId ";
0766: prepStmt = con.prepareStatement(selectStatement);
0767: prepStmt.setLong(1, primaryKey.longValue());
0768: rs = prepStmt.executeQuery();
0769: while (rs.next()) {
0770: activities.add(new Long(rs.getLong(1)));
0771: }
0772: return activities;
0773: } finally {
0774: JDBCUtil.closeAll(rs, prepStmt, con);
0775: }
0776: }
0777:
0778: /**
0779: * This method checks if the activity exists.
0780: * @param primaryKey key to check
0781: * @return If it is ok, it returns true.
0782: */
0783: private boolean selectByPrimaryKey(Long primaryKey)
0784: throws SQLException {
0785: Connection con = null;
0786: PreparedStatement prepStmt = null;
0787: ResultSet rs = null;
0788: try {
0789: con = ds.getConnection();
0790: String selectStatement = "SELECT DBId FROM activity WHERE DBId = ? ";
0791: prepStmt = con.prepareStatement(selectStatement);
0792: prepStmt.setLong(1, primaryKey.longValue());
0793: rs = prepStmt.executeQuery();
0794: boolean result = rs.next();
0795: return result;
0796: } finally {
0797: JDBCUtil.closeAll(rs, prepStmt, con);
0798: }
0799: }
0800:
0801: /**
0802: * This method finds an activity waiting on a channel.
0803: * @param processId the containing process' id
0804: * @param channel the channel
0805: * @return the primary key
0806: */
0807: private Long selectByWaitingOn(Long processId, String channel)
0808: throws SQLException {
0809: Connection con = null;
0810: PreparedStatement prepStmt = null;
0811: ResultSet rs = null;
0812: try {
0813: con = ds.getConnection();
0814: prepStmt = con
0815: .prepareStatement("SELECT DBId FROM Activity "
0816: + "WHERE WaitOnProc = ? AND WaitOnChan = ?");
0817: prepStmt.setLong(1, processId.longValue());
0818: prepStmt.setString(2, channel);
0819: rs = prepStmt.executeQuery();
0820: if (rs.next()) {
0821: return new Long(rs.getLong(1));
0822: }
0823: return null;
0824: } finally {
0825: JDBCUtil.closeAll(rs, prepStmt, con);
0826: }
0827: }
0828:
0829: /**
0830: * Insert a new activity info into database.
0831: */
0832: private void insertActivity() throws SQLException {
0833: Connection con = null;
0834: UniversalPrepStmt prepStmt = null;
0835: try {
0836: con = ds.getConnection();
0837: prepStmt = new UniversalPrepStmt(
0838: ds,
0839: con,
0840: "INSERT INTO activity (DBId, "
0841: + "ProcessMgr, ProcessMgrVersion, ProcessName, ProcessDBId, "
0842: + "Name, Description, BlockActivity, "
0843: + "Implementation, Performer, Priority, Executor, StartMode, "
0844: + "FinishMode, State, StateTime, JoinMode, SplitMode, "
0845: + "ThreadInfo, Subflow, SuspendAccum, PendingException, "
0846: + "WaitOnProc, WaitOnChan, Flags) "
0847: + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
0848: + "?, ?, ?, ?, ?, ?, ?, ?)");
0849: int offset = 1;
0850: prepStmt.setLong(offset++, ((Long) ctx.getPrimaryKey())
0851: .longValue());
0852: prepStmt.setString(offset++, processMgr);
0853: prepStmt.setString(offset++, processMgrVers);
0854: prepStmt.setString(offset++, processName);
0855: prepStmt.setLong(offset++, processPk.longValue());
0856: prepStmt.setString(offset++, paName);
0857: prepStmt.setString(offset++, paDescription);
0858: prepStmt.setLong(offset++, paBlockActivity);
0859: prepStmt.setBinary(offset++, paActImpl);
0860: prepStmt.setString(offset++, paPerformer);
0861: prepStmt.setInt(offset++, paPriority.toInt());
0862: prepStmt.setInt(offset++, paExecStat);
0863: prepStmt.setString(offset++, paStartMode.toString());
0864: prepStmt.setString(offset++, paFinishMode.toString());
0865: prepStmt.setString(offset++, paTypedState.toString());
0866: prepStmt.setTimestamp(offset++, new Timestamp(
0867: paLastStateTime.getTime()));
0868: prepStmt.setString(offset++, paJoinMode.toString());
0869: prepStmt.setString(offset++, paSplitMode.toString());
0870: prepStmt.setBinary(offset++, paThreadInfo);
0871: prepStmt.setLong(offset++, paSubflow == null ? null
0872: : new Long(paSubflow));
0873: prepStmt.setLong(offset++, new Long(0)); // SuspendAccum
0874: prepStmt.setString(offset++, null); // PendingException
0875: prepStmt.setLong(offset++, null); // WaitOnProc
0876: prepStmt.setString(offset++, null); // WaitOnChan
0877: prepStmt.setInt(offset++, paFlags); // Flags
0878: // now execute
0879: prepStmt.executeUpdate();
0880: WfProcessEJB.updateDeadlines(ds, con, processPk, (Long) ctx
0881: .getPrimaryKey(), paDeadlines, false);
0882: } catch (IOException ioe) {
0883: logger.error(ioe.getMessage(), ioe);
0884: } finally {
0885: JDBCUtil.closeAll(null, prepStmt, con);
0886: }
0887: }
0888:
0889: /**
0890: * Store activity info in the database.
0891: */
0892: private void storeActivity() throws SQLException {
0893: Connection con = null;
0894: UniversalPrepStmt prepStmt = null;
0895: try {
0896: con = ds.getConnection();
0897: prepStmt = new UniversalPrepStmt(
0898: ds,
0899: con,
0900: "UPDATE activity "
0901: + "SET State = ?, StateTime = ?, Executor = ?, Subflow = ?, "
0902: + "Flags = ?"
0903: + (execTimesModified ? ", StartTime = ?, SuspendStart = ?, SuspendAccum = ? "
0904: : "")
0905: + (threadInfoModified ? ", ThreadInfo = ? "
0906: : "")
0907: + (waitingOnModified ? ", WaitOnProc = ?, WaitOnChan = ? "
0908: : "")
0909: + (slowlyChangingPaModified ? (", ProcessName = ?, Name = ?, Description = ?, "
0910: + "Implementation = ?, Performer = ?, "
0911: + "Priority = ?, StartMode = ?, "
0912: + "FinishMode = ?, JoinMode = ?, SplitMode = ?, "
0913: + "PendingException = ?")
0914: : "") + " WHERE DBId = ?");
0915: int offset = 1;
0916: prepStmt.setString(offset++, paTypedState.toString());
0917: prepStmt.setTimestamp(offset++, new Timestamp(
0918: paLastStateTime.getTime()));
0919: prepStmt.setInt(offset++, paExecStat);
0920: prepStmt.setLong(offset++, paSubflow == null ? null
0921: : new Long(paSubflow));
0922: prepStmt.setInt(offset++, paFlags);
0923: if (execTimesModified) {
0924: prepStmt.setTimestamp(offset++,
0925: (paStartTime == null ? null : new Timestamp(
0926: paStartTime.getTime())));
0927: prepStmt.setTimestamp(offset++,
0928: (paSuspendStart == null ? null : new Timestamp(
0929: paSuspendStart.getTime())));
0930: prepStmt.setLong(offset++, new Long(paSuspendAccum));
0931: }
0932: if (threadInfoModified) {
0933: prepStmt.setBinary(offset++, paThreadInfo);
0934: }
0935: if (waitingOnModified) {
0936: prepStmt.setLong(offset++, paWaitOnProc);
0937: prepStmt.setString(offset++, paWaitOnChan);
0938: }
0939: if (slowlyChangingPaModified) {
0940: prepStmt.setString(offset++, processName);
0941: prepStmt.setString(offset++, paName);
0942: prepStmt.setString(offset++, paDescription);
0943: prepStmt.setBinary(offset++, paActImpl);
0944: prepStmt.setString(offset++, paPerformer);
0945: prepStmt.setInt(offset++, paPriority.toInt());
0946: prepStmt.setString(offset++, paStartMode.toString());
0947: prepStmt.setString(offset++, paFinishMode.toString());
0948: prepStmt.setString(offset++, paJoinMode.toString());
0949: prepStmt.setString(offset++, paSplitMode.toString());
0950: prepStmt.setString(offset++, paPendingException);
0951: }
0952: // for where statement
0953: prepStmt.setLong(offset++, ((Long) ctx.getPrimaryKey())
0954: .longValue());
0955: int rowCount = prepStmt.executeUpdate();
0956: if (rowCount == 0) {
0957: throw new NoSuchEntityException("Storing row for DBId "
0958: + (Long) ctx.getPrimaryKey() + " failed.");
0959: }
0960: if (deadlinesModified) {
0961: WfProcessEJB.updateDeadlines(ds, con, processPk,
0962: (Long) ctx.getPrimaryKey(), paDeadlines, true);
0963: }
0964: } catch (IOException ioe) {
0965: logger.error(ioe.getMessage(), ioe);
0966: } finally {
0967: JDBCUtil.closeAll(null, prepStmt, con);
0968: }
0969: }
0970:
0971: /**
0972: * Load activity info from the database.
0973: * After sucessful loading, the process attribute structure
0974: * is set with the values just loaded.
0975: */
0976: private void loadActivity() throws SQLException {
0977: Connection con = null;
0978: PreparedStatement prepStmt = null;
0979: ResultSet rs = null;
0980: try {
0981: con = ds.getConnection();
0982: if (haveSelForUp == null) {
0983: haveSelForUp = new Boolean(JDBCUtil.dbProperties(ds,
0984: con).supportsSelectForUpdate());
0985: }
0986: prepStmt = con
0987: .prepareStatement("SELECT "
0988: + "ProcessMgr, ProcessMgrVersion, ProcessName, ProcessDBId, "
0989: + "Name, Description, BlockActivity, Implementation, "
0990: + "Performer, Priority, executor, StartMode, FinishMode, "
0991: + "State, StateTime, JoinMode, SplitMode, ThreadInfo, "
0992: + "Subflow, StartTime, SuspendStart, SuspendAccum, "
0993: + "PendingException, WaitOnProc, WaitOnChan, Flags "
0994: + "FROM activity WHERE DBId = ? "
0995: + (haveSelForUp.booleanValue() ? " FOR UPDATE"
0996: : ""));
0997: prepStmt.setLong(1, ((Long) ctx.getPrimaryKey())
0998: .longValue());
0999: rs = prepStmt.executeQuery();
1000: if (!rs.next()) {
1001: throw new NoSuchEntityException("Row for id "
1002: + (Long) ctx.getPrimaryKey()
1003: + " not found in database.");
1004: }
1005: // read activity from db
1006: int offset = 1;
1007: processMgr = rs.getString(offset++);
1008: processMgrVers = rs.getString(offset++);
1009: processName = rs.getString(offset++);
1010: processPk = new Long(rs.getLong(offset++));
1011: paName = rs.getString(offset++);
1012: paDescription = rs.getString(offset++);
1013: paBlockActivity = JDBCUtil.getLong(rs, offset++);
1014: paActImpl = (Implementation[]) JDBCUtil.getBinary(rs,
1015: offset++);
1016: paPerformer = rs.getString(offset++);
1017: paPriority = Priority.fromInt(rs.getInt(offset++));
1018: paExecStat = JDBCUtil.getInteger(rs, offset++);
1019: paStartMode = StartFinishMode.fromString(rs
1020: .getString(offset++));
1021: paFinishMode = StartFinishMode.fromString(rs
1022: .getString(offset++));
1023: paTypedState = State.fromString(rs.getString(offset++));
1024: paLastStateTime = rs.getTimestamp(offset++);
1025: paJoinMode = JoinAndSplitMode.fromString(rs
1026: .getString(offset++));
1027: paSplitMode = JoinAndSplitMode.fromString(rs
1028: .getString(offset++));
1029: paThreadInfo = (ThreadInfo) JDBCUtil
1030: .getBinary(rs, offset++);
1031: Long sf = JDBCUtil.getLong(rs, offset++);
1032: paSubflow = (sf == null ? null : sf.toString());
1033: paStartTime = rs.getTimestamp(offset++);
1034: paSuspendStart = rs.getTimestamp(offset++);
1035: paSuspendAccum = rs.getLong(offset++);
1036: paPendingException = rs.getString(offset++);
1037: paWaitOnProc = JDBCUtil.getLong(rs, offset++);
1038: paWaitOnChan = rs.getString(offset++);
1039: paFlags = rs.getInt(offset++);
1040: } catch (IOException ioe) {
1041: logger.error(ioe.getMessage(), ioe);
1042: throw new SQLException(ioe.getMessage());
1043: } catch (ClassNotFoundException cnfe) {
1044: logger.error(cnfe.getMessage(), cnfe);
1045: throw new SQLException(cnfe.getMessage());
1046: } catch (InvalidStateException ise) {
1047: logger.error(ise.getMessage(), ise);
1048: throw new SQLException(ise.getMessage());
1049: } catch (InvalidPriorityException ipe) {
1050: logger.error(ipe.getMessage(), ipe);
1051: throw new SQLException(ipe.getMessage());
1052: } finally {
1053: JDBCUtil.closeAll(rs, prepStmt, con);
1054: }
1055: }
1056:
1057: /**
1058: * Remove activity info from the database.
1059: */
1060: private void removeActivity() throws SQLException, RemoteException {
1061: Connection con = null;
1062: PreparedStatement prepStmt = null;
1063: try {
1064: if (!typedState().isSameOrSubState(State.CLOSED)
1065: && !(typedState()
1066: .isSameOrSubState(NotRunningState.NOT_STARTED))) {
1067: releaseResources();
1068: try {
1069: terminateImpl();
1070: } catch (ApplicationNotStoppedException ans) {
1071: logger.warn("Removing activity " + toString()
1072: + " while tool still running.");
1073: }
1074: }
1075: con = ds.getConnection();
1076: String deleteStatement = "DELETE FROM activity WHERE DBId = ? ";
1077: prepStmt = con.prepareStatement(deleteStatement);
1078: prepStmt.setLong(1, ((Long) ctx.getPrimaryKey())
1079: .longValue());
1080: prepStmt.executeUpdate();
1081: // deadlines are removed with the process
1082: } finally {
1083: JDBCUtil.closeAll(null, prepStmt, con);
1084: }
1085: }
1086:
1087: //
1088: // Domain methods and helpers
1089: //
1090:
1091: /**
1092: * Indicates if some other object is equal to this one. <P>
1093: *
1094: * Note that <code>obj</code> must implement the activity's
1095: * remote interface. Comparing a domain object usually
1096: * indicates some violation of the constraints of our
1097: * implementation environment.
1098: *
1099: * @param obj the object to compare with.
1100: * @return <code>true</code> if the other object is equal.
1101: */
1102: public boolean equals(Object obj) {
1103: return ctx.getPrimaryKey().toString().equals(
1104: ((WfActivityLocal) obj).key());
1105: }
1106:
1107: /**
1108: * Return the hash code.<P>
1109: * @return the result.
1110: */
1111: public int hashCode() {
1112: return ctx.getPrimaryKey().toString().hashCode();
1113: }
1114:
1115: /**
1116: * Check if the given assignment is among the assignments of this
1117: * activity.
1118: * @param member the assignment in question.
1119: * @return true if the assignment is among the assignments of this
1120: * activity.
1121: * @ejb.interface-method view-type="remote"
1122: */
1123: public boolean isMemberOfAssignments(WfAssignment member) {
1124: throw new UnsupportedOperationException();
1125: }
1126:
1127: /**
1128: * Return the remote version of this object. This is the client side
1129: * implementation of the remote interface (i.e. the EJB object).
1130: *
1131: * @return the remote stub.
1132: */
1133: public Activity toActivity() {
1134: if (this RemoteCache == null) {
1135: try {
1136: this RemoteCache = ActivityProxy.wrap((ExtActivity) ctx
1137: .getEJBObject(), container(), uniqueKey(),
1138: false);
1139: } catch (RemoteException e) {
1140: // actually, uniqueKey never throws a remote exception in
1141: // this context (and getEJBObject never does)
1142: logger.error(e.getMessage(), e);
1143: throw new IllegalStateException(e.getMessage());
1144: }
1145: }
1146: return this RemoteCache;
1147: }
1148:
1149: /* (non-Javadoc)
1150: * Comment copied from interface or superclass.
1151: */
1152: public ExtActivityLocal toActivityLocal() {
1153: return (ExtActivityLocal) ctx.getEJBLocalObject();
1154: }
1155:
1156: /**
1157: * Returns the <code>WfProcess</code> that this activity is a part of.
1158: * @return the process.
1159: * @ejb.interface-method view-type="remote"
1160: */
1161: public WfProcess container() {
1162: if (containerCache == null) {
1163: try {
1164: containerCache = processHome().findByPrimaryKey(
1165: processPk);
1166: } catch (FinderException fe) {
1167: throw new EJBException(fe);
1168: } catch (RemoteException re) {
1169: throw new EJBException(re);
1170: }
1171: }
1172: return containerCache;
1173: }
1174:
1175: /**
1176: * Returns the <code>WfProcessLocal</code> that this activity is a part of.
1177: * @return the process.
1178: * @ejb.interface-method view-type="local"
1179: */
1180: public WfProcessLocal containerLocal() {
1181: if (containerLocalCache == null) {
1182: try {
1183: containerLocalCache = processLocalHome()
1184: .findByPrimaryKey(processPk);
1185: } catch (FinderException fe) {
1186: throw new EJBException(fe);
1187: } catch (RemoteException re) {
1188: throw new EJBException(re);
1189: }
1190: }
1191: return containerLocalCache;
1192: }
1193:
1194: /**
1195: * Lookup a process by its key.
1196: * @param key the primary key
1197: * @return the process
1198: * @throws RemoteException if a system-level error occurs
1199: * @throws InvalidKeyException if no process with the given key
1200: * exists
1201: */
1202: protected ExtProcessLocal lookupProcessLocal(String key)
1203: throws InvalidKeyException {
1204: try {
1205: return processLocalHome().findByPrimaryKey(new Long(key));
1206: } catch (FinderException fe) {
1207: logger.debug(fe.getMessage(), fe);
1208: throw new InvalidKeyException(fe.getMessage());
1209: } catch (ResourceNotAvailableException e) {
1210: throw new EJBException(e);
1211: } catch (RemoteException e) {
1212: throw new EJBException(e);
1213: }
1214: }
1215:
1216: /**
1217: * Returns an {@link de.danet.an.workflow.spis.ras.ActivityFinder
1218: * <code>ActivityFinder</code>} that identifies this activity
1219: * against a resource assignment service as defined by
1220: * {@link de.danet.an.workflow.spis.ras the ras package}.
1221: *
1222: * @return the activity finder.
1223: */
1224: public ActivityFinder activityFinder() {
1225: if (activityFinderCache == null) {
1226: activityFinderCache = new de.danet.an.workflow.ejbs.admin.ActivityFinder(
1227: "java:comp/env/ejb/Configuration");
1228: }
1229: return activityFinderCache;
1230: }
1231:
1232: /**
1233: * Returns an <code>WfAuditEvent</code> containing container-related
1234: * information.
1235: * @return the audit event
1236: */
1237: protected WfAuditEvent containerAuditEventBase() {
1238: return new DefaultAuditEvent(null, null, processPk.toString(),
1239: processName, processMgr, processMgrVers,
1240: getPaAuditEventSelection(), getPaStoreAuditEvents());
1241: }
1242:
1243: /**
1244: * Returns a <code>WfAuditEvent</code> containing information about the
1245: * activity and its container, only.
1246: * @return the event containing the required information.
1247: * @ejb.interface-method view-type="remote"
1248: */
1249: public WfAuditEvent auditEventBase() {
1250: return auditEventBase(null);
1251: }
1252:
1253: /**
1254: * Returns the list of activities that may follow this activity,
1255: * i.e. to which transitions exist.
1256: * The list follows the order of transitions as returend by the
1257: * container.
1258: * @return the list of {@link de.danet.an.workflow.domain Activity
1259: * <code>Activity</code>} objects.
1260: * @ejb.interface-method view-type="remote"
1261: */
1262: public List nextActivities() {
1263:
1264: // cached result?
1265: if (nextActivitiesCache != null) {
1266: return nextActivitiesCache;
1267: }
1268:
1269: // new evaluation needed
1270: nextActivitiesCache = new ArrayList();
1271: List allTrans = ((ProcessLocal) containerLocal())
1272: .transitionsLocal();
1273: for (Iterator tri = allTrans.iterator(); tri.hasNext();) {
1274: TransitionLocal trans = (TransitionLocal) tri.next();
1275: if (key().equals(trans.from().key())) {
1276: nextActivitiesCache.add(((ExtActivityLocal) trans.to())
1277: .toActivity());
1278: }
1279: }
1280: return nextActivitiesCache;
1281: }
1282:
1283: /**
1284: * Return a <code>ToolInvocationHandler</code>.
1285: * @return a handler.
1286: */
1287: protected ToolInvocationHandler toolInvocationHandler() {
1288: if (toolInvocationHandlerCache == null) {
1289: try {
1290: toolInvocationHandlerCache = new DefaultToolInvocationHandler(
1291: engineLocal(), queuer());
1292: } catch (ResourceNotAvailableException e) {
1293: throw new EJBException(e);
1294: }
1295: }
1296: return toolInvocationHandlerCache;
1297: }
1298:
1299: /**
1300: * Process newly generated event.
1301: * @param evt Event
1302: */
1303: protected void fireAuditEvent(WfAuditEvent evt) {
1304: try {
1305: queuer().queue((DefaultAuditEvent) evt);
1306: } catch (RemoteException e) {
1307: throw new EJBException(e);
1308: }
1309: }
1310:
1311: /**
1312: * Returns a collection of <code>WfAuditEvent</code>s associated with
1313: * this process describing its history.
1314: * @return the collection of audit events
1315: * @throws HistoryNotAvailableException in case the history is not
1316: * available for any reason
1317: * @ejb.interface-method view-type="remote"
1318: */
1319: public Collection history() throws HistoryNotAvailableException {
1320: WorkflowEngine engine = null;
1321: try {
1322: return engineLocal().history(toActivity());
1323: } catch (RemoteException rex) {
1324: throw new EJBException(rex);
1325: }
1326: }
1327:
1328: /**
1329: * Updates the process name (which is cached by the activity EJB)
1330: * if the process name changes.
1331: * @param newName the new process name.
1332: * @ejb.interface-method view-type="remote"
1333: */
1334: public void updateProcessName(String newName) {
1335: processName = newName;
1336: slowlyChangingPaModified = true;
1337: }
1338:
1339: /**
1340: * Check if the given process is among the performers of this requester.
1341: *
1342: * @param member the process in question.
1343: * @return <code>true</code> if the <code>process</code> is among
1344: * the performers of this requester.
1345: */
1346: public boolean isMemberOfPerformers(WfProcess member) {
1347: for (Iterator ps = performers().iterator(); ps.hasNext();) {
1348: WfProcess p = (WfProcess) ps.next();
1349: try {
1350: if (p.key().equals(member.key())) {
1351: return true;
1352: }
1353: } catch (RemoteException e) {
1354: throw new EJBException(e);
1355: }
1356: }
1357: return false;
1358: }
1359:
1360: //
1361: // Timers
1362: //
1363:
1364: /**
1365: * Start a timer that will call <code>handleTimeout</code> at the
1366: * given date with the given info.
1367: * @param due target date
1368: * @param info the context
1369: */
1370: public void startTimer(Date due, Serializable info) {
1371: if (logger.isDebugEnabled()) {
1372: logger.debug("Starting timer for " + toString()
1373: + ", due at " + due);
1374: }
1375: // Adjust duration
1376: long duration = due.getTime() - System.currentTimeMillis();
1377: if (duration <= 0) {
1378: logger.warn("Deadline with zero or negative duration ("
1379: + ((double) duration / 1000) + "s) for "
1380: + toString() + " will be triggered immediately.");
1381: duration = 1;
1382: }
1383: if (ctx.getClass().getName().startsWith("org.jboss.ejb.")) {
1384: // create a timer with interval to circumvent JBoss bug JBAS-2274
1385: ctx.getTimerService().createTimer(duration, 3600 * 1000,
1386: info);
1387: } else {
1388: ctx.getTimerService().createTimer(duration, info);
1389: }
1390: }
1391:
1392: /**
1393: * Stop all timers that this object has created.
1394: */
1395: public void stopTimers() {
1396: for (Iterator i = ctx.getTimerService().getTimers().iterator(); i
1397: .hasNext();) {
1398: Timer timer = (Timer) i.next();
1399: timer.cancel();
1400: }
1401: }
1402:
1403: /**
1404: * Handle the timeout of a timer.
1405: * @param timer the timer that has expired.
1406: */
1407: public void ejbTimeout(Timer timer) {
1408: try {
1409: if (logger.isDebugEnabled()) {
1410: logger.debug("Received timeout from " + timer + " for "
1411: + toString());
1412: }
1413: try {
1414: handleTimeout(timer.getInfo());
1415: if (ctx.getClass().getName().startsWith(
1416: "org.jboss.ejb.")) {
1417: // Because of JBoss bug JBAS-2274 we have an interval and
1418: // must therefore cancel the timer
1419: timer.cancel();
1420: }
1421: } catch (NoSuchObjectLocalException e) {
1422: // JBoss may call this method with a canceled timer
1423: if (timer.getClass().getName().equals(
1424: "org.jboss.ejb.txtimer.TimerImpl")) {
1425: logger.debug("Exception \"" + e.getMessage()
1426: + "\" ignored, caused by JBoss bug.");
1427: return;
1428: }
1429: throw e;
1430: }
1431: } catch (EJBException e) {
1432: throw e;
1433: } catch (Throwable e) {
1434: logger.error("Problem handling timer event " + timer
1435: + "(discarded): " + e.getMessage(), e);
1436: }
1437: }
1438:
1439: //
1440: // Implement accessor methods for the persistent attributes
1441: //
1442:
1443: /**
1444: * The getter method implementation for the persistent
1445: * attribute <code>key</code>.
1446: *
1447: * @return the value of key.
1448: */
1449: protected String getPaKey() {
1450: return ((Long) ctx.getPrimaryKey()).toString();
1451: }
1452:
1453: /**
1454: * The getter method implementation for the persistent
1455: * attribute <code>name</code>.
1456: *
1457: * @see #setPaName
1458: * @return the value of name.
1459: */
1460: protected String getPaName() {
1461: return paName;
1462: }
1463:
1464: /**
1465: * The setter method implementation for the persistent
1466: * attribute <code>name</code>.
1467: *
1468: * @param newName the new value of name.
1469: * @see #getPaName
1470: */
1471: protected void setPaName(String newName) {
1472: paName = newName;
1473: persistentAttributeModified = true;
1474: slowlyChangingPaModified = true;
1475: }
1476:
1477: /**
1478: * The getter method implementation for the persistent
1479: * attribute <code>description</code>.
1480: *
1481: * @see #setPaDescription
1482: * @return the value of description.
1483: */
1484: protected String getPaDescription() {
1485: return paDescription;
1486: }
1487:
1488: /**
1489: * The setter method implementation for the persistent
1490: * attribute <code>description</code>.
1491: *
1492: * @param newDescription the new value of description.
1493: * @see #getPaDescription
1494: */
1495: protected void setPaDescription(String newDescription) {
1496: paDescription = newDescription;
1497: persistentAttributeModified = true;
1498: slowlyChangingPaModified = true;
1499: }
1500:
1501: /**
1502: * The getter method implementation for the persistent
1503: * attribute <code>priority</code>.
1504: *
1505: * @see #setPaPriority
1506: * @return the value of priority.
1507: */
1508: protected Priority getPaPriority() {
1509: return paPriority;
1510: }
1511:
1512: /**
1513: * The setter method implementation for the persistent
1514: * attribute <code>priority</code>.
1515: *
1516: * @param newPriority the new value of priority.
1517: * @see #getPaPriority
1518: */
1519: protected void setPaPriority(Priority newPriority) {
1520: paPriority = newPriority;
1521: persistentAttributeModified = true;
1522: slowlyChangingPaModified = true;
1523: }
1524:
1525: /**
1526: * The getter method implementation for the persistent
1527: * attribute <code>typedState</code>.
1528: *
1529: * @see #setPaTypedState
1530: * @return the value of typedState.
1531: */
1532: protected State getPaTypedState() {
1533: return paTypedState;
1534: }
1535:
1536: /**
1537: * The getter method implementation for the persistent
1538: * attribute <code>lastStateTime</code>.
1539: *
1540: * @see #setPaLastStateTime
1541: * @return the value of lastStateTime.
1542: */
1543: protected Date getPaLastStateTime() {
1544: return paLastStateTime;
1545: }
1546:
1547: /**
1548: * The setter method implementation for the persistent
1549: * attribute <code>lastStateTime</code>.
1550: *
1551: * @param newLastStateTime the new value of lastStateTime.
1552: * @see #getPaLastStateTime
1553: */
1554: protected void setPaLastStateTime(Date newLastStateTime) {
1555: paLastStateTime = newLastStateTime;
1556: persistentAttributeModified = true;
1557: }
1558:
1559: /**
1560: * The setter method implementation for the persistent
1561: * attribute <code>typedState</code>.
1562: *
1563: * @param newTypedState the new value of typedState.
1564: * @see #getPaTypedState
1565: */
1566: protected void setPaTypedState(State newTypedState) {
1567: paTypedState = newTypedState;
1568: persistentAttributeModified = true;
1569: }
1570:
1571: /**
1572: * The getter method implementation for the persistent
1573: * attribute <code>startMode</code>.
1574: *
1575: * @see #setPaStartMode
1576: * @return the value of startMode.
1577: */
1578: protected StartFinishMode getPaStartMode() {
1579: return paStartMode;
1580: }
1581:
1582: /**
1583: * The setter method implementation for the persistent
1584: * attribute <code>startMode</code>.
1585: *
1586: * @param newStartMode the new value of startMode.
1587: * @see #getPaStartMode
1588: */
1589: protected void setPaStartMode(StartFinishMode newStartMode) {
1590: paStartMode = newStartMode;
1591: persistentAttributeModified = true;
1592: slowlyChangingPaModified = true;
1593: }
1594:
1595: /**
1596: * The getter method implementation for the persistent
1597: * attribute <code>finishMode</code>.
1598: *
1599: * @see #setPaFinishMode
1600: * @return the value of finishMode.
1601: */
1602: protected StartFinishMode getPaFinishMode() {
1603: return paFinishMode;
1604: }
1605:
1606: /**
1607: * The setter method implementation for the persistent
1608: * attribute <code>finishMode</code>.
1609: *
1610: * @param newFinishMode the new value of finishMode.
1611: * @see #getPaFinishMode
1612: */
1613: protected void setPaFinishMode(StartFinishMode newFinishMode) {
1614: paFinishMode = newFinishMode;
1615: persistentAttributeModified = true;
1616: slowlyChangingPaModified = true;
1617: }
1618:
1619: /**
1620: * The getter method implementation for the persistent
1621: * attribute <code>joinMode</code>.
1622: *
1623: * @see #setPaJoinMode
1624: * @return the value of joinMode.
1625: */
1626: protected JoinAndSplitMode getPaJoinMode() {
1627: return paJoinMode;
1628: }
1629:
1630: /**
1631: * The setter method implementation for the persistent
1632: * attribute <code>joinMode</code>.
1633: *
1634: * @param newJoinMode the new value of joinMode.
1635: * @see #getPaJoinMode
1636: */
1637: protected void setPaJoinMode(JoinAndSplitMode newJoinMode) {
1638: paJoinMode = newJoinMode;
1639: persistentAttributeModified = true;
1640: slowlyChangingPaModified = true;
1641: }
1642:
1643: /**
1644: * The getter method implementation for the persistent
1645: * attribute <code>splitMode</code>.
1646: *
1647: * @see #setPaSplitMode
1648: * @return the value of splitMode.
1649: */
1650: protected JoinAndSplitMode getPaSplitMode() {
1651: return paSplitMode;
1652: }
1653:
1654: /**
1655: * The setter method implementation for the persistent
1656: * attribute <code>splitMode</code>.
1657: *
1658: * @param newSplitMode the new value of splitMode.
1659: * @see #getPaSplitMode
1660: */
1661: protected void setPaSplitMode(JoinAndSplitMode newSplitMode) {
1662: paSplitMode = newSplitMode;
1663: persistentAttributeModified = true;
1664: slowlyChangingPaModified = true;
1665: }
1666:
1667: /**
1668: * The getter method implementation for the persistent
1669: * attribute <code>executor</code>.
1670: *
1671: * @see #setPaExecStat
1672: * @return the value of executor.
1673: */
1674: protected Integer getPaExecStat() {
1675: return paExecStat;
1676: }
1677:
1678: /**
1679: * The getter method implementation for the persistent
1680: * attribute <code>performer</code>.
1681: *
1682: * @see #setPaPerformer
1683: * @return the value of performer.
1684: */
1685: protected String getPaPerformer() {
1686: return paPerformer;
1687: }
1688:
1689: /**
1690: * The setter method implementation for the persistent
1691: * attribute <code>performer</code>.
1692: *
1693: * @param newPerformer the new value of performer.
1694: * @see #getPaPerformer
1695: */
1696: protected void setPaPerformer(String newPerformer) {
1697: paPerformer = newPerformer;
1698: persistentAttributeModified = true;
1699: slowlyChangingPaModified = true;
1700: }
1701:
1702: /**
1703: * The setter method implementation for the persistent
1704: * attribute <code>executor</code>.
1705: *
1706: * @param newExecutor the new value of executor.
1707: * @see #getPaExecStat
1708: */
1709: protected void setPaExecStat(Integer newExecutor) {
1710: paExecStat = newExecutor;
1711: persistentAttributeModified = true;
1712: }
1713:
1714: /**
1715: * The getter method implementation for the persistent
1716: * attribute <code>actImpl</code>.
1717: *
1718: * @see #setPaActImpl
1719: * @return the value of actImpl.
1720: */
1721: protected Implementation[] getPaActImpl() {
1722: return paActImpl;
1723: }
1724:
1725: /**
1726: * The setter method implementation for the persistent
1727: * attribute <code>actImpl</code>.
1728: *
1729: * @param newActImpl the new value of actImpl.
1730: * @see #getPaActImpl
1731: */
1732: protected void setPaActImpl(Implementation[] newActImpl) {
1733: paActImpl = newActImpl;
1734: persistentAttributeModified = true;
1735: slowlyChangingPaModified = true;
1736: }
1737:
1738: /**
1739: * The getter method implementation for the persistent
1740: * read-only attribute <code>processKey</code>.
1741: *
1742: * @return the value of processKey.
1743: */
1744: protected String getPaProcessKey() {
1745: return processPk.toString();
1746: }
1747:
1748: /**
1749: * The getter method implementation for the persistent
1750: * read-only attribute <code>processName</code>.
1751: *
1752: * @return the value of processName.
1753: */
1754: protected String getPaProcessName() {
1755: return processName;
1756: }
1757:
1758: /**
1759: * The getter method implementation for the persistent
1760: * read-only attribute <code>processMgrName</code>.
1761: *
1762: * @return the value of processMgrName.
1763: */
1764: protected String getPaProcessMgrName() {
1765: return processMgr;
1766: }
1767:
1768: /**
1769: * The getter method implementation for the persistent
1770: * read-only attribute <code>processMgrVersion</code>.
1771: *
1772: * @return the value of processMgrVersion.
1773: */
1774: protected String getPaProcessMgrVersion() {
1775: return processMgrVers;
1776: }
1777:
1778: /**
1779: * The getter method implementation for the persistent
1780: * attribute <code>threadInfo</code>.
1781: *
1782: * @see #setPaThreadInfo
1783: * @return the value of threadInfo.
1784: */
1785: protected ThreadInfo getPaThreadInfo() {
1786: return paThreadInfo;
1787: }
1788:
1789: /**
1790: * The setter method implementation for the persistent
1791: * attribute <code>threadInfo</code>.
1792: *
1793: * @param newThreadInfo the new value of threadInfo.
1794: * @see #getPaThreadInfo
1795: */
1796: protected void setPaThreadInfo(ThreadInfo newThreadInfo) {
1797: paThreadInfo = newThreadInfo;
1798: persistentAttributeModified = true;
1799: threadInfoModified = true;
1800: }
1801:
1802: /**
1803: * The getter method implementation for the persistent
1804: * attribute <code>Subflow</code>.
1805: *
1806: * @see #setPaSubflow
1807: * @return the value of Subflow.
1808: */
1809: protected String getPaSubflow() {
1810: return paSubflow;
1811: }
1812:
1813: /**
1814: * The setter method implementation for the persistent
1815: * attribute <code>Subflow</code>.
1816: *
1817: * @param newSubflow the new value of Subflow.
1818: * @see #getPaSubflow
1819: */
1820: protected void setPaSubflow(String newSubflow) {
1821: paSubflow = newSubflow;
1822: persistentAttributeModified = true;
1823: }
1824:
1825: /**
1826: * The getter method implementation for the persistent
1827: * attribute <code>deadlines</code>.
1828: *
1829: * @see #setPaDeadlines
1830: * @return the value of deadlines.
1831: */
1832: protected List getPaDeadlines() {
1833: if (paDeadlines == null) {
1834: try {
1835: paDeadlines = WfProcessEJB.loadDeadlines(ds, (Long) ctx
1836: .getPrimaryKey());
1837: } catch (SQLException e) {
1838: throw new EJBException(e);
1839: } catch (IOException e) {
1840: throw new EJBException(e);
1841: }
1842: }
1843: return paDeadlines;
1844: }
1845:
1846: /**
1847: * The setter method implementation for the persistent
1848: * attribute <code>deadlines</code>.
1849: *
1850: * @param newDeadlines the new value of deadlines.
1851: * @see #getPaDeadlines
1852: */
1853: protected void setPaDeadlines(List newDeadlines) {
1854: paDeadlines = newDeadlines;
1855: persistentAttributeModified = true;
1856: deadlinesModified = true;
1857: }
1858:
1859: /**
1860: * The getter method implementation for the persistent
1861: * attribute <code>startTime</code>.
1862: *
1863: * @see #setPaStartTime
1864: * @return the value of startTime.
1865: */
1866: protected Date getPaStartTime() {
1867: return paStartTime;
1868: }
1869:
1870: /**
1871: * The setter method implementation for the persistent
1872: * attribute <code>startTime</code>.
1873: *
1874: * @param newStartTime the new value of startTime.
1875: * @see #getPaStartTime
1876: */
1877: protected void setPaStartTime(Date newStartTime) {
1878: paStartTime = newStartTime;
1879: execTimesModified = true;
1880: persistentAttributeModified = true;
1881: }
1882:
1883: /**
1884: * The getter method implementation for the persistent
1885: * attribute <code>suspendStart</code>.
1886: *
1887: * @see #setPaSuspendStart
1888: * @return the value of suspendStart.
1889: */
1890: protected Date getPaSuspendStart() {
1891: return paSuspendStart;
1892: }
1893:
1894: /**
1895: * The setter method implementation for the persistent
1896: * attribute <code>suspendStart</code>.
1897: *
1898: * @param newSuspendStart the new value of suspendStart.
1899: * @see #getPaSuspendStart
1900: */
1901: protected void setPaSuspendStart(Date newSuspendStart) {
1902: paSuspendStart = newSuspendStart;
1903: persistentAttributeModified = true;
1904: execTimesModified = true;
1905: }
1906:
1907: /**
1908: * The getter method implementation for the persistent
1909: * attribute <code>suspendAccum</code>.
1910: *
1911: * @see #setPaSuspendAccum
1912: * @return the value of suspendAccum.
1913: */
1914: protected long getPaSuspendAccum() {
1915: return paSuspendAccum;
1916: }
1917:
1918: /**
1919: * The setter method implementation for the persistent
1920: * attribute <code>suspendAccum</code>.
1921: *
1922: * @param newSuspendAccum the new value of suspendAccum.
1923: * @see #getPaSuspendAccum
1924: */
1925: protected void setPaSuspendAccum(long newSuspendAccum) {
1926: paSuspendAccum = newSuspendAccum;
1927: persistentAttributeModified = true;
1928: execTimesModified = true;
1929: }
1930:
1931: /**
1932: * The getter method implementation for the persistent
1933: * attribute <code>pendingException</code>.
1934: *
1935: * @see #setPaPendingException
1936: * @return the value of pendingException.
1937: */
1938: protected String getPaPendingException() {
1939: return paPendingException;
1940: }
1941:
1942: /**
1943: * The setter method implementation for the persistent
1944: * attribute <code>pendingException</code>.
1945: *
1946: * @param newPendingException the new value of pendingException.
1947: * @see #getPaPendingException
1948: */
1949: protected void setPaPendingException(String newPendingException) {
1950: paPendingException = newPendingException;
1951: persistentAttributeModified = true;
1952: slowlyChangingPaModified = true;
1953: }
1954:
1955: /** Persistent attribute <code>blockActivity</code>. */
1956: private Long paBlockActivity;
1957:
1958: /**
1959: * The getter method implementation for the persistent
1960: * attribute <code>blockActivity</code>.
1961: *
1962: * @see #setPaBlockActivity
1963: * @return the value of blockActivity.
1964: */
1965: protected Long getPaBlockActivity() {
1966: return paBlockActivity;
1967: }
1968:
1969: /**
1970: * The setter method implementation for the persistent attribute
1971: * <code>blockActivity</code>. May only be used in base class'
1972: * init.
1973: *
1974: * @param newBlockActivity the new value of blockActivity.
1975: * @see #getPaBlockActivity
1976: */
1977: protected void setPaBlockActivity(Long newBlockActivity) {
1978: paBlockActivity = newBlockActivity;
1979: }
1980:
1981: /**
1982: * The getter method implementation for the persistent
1983: * attribute <code>waitOnProc</code>.
1984: *
1985: * @see #setPaWaitOnProc
1986: * @return the value of waitOnProc.
1987: */
1988: protected Long getPaWaitOnProc() {
1989: return paWaitOnProc;
1990: }
1991:
1992: /**
1993: * The setter method implementation for the persistent
1994: * attribute <code>waitOnProc</code>.
1995: *
1996: * @param newWaitOnProc the new value of waitingOn.
1997: * @see #getPaWaitOnProc
1998: */
1999: protected void setPaWaitOnProc(Long newWaitOnProc) {
2000: if (newWaitOnProc == null
2001: && paWaitOnProc == null
2002: || (newWaitOnProc != null && paWaitOnProc != null && newWaitOnProc
2003: .equals(paWaitOnProc))) {
2004: return;
2005: }
2006: paWaitOnProc = newWaitOnProc;
2007: persistentAttributeModified = true;
2008: waitingOnModified = true;
2009: }
2010:
2011: /**
2012: * The getter method implementation for the persistent
2013: * attribute <code>waitOnChan</code>.
2014: *
2015: * @see #setPaWaitOnChan
2016: * @return the value of waitOnChan.
2017: */
2018: protected String getPaWaitOnChan() {
2019: return paWaitOnChan;
2020: }
2021:
2022: /**
2023: * The setter method implementation for the persistent
2024: * attribute <code>waitOnChan</code>.
2025: *
2026: * @param newWaitOnChan the new value of waitingOn.
2027: * @see #getPaWaitOnChan
2028: */
2029: protected void setPaWaitOnChan(String newWaitOnChan) {
2030: if (newWaitOnChan == null
2031: && paWaitOnChan == null
2032: || (newWaitOnChan != null && paWaitOnChan != null && newWaitOnChan
2033: .equals(paWaitOnChan))) {
2034: return;
2035: }
2036: paWaitOnChan = newWaitOnChan;
2037: persistentAttributeModified = true;
2038: waitingOnModified = true;
2039: }
2040:
2041: /**
2042: * The getter method implementation for the persistent
2043: * attribute <code>debug</code>.
2044: *
2045: * @see #setPaDebug
2046: * @return the value of debug.
2047: */
2048: protected boolean getPaDebug() {
2049: return (paFlags & FLAGS_DEBUG) != 0;
2050: }
2051:
2052: /**
2053: * The setter method implementation for the persistent
2054: * attribute <code>debug</code>.
2055: *
2056: * @param newDebug the new value of debug.
2057: * @see #getPaDebug
2058: */
2059: protected void setPaDebug(boolean newDebug) {
2060: paFlags = (paFlags & ~FLAGS_DEBUG)
2061: | (newDebug ? FLAGS_DEBUG : 0);
2062: persistentAttributeModified = true;
2063: }
2064:
2065: /**
2066: * The getter method implementation for the persistent
2067: * attribute <code>subStateBackup</code>.
2068: *
2069: * @see #setPaSubStateBackup
2070: * @return the value of subStateBackup.
2071: */
2072: protected int getPaSubStateBackup() {
2073: return (paFlags & FLAGS_SUB_STATE_MASK) >> FLAGS_SUB_STATE_SHIFT;
2074: }
2075:
2076: /**
2077: * The setter method implementation for the persistent
2078: * attribute <code>subStateBackup</code>.
2079: *
2080: * @param newSubStateBackup the new value of subStateBackup.
2081: * @see #getPaSubStateBackup
2082: */
2083: protected void setPaSubStateBackup(int newSubStateBackup) {
2084: paFlags = (paFlags & ~FLAGS_SUB_STATE_MASK)
2085: | (newSubStateBackup << FLAGS_SUB_STATE_SHIFT);
2086: persistentAttributeModified = true;
2087: }
2088:
2089: /**
2090: * The getter method implementation for the persistent
2091: * attribute <code>deferChoiceOnSplit</code>.
2092: *
2093: * @see #setPaDeferChoiceOnSplit
2094: * @return the value of deferChoiceOnSplit.
2095: */
2096: protected boolean getPaDeferChoiceOnSplit() {
2097: return (paFlags & FLAGS_DEFERRED_CHOICE) != 0;
2098: }
2099:
2100: /**
2101: * The setter method implementation for the persistent
2102: * attribute <code>deferChoiceOnSplit</code>.
2103: *
2104: * @param newDeferChoiceOnSplit the new value of deferChoiceOnSplit.
2105: * @see #getPaDeferChoiceOnSplit
2106: */
2107: protected void setPaDeferChoiceOnSplit(boolean newDeferChoiceOnSplit) {
2108: paFlags = (paFlags & ~FLAGS_DEFERRED_CHOICE)
2109: | (newDeferChoiceOnSplit ? FLAGS_DEFERRED_CHOICE : 0);
2110: persistentAttributeModified = true;
2111: }
2112:
2113: /**
2114: * The getter method implementation for the persistent
2115: * attribute <code>preliminaryChosen</code>.
2116: *
2117: * @see #setPaPreliminarilyChosen
2118: * @return the value of preliminarilyChosen.
2119: */
2120: protected boolean getPaPreliminarilyChosen() {
2121: return (paFlags & FLAGS_PRELIMINARILY_CHOSEN) != 0;
2122: }
2123:
2124: /**
2125: * The setter method implementation for the persistent
2126: * attribute <code>preliminaryChosen</code>.
2127: *
2128: * @param newPreliminarilyChosen the new value of preliminarilyChosen.
2129: * @see #getPaPreliminarilyChosen
2130: */
2131: protected void setPaPreliminarilyChosen(
2132: boolean newPreliminarilyChosen) {
2133: paFlags = (paFlags & ~FLAGS_PRELIMINARILY_CHOSEN)
2134: | (newPreliminarilyChosen ? FLAGS_PRELIMINARILY_CHOSEN
2135: : 0);
2136: persistentAttributeModified = true;
2137: }
2138:
2139: /**
2140: * The getter method implementation for the persistent
2141: * attribute <code>noAssignments</code>.
2142: *
2143: * @see #setPaNoAssignments
2144: * @return the value of noAssignments.
2145: */
2146: protected boolean getPaNoAssignments() {
2147: return (paFlags & FLAGS_NO_ASSIGNMENTS) != 0;
2148: }
2149:
2150: /**
2151: * The setter method implementation for the persistent
2152: * attribute <code>noAssignments</code>.
2153: *
2154: * @param newNoAssignments the new value of noAssignments.
2155: * @see #getPaNoAssignments
2156: */
2157: protected void setPaNoAssignments(boolean newNoAssignments) {
2158: paFlags = (paFlags & ~FLAGS_NO_ASSIGNMENTS)
2159: | (newNoAssignments ? FLAGS_NO_ASSIGNMENTS : 0);
2160: persistentAttributeModified = true;
2161: }
2162:
2163: /**
2164: * The getter method for the persistent flag
2165: * <code>pendingExceptionIsFromBlock</code>.
2166: *
2167: * @return the value of the flag.
2168: * @see #setPaPendingExceptionIsFromBlock
2169: */
2170: protected boolean getPaPendingExceptionIsFromBlock() {
2171: return (paFlags & FLAGS_PENDING_EXCEPTION_IS_FROM_BLOCK) != 0;
2172: }
2173:
2174: /**
2175: * The setter method for the persistent flags
2176: * <code>pendingExceptionIsFromBlock</code>.
2177: *
2178: * @param newValue the new value of the flag.
2179: * @see #getPaPendingExceptionIsFromBlock
2180: */
2181: protected void setPaPendingExceptionIsFromBlock(boolean newValue) {
2182: paFlags = (paFlags & ~FLAGS_PENDING_EXCEPTION_IS_FROM_BLOCK)
2183: | (newValue ? FLAGS_PENDING_EXCEPTION_IS_FROM_BLOCK : 0);
2184: persistentAttributeModified = true;
2185: }
2186:
2187: /**
2188: * The getter method implementation for the persistent
2189: * attribute <code>auditEventSelection</code>.
2190: *
2191: * @see #setPaAuditEventSelection
2192: * @return the value of auditEventSelection.
2193: */
2194: protected int getPaAuditEventSelection() {
2195: return (paFlags & FLAGS_AUDIT_SELECTION_MASK) >> FLAGS_AUDIT_SELECTION_SHIFT;
2196: }
2197:
2198: /**
2199: * The setter method implementation for the persistent
2200: * attribute <code>auditEventSelection</code>.
2201: *
2202: * @param newValue the new value of auditEventSelection.
2203: * @see #getPaAuditEventSelection
2204: */
2205: protected void setPaAuditEventSelection(int newValue) {
2206: paFlags = (paFlags & ~FLAGS_AUDIT_SELECTION_MASK)
2207: | (newValue << FLAGS_AUDIT_SELECTION_SHIFT);
2208: persistentAttributeModified = true;
2209: }
2210:
2211: /**
2212: * The getter method implementation for the persistent
2213: * attribute <code>storeAuditEvents</code>.
2214: *
2215: * @see #setPaStoreAuditEvents
2216: * @return the value of storeAuditEvents.
2217: */
2218: protected boolean getPaStoreAuditEvents() {
2219: return (paFlags & FLAGS_STORE_AUDIT_EVENTS) != 0;
2220: }
2221:
2222: /**
2223: * The setter method implementation for the persistent
2224: * attribute <code>storeAuditEvents</code>.
2225: *
2226: * @param newValue the new value of storeAuditEvents.
2227: * @see #getPaStoreAuditEvents
2228: */
2229: protected void setPaStoreAuditEvents(boolean newValue) {
2230: paFlags = (paFlags & ~FLAGS_STORE_AUDIT_EVENTS)
2231: | (newValue ? FLAGS_STORE_AUDIT_EVENTS : 0);
2232: persistentAttributeModified = true;
2233: }
2234:
2235: }
|