001: /*
002: * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.jndi.ldap;
027:
028: import java.io.*;
029: import java.util.Vector;
030: import java.util.EventObject;
031:
032: import javax.naming.event.NamingEvent;
033: import javax.naming.event.NamingExceptionEvent;
034: import javax.naming.event.NamingListener;
035: import javax.naming.ldap.UnsolicitedNotificationEvent;
036: import javax.naming.ldap.UnsolicitedNotificationListener;
037:
038: /**
039: * Package private class used by EventSupport to dispatch events.
040: * This class implements an event queue, and a dispatcher thread that
041: * dequeues and dispatches events from the queue.
042: *
043: * Pieces stolen from sun.misc.Queue.
044: *
045: * @author Bill Shannon (from javax.mail.event)
046: * @author Rosanna Lee (modified for JNDI-related events)
047: */
048: final class EventQueue implements Runnable {
049: final static private boolean debug = false;
050:
051: private static class QueueElement {
052: QueueElement next = null;
053: QueueElement prev = null;
054: EventObject event = null;
055: Vector vector = null;
056:
057: QueueElement(EventObject event, Vector vector) {
058: this .event = event;
059: this .vector = vector;
060: }
061: }
062:
063: private QueueElement head = null;
064: private QueueElement tail = null;
065: private Thread qThread;
066:
067: // package private
068: EventQueue() {
069: qThread = Obj.helper.createThread(this );
070: qThread.setDaemon(true); // not a user thread
071: qThread.start();
072: }
073:
074: // package private;
075: /**
076: * Enqueue an event.
077: * @param event Either a <tt>NamingExceptionEvent</tt> or a subclass
078: * of <tt>NamingEvent</tt> or
079: * <tt>UnsolicitedNotificatoniEvent</tt>.
080: * If it is a subclass of <tt>NamingEvent</tt>, all listeners must implement
081: * the corresponding subinterface of <tt>NamingListener</tt>.
082: * For example, for a <tt>ObjectAddedEvent</tt>, all listeners <em>must</em>
083: * implement the <tt>ObjectAddedListener</tt> interface.
084: * <em>The current implementation does not check this before dispatching
085: * the event.</em>
086: * If the event is a <tt>NamingExceptionEvent</tt>, then all listeners
087: * are notified.
088: * @param vector List of NamingListeners that will be notified of event.
089: */
090: synchronized void enqueue(EventObject event, Vector vector) {
091: QueueElement newElt = new QueueElement(event, vector);
092:
093: if (head == null) {
094: head = newElt;
095: tail = newElt;
096: } else {
097: newElt.next = head;
098: head.prev = newElt;
099: head = newElt;
100: }
101: notify();
102: }
103:
104: /**
105: * Dequeue the oldest object on the queue.
106: * Used only by the run() method.
107: *
108: * @return the oldest object on the queue.
109: * @exception java.lang.InterruptedException if any thread has
110: * interrupted this thread.
111: */
112: private synchronized QueueElement dequeue()
113: throws InterruptedException {
114: while (tail == null)
115: wait();
116: QueueElement elt = tail;
117: tail = elt.prev;
118: if (tail == null) {
119: head = null;
120: } else {
121: tail.next = null;
122: }
123: elt.prev = elt.next = null;
124: return elt;
125: }
126:
127: /**
128: * Pull events off the queue and dispatch them.
129: */
130: public void run() {
131: QueueElement qe;
132:
133: try {
134: while ((qe = dequeue()) != null) {
135: EventObject e = qe.event;
136: Vector v = qe.vector;
137:
138: for (int i = 0; i < v.size(); i++) {
139:
140: // Dispatch to corresponding NamingListener
141: // The listener should only be getting the event that
142: // it is interested in. (No need to check mask or
143: // instanceof subinterfaces.)
144: // It is the responsibility of the enqueuer to
145: // only enqueue events with listseners of the correct type.
146:
147: if (e instanceof NamingEvent) {
148: ((NamingEvent) e).dispatch((NamingListener) v
149: .elementAt(i));
150:
151: // An exception occurred: if notify all naming listeners
152: } else if (e instanceof NamingExceptionEvent) {
153: ((NamingExceptionEvent) e)
154: .dispatch((NamingListener) v
155: .elementAt(i));
156: } else if (e instanceof UnsolicitedNotificationEvent) {
157: ((UnsolicitedNotificationEvent) e)
158: .dispatch((UnsolicitedNotificationListener) v
159: .elementAt(i));
160: }
161: }
162:
163: qe = null;
164: e = null;
165: v = null;
166: }
167: } catch (InterruptedException e) {
168: // just die
169: }
170: }
171:
172: // package private; used by EventSupport;
173: /**
174: * Stop the dispatcher so we can be destroyed.
175: */
176: void stop() {
177: if (debug)
178: System.err.println("EventQueue stopping");
179: if (qThread != null) {
180: qThread.interrupt(); // kill our thread
181: qThread = null;
182: }
183: }
184: }
|