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