/*
* 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: EventWatch.java 1607 2006-09-29 12:32:13Z drmlipp $
*
* $Log$
* Revision 1.1.1.2 2003/12/19 13:01:43 drmlipp
* Updated to 1.1rc1
*
* Revision 1.6 2003/10/27 10:02:42 lipp
* Reduced number of event listeners and thus drastically increased
* performance (and avoiding timeouts).
*
* Revision 1.5 2003/06/27 09:44:03 lipp
* Fixed copyright/license information.
*
* Revision 1.4 2003/04/26 16:12:22 lipp
* Moved some classes to reduce package dependencies.
*
* Revision 1.3 2003/04/16 19:58:49 lipp
* Adapted to jdk 1.4
*
* Revision 1.2 2003/03/03 10:17:47 lipp
* Adjusted some timings.
*
* Revision 1.1 2003/02/12 16:14:43 lipp
* Delays now based on events.
*
*/
package process;
import java.rmi.RemoteException;
import java.util.Date;
import javax.naming.TimeLimitExceededException;
import de.danet.an.workflow.api.FactoryConfigurationError;
import de.danet.an.workflow.api.WorkflowService;
import de.danet.an.workflow.api.WorkflowServiceFactory;
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.WfObject;
import de.danet.an.workflow.omgcore.WfStateAuditEvent;
/**
* This class provides ...
*
* @author <a href="mailto:lipp@danet.de"></a>
* @version $Revision: 1607 $
*/
public class EventWatch {
private static WorkflowService wfsCache = null;
private WorkflowService workflowService() {
if (wfsCache == null) {
try {
WorkflowServiceFactory wfsf
= WorkflowServiceFactory.newInstance ();
wfsCache = wfsf.newWorkflowService();
} catch (FactoryConfigurationError e) {
throw new IllegalStateException (e.getMessage());
}
}
return wfsCache;
}
private static Object syncObj = new Object ();
private static int count = 0;
private String id = null;
private WfObject eventReceiver = null;
private boolean doLog = false;
private String filterProcKey = null;
private String filterActKey = null;
private Class filterEvtType = null;
private String filterNewState = null;
private boolean gotcha = true;
private class EventFilter implements WfAuditHandler {
public EventFilter() {
}
/**
* Describe <code>receiveEvent</code> method here.
*
* @param wfAuditEvent a <code>WfAuditEvent</code> value
* @exception InvalidPerformerException if an error occurs
* @exception RemoteException if an error occurs
*/
public void receiveEvent(WfAuditEvent wfAuditEvent)
throws InvalidPerformerException, RemoteException {
if (doLog) {
System.err.println
("EventWatch " + id + " got: " + wfAuditEvent);
}
if (!gotcha
&& (filterProcKey == null
|| filterProcKey.equals (wfAuditEvent.processKey()))
&& (filterActKey == null
|| filterActKey.equals (wfAuditEvent.activityKey()))
&& (filterEvtType == null
|| (filterEvtType.getClass()
.isAssignableFrom (wfAuditEvent.getClass())))
&& (filterNewState == null
|| (((filterProcKey != null && wfAuditEvent.eventType()
.equals (WfAuditEvent.PROCESS_STATE_CHANGED))
|| (filterActKey != null && wfAuditEvent.eventType()
.equals (WfAuditEvent.ACTIVITY_STATE_CHANGED)))
&& (((WfStateAuditEvent)wfAuditEvent).newState()
.startsWith (filterNewState))))) {
if (doLog) {
System.err.println ("EventWatch " + id + " triggers.");
}
synchronized (eventReceiver) {
gotcha = true;
eventReceiver.notifyAll ();
}
}
}
}
/**
* Creates an instance of <code>EventWatch</code>
* with all attributes initialized to default values.
*/
public EventWatch () throws Exception {
this (null);
}
/**
* Creates an instance of <code>EventWatch</code>
* with all attributes initialized to default values.
*/
public EventWatch (String key) throws Exception {
if (key != null) {
id = key;
} else {
synchronized (syncObj) {
id = "EW" + ++count;
}
}
}
public void setup (String procKey, String actKey,
Class evtType, String newState)
throws RemoteException {
setup (procKey, actKey, evtType, newState, false);
}
public void setup (String procKey, String actKey,
Class evtType, String newState, boolean log)
throws RemoteException {
filterProcKey = procKey;
filterActKey = actKey;
filterEvtType = evtType;
filterNewState = newState;
doLog = log;
gotcha = false;
if (eventReceiver == null) {
eventReceiver = workflowService()
.eventReceiver (new EventFilter ());
}
if (log) {
System.err.println
(this + " looking for: processKey="
+ filterProcKey + " && activityKey=" + filterActKey
+ " && eventClass=" + filterEvtType + " && newState="
+ filterNewState);
}
}
public void waitForEvent () throws TimeLimitExceededException {
long start = (new Date()).getTime();
synchronized (eventReceiver) {
while (! gotcha) {
long now = (new Date()).getTime();
long waitTime = 15000 - (now - start);
if (waitTime <= 0) {
if (doLog) {
System.err.println
(this + " timed out after " + (now - start) + "s.");
}
throw new TimeLimitExceededException ("State not reached.");
}
try {
eventReceiver.wait (waitTime);
} catch (InterruptedException e) {
}
}
}
workflowService().release (eventReceiver);
eventReceiver = null;
}
/**
* Retrieve a String representation of this object
*
* @return a <code>String</code> representation of this object.
* @see Object#toString()
*/
public String toString() {
return "EventWatch[id=" + id + "]";
}
}