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: EventWatch.java,v 1.2 2006/09/29 12:32:07 drmlipp Exp $
021: *
022: * $Log: EventWatch.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 2003/12/19 13:01:43 drmlipp
027: * Updated to 1.1rc1
028: *
029: * Revision 1.6 2003/10/27 10:02:42 lipp
030: * Reduced number of event listeners and thus drastically increased
031: * performance (and avoiding timeouts).
032: *
033: * Revision 1.5 2003/06/27 09:44:03 lipp
034: * Fixed copyright/license information.
035: *
036: * Revision 1.4 2003/04/26 16:12:22 lipp
037: * Moved some classes to reduce package dependencies.
038: *
039: * Revision 1.3 2003/04/16 19:58:49 lipp
040: * Adapted to jdk 1.4
041: *
042: * Revision 1.2 2003/03/03 10:17:47 lipp
043: * Adjusted some timings.
044: *
045: * Revision 1.1 2003/02/12 16:14:43 lipp
046: * Delays now based on events.
047: *
048: */
049: package process;
050:
051: import java.rmi.RemoteException;
052: import java.util.Date;
053:
054: import javax.naming.TimeLimitExceededException;
055:
056: import de.danet.an.workflow.api.FactoryConfigurationError;
057: import de.danet.an.workflow.api.WorkflowService;
058: import de.danet.an.workflow.api.WorkflowServiceFactory;
059: import de.danet.an.workflow.omgcore.InvalidPerformerException;
060: import de.danet.an.workflow.omgcore.WfAuditEvent;
061: import de.danet.an.workflow.omgcore.WfAuditHandler;
062: import de.danet.an.workflow.omgcore.WfObject;
063: import de.danet.an.workflow.omgcore.WfStateAuditEvent;
064:
065: /**
066: * This class provides ...
067: *
068: * @author <a href="mailto:lipp@danet.de"></a>
069: * @version $Revision: 1.2 $
070: */
071:
072: public class EventWatch {
073:
074: private static WorkflowService wfsCache = null;
075:
076: private WorkflowService workflowService() {
077: if (wfsCache == null) {
078: try {
079: WorkflowServiceFactory wfsf = WorkflowServiceFactory
080: .newInstance();
081: wfsCache = wfsf.newWorkflowService();
082: } catch (FactoryConfigurationError e) {
083: throw new IllegalStateException(e.getMessage());
084: }
085: }
086: return wfsCache;
087: }
088:
089: private static Object syncObj = new Object();
090: private static int count = 0;
091: private String id = null;
092:
093: private WfObject eventReceiver = null;
094: private boolean doLog = false;
095: private String filterProcKey = null;
096: private String filterActKey = null;
097: private Class filterEvtType = null;
098: private String filterNewState = null;
099: private boolean gotcha = true;
100:
101: private class EventFilter implements WfAuditHandler {
102: public EventFilter() {
103: }
104:
105: /**
106: * Describe <code>receiveEvent</code> method here.
107: *
108: * @param wfAuditEvent a <code>WfAuditEvent</code> value
109: * @exception InvalidPerformerException if an error occurs
110: * @exception RemoteException if an error occurs
111: */
112: public void receiveEvent(WfAuditEvent wfAuditEvent)
113: throws InvalidPerformerException, RemoteException {
114: if (doLog) {
115: System.err.println("EventWatch " + id + " got: "
116: + wfAuditEvent);
117: }
118: if (!gotcha
119: && (filterProcKey == null || filterProcKey
120: .equals(wfAuditEvent.processKey()))
121: && (filterActKey == null || filterActKey
122: .equals(wfAuditEvent.activityKey()))
123: && (filterEvtType == null || (filterEvtType
124: .getClass().isAssignableFrom(wfAuditEvent
125: .getClass())))
126: && (filterNewState == null || (((filterProcKey != null && wfAuditEvent
127: .eventType().equals(
128: WfAuditEvent.PROCESS_STATE_CHANGED)) || (filterActKey != null && wfAuditEvent
129: .eventType()
130: .equals(WfAuditEvent.ACTIVITY_STATE_CHANGED))) && (((WfStateAuditEvent) wfAuditEvent)
131: .newState().startsWith(filterNewState))))) {
132: if (doLog) {
133: System.err.println("EventWatch " + id
134: + " triggers.");
135: }
136: synchronized (eventReceiver) {
137: gotcha = true;
138: eventReceiver.notifyAll();
139: }
140: }
141: }
142: }
143:
144: /**
145: * Creates an instance of <code>EventWatch</code>
146: * with all attributes initialized to default values.
147: */
148: public EventWatch() throws Exception {
149: this (null);
150: }
151:
152: /**
153: * Creates an instance of <code>EventWatch</code>
154: * with all attributes initialized to default values.
155: */
156: public EventWatch(String key) throws Exception {
157: if (key != null) {
158: id = key;
159: } else {
160: synchronized (syncObj) {
161: id = "EW" + ++count;
162: }
163: }
164: }
165:
166: public void setup(String procKey, String actKey, Class evtType,
167: String newState) throws RemoteException {
168: setup(procKey, actKey, evtType, newState, false);
169: }
170:
171: public void setup(String procKey, String actKey, Class evtType,
172: String newState, boolean log) throws RemoteException {
173: filterProcKey = procKey;
174: filterActKey = actKey;
175: filterEvtType = evtType;
176: filterNewState = newState;
177: doLog = log;
178: gotcha = false;
179: if (eventReceiver == null) {
180: eventReceiver = workflowService().eventReceiver(
181: new EventFilter());
182: }
183: if (log) {
184: System.err.println(this + " looking for: processKey="
185: + filterProcKey + " && activityKey=" + filterActKey
186: + " && eventClass=" + filterEvtType
187: + " && newState=" + filterNewState);
188: }
189: }
190:
191: public void waitForEvent() throws TimeLimitExceededException {
192: long start = (new Date()).getTime();
193: synchronized (eventReceiver) {
194: while (!gotcha) {
195: long now = (new Date()).getTime();
196: long waitTime = 15000 - (now - start);
197: if (waitTime <= 0) {
198: if (doLog) {
199: System.err.println(this + " timed out after "
200: + (now - start) + "s.");
201: }
202: throw new TimeLimitExceededException(
203: "State not reached.");
204: }
205: try {
206: eventReceiver.wait(waitTime);
207: } catch (InterruptedException e) {
208: }
209: }
210: }
211: workflowService().release(eventReceiver);
212: eventReceiver = null;
213: }
214:
215: /**
216: * Retrieve a String representation of this object
217: *
218: * @return a <code>String</code> representation of this object.
219: * @see Object#toString()
220: */
221: public String toString() {
222: return "EventWatch[id=" + id + "]";
223: }
224:
225: }
|