Source Code Cross Referenced for StandardResourceAssignmentService.java in  » Workflow-Engines » wfmopen-2.1.1 » de » danet » an » workflow » assignment » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Workflow Engines » wfmopen 2.1.1 » de.danet.an.workflow.assignment 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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: StandardResourceAssignmentService.java,v 1.8 2007/03/27 21:59:43 mlipp Exp $
021:         *
022:         * $Log: StandardResourceAssignmentService.java,v $
023:         * Revision 1.8  2007/03/27 21:59:43  mlipp
024:         * Fixed lots of checkstyle warnings.
025:         *
026:         * Revision 1.7  2007/02/27 14:34:18  drmlipp
027:         * Some refactoring to reduce cyclic dependencies.
028:         *
029:         * Revision 1.6  2006/10/15 19:29:51  mlipp
030:         * Merged changes from 1.4.x up to 1.4ea3pre1.
031:         *
032:         * Revision 1.5.2.2  2006/10/15 18:25:12  mlipp
033:         * Fixed visibility.
034:         *
035:         * Revision 1.5.2.1  2006/10/14 21:34:06  mlipp
036:         * Simplified resource assignment service implementation.
037:         *
038:         * Revision 1.5  2006/09/29 12:32:12  drmlipp
039:         * Consistently using WfMOpen as projct name now.
040:         *
041:         * Revision 1.4  2005/10/15 21:19:38  mlipp
042:         * Added support for providing WfAssignment
043:         * implementations based purely on methods of Activity.
044:         *
045:         * Revision 1.3  2005/08/17 21:15:31  mlipp
046:         * Synchronized with 1.3.1p3.
047:         *
048:         * Revision 1.1.1.2.6.1  2005/08/16 14:04:04  drmlipp
049:         * Backported LDAP RMS and security role fixes.
050:         *
051:         * Revision 1.1.1.2.4.2  2005/08/15 16:38:13  drmlipp
052:         * Improved sealing of exceptions from RMS.
053:         *
054:         * Revision 1.1.1.2.4.1  2005/08/14 21:07:55  drmlipp
055:         * Fixed initialization problem (RMS initialized in wrong context).
056:         *
057:         * Revision 1.2  2005/07/04 20:40:25  mlipp
058:         * Improved problem reporting.
059:         *
060:         * Revision 1.1.1.2  2004/08/18 15:17:36  drmlipp
061:         * Update to 1.2
062:         *
063:         * Revision 1.28  2004/06/14 19:37:19  lipp
064:         * Fixed assignment functions and cleaned up assignment related
065:         * interfaces.
066:         *
067:         * Revision 1.27  2004/03/03 17:23:13  lipp
068:         * Implemented setAssignee and cleaned up code a bit.
069:         *
070:         * Revision 1.26  2003/06/27 08:51:46  lipp
071:         * Fixed copyright/license information.
072:         *
073:         * Revision 1.25  2003/04/26 16:11:15  lipp
074:         * Moved some classes to reduce package dependencies.
075:         *
076:         * Revision 1.24  2003/04/25 14:50:59  lipp
077:         * Fixed javadoc errors and warnings.
078:         *
079:         * Revision 1.23  2002/12/19 21:37:43  lipp
080:         * Reorganized interfaces.
081:         *
082:         * Revision 1.22  2002/11/26 11:23:30  lipp
083:         * Modified RemoteException comment.
084:         *
085:         * Revision 1.21  2002/06/27 10:55:35  lipp
086:         * Delayed initialization even more.
087:         *
088:         * Revision 1.20  2002/01/23 15:22:53  huaiyang
089:         * Add M:<name> as resource selection in autoAssignResources method.
090:         *
091:         * Revision 1.19  2002/01/15 13:42:21  lipp
092:         * Added resourceByKey to ResourceAssignmentService and some missing
093:         * NoSuchResourceExceptions in various methods.
094:         *
095:         * Revision 1.18  2002/01/15 11:25:59  huaiyang
096:         * Add the assigned activity function to the mgmt client.
097:         *
098:         * Revision 1.17  2002/01/09 14:48:51  lipp
099:         * Changed access to current user as resource.
100:         *
101:         * Revision 1.16  2002/01/09 14:00:01  lipp
102:         * Cleaned up relation between wfcore, resource assignment and resource
103:         * management service.
104:         *
105:         * Revision 1.15  2002/01/08 18:12:06  lipp
106:         * Method to determined currently logged on user moved to resource
107:         * management service.
108:         *
109:         * Revision 1.14  2001/12/20 22:32:06  lipp
110:         * Removed no longer needed method.
111:         *
112:         * Revision 1.13  2001/12/20 22:27:34  lipp
113:         * WfResource release semantics fixed.
114:         *
115:         * Revision 1.12  2001/12/20 22:22:50  lipp
116:         * Resource release implemented.
117:         *
118:         * Revision 1.11  2001/12/20 16:24:25  lipp
119:         * Resource assignment extended.
120:         *
121:         * Revision 1.10  2001/12/19 22:07:29  lipp
122:         * Automatic resource assignment (workflow core part) implemented.
123:         *
124:         * Revision 1.9  2001/12/18 22:16:52  lipp
125:         * Restructured DOM generation, implemented "assignments" method from ras.
126:         *
127:         * Revision 1.8  2001/12/18 15:35:11  lipp
128:         * Implemented workItems and isMemberOfWorkItem.
129:         *
130:         * Revision 1.7  2001/12/17 19:56:03  lipp
131:         * Implementation of equality checking improved.
132:         *
133:         * Revision 1.6  2001/12/17 15:50:57  lipp
134:         * Better handling of resource refs.
135:         *
136:         * Revision 1.5  2001/12/17 12:14:04  lipp
137:         * Adapted to configurable ResourceManagement/AssignmentServices.
138:         *
139:         * Revision 1.4  2001/12/17 10:52:19  lipp
140:         * Added configurable resource management service.
141:         *
142:         * Revision 1.3  2001/12/17 09:15:50  lipp
143:         * Javadoc fixes.
144:         *
145:         * Revision 1.2  2001/12/16 21:48:57  lipp
146:         * addAssignment implemented.
147:         *
148:         * Revision 1.1  2001/12/16 10:37:35  lipp
149:         * Assignment service implemented.
150:         *
151:         */
152:        package de.danet.an.workflow.assignment;
153:
154:        import java.util.ArrayList;
155:        import java.util.Collection;
156:        import java.util.HashMap;
157:        import java.util.Iterator;
158:        import java.util.Map;
159:
160:        import java.io.IOException;
161:        import java.io.OptionalDataException;
162:        import java.rmi.RemoteException;
163:        import java.security.Principal;
164:        import java.sql.Connection;
165:        import java.sql.PreparedStatement;
166:        import java.sql.ResultSet;
167:        import java.sql.SQLException;
168:
169:        import javax.ejb.EJBException;
170:        import javax.sql.DataSource;
171:
172:        import de.danet.an.util.EJBUtil;
173:        import de.danet.an.util.JDBCUtil;
174:        import de.danet.an.util.ResourceNotAvailableException;
175:        import de.danet.an.util.UniversalPrepStmt;
176:        import de.danet.an.workflow.omgcore.InvalidResourceException;
177:        import de.danet.an.workflow.omgcore.NotAssignedException;
178:        import de.danet.an.workflow.omgcore.WfActivity;
179:        import de.danet.an.workflow.omgcore.WfAssignment;
180:        import de.danet.an.workflow.omgcore.WfResource;
181:
182:        import de.danet.an.workflow.api.AlreadyAssignedException;
183:        import de.danet.an.workflow.api.InvalidKeyException;
184:        import de.danet.an.workflow.api.NoSuchResourceException;
185:        import de.danet.an.workflow.api.Participant;
186:        import de.danet.an.workflow.api.Participant.ParticipantType;
187:
188:        import de.danet.an.workflow.spis.ras.ActivityFinder;
189:        import de.danet.an.workflow.spis.ras.FactoryConfigurationError;
190:        import de.danet.an.workflow.spis.ras.NoSuchActivityException;
191:        import de.danet.an.workflow.spis.ras.ResourceAssignmentService;
192:        import de.danet.an.workflow.spis.rms.ResourceAssignmentContext;
193:        import de.danet.an.workflow.spis.rms.ResourceManagementService;
194:        import de.danet.an.workflow.spis.rms.ResourceManagementServiceFactory;
195:        import de.danet.an.workflow.spis.rms.ResourceNotFoundException;
196:
197:        /**
198:         * This class implements the standard resource assignment service provided
199:         * as part of the workflow package.
200:         */
201:        public class StandardResourceAssignmentService implements 
202:                ResourceAssignmentService {
203:
204:            private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
205:                    .getLog(StandardResourceAssignmentService.class);
206:
207:            /** Warned about RMS not supporting resource selection? */
208:            private static boolean rmsUnsuppportedWarned = false;
209:
210:            /** An in memory representation of the known finders. */
211:            private static Map finderByDBIdCache = new HashMap(); // used for sync
212:            private static Map dbIdByFinderCache = null; // indicates uninitialized
213:
214:            /**
215:             * The data source of the database.
216:             * @see javax.sql.DataSource
217:             */
218:            private DataSource ds = null;
219:
220:            /** The resource management service associated with this service. */
221:            private ResourceManagementService rms = null;
222:
223:            /**
224:             * Constructs a new resource assignment service.
225:             *
226:             * @param rasCtx an implementation of the resource Assignment context
227:             * @param rmsFac the resource management service factory.
228:             * @throws FactoryConfigurationError if a problem creating the RMS
229:             * occurs
230:             */
231:            public StandardResourceAssignmentService(
232:                    ResourceManagementServiceFactory rmsFac,
233:                    ResourceAssignmentContext rasCtx, DataSource ds)
234:                    throws FactoryConfigurationError {
235:                try {
236:                    rmsFac.setResourceAssignmentContext(rasCtx);
237:                    rms = rmsFac.newResourceManagementService();
238:                } catch (de.danet.an.workflow.spis.rms.FactoryConfigurationError e) {
239:                    throw (FactoryConfigurationError) (new FactoryConfigurationError(
240:                            "Cannot create RMS: " + e.getMessage()))
241:                            .initCause(e);
242:                }
243:                this .ds = ds;
244:            }
245:
246:            /**
247:             * Return the data source oassed to the constructor.
248:             * @return Returns the data source.
249:             */
250:            protected DataSource getDataSource() {
251:                return ds;
252:            }
253:
254:            /**
255:             * Return the resource management service passed to the constructor.
256:             * @return Returns the rms.
257:             */
258:            protected ResourceManagementService getResourceManagementService() {
259:                return rms;
260:            }
261:
262:            /**
263:             * @throws EJBException
264:             */
265:            private void initFinderCache() throws EJBException {
266:                synchronized (finderByDBIdCache) {
267:                    if (dbIdByFinderCache == null) {
268:                        // read finders from database. we cannot do lazy loading,
269:                        // because we cannot lookup by finder (being binary)
270:                        Map finderLookup = new HashMap();
271:                        Map dbIdLookup = new HashMap();
272:                        try {
273:                            Connection con = null;
274:                            PreparedStatement prepStmt = null;
275:                            ResultSet rs = null;
276:                            try {
277:                                con = ds.getConnection();
278:                                String selectStatement = "SELECT DBId, LocData FROM ActivityFinders";
279:                                prepStmt = con
280:                                        .prepareStatement(selectStatement);
281:                                rs = prepStmt.executeQuery();
282:                                while (rs.next()) {
283:                                    long idx = rs.getLong(1);
284:                                    Object finder = JDBCUtil.getBinary(rs, 2);
285:                                    finderLookup.put(new Long(idx), finder);
286:                                    dbIdLookup.put(finder, new Long(idx));
287:                                }
288:                            } finally {
289:                                JDBCUtil.closeAll(rs, prepStmt, con);
290:                            }
291:                        } catch (SQLException se) {
292:                            throw new EJBException(se);
293:                        } catch (OptionalDataException ode) {
294:                            throw new EJBException(ode);
295:                        } catch (IOException ioe) {
296:                            throw new EJBException(ioe);
297:                        } catch (ClassNotFoundException cnf) {
298:                            throw new EJBException(cnf);
299:                        }
300:                        finderByDBIdCache = finderLookup;
301:                        dbIdByFinderCache = dbIdLookup;
302:                    }
303:                }
304:            }
305:
306:            /**
307:             * Get the finder id for a finder.
308:             *
309:             * @param finder the activity finder in question.
310:             * @return the associated index.
311:             * @throws RemoteException if a system-level error occurs.
312:             */
313:            protected long finderId(ActivityFinder finder)
314:                    throws RemoteException {
315:                synchronized (finderByDBIdCache) {
316:                    initFinderCache();
317:                    Long idx = (Long) dbIdByFinderCache.get(finder);
318:                    if (idx != null) {
319:                        return idx.longValue();
320:                    }
321:                    // new finder, insert
322:                    try {
323:                        Connection con = ds.getConnection();
324:                        UniversalPrepStmt prepStmt = null;
325:                        long newIdx = EJBUtil.newPrimaryKey("ActivityFinders");
326:                        try {
327:                            prepStmt = new UniversalPrepStmt(ds, con,
328:                                    "INSERT INTO ActivityFinders (DBId, LocData) "
329:                                            + "VALUES (?, ?)");
330:                            prepStmt.setLong(1, newIdx);
331:                            prepStmt.setBinary(2, finder);
332:                            prepStmt.executeUpdate();
333:                        } finally {
334:                            JDBCUtil.closeAll(null, prepStmt, con);
335:                        }
336:                        finderByDBIdCache.put(new Long(newIdx), finder);
337:                        dbIdByFinderCache.put(finder, new Long(newIdx));
338:                        return newIdx;
339:                    } catch (ResourceNotAvailableException e) {
340:                        throw new EJBException(e);
341:                    } catch (SQLException se) {
342:                        throw new EJBException(se);
343:                    } catch (OptionalDataException ode) {
344:                        throw new EJBException(ode);
345:                    } catch (IOException ioe) {
346:                        throw new EJBException(ioe);
347:                    }
348:                }
349:            }
350:
351:            /**
352:             * Lookup a finder for a given finder id.
353:             * 
354:             * @param finderId the finder id
355:             * @return the finder
356:             */
357:            protected ActivityFinder finderByIndex(long finderId) {
358:                initFinderCache();
359:                return (ActivityFinder) finderByDBIdCache
360:                        .get(new Long(finderId));
361:            }
362:
363:            /**
364:             * Change an assignment for enacting an activity.<P>
365:             *
366:             * @param finder the finder used to lookup activities by 
367:             * their <code>finderId</code>s
368:             * @param actId a unique (with respect to an <code>ActivityFinder</code>)
369:             * identifier for the Activity. The length of <code>actId</code> is 
370:             * guaranteed not to exceed 64
371:             * @param activity the activity being enacted
372:             * @param oldResource the resource that has its assignment removed
373:             * @param newResource the resource to be assigned
374:             * @throws RemoteException if a system-level error occurs
375:             * @throws InvalidResourceException if the resource is invalid.
376:             * As the environment is a concurrent multi user environment, 
377:             * <code>WfResource</code> objects may become invalid
378:             * @throws AlreadyAssignedException if the assignment already
379:             * exists
380:             * @throws NotAssignedException if there is no assignment to the
381:             * old resource
382:             * @see ActivityFinder
383:             */
384:            public void changeAssignment(ActivityFinder finder, String actId,
385:                    WfActivity activity, WfResource oldResource,
386:                    WfResource newResource) throws RemoteException,
387:                    InvalidResourceException, AlreadyAssignedException,
388:                    NotAssignedException {
389:                long finderId = finderId(finder);
390:                try {
391:                    Connection con = null;
392:                    PreparedStatement prepStmt = null;
393:                    ResultSet rs = null;
394:                    try {
395:                        con = ds.getConnection();
396:                        prepStmt = con
397:                                .prepareStatement("UPDATE Assignments SET assignedresource=? WHERE "
398:                                        + "actfinder=? AND activity=? AND assignedresource=?");
399:                        prepStmt.setString(1, newResource.resourceKey());
400:                        prepStmt.setLong(2, finderId);
401:                        prepStmt.setString(3, actId);
402:                        prepStmt.setString(4, oldResource.resourceKey());
403:                        if (prepStmt.executeUpdate() != 1) {
404:                            throw new NotAssignedException();
405:                        }
406:                    } finally {
407:                        JDBCUtil.closeAll(rs, prepStmt, con);
408:                    }
409:                } catch (SQLException se) {
410:                    throw new EJBException(se);
411:                }
412:            }
413:
414:            /**
415:             * Remove the assignment of a resource to an activity. This method
416:             * is called by the workflow engine to implement the assignment
417:             * manipulation methods provided by its API.<P>
418:             *
419:             * @param actId a unique (with respect to an <code>ActivityFinder</code>)
420:             * identifier for the Activity. The length of <code>actId</code> is 
421:             * guaranteed not to exceed 64.
422:             * @param finder the finder used to lookup activities by 
423:             * their <code>finderId</code>s.
424:             * @param activity the activity that is about to become ready.
425:             * @param resource the resource to be assigned.
426:             * @throws RemoteException if a system-level error occurs.
427:             * @throws InvalidResourceException if the resource is invalid.
428:             * @throws NotAssignedException if the resource is not assigned to
429:             * the given activity
430:             * @see ActivityFinder
431:             */
432:            public void removeAssignment(ActivityFinder finder, String actId,
433:                    WfActivity activity, WfResource resource)
434:                    throws RemoteException, InvalidResourceException,
435:                    NotAssignedException {
436:                long finderId = finderId(finder);
437:                try {
438:                    Connection con = null;
439:                    PreparedStatement prepStmt = null;
440:                    ResultSet rs = null;
441:                    try {
442:                        con = ds.getConnection();
443:                        prepStmt = con
444:                                .prepareStatement("DELETE FROM Assignments WHERE "
445:                                        + "actfinder=? AND activity=? AND assignedresource=?");
446:                        prepStmt.setLong(1, finderId);
447:                        prepStmt.setString(2, actId);
448:                        prepStmt.setString(3, resource.resourceKey());
449:                        if (prepStmt.executeUpdate() != 1) {
450:                            throw new NotAssignedException();
451:                        }
452:                    } finally {
453:                        JDBCUtil.closeAll(rs, prepStmt, con);
454:                    }
455:                } catch (SQLException se) {
456:                    throw new EJBException(se);
457:                }
458:            }
459:
460:            /**
461:             * Get the resource associated with an Assignment.<P>
462:             *
463:             * @param asnmnt the assignment
464:             * @return the resource
465:             * @throws RemoteException if a system-level error occurs.
466:             * @see de.danet.an.workflow.spis.ras.ActivityFinder
467:             * @ejb.interface-method view-type="remote"
468:             */
469:            public WfResource getResource(WfAssignment asnmnt)
470:                    throws RemoteException {
471:                String resKey = null;
472:                Connection con = null;
473:                PreparedStatement prepStmt = null;
474:                ResultSet rs = null;
475:                try {
476:                    con = ds.getConnection();
477:                    try {
478:                        prepStmt = con
479:                                .prepareStatement("SELECT AssignedResource FROM Assignments WHERE DBId = ?");
480:                        prepStmt.setLong(1, ((Assignment) asnmnt).key());
481:                        rs = prepStmt.executeQuery();
482:                        if (!rs.next()) {
483:                            throw new IllegalStateException(
484:                                    "Cannot access assignment info, "
485:                                            + "assignment has probably been removed");
486:                        }
487:                        resKey = rs.getString(1);
488:                    } finally {
489:                        JDBCUtil.closeAll(rs, prepStmt, con);
490:                    }
491:                } catch (SQLException se) {
492:                    throw new EJBException(se);
493:                }
494:                try {
495:                    return rms.resourceByKey(resKey);
496:                } catch (ResourceNotFoundException rnf) {
497:                    logger.error(rnf.getMessage(), rnf);
498:                    throw new IllegalStateException("Cannot lookup resource, "
499:                            + "has probably been deleted while being assigned");
500:                } catch (RemoteException e) {
501:                    throw e;
502:                } catch (Exception e) {
503:                    logger.error(rms + " has thrown an unexpected exception "
504:                            + "(mapped to IllegalStateException): "
505:                            + e.getMessage(), e);
506:                    throw (IllegalStateException) (new IllegalStateException(
507:                            "Unexpected exception from RMS: " + e.getMessage()))
508:                            .initCause(e);
509:                }
510:            }
511:
512:            /**
513:             * Return the assignments to an activity.
514:             *
515:             * @param actId a unique (with respect to an <code>ActivityFinder</code>)
516:             * identifier for the Activity. The length of <code>actId</code> is 
517:             * guaranteed not to exceed 64.
518:             * @param finder the finder used to lookup activities by 
519:             * their <code>finderId</code>s.
520:             * @param activity the activity.
521:             * @return the collection of assignments (instances of
522:             * {@link de.danet.an.workflow.omgcore.WfAssignment
523:             * <code>WfAssignment</code>}).
524:             * @throws RemoteException if a system-level error occurs.
525:             */
526:            public Collection assignments(ActivityFinder finder, String actId,
527:                    WfActivity activity) throws RemoteException {
528:                Collection res = new ArrayList();
529:                Connection con = null;
530:                PreparedStatement prepStmt = null;
531:                ResultSet rs = null;
532:                try {
533:                    try {
534:                        con = ds.getConnection();
535:                        String selectStatement = "SELECT DBId FROM Assignments "
536:                                + "WHERE actfinder=? AND activity=?";
537:                        prepStmt = con.prepareStatement(selectStatement);
538:                        prepStmt.setLong(1, finderId(finder));
539:                        prepStmt.setString(2, actId);
540:                        rs = prepStmt.executeQuery();
541:                        while (rs.next()) {
542:                            res.add(new Assignment(rs.getLong(1), activity));
543:                        }
544:                    } finally {
545:                        JDBCUtil.closeAll(rs, prepStmt, con);
546:                    }
547:                } catch (SQLException se) {
548:                    throw new EJBException(se);
549:                }
550:                return res;
551:            }
552:
553:            /**
554:             * Return the assignments of a given resource.
555:             *
556:             * @param resource the resource.
557:             * @return the collection of assigned work items (instances of
558:             * {@link de.danet.an.workflow.omgcore.WfAssignment
559:             * <code>WfAssignment</code>}).
560:             * @throws RemoteException if a system-level error occurs.
561:             * @see de.danet.an.workflow.spis.rms
562:             */
563:            public Collection workItems(WfResource resource)
564:                    throws RemoteException {
565:                Connection con = null;
566:                PreparedStatement prepStmt = null;
567:                ResultSet rs = null;
568:                Collection res = new ArrayList();
569:                try {
570:                    try {
571:                        con = ds.getConnection();
572:                        prepStmt = con
573:                                .prepareStatement("SELECT DBId, actfinder, activity FROM Assignments "
574:                                        + "WHERE assignedresource=?");
575:                        prepStmt.setString(1, resource.resourceKey());
576:                        rs = prepStmt.executeQuery();
577:                        while (rs.next()) {
578:                            long dbid = rs.getLong(1);
579:                            long idx = rs.getLong(2);
580:                            ActivityFinder finder = finderByIndex(idx);
581:                            String actKey = rs.getString(3);
582:                            try {
583:                                res.add(new Assignment(dbid, finder
584:                                        .find(actKey)));
585:                            } catch (NoSuchActivityException e) {
586:                                // race condition
587:                                logger
588:                                        .debug("Found assignment to activity key "
589:                                                + actKey
590:                                                + " but not the activity: "
591:                                                + e.getMessage());
592:                            } catch (RemoteException rex) {
593:                                throw new EJBException(rex);
594:                            }
595:                        }
596:                    } finally {
597:                        JDBCUtil.closeAll(rs, prepStmt, con);
598:                    }
599:                } catch (RemoteException e) {
600:                    throw new EJBException(e);
601:                } catch (SQLException se) {
602:                    throw new EJBException(se);
603:                }
604:                return res;
605:            }
606:
607:            /**
608:             * Find out if a given assignment belongs to the work items assigned to 
609:             * a particular resource.
610:             *
611:             * @param resource the resource.
612:             * @param assignment the assignment in question.
613:             * @return <code>true</code> if the <code>assignment</code> belongs to 
614:             * the work items of the <code>resource</code>.
615:             * @throws RemoteException if a system-level error occurs.
616:             * @throws NoSuchResourceException if the resource is invalid.
617:             * @see de.danet.an.workflow.spis.rms
618:             */
619:            public boolean isMemberOfWorkItems(WfResource resource,
620:                    WfAssignment assignment) throws RemoteException,
621:                    NoSuchResourceException {
622:                if (!(assignment instanceof  Assignment)) {
623:                    return false;
624:                }
625:                Assignment assmnt = (Assignment) assignment;
626:                return resource.equals(assmnt.assignee());
627:            }
628:
629:            /**
630:             * Triggers the automatic assignment of resources to an activity that
631:             * is about to become ready.<P>
632:             *
633:             * If <code>resSel</code> is of type string, the following cases
634:             * are handled by the assignment service:
635:             * <dl>
636:             *   <dt><code>!:currentUser</code></dt>
637:             *   <dd>Assigns the current user.</dd>
638:             * </dl>
639:             * 
640:             * In all other cases the parameter <code>resSel</code> is simply
641:             * passed through to
642:             * {@link ResourceManagementService#selectResources the resource
643:             * selection service}.
644:             *
645:             * @param actId a unique (with respect to an <code>ActivityFinder</code>)
646:             * identifier for the Activity. The length of <code>actId</code> is 
647:             * guaranteed not to exceed 64.
648:             * @param finder the finder used to lookup activities by 
649:             * their <code>finderId</code>s.
650:             * @param activity the activity that is about to become ready.
651:             * @param principal the current caller as known in the EJB context,
652:             * may be <code>null</code>.
653:             * @param participant the <code>Participant</code> that describes the 
654:             * resource selection criteria.
655:             * @return the assigned resources (instances of {@link
656:             * de.danet.an.workflow.omgcore.WfResource
657:             * <code>WfResource</code>}).
658:             * @throws RemoteException if a system-level error occurs.
659:             * @see ActivityFinder
660:             */
661:            public Collection autoAssignResources(ActivityFinder finder,
662:                    String actId, WfActivity activity, Principal principal,
663:                    Participant participant) throws RemoteException {
664:                if (participant == null) {
665:                    return new ArrayList();
666:                }
667:
668:                Object resSel = null;
669:                ParticipantType type = participant.getParticipantType();
670:                Collection assigned = new ArrayList();
671:                if (type.isResourceSet()) {
672:                    resSel = "G:" + participant.getName();
673:                } else if (type.isRole()) {
674:                    resSel = "R:" + participant.getName();
675:                } else if (type.isHuman()) {
676:                    String crit = (String) participant.getResourceSelection();
677:                    if (crit != null && crit.startsWith("!:currentUser")
678:                            && principal != null) {
679:                        try {
680:                            WfResource res = asResource(principal);
681:                            assigned.add(res);
682:                            addAssignment(finderId(finder), actId, res);
683:                            return assigned;
684:                        } catch (AlreadyAssignedException rnf) {
685:                            return assigned;
686:                        } catch (InvalidKeyException rnf) {
687:                            return assigned;
688:                        }
689:                    }
690:                    resSel = "M:" + participant.getName();
691:                }
692:
693:                // fall through
694:                try {
695:                    Collection reses = rms.selectResources(resSel);
696:                    if (reses.size() == 0) {
697:                        return assigned;
698:                    }
699:                    long finderId = finderId(finder);
700:                    for (Iterator i = reses.iterator(); i.hasNext();) {
701:                        WfResource res = (WfResource) i.next();
702:                        assigned.add(res);
703:                        addAssignment(finderId, actId, res);
704:                    }
705:                    return assigned;
706:                } catch (AlreadyAssignedException rnf) {
707:                    return assigned;
708:                } catch (UnsupportedOperationException uo) {
709:                    if (!rmsUnsuppportedWarned) {
710:                        logger.warn("Configured RMS does not support resource "
711:                                + "selection, no resources assigned.");
712:                        rmsUnsuppportedWarned = true;
713:                    }
714:                    return assigned;
715:                } catch (RemoteException e) {
716:                    throw e;
717:                } catch (Exception e) {
718:                    logger
719:                            .error(rms
720:                                    + " has thrown an unexpected exception, "
721:                                    + "no resources are assigned: "
722:                                    + e.getMessage(), e);
723:                    return assigned;
724:                }
725:            }
726:
727:            /**
728:             * Assign a resource to an activity.
729:             *
730:             * @param actId a unique (with respect to an <code>ActivityFinder</code>)
731:             * identifier for the Activity. The length of <code>actId</code> is 
732:             * guaranteed not to exceed 64.
733:             * @param finderId the <code>finderId</code>s.
734:             * @param activity the activity that is about to become ready.
735:             * @param resource the resource to be assigned.
736:             * @throws RemoteException if a system-level error occurs.
737:             * @throws NoSuchResourceException if the resource is invalid.
738:             * @see ActivityFinder
739:             * @throws AlreadyAssignedException if the assignment already
740:             * exists
741:             */
742:            protected void addAssignment(long finderId, String actId,
743:                    WfResource resource) throws RemoteException,
744:                    AlreadyAssignedException {
745:                try {
746:                    Connection con = null;
747:                    PreparedStatement prepStmt = null;
748:                    ResultSet rs = null;
749:                    try {
750:                        con = ds.getConnection();
751:                        prepStmt = con
752:                                .prepareStatement("SELECT DBId FROM Assignments WHERE "
753:                                        + "actfinder=? AND activity=? AND assignedresource=?");
754:                        prepStmt.setLong(1, finderId);
755:                        prepStmt.setString(2, actId);
756:                        prepStmt.setString(3, resource.resourceKey());
757:                        rs = prepStmt.executeQuery();
758:                        if (rs.next()) {
759:                            throw new AlreadyAssignedException();
760:                        }
761:                        rs.close();
762:                        rs = null;
763:                        prepStmt.close();
764:                        prepStmt = con
765:                                .prepareStatement("INSERT INTO Assignments "
766:                                        + "(DBId, actfinder, activity, assignedresource) "
767:                                        + "VALUES (?, ?, ?, ?)");
768:                        long id = EJBUtil.newPrimaryKey("Assignments");
769:                        prepStmt.setLong(1, id);
770:                        prepStmt.setLong(2, finderId);
771:                        prepStmt.setString(3, actId);
772:                        prepStmt.setString(4, resource.resourceKey());
773:                        prepStmt.executeUpdate();
774:                    } catch (ResourceNotAvailableException e) {
775:                        throw new SQLException("Cannot get primary key"
776:                                + e.getMessage());
777:                    } finally {
778:                        JDBCUtil.closeAll(rs, prepStmt, con);
779:                    }
780:                } catch (SQLException se) {
781:                    throw new EJBException(se);
782:                }
783:
784:            }
785:
786:            /**
787:             * Returns at least the collection of all the workflow resources whom has 
788:             * been assigned work items, but optionally it can return the additional
789:             * workflow resources who are known to the resource assignment service.
790:             *
791:             * @return the collection of the known resources to the ras (instances of
792:             * {@link de.danet.an.workflow.omgcore.WfResource
793:             * <code>WfResource</code>}).
794:             * @throws RemoteException if a system-level error occurs.
795:             * @see de.danet.an.workflow.assignment
796:             */
797:            public Collection knownResources() throws RemoteException {
798:                try {
799:                    return rms.listResources();
800:                } catch (RemoteException e) {
801:                    throw e;
802:                } catch (Exception e) {
803:                    logger.error(rms + " has thrown an unexpected exception, "
804:                            + "no resources are listed: " + e.getMessage(), e);
805:                    return new ArrayList();
806:                }
807:            }
808:
809:            /* Comment copied from interface. */
810:            public Collection authorizers(WfResource resource)
811:                    throws RemoteException {
812:                try {
813:                    return rms.authorizers(resource);
814:                } catch (RemoteException e) {
815:                    throw e;
816:                } catch (Exception e) {
817:                    logger.error(rms + " has thrown an unexpected exception, "
818:                            + "no authorizers returned: " + e.getMessage(), e);
819:                    return new ArrayList();
820:                }
821:            }
822:
823:            /**
824:             * Given a {@link java.security.Principal principal}, return the
825:             * workflow resource associated with this principal. This implementation
826:             * simply delegates the request to the resource management service.
827:             *
828:             * @param principal the principal.
829:             * @return a <code>WfResource</code> object corresponding to the
830:             * given principal.
831:             * @throws NoSuchResourceException if the StaffMember with the given key
832:             * can't be found or the key is not associate with an StaffMember object.
833:             * @throws RemoteException if a system-level error occurs.
834:             */
835:            public WfResource asResource(Principal principal)
836:                    throws RemoteException, InvalidKeyException {
837:                try {
838:                    return rms.asResource(principal);
839:                } catch (ResourceNotFoundException rnf) {
840:                    throw new InvalidKeyException(rnf.getMessage());
841:                }
842:            }
843:
844:            /**
845:             * Given the <code>key</code> of a <code>WfResource</code>
846:             * (obtained with {@link WfResource#resourceKey
847:             * <code>resourceKey()</code>}), return the workflow resource
848:             * associated with this key.<P>
849:             *
850:             * This method is implemented by simply calling
851:             * {@link ResourceManagementService#resourceByKey
852:             * <code>resourceByKey</code>} of the underlying resource
853:             * management service.
854:             *
855:             * @param key the key.
856:             * @return a <code>WfResource</code> object corresponding to the
857:             * given key.
858:             * @throws NoSuchResourceException if the resource with the given
859:             * key can't be found. As the environment is a concurrent multi
860:             * user environment, <code>WfResource</code> objects (and keys obtained
861:             * from <code>WfResource</code> objects) may become invalid.
862:             * @throws RemoteException if a system-level error occurs.
863:             */
864:            public WfResource resourceByKey(String key)
865:                    throws InvalidKeyException, RemoteException {
866:                try {
867:                    return rms.resourceByKey(key);
868:                } catch (ResourceNotFoundException rnf) {
869:                    throw new InvalidKeyException(rnf.getMessage());
870:                }
871:            }
872:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.