001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: ProcessDirectoryEJB.java,v 1.9 2007/07/04 21:49:29 mlipp Exp $
021: *
022: * $Log: ProcessDirectoryEJB.java,v $
023: * Revision 1.9 2007/07/04 21:49:29 mlipp
024: * Removed no longer required method.
025: *
026: * Revision 1.8 2007/05/03 21:58:25 mlipp
027: * Internal refactoring for making better use of local EJBs.
028: *
029: */
030: package de.danet.an.workflow.ejbs.admin;
031:
032: import java.util.ArrayList;
033: import java.util.Collection;
034: import java.util.Iterator;
035:
036: import java.rmi.RemoteException;
037: import java.sql.Connection;
038: import java.sql.ResultSet;
039: import java.sql.SQLException;
040: import java.sql.Statement;
041:
042: import javax.ejb.CreateException;
043: import javax.ejb.EJBException;
044: import javax.ejb.FinderException;
045: import javax.ejb.ObjectNotFoundException;
046: import javax.ejb.RemoveException;
047: import javax.ejb.SessionBean;
048: import javax.ejb.SessionContext;
049: import javax.naming.NamingException;
050: import javax.sql.DataSource;
051:
052: import de.danet.an.util.EJBUtil;
053: import de.danet.an.util.JDBCUtil;
054: import de.danet.an.util.ResourceNotAvailableException;
055:
056: import de.danet.an.workflow.localapi.ProcessLocal;
057: import de.danet.an.workflow.omgcore.WfRequester;
058:
059: import de.danet.an.workflow.api.Activity;
060: import de.danet.an.workflow.api.ActivityUniqueKey;
061: import de.danet.an.workflow.api.CannotRemoveException;
062: import de.danet.an.workflow.api.InvalidKeyException;
063: import de.danet.an.workflow.api.Process;
064:
065: import de.danet.an.workflow.ejbs.core.WfActivityHome;
066: import de.danet.an.workflow.ejbs.core.WfProcess;
067: import de.danet.an.workflow.ejbs.core.WfProcessHome;
068: import de.danet.an.workflow.ejbs.core.WfProcessLocalHome;
069:
070: /**
071: * The session bean <code>ProcessDirectoryEJB</code> manage the
072: * processes and activities of a contributor.
073: *
074: * @ejb.bean name="ProcessDirectory" display-name="ProcessDirectory"
075: * jndi-name="ejb/@@@_JNDI_Name_Prefix_@@@ProcessDirectory"
076: * type="Stateless" transaction-type="Container" view-type="both"
077: * @jonas.bean ejb-name="ProcessDirectory"
078: * @ejb.home
079: * remote-class="de.danet.an.workflow.ejbs.admin.ProcessDirectoryHome"
080: * local-class="de.danet.an.workflow.ejbs.admin.ProcessDirectoryLocalHome"
081: * @ejb.interface
082: * extends="javax.ejb.EJBObject, de.danet.an.workflow.apix.ExtProcessDirectory"
083: * remote-class="de.danet.an.workflow.ejbs.admin.ProcessDirectory"
084: * local-extends="javax.ejb.EJBLocalObject, de.danet.an.workflow.internalapi.ExtProcessDirectoryLocal"
085: * local-class="de.danet.an.workflow.ejbs.admin.ProcessDirectoryLocal"
086: * @ejb.ejb-ref ejb-name="ProcessDefinitionDirectory"
087: * view-type="remote"
088: * @ejb.ejb-ref ejb-name="ActivityBean" view-type="remote"
089: * @ejb.ejb-ref ejb-name="ProcessBean" view-type="remote"
090: * @ejb.ejb-ref ejb-name="ProcessBean" view-type="local"
091: * @ejb.resource-ref res-ref-name="jdbc/WfEngine"
092: * res-type="javax.sql.DataSource" res-auth="Container"
093: * @jonas.resource res-ref-name="jdbc/WfEngine" jndi-name="jdbc_1"
094: * @weblogic.resource-description
095: * res-ref-name="jdbc/WfEngine" jndi-name="DefaultDS"
096: * @ejb.transaction type="Required"
097: * @ejb.permission role-name="WfMOpenAdmin"
098: * @weblogic.enable-call-by-reference True
099: * @weblogic.transaction-isolation TRANSACTION_READ_COMMITTED
100: */
101: public class ProcessDirectoryEJB implements SessionBean {
102:
103: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
104: .getLog(ProcessDirectoryEJB.class);
105:
106: /** The SessionContext interface of the instance. */
107: private SessionContext ctx;
108:
109: /**
110: * The data source of the database.
111: * @see javax.sql.DataSource
112: */
113: private DataSource ds = null;
114:
115: /** Database name. */
116: private static final String DB_NAME = "java:comp/env/jdbc/WfEngine";
117:
118: /** The cached home interface of the activity EJB. */
119: private WfActivityHome activityHomeCache = null;
120:
121: /** The cached home interface of the process EJB. */
122: private WfProcessHome processHomeCache = null;
123: private WfProcessLocalHome processLocalHomeCache = null;
124:
125: /**
126: * This operation method delivers a WfActivity home interface.
127: * @return home of ActivityBean
128: * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfActivity</code>}
129: */
130: private WfActivityHome activityHome()
131: throws ResourceNotAvailableException {
132: if (activityHomeCache == null) {
133: activityHomeCache = (WfActivityHome) EJBUtil
134: .retrieveEJBHome(WfActivityHome.class,
135: "java:comp/env/ejb/ActivityBean");
136: }
137: return activityHomeCache;
138: }
139:
140: /**
141: * This operation method delivers a WFProcessHome interface.
142: * @return home interface of WfProcessBean
143: * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfProcess</code>}
144: */
145: private WfProcessHome processHome()
146: throws ResourceNotAvailableException {
147: if (processHomeCache == null) {
148: processHomeCache = (WfProcessHome) EJBUtil.retrieveEJBHome(
149: WfProcessHome.class,
150: "java:comp/env/ejb/ProcessBean");
151: }
152: return processHomeCache;
153: }
154:
155: /**
156: * This operation method delivers a WFProcessHome interface.
157: * @return home interface of WfProcessBean
158: * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfProcess</code>}
159: */
160: private WfProcessLocalHome processLocalHome()
161: throws ResourceNotAvailableException {
162: if (processLocalHomeCache == null) {
163: processLocalHomeCache = (WfProcessLocalHome) EJBUtil
164: .retrieveEJBLocalHome(WfProcessLocalHome.class,
165: "java:comp/env/ejb/ProcessBeanLocal");
166: }
167: return processLocalHomeCache;
168: }
169:
170: public void setSessionContext(SessionContext context)
171: throws EJBException {
172: ctx = context;
173: activityHomeCache = null;
174: processHomeCache = null;
175: try {
176: // getting new data source
177: ds = JDBCUtil.refreshDS(null, DB_NAME);
178: } catch (NamingException ne) {
179: throw new EJBException(ne);
180: }
181: }
182:
183: /**
184: * Not called for stateless session beans.
185: * @see javax.ejb.SessionBean
186: */
187: public void ejbActivate() throws EJBException {
188: }
189:
190: /**
191: * Not called for stateless session beans.
192: * @see javax.ejb.SessionBean
193: */
194: public void ejbPassivate() throws EJBException {
195: }
196:
197: public void ejbRemove() {
198: ds = null;
199: activityHomeCache = null;
200: processHomeCache = null;
201: ctx = null;
202: }
203:
204: /**
205: * Create an new instance of ProcessDirectoryBean for the Contributor.
206: * @throws CreateException Throws if the ProcessDirectoryBean can not
207: * be create.
208: */
209: public void ejbCreate() throws CreateException {
210: // Write your code here
211: }
212:
213: /**
214: * This operation method delivers a collection of process types
215: * of created processes or an empty collection if no processes
216: * are found.
217: *
218: * @return collection of process definition types as String objects
219: * or an empty collection if no processes are found.
220: * @ejb.interface-method
221: * view-type="remote"
222: */
223: public Collection processMgrNames() {
224: Collection definitionTypes = new ArrayList();
225: Connection con = null;
226: Statement stmt = null;
227: ResultSet rs = null;
228: try {
229: try {
230: con = ds.getConnection();
231: String selectStatement = "SELECT distinct processMgr FROM process";
232: stmt = con.createStatement();
233: rs = stmt.executeQuery(selectStatement);
234: while (rs.next()) {
235: String type = rs.getString(1);
236: definitionTypes.add(type);
237: }
238: } finally {
239: JDBCUtil.closeAll(rs, stmt, con);
240: }
241: } catch (SQLException se) {
242: throw new EJBException(se);
243: }
244: return definitionTypes;
245: }
246:
247: /**
248: * This operation method creates and delivers a collection of all
249: * known processes. The objects of the collection are
250: * remote interface of type
251: * {@link de.danet.an.workflow.omgcore.WfProcess <code>WfProcess</code>}.
252: * @return a Collection object
253: * @ejb.interface-method
254: * view-type="remote"
255: */
256: public Collection processes() {
257: try {
258: return processHome().findAll();
259: } catch (ResourceNotAvailableException re) {
260: throw new EJBException(re);
261: } catch (FinderException ne) {
262: throw new EJBException(ne);
263: } catch (RemoteException re) {
264: throw new EJBException(re);
265: }
266: }
267:
268: /**
269: * This method finds the process identified by the given
270: * type and key.
271: *
272: * @param processMgrName type of the given process.
273: * @param processKey key of the process.
274: * @return the process found.
275: * @throws InvalidKeyException if no such process can be
276: * found.
277: * @ejb.interface-method
278: * view-type="remote"
279: */
280: public de.danet.an.workflow.api.Process lookupProcess(
281: String processMgrName, String processKey)
282: throws InvalidKeyException {
283: try {
284: return processHome().findByProcessKey(processKey);
285: } catch (ObjectNotFoundException onfe) {
286: ctx.setRollbackOnly();
287: throw new InvalidKeyException("No process of type = "
288: + processMgrName + ", key = " + processKey + ": "
289: + onfe.getMessage());
290: } catch (ResourceNotAvailableException re) {
291: throw new EJBException(re);
292: } catch (FinderException fe) {
293: throw new EJBException(fe);
294: } catch (RemoteException re) {
295: throw new EJBException(re);
296: }
297: }
298:
299: /**
300: * This method finds the process identified by the given
301: * type and key.
302: *
303: * @param processMgrName type of the given process.
304: * @param processKey key of the process.
305: * @return the process found.
306: * @throws InvalidKeyException if no such process can be
307: * found.
308: * @ejb.interface-method
309: * view-type="remote"
310: */
311: public ProcessLocal lookupProcessLocal(String processMgrName,
312: String processKey) throws InvalidKeyException {
313: try {
314: return processLocalHome().findByProcessKey(processKey);
315: } catch (ObjectNotFoundException onfe) {
316: ctx.setRollbackOnly();
317: throw new InvalidKeyException("No process of type = "
318: + processMgrName + ", key = " + processKey + ": "
319: + onfe.getMessage());
320: } catch (ResourceNotAvailableException re) {
321: throw new EJBException(re);
322: } catch (FinderException fe) {
323: throw new EJBException(fe);
324: } catch (RemoteException re) {
325: throw new EJBException(re);
326: }
327: }
328:
329: /**
330: * Return the processes requested by the given requester. This is
331: * a helper method intended to be used when implementing a
332: * <code>WfRequester</code>. Applications should use {@link
333: * de.danet.an.workflow.omgcore.WfRequester#performers
334: * <code>WfRequester.performers</code>} instead.
335: * @param req the requester.
336: * @return the processes created with the given requester.
337: * @ejb.interface-method view-type="remote"
338: */
339: public Collection requestedBy(WfRequester req) {
340: Collection res = new ArrayList();
341: try {
342: Collection hashEqual = processHome().findByRequesterHash(
343: req.hashCode());
344: for (Iterator i = hashEqual.iterator(); i.hasNext();) {
345: Process p = (Process) i.next();
346: if (p.requester().equals(req)) {
347: res.add(p);
348: }
349: }
350: return res;
351: } catch (ResourceNotAvailableException re) {
352: throw new EJBException(re);
353: } catch (FinderException ne) {
354: throw new EJBException(ne);
355: } catch (RemoteException re) {
356: throw new EJBException(re);
357: }
358: }
359:
360: /**
361: * Removes the given process. The process can be removed, only and if only
362: * it is in state "closed".
363: *
364: * @param process the process to remove.
365: * @throws CannotRemoveException if the process cannot be removed,
366: * because it is still in progress.
367: * @ejb.interface-method view-type="remote"
368: */
369: public void removeProcess(
370: de.danet.an.workflow.omgcore.WfProcess process)
371: throws CannotRemoveException {
372: try {
373: ((WfProcess) process).remove();
374: } catch (RemoteException re) {
375: throw new CannotRemoveException(re.getMessage());
376: } catch (RemoveException re) {
377: throw new CannotRemoveException(re.getMessage());
378: }
379: }
380:
381: /**
382: * This method returns the activity identified be the given unique
383: * key.
384: *
385: * @param key denotes the activity to be looked up.
386: * @return the corresponding <code>Activity</code> value
387: * @exception InvalidKeyException if the activity specified by
388: * <code>key</code> cannot be found.
389: * @ejb.interface-method
390: * view-type="remote"
391: */
392: public Activity lookupActivity(ActivityUniqueKey key)
393: throws InvalidKeyException {
394: try {
395: Long pk = Long.valueOf(key.activityKey());
396: return activityHome().findByPrimaryKey(pk);
397: } catch (NumberFormatException nex) {
398: ctx.setRollbackOnly();
399: throw new InvalidKeyException("Cause: " + nex.getMessage());
400: } catch (FinderException nex) {
401: throw new InvalidKeyException("Cause: " + nex.getMessage());
402: } catch (RemoteException nex) {
403: throw new EJBException(nex);
404: }
405: }
406:
407: /**
408: * This method finds the activity identified be the given unique
409: * key and returns all available information about it.
410: *
411: * @param key denotes the activity to be looked up.
412: * @return the corresponding <code>Activity.Info</code> value
413: * @exception InvalidKeyException if the activity specified by
414: * <code>key</code> cannot be found.
415: * @ejb.interface-method
416: * view-type="remote"
417: */
418: public de.danet.an.workflow.api.Activity.Info lookupActivityInfo(
419: ActivityUniqueKey key) throws InvalidKeyException {
420: try {
421: Long pk = Long.valueOf(key.activityKey());
422: return activityHome().findByPrimaryKey(pk).activityInfo();
423: } catch (NumberFormatException nex) {
424: ctx.setRollbackOnly();
425: throw new InvalidKeyException("Cause: " + nex.getMessage());
426: } catch (FinderException nex) {
427: throw new EJBException(nex);
428: } catch (RemoteException nex) {
429: throw new EJBException(nex);
430: }
431: }
432:
433: }
|