Source Code Cross Referenced for EventSupport.java in  » 6.0-JDK-Modules-com.sun » jndi » com » sun » jndi » ldap » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules com.sun » jndi » com.sun.jndi.ldap 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 1999-2000 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.util.Hashtable;
029:        import java.util.Vector;
030:        import java.util.Enumeration;
031:        import java.util.EventObject;
032:
033:        import javax.naming.*;
034:        import javax.naming.directory.*;
035:        import javax.naming.event.*;
036:        import javax.naming.directory.SearchControls;
037:        import javax.naming.ldap.UnsolicitedNotificationListener;
038:        import javax.naming.ldap.UnsolicitedNotificationEvent;
039:        import javax.naming.ldap.UnsolicitedNotification;
040:
041:        /**
042:         * This is a utility class that can be used by a context that supports 
043:         * event notification.  You can use an instance of this class as a member field
044:         * of your context and delegate various work to it.
045:         * It is currently structured so that each context should have its own
046:         * EventSupport (instead of static version shared by all contexts
047:         * of a service provider).
048:         *<p>
049:         * This class supports two types of listeners: those that register for
050:         * NamingEvents, and those for UnsolicitedNotificationEvents (they can be mixed
051:         * into the same listener).
052:         * For NamingEvent listeners, it maintains a hashtable that maps 
053:         * registration requests--the key--to
054:         * <em>notifiers</em>--the value. Each registration request consists of:
055:         *<ul>
056:         *<li>The name argument of the registration.
057:         *<li>The filter (default is "(objectclass=*)").
058:         *<li>The search controls (default is null SearchControls).
059:         *<li>The events that the listener is interested in. This is determined by
060:         * finding out which <tt>NamingListener</tt> interface the listener supports.
061:         *</ul>
062:         *<p>
063:         *A notifier (<tt>NamingEventNotifier</tt>) is a worker thread that is responsible
064:         *for gathering information for generating events requested by its listeners.
065:         *Each notifier maintains its own list of listeners; these listeners have
066:         *all made the same registration request (at different times) and implements
067:         *the same <tt>NamingListener</tt> interfaces.
068:         *<p>
069:         *For unsolicited listeners, this class maintains a vector, unsolicited.
070:         *When an unsolicited listener is registered, this class adds itself
071:         *to the context's LdapClient. When LdapClient receives an unsolicited
072:         *notification, it notifies this EventSupport to fire an event to the
073:         *the listeners. Special handling in LdapClient is done for the DISCONNECT
074:         *notification. [It results in the EventSupport firing also a 
075:         *NamingExceptionEvent to the unsolicited listeners.]
076:         *<p>
077:         *
078:         *When a context no longer needs this EventSupport, it should invoke
079:         *cleanup() on it.
080:         *<p>
081:         *<h4>Registration</h4>
082:         *When a registration request is made, this class attempts to find an
083:         *existing notifier that's already working on the request. If one is
084:         *found, the listener is added to the notifier's list. If one is not found,
085:         *a new notifier is created for the listener.
086:         *
087:         *<h4>Deregistration</h4>
088:         *When a deregistration request is made, this class attemps to find its
089:         *corresponding notifier. If the notifier is found, the listener is removed
090:         *from the notifier's list. If the listener is the last listener on the list,
091:         *the notifier's thread is terminated and removed from this class's hashtable.
092:         *Nothing happens if the notifier is not found.
093:         *
094:         *<h4>Event Dispatching</h4>
095:         *The notifiers are responsible for gather information for generating events
096:         *requested by their respective listeners. When a notifier gets sufficient
097:         *information to generate an event, it creates invokes the
098:         *appropriate <tt>fireXXXEvent</tt> on this class with the information and list of
099:         *listeners. This causes an event and the list of listeners to be added
100:         *to the <em>event queue</em>.
101:         *This class maintains an event queue and a dispatching thread that dequeues
102:         *events from the queue and dispatches them to the listeners.
103:         *
104:         *<h4>Synchronization</h4>
105:         *This class is used by the main thread (LdapCtx) to add/remove listeners.
106:         *It is also used asynchronously by NamingEventNotifiers threads and
107:         *the context's Connection thread. It is used by the notifier threads to
108:         *queue events and to update the notifiers list when the notifiers exit.
109:         *It is used by the Connection thread to fire unsolicited notifications.
110:         *Methods that access/update the 'unsolicited' and 'notifiers' lists are
111:         *thread-safe.
112:         *
113:         * @author Rosanna Lee
114:         */
115:        final class EventSupport {
116:            final static private boolean debug = false;
117:
118:            private LdapCtx ctx;
119:
120:            /**
121:             * NamingEventNotifiers; hashed by search arguments;
122:             */
123:            private Hashtable notifiers = new Hashtable(11);
124:
125:            /**
126:             * List of unsolicited notification listeners.
127:             */
128:            private Vector unsolicited = null;
129:
130:            /**
131:             * Constructs EventSupport for ctx.
132:             * <em>Do we need to record the name of the target context?
133:             * Or can we assume that EventSupport is called on a resolved
134:             * context? Do we need other add/remove-NamingListener methods? 
135:             * package private;
136:             */
137:            EventSupport(LdapCtx ctx) {
138:                this .ctx = ctx;
139:            }
140:
141:            /**
142:             * Adds <tt>l</tt> to list of listeners interested in <tt>nm</tt>.
143:             */
144:            /*
145:             * Make the add/removeNamingListeners synchronized to:
146:             * 1. protect usage of 'unsolicited', which may be read by
147:             *    the Connection thread when dispatching unsolicited notification.
148:             * 2. ensure that NamingEventNotifier thread's access to 'notifiers'
149:             *    is safe
150:             */
151:            synchronized void addNamingListener(String nm, int scope,
152:                    NamingListener l) throws NamingException {
153:
154:                if (l instanceof  ObjectChangeListener
155:                        || l instanceof  NamespaceChangeListener) {
156:                    NotifierArgs args = new NotifierArgs(nm, scope, l);
157:
158:                    NamingEventNotifier notifier = (NamingEventNotifier) notifiers
159:                            .get(args);
160:                    if (notifier == null) {
161:                        notifier = new NamingEventNotifier(this , ctx, args, l);
162:                        notifiers.put(args, notifier);
163:                    } else {
164:                        notifier.addNamingListener(l);
165:                    }
166:                }
167:                if (l instanceof  UnsolicitedNotificationListener) {
168:                    // Add listener to this's list of unsolicited notifiers
169:                    if (unsolicited == null) {
170:                        unsolicited = new Vector(3);
171:                    }
172:
173:                    unsolicited.addElement(l);
174:                }
175:            }
176:
177:            /**
178:             * Adds <tt>l</tt> to list of listeners interested in <tt>nm</tt>
179:             * and filter.
180:             */
181:            synchronized void addNamingListener(String nm, String filter,
182:                    SearchControls ctls, NamingListener l)
183:                    throws NamingException {
184:
185:                if (l instanceof  ObjectChangeListener
186:                        || l instanceof  NamespaceChangeListener) {
187:                    NotifierArgs args = new NotifierArgs(nm, filter, ctls, l);
188:
189:                    NamingEventNotifier notifier = (NamingEventNotifier) notifiers
190:                            .get(args);
191:                    if (notifier == null) {
192:                        notifier = new NamingEventNotifier(this , ctx, args, l);
193:                        notifiers.put(args, notifier);
194:                    } else {
195:                        notifier.addNamingListener(l);
196:                    }
197:                }
198:                if (l instanceof  UnsolicitedNotificationListener) {
199:                    // Add listener to this's list of unsolicited notifiers
200:                    if (unsolicited == null) {
201:                        unsolicited = new Vector(3);
202:                    }
203:                    unsolicited.addElement(l);
204:                }
205:            }
206:
207:            /**
208:             * Removes <tt>l</tt> from all notifiers in this context.
209:             */
210:            synchronized void removeNamingListener(NamingListener l) {
211:                Enumeration allnotifiers = notifiers.elements();
212:                NamingEventNotifier notifier;
213:
214:                if (debug)
215:                    System.err.println("EventSupport removing listener");
216:
217:                // Go through list of notifiers, remove 'l' from each.
218:                // If 'l' is notifier's only listener, remove notifier too.
219:                while (allnotifiers.hasMoreElements()) {
220:                    notifier = (NamingEventNotifier) allnotifiers.nextElement();
221:                    if (notifier != null) {
222:                        if (debug)
223:                            System.err
224:                                    .println("EventSupport removing listener from notifier");
225:                        notifier.removeNamingListener(l);
226:                        if (!notifier.hasNamingListeners()) {
227:                            if (debug)
228:                                System.err
229:                                        .println("EventSupport stopping notifier");
230:                            notifier.stop();
231:                            notifiers.remove(notifier.info);
232:                        }
233:                    }
234:                }
235:
236:                // Remove from list of unsolicited notifier
237:                if (debug)
238:                    System.err.println("EventSupport removing unsolicited: "
239:                            + unsolicited);
240:                if (unsolicited != null) {
241:                    unsolicited.removeElement(l);
242:                }
243:
244:            }
245:
246:            synchronized boolean hasUnsolicited() {
247:                return (unsolicited != null && unsolicited.size() > 0);
248:            }
249:
250:            /**
251:             * package private;
252:             * Called by NamingEventNotifier to remove itself when it encounters
253:             * a NamingException.
254:             */
255:            synchronized void removeDeadNotifier(NotifierArgs info) {
256:                if (debug) {
257:                    System.err.println("EventSupport.removeDeadNotifier: "
258:                            + info.name);
259:                }
260:                notifiers.remove(info);
261:            }
262:
263:            /**
264:             * Fire an event to unsolicited listeners.
265:             * package private;
266:             * Called by LdapCtx when its clnt receives an unsolicited notification.
267:             */
268:            synchronized void fireUnsolicited(Object obj) {
269:                if (debug) {
270:                    System.err.println("EventSupport.fireUnsolicited: " + obj
271:                            + " " + unsolicited);
272:                }
273:                if (unsolicited == null || unsolicited.size() == 0) {
274:                    // This shouldn't really happen, but might in case
275:                    // there is a timing problem that removes a listener
276:                    // before a fired event event reaches here.
277:                    return;
278:                }
279:
280:                if (obj instanceof  UnsolicitedNotification) {
281:
282:                    // Fire UnsolicitedNotification to unsolicited listeners
283:
284:                    UnsolicitedNotificationEvent evt = new UnsolicitedNotificationEvent(
285:                            ctx, (UnsolicitedNotification) obj);
286:                    queueEvent(evt, unsolicited);
287:
288:                } else if (obj instanceof  NamingException) {
289:
290:                    // Fire NamingExceptionEvent to unsolicited listeners.
291:
292:                    NamingExceptionEvent evt = new NamingExceptionEvent(ctx,
293:                            (NamingException) obj);
294:                    queueEvent(evt, unsolicited);
295:
296:                    // When an exception occurs, the unsolicited listeners
297:                    // are automatically deregistered.
298:                    // When LdapClient.processUnsolicited() fires a NamingException,
299:                    // it will update its listener list so we don't have to.
300:                    // Likewise for LdapCtx.
301:
302:                    unsolicited = null;
303:                }
304:            }
305:
306:            /**
307:             * Stops notifier threads that are collecting event data and
308:             * stops the event queue from dispatching events.
309:             * Package private; used by LdapCtx.
310:             */
311:            synchronized void cleanup() {
312:                if (debug)
313:                    System.err.println("EventSupport clean up");
314:                if (notifiers != null) {
315:                    for (Enumeration ns = notifiers.elements(); ns
316:                            .hasMoreElements();) {
317:                        ((NamingEventNotifier) ns.nextElement()).stop();
318:                    }
319:                    notifiers = null;
320:                }
321:                if (eventQueue != null) {
322:                    eventQueue.stop();
323:                    eventQueue = null;
324:                }
325:                // %%% Should we fire NamingExceptionEvents to unsolicited listeners?
326:            }
327:
328:            /*
329:             * The queue of events to be delivered.
330:             */
331:            private EventQueue eventQueue;
332:
333:            /**
334:             * Add the event and vector of listeners to the queue to be delivered.
335:             * An event dispatcher thread dequeues events from the queue and dispatches
336:             * them to the registered listeners.
337:             * Package private; used by NamingEventNotifier to fire events
338:             */
339:            synchronized void queueEvent(EventObject event, Vector vector) {
340:                if (eventQueue == null)
341:                    eventQueue = new EventQueue();
342:
343:                /*
344:                 * Copy the vector in order to freeze the state of the set
345:                 * of EventListeners the event should be delivered to prior
346:                 * to delivery.  This ensures that any changes made to the
347:                 * Vector from a target listener's method during the delivery
348:                 * of this event will not take effect until after the event is
349:                 * delivered.
350:                 */
351:                Vector v = (Vector) vector.clone();
352:                eventQueue.enqueue(event, v);
353:            }
354:
355:            // No finalize() needed because EventSupport is always owned by
356:            // an LdapCtx. LdapCtx's finalize() and close() always call cleanup() so
357:            // there is no need for EventSupport to have a finalize().
358:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.