/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: DefaultRequester.java 1607 2006-09-29 12:32:13Z drmlipp $
*
* $Log$
* Revision 1.1.1.2 2004/08/18 15:17:36 drmlipp
* Update to 1.2
*
* Revision 1.7 2004/02/21 11:54:23 lipp
* Provided backward compatibility to 1.1.
*
* Revision 1.6 2004/01/22 15:06:09 lipp
* Clarified serializability of workflow service.
*
* Revision 1.5 2003/06/27 08:51:46 lipp
* Fixed copyright/license information.
*
* Revision 1.4 2003/04/26 16:11:15 lipp
* Moved some classes to reduce package dependencies.
*
* Revision 1.3 2003/04/25 14:50:59 lipp
* Fixed javadoc errors and warnings.
*
* Revision 1.2 2003/04/17 13:29:47 lipp
* Made workflow service transient.
*
* Revision 1.1 2003/02/25 17:08:05 lipp
* Reorganized requester implementation.
*
* Revision 1.3 2003/02/07 15:56:19 lipp
* Implemented Requester notifications.
*
* Revision 1.2 2003/02/06 12:47:14 lipp
* Implemented Requester (no event handling yet).
*
* Revision 1.1 2003/02/05 15:57:06 lipp
* Replaced DummyRequester with DefaultRequester.
*
*/
package de.danet.an.workflow.api;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.rmi.RemoteException;
import de.danet.an.workflow.omgcore.InvalidPerformerException;
import de.danet.an.workflow.omgcore.WfAuditEvent;
import de.danet.an.workflow.omgcore.WfAuditHandler;
import de.danet.an.workflow.omgcore.WfProcess;
import de.danet.an.workflow.omgcore.WfRequester;
/**
* This class provides an implementation of a {@link
* de.danet.an.workflow.omgcore.WfRequester <code>WfRequester</code>}.
* It class may be used directly if the events that are usually
* delivered to a requester are of no interest.<P>
*
* If events are to be processed, <code>DefaultRequester</code> must
* be subclassed with {@link #receiveEvent <code>receiveEvent</code>}
* overridden with the event handling code.<P>
*
* As an alternative to subclassing, a handler may be passed to the
* {@link #DefaultRequester(WorkflowService,WfAuditHandler)
* constructor}. Events will then be forwarded to the handler. This is
* convenient in situation where the implementation of {@link
* WfAuditHandler <code>WfAuditHandler</code>} already exists and a
* subclass would only do the forwarding. Note that the reference to the
* handler is <code>transient</code>.
*
* @author <a href="mailto:lipp@danet.de"></a>
* @version $Revision: 1607 $
*/
public class DefaultRequester implements WfRequester, Serializable {
/** Serial version UID. */
static final long serialVersionUID = -8223771945188082329L;
/**
* Provide backward compatibility with instances serialized
* with WfMOpen up to 1.1.
*/
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = stream.readFields();
id = (String)fields.get("id", null);
// New field in WfMOpen > 1.1
wfServiceProps = (Map)fields.get("wfServiceProps", null);
}
private transient WorkflowService wfServiceCache = null;
private Map wfServiceProps = null;
private String id;
private transient WfAuditHandler handler = null;
/**
* Creates a <code>DefaultRequester</code> for use with the given
* workflow service. The created requester will not receive events
* until registered with a {@link WorkflowService
* <code>WorkflowService</code>}.
* @param wfs the workflow service.
* @throws RemoteException if thrown during {@link
* WorkflowService#registerRequester requester registration}.
*/
public DefaultRequester (WorkflowService wfs)
throws RemoteException {
this (wfs, false);
}
/**
* Creates a <code>DefaultRequester</code> for use with the given
* workflow service. The created requester will forward received events
* to the given handler.
* @param wfs the workflow service.
* @param hdlr the event handler.
* @throws RemoteException if thrown during {@link
* WorkflowService#registerRequester requester registration}.
*/
public DefaultRequester (WorkflowService wfs, WfAuditHandler hdlr)
throws RemoteException {
this (wfs, true);
handler = hdlr;
}
/**
* Creates a <code>DefaultRequester</code> for use with the given
* workflow service. The created requester is automatically
* registered at the given {@link WorkflowService
* <code>WorkflowService</code>}.
* @param wfs the workflow service.
* @param register if <code>true</code> the requester will be
* registered at the workflow service.
* @throws RemoteException if thrown during {@link
* WorkflowService#registerRequester requester registration}.
*/
protected DefaultRequester (WorkflowService wfs, boolean register)
throws RemoteException {
if (wfs == null) {
throw new IllegalArgumentException
("WorkflowService may not be null.");
}
wfServiceCache = wfs;
wfServiceProps = wfs.serviceProperties ();
String host = "(unknown)";
try {
host = java.net.InetAddress.getLocalHost().toString();
} catch (java.net.UnknownHostException ex) {
// ignore
}
id = (new java.rmi.server.UID()).toString() + "@" + host;
if (register) {
wfService().registerRequester (this);
}
}
private WorkflowService wfService() {
if (wfServiceCache == null) {
try {
WorkflowServiceFactory wfsf
= WorkflowServiceFactory.newInstance ();
// for backward compatibility of instances serialized
// with WfMOpen up to 1.1
if (wfServiceProps != null) {
wfsf.setProperties (wfServiceProps);
}
wfServiceCache = wfsf.newWorkflowService();
} catch (FactoryConfigurationError e) {
throw new IllegalStateException (e.getMessage());
}
}
return wfServiceCache;
}
/* Comment copied from interface. */
public Collection performers() throws RemoteException {
return wfService().requestedBy (this);
}
/* Comment copied from interface. */
public boolean isMemberOfPerformers(WfProcess wfProcess)
throws RemoteException {
for (Iterator ps = performers().iterator(); ps.hasNext();) {
WfProcess p = (WfProcess)ps.next();
if (p.key().equals (wfProcess.key())) {
return true;
}
}
return false;
}
/* Comment copied from interface. */
public void receiveEvent(WfAuditEvent wfAuditEvent)
throws InvalidPerformerException, RemoteException {
if (handler != null) {
String procKey = wfAuditEvent.processKey();
handler.receiveEvent (wfAuditEvent);
}
}
/**
* Indicates whether some other object is "equal to" this one.
* @param obj the other object.
* @return <code>true</code> if the objects are equal.
*/
public boolean equals (Object obj) {
if (! (obj instanceof DefaultRequester)) {
return false;
}
return id.equals (((DefaultRequester)obj).id);
}
/**
* Returns a hash code value for the object.
* @return the hash code
*/
public int hashCode () {
return id.hashCode();
}
/**
* Return a string representation for debugging purposes.
* @return the string representation.
*/
public String toString () {
return "DefaultRequester[id=" + id + "]";
}
}