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: DefaultRequester.java,v 1.2 2006/09/29 12:32:07 drmlipp Exp $
021: *
022: * $Log: DefaultRequester.java,v $
023: * Revision 1.2 2006/09/29 12:32:07 drmlipp
024: * Consistently using WfMOpen as projct name now.
025: *
026: * Revision 1.1.1.2 2004/08/18 15:17:36 drmlipp
027: * Update to 1.2
028: *
029: * Revision 1.7 2004/02/21 11:54:23 lipp
030: * Provided backward compatibility to 1.1.
031: *
032: * Revision 1.6 2004/01/22 15:06:09 lipp
033: * Clarified serializability of workflow service.
034: *
035: * Revision 1.5 2003/06/27 08:51:46 lipp
036: * Fixed copyright/license information.
037: *
038: * Revision 1.4 2003/04/26 16:11:15 lipp
039: * Moved some classes to reduce package dependencies.
040: *
041: * Revision 1.3 2003/04/25 14:50:59 lipp
042: * Fixed javadoc errors and warnings.
043: *
044: * Revision 1.2 2003/04/17 13:29:47 lipp
045: * Made workflow service transient.
046: *
047: * Revision 1.1 2003/02/25 17:08:05 lipp
048: * Reorganized requester implementation.
049: *
050: * Revision 1.3 2003/02/07 15:56:19 lipp
051: * Implemented Requester notifications.
052: *
053: * Revision 1.2 2003/02/06 12:47:14 lipp
054: * Implemented Requester (no event handling yet).
055: *
056: * Revision 1.1 2003/02/05 15:57:06 lipp
057: * Replaced DummyRequester with DefaultRequester.
058: *
059: */
060: package de.danet.an.workflow.api;
061:
062: import java.io.IOException;
063: import java.io.ObjectInputStream;
064: import java.io.Serializable;
065:
066: import java.util.Collection;
067: import java.util.Iterator;
068: import java.util.Map;
069:
070: import java.rmi.RemoteException;
071:
072: import de.danet.an.workflow.omgcore.InvalidPerformerException;
073: import de.danet.an.workflow.omgcore.WfAuditEvent;
074: import de.danet.an.workflow.omgcore.WfAuditHandler;
075: import de.danet.an.workflow.omgcore.WfProcess;
076: import de.danet.an.workflow.omgcore.WfRequester;
077:
078: /**
079: * This class provides an implementation of a {@link
080: * de.danet.an.workflow.omgcore.WfRequester <code>WfRequester</code>}.
081: * It class may be used directly if the events that are usually
082: * delivered to a requester are of no interest.<P>
083: *
084: * If events are to be processed, <code>DefaultRequester</code> must
085: * be subclassed with {@link #receiveEvent <code>receiveEvent</code>}
086: * overridden with the event handling code.<P>
087: *
088: * As an alternative to subclassing, a handler may be passed to the
089: * {@link #DefaultRequester(WorkflowService,WfAuditHandler)
090: * constructor}. Events will then be forwarded to the handler. This is
091: * convenient in situation where the implementation of {@link
092: * WfAuditHandler <code>WfAuditHandler</code>} already exists and a
093: * subclass would only do the forwarding. Note that the reference to the
094: * handler is <code>transient</code>.
095: *
096: * @author <a href="mailto:lipp@danet.de"></a>
097: * @version $Revision: 1.2 $
098: */
099:
100: public class DefaultRequester implements WfRequester, Serializable {
101:
102: /** Serial version UID. */
103: static final long serialVersionUID = -8223771945188082329L;
104:
105: /**
106: * Provide backward compatibility with instances serialized
107: * with WfMOpen up to 1.1.
108: */
109: private void readObject(ObjectInputStream stream)
110: throws IOException, ClassNotFoundException {
111: ObjectInputStream.GetField fields = stream.readFields();
112: id = (String) fields.get("id", null);
113: // New field in WfMOpen > 1.1
114: wfServiceProps = (Map) fields.get("wfServiceProps", null);
115: }
116:
117: private transient WorkflowService wfServiceCache = null;
118: private Map wfServiceProps = null;
119: private String id;
120: private transient WfAuditHandler handler = null;
121:
122: /**
123: * Creates a <code>DefaultRequester</code> for use with the given
124: * workflow service. The created requester will not receive events
125: * until registered with a {@link WorkflowService
126: * <code>WorkflowService</code>}.
127: * @param wfs the workflow service.
128: * @throws RemoteException if thrown during {@link
129: * WorkflowService#registerRequester requester registration}.
130: */
131: public DefaultRequester(WorkflowService wfs) throws RemoteException {
132: this (wfs, false);
133: }
134:
135: /**
136: * Creates a <code>DefaultRequester</code> for use with the given
137: * workflow service. The created requester will forward received events
138: * to the given handler.
139: * @param wfs the workflow service.
140: * @param hdlr the event handler.
141: * @throws RemoteException if thrown during {@link
142: * WorkflowService#registerRequester requester registration}.
143: */
144: public DefaultRequester(WorkflowService wfs, WfAuditHandler hdlr)
145: throws RemoteException {
146: this (wfs, true);
147: handler = hdlr;
148: }
149:
150: /**
151: * Creates a <code>DefaultRequester</code> for use with the given
152: * workflow service. The created requester is automatically
153: * registered at the given {@link WorkflowService
154: * <code>WorkflowService</code>}.
155: * @param wfs the workflow service.
156: * @param register if <code>true</code> the requester will be
157: * registered at the workflow service.
158: * @throws RemoteException if thrown during {@link
159: * WorkflowService#registerRequester requester registration}.
160: */
161: protected DefaultRequester(WorkflowService wfs, boolean register)
162: throws RemoteException {
163: if (wfs == null) {
164: throw new IllegalArgumentException(
165: "WorkflowService may not be null.");
166: }
167: wfServiceCache = wfs;
168: wfServiceProps = wfs.serviceProperties();
169: String host = "(unknown)";
170: try {
171: host = java.net.InetAddress.getLocalHost().toString();
172: } catch (java.net.UnknownHostException ex) {
173: // ignore
174: }
175: id = (new java.rmi.server.UID()).toString() + "@" + host;
176: if (register) {
177: wfService().registerRequester(this );
178: }
179: }
180:
181: private WorkflowService wfService() {
182: if (wfServiceCache == null) {
183: try {
184: WorkflowServiceFactory wfsf = WorkflowServiceFactory
185: .newInstance();
186: // for backward compatibility of instances serialized
187: // with WfMOpen up to 1.1
188: if (wfServiceProps != null) {
189: wfsf.setProperties(wfServiceProps);
190: }
191: wfServiceCache = wfsf.newWorkflowService();
192: } catch (FactoryConfigurationError e) {
193: throw new IllegalStateException(e.getMessage());
194: }
195: }
196: return wfServiceCache;
197: }
198:
199: /* Comment copied from interface. */
200: public Collection performers() throws RemoteException {
201: return wfService().requestedBy(this );
202: }
203:
204: /* Comment copied from interface. */
205: public boolean isMemberOfPerformers(WfProcess wfProcess)
206: throws RemoteException {
207: for (Iterator ps = performers().iterator(); ps.hasNext();) {
208: WfProcess p = (WfProcess) ps.next();
209: if (p.key().equals(wfProcess.key())) {
210: return true;
211: }
212: }
213: return false;
214: }
215:
216: /* Comment copied from interface. */
217: public void receiveEvent(WfAuditEvent wfAuditEvent)
218: throws InvalidPerformerException, RemoteException {
219: if (handler != null) {
220: String procKey = wfAuditEvent.processKey();
221: handler.receiveEvent(wfAuditEvent);
222: }
223: }
224:
225: /**
226: * Indicates whether some other object is "equal to" this one.
227: * @param obj the other object.
228: * @return <code>true</code> if the objects are equal.
229: */
230: public boolean equals(Object obj) {
231: if (!(obj instanceof DefaultRequester)) {
232: return false;
233: }
234: return id.equals(((DefaultRequester) obj).id);
235: }
236:
237: /**
238: * Returns a hash code value for the object.
239: * @return the hash code
240: */
241: public int hashCode() {
242: return id.hashCode();
243: }
244:
245: /**
246: * Return a string representation for debugging purposes.
247: * @return the string representation.
248: */
249: public String toString() {
250: return "DefaultRequester[id=" + id + "]";
251: }
252: }
|