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: ResourceManagementServiceFactory.java,v 1.5 2006/10/15 19:29:51 mlipp Exp $
021: *
022: * $Log: ResourceManagementServiceFactory.java,v $
023: * Revision 1.5 2006/10/15 19:29:51 mlipp
024: * Merged changes from 1.4.x up to 1.4ea3pre1.
025: *
026: * Revision 1.4.2.1 2006/10/14 21:34:05 mlipp
027: * Simplified resource assignment service implementation.
028: *
029: * Revision 1.4 2006/09/29 12:32:12 drmlipp
030: * Consistently using WfMOpen as projct name now.
031: *
032: * Revision 1.3 2006/03/08 14:46:43 drmlipp
033: * Synchronized with 1.3.3p5.
034: *
035: * Revision 1.2 2005/06/29 08:15:22 drmlipp
036: * Improved error reporting.
037: *
038: * Revision 1.1.1.1 2003/06/30 20:05:17 drmlipp
039: * Initial import
040: *
041: * Revision 1.3 2003/06/27 08:51:44 lipp
042: * Fixed copyright/license information.
043: *
044: * Revision 1.2 2003/04/25 14:50:58 lipp
045: * Fixed javadoc errors and warnings.
046: *
047: * Revision 1.1 2002/12/19 21:37:42 lipp
048: * Reorganized interfaces.
049: *
050: * Revision 1.23 2002/10/15 13:22:32 huaiyang
051: * Remove system.out.println and printStackTrace.
052: *
053: * Revision 1.22 2002/09/15 12:06:44 lipp
054: * Renamed ServiceLookup to ServiceMgmt.
055: *
056: * Revision 1.21 2002/08/26 14:17:07 lipp
057: * JavaDoc fixes.
058: *
059: * Revision 1.20 2002/08/17 11:24:36 lipp
060: * Fixed class loading.
061: *
062: * Revision 1.19 2002/06/27 10:56:47 lipp
063: * Now using resource assignment service instead of factory for
064: * initialization.
065: *
066: * Revision 1.18 2002/01/09 14:00:01 lipp
067: * Cleaned up relation between wfcore, resource assignment and resource
068: * management service.
069: *
070: * Revision 1.17 2002/01/09 11:53:01 lipp
071: * Clarified documentation.
072: *
073: * Revision 1.16 2001/12/18 13:22:28 robert
074: * JavaDoc
075: *
076: * Revision 1.15 2001/12/17 12:14:04 lipp
077: * Adapted to configurable ResourceManagement/AssignmentServices.
078: *
079: * Revision 1.14 2001/12/17 10:51:06 lipp
080: * Improved comment.
081: *
082: * Revision 1.13 2001/12/17 10:15:15 robert
083: * User preferences service implemented.
084: *
085: * Revision 1.12 2001/12/17 09:15:50 lipp
086: * Javadoc fixes.
087: *
088: * Revision 1.11 2001/12/17 08:44:19 lipp
089: * Added configurable resource assignment service.
090: *
091: * Revision 1.10 2001/12/13 16:19:59 robert
092: * Temporary test method for resource management service.
093: *
094: * Revision 1.9 2001/12/13 12:17:34 robert
095: * corrected the JNDI lookup
096: *
097: * Revision 1.8 2001/12/12 16:18:01 robert
098: * Added JNDI lookup.
099: *
100: * Revision 1.7 2001/12/09 14:03:08 lipp
101: * Improved design of workflow/resource management interface.
102: *
103: * Revision 1.6 2001/12/06 14:08:36 robert
104: * error handling
105: *
106: * Revision 1.5 2001/12/06 12:39:12 lipp
107: * Instatiation fixed.
108: *
109: * Revision 1.4 2001/12/06 12:09:16 robert
110: * temporary status
111: *
112: * Revision 1.3 2001/12/05 13:50:54 robert
113: * first working version
114: *
115: * Revision 1.2 2001/11/30 11:43:26 lipp
116: * javadoc fixes.
117: *
118: * Revision 1.1 2001/11/27 18:26:42 lipp
119: * Resource handling redesigned.
120: *
121: */
122: package de.danet.an.workflow.spis.rms;
123:
124: import java.io.Serializable;
125:
126: import java.util.List;
127:
128: import javax.naming.NamingException;
129:
130: import de.danet.an.util.EJBUtil;
131: import de.danet.an.util.ServiceMgmt;
132:
133: import de.danet.an.workflow.spis.ras.ResourceAssignmentService;
134:
135: /**
136: * Defines a factory API that enables a workflow component to obtain a workflow
137: * resource management service.
138: */
139: public abstract class ResourceManagementServiceFactory implements
140: Serializable {
141:
142: /** The configured resource assignment service. */
143: private ResourceAssignmentService ras = null;
144:
145: /** The configured resource assignment context. */
146: private ResourceAssignmentContext resourceAssignmentContext = null;
147:
148: /**
149: * Constructor. Must be overridden with a parameterless public constructor
150: * by derived class.
151: */
152: protected ResourceManagementServiceFactory() {
153: }
154:
155: /**
156: * Obtain a new instance of a <code>ResourceManagementServiceFactory</code>.
157: * This static method creates a new factory instance . The method uses the
158: * following ordered lookup procedure to determine the
159: * <code>ResourceManagementServiceFactory</code> implementation class to
160: * load:
161: * <ul>
162: * <li>If an {@link javax.naming.InitialContext initial naming context} is
163: * available, look for a a classname in
164: * <code>java:comp/env/de.danet.an.workflow.spis.rms.ResourceManagementServiceFactory</code>.
165: * The configuration for a class as resource management service thus looks
166: * like:
167: *
168: * <PRE>
169: *
170: * <env-entry> <description>Configure the resource management
171: * factory</description>
172: * <env-entry-name>de.danet.an.workflow.spis.ras.ResourceManagementServiceFactory</env-entry-name>
173: * <env-entry-type>java.lang.String</env-entry-type>
174: * <env-entry-value><i>FactoryImplementationClass</i></env-entry-value>
175: * </env-entry> <env-entry>
176: *
177: * </PRE>
178: *
179: * Note that this environment entry must be inserted in the
180: * <code>ejb-jar.xml</code> or <code>web.xml</code> for every EJB resp.
181: * servlet that calls the
182: * {@link de.danet.an.workflow.spis.rms.ResourceManagementServiceFactory#newInstance
183: * <code>newInstance</code>} method of
184: * <code>ResourceManagementServiceFactory</code>.</li>
185: *
186: * <li>Use the services API (as detailed in the JAR specification), if
187: * available, to determine the classname. The Services API will look for a
188: * classname in the file
189: * <code>META-INF/services/de.danet.an.workflow.spis.rms.ResourceManagementServiceFactory</code>.
190: * in jars available to the runtime.</li>
191: * </ul>
192: *
193: * @return an instance of the <code>ResourceManagementServiceFactory</code>.
194: * @throws FactoryConfigurationError
195: * if a factory instance can't be created.
196: */
197: public static ResourceManagementServiceFactory newInstance()
198: throws FactoryConfigurationError {
199: if (factoryClass == null) {
200: factoryClass = findFactoryClass();
201: }
202: try {
203: return ((ResourceManagementServiceFactory) factoryClass
204: .newInstance());
205: } catch (InstantiationException e) {
206: throw new FactoryConfigurationError(e);
207: } catch (IllegalAccessException e) {
208: throw new FactoryConfigurationError(e);
209: }
210: }
211:
212: private static Class factoryClass = null;
213:
214: private static Class findFactoryClass()
215: throws FactoryConfigurationError {
216: // Lookup in JNDI
217: try {
218: String clsname = (String) EJBUtil
219: .lookupJNDIEntry("java:comp/env/de.danet.an.workflow.spis.rms"
220: + ".ResourceManagementServiceFactory");
221: ClassLoader cl = Thread.currentThread()
222: .getContextClassLoader();
223: return cl.loadClass(clsname);
224: } catch (NamingException ne) {
225: // Name not defined
226: } catch (ClassNotFoundException e) {
227: throw new FactoryConfigurationError(e);
228: } catch (ClassCastException e) {
229: throw new FactoryConfigurationError(e);
230: }
231: // Lookup as service in JARs
232: List cls = ServiceMgmt
233: .providerClassesFromJARs(ResourceManagementServiceFactory.class);
234: if (cls.size() > 0) {
235: return (Class) cls.get(0);
236: }
237: throw new FactoryConfigurationError(
238: "No RMS factory class configured");
239: }
240:
241: /**
242: * Specifies the resource assignment service to be used by the instances of
243: * {@link ResourceManagementService <code>ResourceManagementService</code>}
244: * subsequently created (by calling {@link #newResourceManagementService
245: * <code>newResourceManagementService()</code>}).
246: * <P>
247: *
248: * A resource management service needs a reference to a resource assignment
249: * service to be able to implement
250: * {@link de.danet.an.workflow.omgcore.WfResource <code>WfResource</code>}
251: * objects. The method <code>workItems</code> requires that a
252: * <code>WfAssignment</code> be returned, something that can only be done
253: * in cooperation with the resource assignment service.
254: * <P>
255: *
256: * An implementation problem may arise from the requirement to set a
257: * <code>ResourceAssignmentService</code> as implementations of
258: * <code>ResourceAssignmentService</code> that in turn rely on a
259: * <code>ResourceManagementService</code> may need a
260: * <code>ResourceManagementService</code> in order to be instantiated.
261: * Such implementations of <code>ResourceAssignmentService</code> have
262: * therefore to delay the actual request for a
263: * <code>ResourceManagementService</code> instance until they have made
264: * themselves known to the <code>ResourceManagementServiceFactory</code>.
265: *
266: * @deprecated the resource management service needs only a small subset of
267: * the methods provided by a
268: * <code>ResourceAssignmentService</code>. To allow greater
269: * flexibility when implementing a resource management service,
270: * the requirement for a complete resource assignment service
271: * has been replaced with the requirement for a
272: * <code>ResourceAssignmentContext</code>.
273: * @param service
274: * the resource management service.
275: * @see #getResourceAssignmentService
276: */
277: public void setResourceAssignmentService(
278: ResourceAssignmentService service) {
279: ras = service;
280: }
281:
282: /**
283: * Return the resource assignment service set with
284: * {@link #setResourceAssignmentService
285: * <code>setResourceAssignmentService</code>}.
286: *
287: * @deprecated see
288: * {@link #setResourceAssignmentService <code>setResourceAssignmentService</code>}
289: * @return the resource assignment service.
290: * @see #setResourceAssignmentService
291: */
292: public ResourceAssignmentService getResourceAssignmentService() {
293: return ras;
294: }
295:
296: /**
297: * Creates a new instance of a {@link ResourceManagementService
298: * <code>ResourceManagementService</code>}.
299: *
300: * @return the resource management service.
301: * @throws FactoryConfigurationError
302: * if a service instance can't be created.
303: */
304: public abstract ResourceManagementService newResourceManagementService()
305: throws FactoryConfigurationError;
306:
307: /**
308: * Specifies the resource assignment service to be used by the instances of
309: * {@link ResourceManagementService <code>ResourceManagementService</code>}
310: * subsequently created (by calling {@link #newResourceManagementService
311: * <code>newResourceManagementService()</code>}).
312: * <P>
313: * A resource management service needs a reference to a resource assignment
314: * context to be able to implement
315: * {@link de.danet.an.workflow.omgcore.WfResource <code>WfResource</code>}
316: * objects. E.g. the method <code>workItems</code> requires that a
317: * <code>WfAssignment</code> be returned, something that can only be done
318: * in cooperation with the resource assignment service.
319: *
320: * @param resourceAssignmentContext
321: * The resourceAssignmentContext to set.
322: */
323: public void setResourceAssignmentContext(
324: ResourceAssignmentContext resourceAssignmentContext) {
325: this .resourceAssignmentContext = resourceAssignmentContext;
326: }
327:
328: /**
329: * @return Returns the configured resource assignment context.
330: * @see #setResourceAssignmentContext(ResourceAssignmentContext)
331: */
332: public ResourceAssignmentContext getResourceAssignmentContext() {
333: return resourceAssignmentContext;
334: }
335:
336: }
|