// ResourceEventQueue.java
// $Id: ResourceEventQueue.java,v 1.5 2000/10/13 16:37:58 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.tools.resources.event;
import org.w3c.tools.resources.FramedResource;
import org.w3c.tools.resources.InvalidResourceException;
import org.w3c.tools.resources.Resource;
import org.w3c.tools.resources.ResourceReference;
public class ResourceEventQueue {
public final static boolean debug = false;
class QueueCell {
ResourceEvent event;
QueueCell next;
int id;
QueueCell (ResourceEvent revt) {
this.event = revt;
this.next = null;
this.id = revt.getID();
}
}
private QueueCell queue = null;
private QueueCell last = null;
/**
* Send a ResourceEvent in the queue.
* @param evt The Resource Event to put in the queue.
*/
public synchronized void sendEvent(ResourceEvent evt) {
if (debug)
System.out.println("[QUEUE] : sendEvent "+evt.getID());
// => lock()
QueueCell ncell = new QueueCell(evt);
if (queue == null) {
queue = ncell;
last = ncell;
notifyAll();
} else {
if ((ncell.id == Events.RESOURCE_MODIFIED) ||
(ncell.id == Events.FRAME_MODIFIED)) {
if (debug)
System.out.println("[QUEUE] : remove old modified event");
QueueCell cell = queue;
while (cell != null) {
if ((cell.id == ncell.id) &&
(cell.event.getSource() == ncell.event.getSource()))
{
if (debug)
System.out.println("[QUEUE] : Found one!");
cell.event = ncell.event;
break;
}
cell = cell.next;
}
if (cell == null) {
if (debug)
System.out.println("[QUEUE] : add new event.");
last.next = ncell;
last = ncell;
}
} else {
last.next = ncell;
last = ncell;
}
}
}
/**
* Get the next Event in the queue, wait if there is no event
* available in the queue.
* @return a ResourceEvent instance.
* @exception InterruptedException Is unable to get the next event due to
* some interruption.
*/
public synchronized ResourceEvent getNextEvent()
throws InterruptedException
{
while (queue == null)
wait();
QueueCell next = queue;
queue = queue.next;
if (queue == null)
last = null;
return next.event;
}
/**
* Remove all the Events comming from the given source object.
* @param source The Object where the events to remove are comming from.
*/
public synchronized void removeSourceEvents(Object source) {
QueueCell current = queue;
QueueCell prev = null;
while (current != null) {
if (current.event.getSource() == source) {
if (prev == null)
queue = current.next;
else {
prev.next = current.next;
if (prev.next == null)
last = prev;
}
}
prev = current;
current = current.next;
}
}
public ResourceEventQueue() {
queue = null;
new Dispatcher("ResourceEventQueue Dispatcher", this).start();
}
}
class Dispatcher extends Thread {
private ResourceEventQueue queue = null;
private boolean dispatch = true;
public void stopDispatching() {
dispatch = false;
}
public void run() {
while (dispatch) {
try {
ResourceEvent event = queue.getNextEvent();
if (queue.debug)
System.out.println("[QUEUE] : getNextEvent()");
Object src = event.getSource();
ResourceReference rr = null;
try {
FramedResource source = null;
if (src instanceof ResourceReference) {
rr = (ResourceReference)src;
Resource res = rr.lock();
if (res instanceof FramedResource)
source = (FramedResource) res;
else
source = null;
} else if (src instanceof FramedResource) {
source = (FramedResource) src;
}
if (source != null) {
if (queue.debug)
System.out.println("[QUEUE] : processEvent "+
event);
source.processEvent(event);
}
} catch (InvalidResourceException ex) {
if (queue.debug) {
System.err.println("Exception occurred "+
"in EventDispatcher:");
ex.printStackTrace();
}
} finally {
if (rr != null)
rr.unlock();
}
} catch (ThreadDeath death) {
return;
} catch (Throwable e) {
if (queue.debug) {
System.err.println("Exception occurred "+
"during event dispatching:");
e.printStackTrace();
}
}
}
}
Dispatcher (String name, ResourceEventQueue queue) {
super(name);
this.queue = queue;
}
}