8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jndi.ldap; 27 28 import java.io.*; 29 import java.util.Vector; 30 import java.util.EventObject; 31 32 import javax.naming.event.NamingEvent; 33 import javax.naming.event.NamingExceptionEvent; 34 import javax.naming.event.NamingListener; 35 import javax.naming.ldap.UnsolicitedNotificationEvent; 36 import javax.naming.ldap.UnsolicitedNotificationListener; 37 38 /** 39 * Package private class used by EventSupport to dispatch events. 40 * This class implements an event queue, and a dispatcher thread that 41 * dequeues and dispatches events from the queue. 42 * 43 * Pieces stolen from sun.misc.Queue. 44 * 45 * @author Bill Shannon (from javax.mail.event) 46 * @author Rosanna Lee (modified for JNDI-related events) 47 */ 48 final class EventQueue implements Runnable { 49 final static private boolean debug = false; 50 51 private static class QueueElement { 52 QueueElement next = null; 53 QueueElement prev = null; 54 EventObject event = null; 55 Vector vector = null; 56 57 QueueElement(EventObject event, Vector vector) { 58 this.event = event; 59 this.vector = vector; 60 } 61 } 62 63 private QueueElement head = null; 64 private QueueElement tail = null; 65 private Thread qThread; 66 67 // package private 68 EventQueue() { 69 qThread = Obj.helper.createThread(this); 70 qThread.setDaemon(true); // not a user thread 71 qThread.start(); 72 } 73 74 // package private; 75 /** 76 * Enqueue an event. 77 * @param event Either a <tt>NamingExceptionEvent</tt> or a subclass 78 * of <tt>NamingEvent</tt> or 79 * <tt>UnsolicitedNotificatoniEvent</tt>. 80 * If it is a subclass of <tt>NamingEvent</tt>, all listeners must implement 81 * the corresponding subinterface of <tt>NamingListener</tt>. 82 * For example, for a <tt>ObjectAddedEvent</tt>, all listeners <em>must</em> 83 * implement the <tt>ObjectAddedListener</tt> interface. 84 * <em>The current implementation does not check this before dispatching 85 * the event.</em> 86 * If the event is a <tt>NamingExceptionEvent</tt>, then all listeners 87 * are notified. 88 * @param vector List of NamingListeners that will be notified of event. 89 */ 90 synchronized void enqueue(EventObject event, Vector vector) { 91 QueueElement newElt = new QueueElement(event, vector); 92 93 if (head == null) { 94 head = newElt; 95 tail = newElt; 96 } else { 97 newElt.next = head; 98 head.prev = newElt; 99 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. 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.elementAt(i)); 149 150 // An exception occurred: if notify all naming listeners 151 } else if (e instanceof NamingExceptionEvent) { 152 ((NamingExceptionEvent)e).dispatch( 153 (NamingListener)v.elementAt(i)); 154 } else if (e instanceof UnsolicitedNotificationEvent) { 155 ((UnsolicitedNotificationEvent)e).dispatch( 156 (UnsolicitedNotificationListener)v.elementAt(i)); 157 } 158 } 159 160 qe = null; e = null; v = null; 161 } 162 } catch (InterruptedException e) { 163 // just die 164 } 165 } 166 167 // package private; used by EventSupport; 168 /** 169 * Stop the dispatcher so we can be destroyed. 170 */ 171 void stop() { 172 if (debug) System.err.println("EventQueue stopping"); 173 if (qThread != null) { | 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jndi.ldap; 27 28 import java.util.Vector; 29 import java.util.EventObject; 30 31 import javax.naming.event.NamingEvent; 32 import javax.naming.event.NamingExceptionEvent; 33 import javax.naming.event.NamingListener; 34 import javax.naming.ldap.UnsolicitedNotificationEvent; 35 import javax.naming.ldap.UnsolicitedNotificationListener; 36 37 /** 38 * Package private class used by EventSupport to dispatch events. 39 * This class implements an event queue, and a dispatcher thread that 40 * dequeues and dispatches events from the queue. 41 * 42 * Pieces stolen from sun.misc.Queue. 43 * 44 * @author Bill Shannon (from javax.mail.event) 45 * @author Rosanna Lee (modified for JNDI-related events) 46 */ 47 final class EventQueue implements Runnable { 48 final static private boolean debug = false; 49 50 private static class QueueElement { 51 QueueElement next = null; 52 QueueElement prev = null; 53 EventObject event = null; 54 Vector<NamingListener> vector = null; 55 56 QueueElement(EventObject event, Vector<NamingListener> vector) { 57 this.event = event; 58 this.vector = vector; 59 } 60 } 61 62 private QueueElement head = null; 63 private QueueElement tail = null; 64 private Thread qThread; 65 66 // package private 67 EventQueue() { 68 qThread = Obj.helper.createThread(this); 69 qThread.setDaemon(true); // not a user thread 70 qThread.start(); 71 } 72 73 // package private; 74 /** 75 * Enqueue an event. 76 * @param event Either a <tt>NamingExceptionEvent</tt> or a subclass 77 * of <tt>NamingEvent</tt> or 78 * <tt>UnsolicitedNotificatoniEvent</tt>. 79 * If it is a subclass of <tt>NamingEvent</tt>, all listeners must implement 80 * the corresponding subinterface of <tt>NamingListener</tt>. 81 * For example, for a <tt>ObjectAddedEvent</tt>, all listeners <em>must</em> 82 * implement the <tt>ObjectAddedListener</tt> interface. 83 * <em>The current implementation does not check this before dispatching 84 * the event.</em> 85 * If the event is a <tt>NamingExceptionEvent</tt>, then all listeners 86 * are notified. 87 * @param vector List of NamingListeners that will be notified of event. 88 */ 89 synchronized void enqueue(EventObject event, Vector<NamingListener> vector) { 90 QueueElement newElt = new QueueElement(event, vector); 91 92 if (head == null) { 93 head = newElt; 94 tail = newElt; 95 } else { 96 newElt.next = head; 97 head.prev = newElt; 98 head = newElt; 99 } 100 notify(); 101 } 102 103 /** 104 * Dequeue the oldest object on the queue. 105 * Used only by the run() method. 106 * 107 * @return the oldest object on the queue. 108 * @exception java.lang.InterruptedException if any thread has 109 * interrupted this thread. 115 QueueElement elt = tail; 116 tail = elt.prev; 117 if (tail == null) { 118 head = null; 119 } else { 120 tail.next = null; 121 } 122 elt.prev = elt.next = null; 123 return elt; 124 } 125 126 /** 127 * Pull events off the queue and dispatch them. 128 */ 129 public void run() { 130 QueueElement qe; 131 132 try { 133 while ((qe = dequeue()) != null) { 134 EventObject e = qe.event; 135 Vector<NamingListener> v = qe.vector; 136 137 for (int i = 0; i < v.size(); i++) { 138 139 // Dispatch to corresponding NamingListener 140 // The listener should only be getting the event that 141 // it is interested in. (No need to check mask or 142 // instanceof subinterfaces.) 143 // It is the responsibility of the enqueuer to 144 // only enqueue events with listseners of the correct type. 145 146 if (e instanceof NamingEvent) { 147 ((NamingEvent)e).dispatch(v.elementAt(i)); 148 149 // An exception occurred: if notify all naming listeners 150 } else if (e instanceof NamingExceptionEvent) { 151 ((NamingExceptionEvent)e).dispatch(v.elementAt(i)); 152 } else if (e instanceof UnsolicitedNotificationEvent) { 153 ((UnsolicitedNotificationEvent)e).dispatch( 154 (UnsolicitedNotificationListener)v.elementAt(i)); 155 } 156 } 157 158 qe = null; e = null; v = null; 159 } 160 } catch (InterruptedException e) { 161 // just die 162 } 163 } 164 165 // package private; used by EventSupport; 166 /** 167 * Stop the dispatcher so we can be destroyed. 168 */ 169 void stop() { 170 if (debug) System.err.println("EventQueue stopping"); 171 if (qThread != null) { |