Source Code Cross Referenced for NotificationBroadcasterSupport.java in  » JMX » mx4j » javax » management » 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 » JMX » mx4j » javax.management 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (C) The MX4J Contributors.
003:         * All rights reserved.
004:         *
005:         * This software is distributed under the terms of the MX4J License version 1.0.
006:         * See the terms of the MX4J License in the documentation provided with this software.
007:         */
008:
009:        package javax.management;
010:
011:        import java.util.ArrayList;
012:        import java.util.HashMap;
013:        import java.util.Iterator;
014:
015:        import mx4j.log.Log;
016:        import mx4j.log.Logger;
017:
018:        /**
019:         * Provides an implementation of NotificationEmitter interface.
020:         * This can be used as the super class of an MBean that sends notifications.
021:         * It is not specified whether the notification dispatch model is synchronous or asynchronous.
022:         * That is, when a thread calls sendNotification, the NotificationListener.handleNotification
023:         * method of each listener may be called within that thread (a synchronous model)
024:         * or within some other thread (an asynchronous model).
025:         * Applications should not depend on notification dispatch being synchronous or being asynchronous. Thus:
026:         * <ul>
027:         * <li>Applications should not assume a synchronous model. When the sendNotification method returns,
028:         * it is not guaranteed that every listener's handleNotification method has been called.
029:         * It is not guaranteed either that a listener will see notifications in the same order as they were generated.
030:         * Listeners that depend on order should use the sequence number of notifications to determine their order
031:         * (see Notification.getSequenceNumber()).</li>
032:         * <li>Applications should not assume an asynchronous model.
033:         * If the actions performed by a listener are potentially slow, the listener should arrange for them to be performed
034:         * in another thread, to avoid holding up other listeners and the caller of sendNotification.</li>
035:         * </ul>
036:         *
037:         * @version $Revision: 1.19 $
038:         */
039:        public class NotificationBroadcasterSupport implements 
040:                NotificationEmitter {
041:            private static final NotificationFilter NULL_FILTER = new NotificationFilter() {
042:                public boolean isNotificationEnabled(Notification notification) {
043:                    return true;
044:                }
045:
046:                public String toString() {
047:                    return "null filter";
048:                }
049:            };
050:
051:            private static final Object NULL_HANDBACK = new Object() {
052:                public String toString() {
053:                    return "null handback";
054:                }
055:            };
056:
057:            private HashMap m_listeners = new HashMap();
058:
059:            public NotificationBroadcasterSupport() {
060:            }
061:
062:            private Logger getLogger() {
063:                return Log.getLogger(getClass().getName());
064:            }
065:
066:            public void addNotificationListener(NotificationListener listener,
067:                    NotificationFilter filter, Object handback) {
068:                Logger logger = getLogger();
069:
070:                if (logger.isEnabledFor(Logger.TRACE))
071:                    logger.trace("Adding notification listener: " + listener
072:                            + ", filter: " + filter + ", handback: " + handback
073:                            + " to " + this );
074:
075:                if (listener == null)
076:                    throw new IllegalArgumentException(
077:                            "Notification listener cannot be null");
078:
079:                // Normalize the arguments
080:                if (filter == null)
081:                    filter = NULL_FILTER;
082:                if (handback == null)
083:                    handback = NULL_HANDBACK;
084:
085:                FilterHandbackPair pair = new FilterHandbackPair(filter,
086:                        handback);
087:
088:                synchronized (this ) {
089:                    ArrayList pairs = (ArrayList) m_listeners.get(listener);
090:
091:                    if (pairs == null) {
092:                        // A new listener, register it
093:                        pairs = new ArrayList();
094:                        pairs.add(pair);
095:                        m_listeners.put(listener, pairs);
096:                    } else {
097:                        // Check that the same triple (listener, filter, handback) is not already registered
098:                        for (int i = 0; i < pairs.size(); ++i) {
099:                            FilterHandbackPair other = (FilterHandbackPair) pairs
100:                                    .get(i);
101:                            if (pair.filter.equals(other.filter)
102:                                    && pair.handback.equals(other.handback)) {
103:                                // Same filter and same handback for the same listener, it's already registered
104:                                throw new RuntimeOperationsException(
105:                                        new IllegalArgumentException(
106:                                                "Notification listener is already registered"));
107:                            }
108:                        }
109:                        // Not yet registered, register.
110:                        // Do not merge this call with the one in the if branch: like this is easier to debug
111:                        // (I know the if-else branch from where I'm coming)
112:                        pairs.add(pair);
113:                    }
114:
115:                    if (logger.isEnabledFor(Logger.TRACE))
116:                        logger.trace("Filters - Handbacks for this listener: "
117:                                + pairs);
118:                }
119:
120:                if (logger.isEnabledFor(Logger.TRACE))
121:                    logger.trace("Notification listener added successfully to "
122:                            + this );
123:            }
124:
125:            public void removeNotificationListener(NotificationListener listener)
126:                    throws ListenerNotFoundException {
127:                Logger logger = getLogger();
128:                if (logger.isEnabledFor(Logger.TRACE))
129:                    logger.trace("Removing notification listener: " + listener);
130:
131:                int removed = removeNotificationListenerImpl(listener, null,
132:                        null);
133:
134:                if (logger.isEnabledFor(Logger.TRACE))
135:                    logger
136:                            .trace(removed
137:                                    + " notification listener(s) removed successfully from "
138:                                    + this );
139:            }
140:
141:            public void removeNotificationListener(
142:                    NotificationListener listener, NotificationFilter filter,
143:                    Object handback) throws ListenerNotFoundException {
144:                Logger logger = getLogger();
145:                if (logger.isEnabledFor(Logger.TRACE))
146:                    logger
147:                            .trace("Removing notification listener: "
148:                                    + listener + ", filter: " + filter
149:                                    + ", handback: " + handback);
150:
151:                // Normalize the arguments if necessary
152:                if (filter == null)
153:                    filter = NULL_FILTER;
154:                if (handback == null)
155:                    handback = NULL_HANDBACK;
156:
157:                int removed = removeNotificationListenerImpl(listener, filter,
158:                        handback);
159:
160:                if (logger.isEnabledFor(Logger.TRACE))
161:                    logger
162:                            .trace(removed
163:                                    + " notification listener(s) removed successfully from "
164:                                    + this );
165:            }
166:
167:            private int removeNotificationListenerImpl(
168:                    NotificationListener listener, NotificationFilter filter,
169:                    Object handback) throws ListenerNotFoundException {
170:                Logger logger = getLogger();
171:                synchronized (this ) {
172:                    if (logger.isEnabledFor(Logger.TRACE))
173:                        logger.trace("Listeners for " + this  + " are: "
174:                                + m_listeners);
175:
176:                    ArrayList pairs = (ArrayList) m_listeners.get(listener);
177:
178:                    if (pairs == null)
179:                        throw new ListenerNotFoundException(
180:                                "NotificationListener " + listener
181:                                        + " not found");
182:
183:                    if (filter == null) {
184:                        if (handback == null) {
185:                            // Means I want to remove all triplets for this listener
186:
187:                            ArrayList removed = (ArrayList) m_listeners
188:                                    .remove(listener);
189:                            return removed.size();
190:                        } else {
191:                            // Means I want to remove all triplets with the given handback for this listener
192:
193:                            int count = 0;
194:                            for (int i = 0; i < pairs.size(); ++i) {
195:                                Object hand = ((FilterHandbackPair) pairs
196:                                        .get(i)).handback;
197:                                if (handback.equals(hand)) {
198:                                    pairs.remove(i);
199:                                    ++count;
200:                                }
201:                            }
202:                            if (count == 0)
203:                                throw new ListenerNotFoundException(
204:                                        "NotificationListener " + listener
205:                                                + " with handback " + handback
206:                                                + " not found");
207:
208:                            // Check if it was the last listener
209:                            if (pairs.isEmpty())
210:                                m_listeners.remove(listener);
211:
212:                            return count;
213:                        }
214:                    } else {
215:                        if (handback == null) {
216:                            // Means I want to remove all triplets with the given filter for this listener
217:
218:                            int count = 0;
219:                            for (int i = 0; i < pairs.size(); ++i) {
220:                                Object filt = ((FilterHandbackPair) pairs
221:                                        .get(i)).filter;
222:                                if (filter.equals(filt)) {
223:                                    pairs.remove(i);
224:                                    ++count;
225:                                }
226:                            }
227:                            if (count == 0)
228:                                throw new ListenerNotFoundException(
229:                                        "NotificationListener " + listener
230:                                                + " with filter " + filter
231:                                                + " not found");
232:
233:                            // Check if it was the last listener
234:                            if (pairs.isEmpty())
235:                                m_listeners.remove(listener);
236:
237:                            return count;
238:                        } else {
239:                            // Means I want to remove all triplets with the given filter and handback for this listener
240:
241:                            int count = 0;
242:                            for (int i = 0; i < pairs.size(); ++i) {
243:                                FilterHandbackPair pair = (FilterHandbackPair) pairs
244:                                        .get(i);
245:                                if (filter.equals(pair.filter)
246:                                        && handback.equals(pair.handback)) {
247:                                    pairs.remove(i);
248:                                    ++count;
249:                                }
250:                            }
251:                            if (count == 0)
252:                                throw new ListenerNotFoundException(
253:                                        "NotificationListener " + listener
254:                                                + " with filter " + filter
255:                                                + " and handback " + handback
256:                                                + " not found");
257:
258:                            // Check if it was the last listener
259:                            if (pairs.isEmpty())
260:                                m_listeners.remove(listener);
261:
262:                            return count;
263:                        }
264:                    }
265:                }
266:            }
267:
268:            public MBeanNotificationInfo[] getNotificationInfo() {
269:                // Subclasses should override returning more informations
270:                return new MBeanNotificationInfo[0];
271:            }
272:
273:            /**
274:             * Sends the given notification to all registered listeners
275:             *
276:             * @param notification The notification to send
277:             */
278:            public void sendNotification(Notification notification) {
279:                Logger logger = getLogger();
280:                boolean trace = logger.isEnabledFor(Logger.TRACE);
281:                boolean info = logger.isEnabledFor(Logger.INFO);
282:
283:                HashMap listeners = null;
284:
285:                synchronized (this ) {
286:                    // Clone the listeners, so we can notify without holding any lock
287:                    // It is a shallow copy, below we will clone the pairs as well
288:                    // I don't care if in the middle someone else adds or remove other pairs
289:                    listeners = (HashMap) m_listeners.clone();
290:                }
291:
292:                // Loop over all listeners
293:                Iterator i = listeners.keySet().iterator();
294:
295:                if (i.hasNext() && trace)
296:                    logger.trace("Sending notifications from " + this );
297:
298:                while (i.hasNext()) {
299:                    NotificationListener listener = (NotificationListener) i
300:                            .next();
301:                    if (trace)
302:                        logger.trace("\tListener is: " + listener);
303:
304:                    // Clone again the pairs for this listener.
305:                    // I freezed the listeners with the first clone, if someone removes a pair
306:                    // in the middle of notifications I don't care: here I clone the actual pairs
307:                    ArrayList pairs = null;
308:                    synchronized (this ) {
309:                        pairs = (ArrayList) listeners.get(listener);
310:                        pairs = (ArrayList) pairs.clone();
311:                    }
312:
313:                    if (trace)
314:                        logger.trace("\tFilters - Handback for this listener: "
315:                                + pairs);
316:
317:                    // Loop over the same listener that registered many times with different filter / handbacks
318:                    for (int j = 0; j < pairs.size(); ++j) {
319:                        FilterHandbackPair pair = (FilterHandbackPair) pairs
320:                                .get(j);
321:
322:                        NotificationFilter filter = pair.filter;
323:                        Object handback = pair.handback;
324:
325:                        // Denormalize filter and handback if necessary
326:                        if (filter == NULL_FILTER)
327:                            filter = null;
328:                        if (handback == NULL_HANDBACK)
329:                            handback = null;
330:
331:                        boolean enabled = false;
332:                        try {
333:                            enabled = filter == null
334:                                    || filter
335:                                            .isNotificationEnabled(notification);
336:                        } catch (Throwable x) {
337:                            if (info)
338:                                logger
339:                                        .info(
340:                                                "Throwable caught from isNotificationEnabled",
341:                                                x);
342:                            // And go on
343:                        }
344:
345:                        if (trace)
346:                            logger.trace("\t\tFilter is: " + filter
347:                                    + ", enabled: " + enabled);
348:
349:                        if (enabled) {
350:                            if (trace) {
351:                                logger.debug("\t\tHandback is: " + handback);
352:                                logger.debug("\t\tSending notification "
353:                                        + notification);
354:                            }
355:
356:                            try {
357:                                handleNotification(listener, notification,
358:                                        handback);
359:                            } catch (Throwable x) {
360:                                if (info)
361:                                    logger
362:                                            .info(
363:                                                    "Throwable caught from handleNotification",
364:                                                    x);
365:                                // And go on with next listener
366:                            }
367:                        }
368:                    }
369:                }
370:            }
371:
372:            /**
373:             * This method is called by {@link #sendNotification} for each listener in order to send the notification to that listener.
374:             * It can be overridden in subclasses to change the behaviour of notification delivery,
375:             * for instance to deliver the notification in a separate thread.
376:             * It is not guaranteed that this method is called by the same thread as the one that called sendNotification.
377:             * The default implementation of this method is equivalent to
378:             * <code>listener.handleNotification(notif, handback);</code>
379:             *
380:             * @param listener     - the listener to which the notification is being delivered.
381:             * @param notification - the notification being delivered to the listener.
382:             * @param handback     - the handback object that was supplied when the listener was added.
383:             * @since JMX 1.2
384:             */
385:            protected void handleNotification(NotificationListener listener,
386:                    Notification notification, Object handback) {
387:                listener.handleNotification(notification, handback);
388:            }
389:
390:            private static class FilterHandbackPair {
391:                private NotificationFilter filter;
392:                private Object handback;
393:
394:                private FilterHandbackPair(NotificationFilter filter,
395:                        Object handback) {
396:                    this.filter = filter;
397:                    this.handback = handback;
398:                }
399:            }
400:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.