KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > appserv > management > util > jmx > NotificationListenerBase


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.appserv.management.util.jmx;
24
25 import java.util.Set JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Collections JavaDoc;
28
29 import java.io.IOException JavaDoc;
30
31 import javax.management.ObjectName JavaDoc;
32 import javax.management.Notification JavaDoc;
33 import javax.management.NotificationListener JavaDoc;
34 import javax.management.NotificationFilter JavaDoc;
35 import javax.management.MBeanServerNotification JavaDoc;
36 import javax.management.MBeanServer JavaDoc;
37 import javax.management.MBeanServerConnection JavaDoc;
38 import javax.management.InstanceNotFoundException JavaDoc;
39 import javax.management.JMException JavaDoc;
40
41 import com.sun.appserv.management.util.misc.GSetUtil;
42
43 /**
44     Convenience base class for listening for Notifications
45     from one or more MBeans, which may be specified as
46     a specific MBean ObjectName, or an ObjectName pattern.
47     If the ObjectName is a pattern, the list of listenees
48     is dynamically maintained.
49     <p>
50     Caller should call {@link #cleanup} when done, because
51     a listener is maintained on the MBeanServer delegate.
52     
53  */

54 public abstract class NotificationListenerBase
55     implements NotificationListener JavaDoc
56 {
57     private final MBeanServerConnection JavaDoc mConn;
58     
59     /** actual MBean ObjectNames, not patterns */
60     private final Set JavaDoc<ObjectName JavaDoc> mListenees;
61     
62     /** targets as specified by caller, may be a pattern or fixed ObjectName */
63     private final ObjectName JavaDoc mPattern;
64     private final NotificationFilter JavaDoc mFilter;
65     private final Object JavaDoc mHandback;
66     
67     private RegistrationListener mDelegateListener;
68     
69     /**
70         Calls this( conn, listenTo, null, null ).
71      */

72         public
73     NotificationListenerBase(
74         final MBeanServerConnection JavaDoc conn,
75         final ObjectName JavaDoc pattern )
76         throws InstanceNotFoundException JavaDoc, IOException JavaDoc
77     {
78         this( conn, pattern, null );
79     }
80     
81     /**
82         Listen to all MBean(s) which match the pattern
83         'listenTo'
84         @param conn the MBeanServerConnection or MBeanServer
85         @param pattern an MBean ObjectName, or an ObjectName pattern
86         @param filter optional NotificationFilter
87      */

88         public
89     NotificationListenerBase(
90         final MBeanServerConnection JavaDoc conn,
91         final ObjectName JavaDoc pattern,
92         final NotificationFilter JavaDoc filter )
93         throws InstanceNotFoundException JavaDoc, IOException JavaDoc
94     {
95         mConn = conn;
96         mPattern = pattern;
97         mFilter = filter;
98         mHandback = null;
99         mDelegateListener = null;
100         
101         mListenees = Collections.synchronizedSet( new HashSet JavaDoc<ObjectName JavaDoc>() );
102         
103         // test connection for validity
104
if ( ! conn.isRegistered( JMXUtil.getMBeanServerDelegateObjectName() ) )
105         {
106             throw new IllegalArgumentException JavaDoc();
107         }
108         
109         setupListening( );
110     }
111
112     /**
113         Subclass should implement this routine.
114      */

115     public abstract void
116         handleNotification( final Notification JavaDoc notif, final Object JavaDoc handback);
117     
118     
119         protected synchronized void
120     listenToMBean( final ObjectName JavaDoc objectName )
121         throws InstanceNotFoundException JavaDoc, IOException JavaDoc
122     {
123         if ( ! mListenees.contains( objectName ) )
124         {
125             mListenees.add( objectName );
126             getMBeanServerConnection().addNotificationListener(
127                 objectName, this, mFilter, null );
128         }
129     }
130     
131         private void
132     setupListening()
133         throws InstanceNotFoundException JavaDoc, IOException JavaDoc
134     {
135         if ( mPattern.isPattern() )
136         {
137             // it's crucial we listen for registration/unregistration events
138
// so that any patterns are maintained.
139
// do this BEFORE the code below, of we could
140
// miss a registration.
141
mDelegateListener = new RegistrationListener();
142             JMXUtil.listenToMBeanServerDelegate( mConn,
143                 mDelegateListener, null, null );
144         }
145         
146         
147         Set JavaDoc<ObjectName JavaDoc> s = null;
148         
149         if ( mPattern.isPattern() )
150         {
151             s = JMXUtil.queryNames( getConn(), mPattern, null );
152         }
153         else
154         {
155             s = GSetUtil.newSet( mPattern );
156         }
157         
158         synchronized( this )
159         {
160             for( final ObjectName JavaDoc objectName : s )
161             {
162                 listenToMBean( objectName );
163             }
164         }
165     }
166     
167     /**
168         Get the filter originally specified when constructing this object.
169      */

170         public final NotificationFilter JavaDoc
171     getNotificationFilter( final ObjectName JavaDoc objectName)
172     {
173         return mFilter;
174     }
175     
176     
177         protected synchronized void
178     listenToIfMatch( final ObjectName JavaDoc objectName )
179         throws IOException JavaDoc, InstanceNotFoundException JavaDoc
180     {
181         if ( ! mListenees.contains( objectName ) )
182         {
183             final String JavaDoc defaultDomain = getConn().getDefaultDomain();
184             
185             if ( JMXUtil.matchesPattern( defaultDomain, mPattern, objectName ) )
186             {
187                 listenToMBean( objectName );
188             }
189         }
190     }
191     /**
192         tracks coming and going of MBeans being listened to which
193         match our patterns.
194       */

195     private final class RegistrationListener implements NotificationListener JavaDoc
196     {
197         public RegistrationListener() {}
198         
199             public void
200         handleNotification(
201             final Notification JavaDoc notifIn,
202             final Object JavaDoc handback)
203         {
204             if ( notifIn instanceof MBeanServerNotification JavaDoc )
205             {
206                 final MBeanServerNotification JavaDoc notif = (MBeanServerNotification JavaDoc)notifIn;
207                 
208                 final ObjectName JavaDoc objectName = notif.getMBeanName();
209                 final String JavaDoc type = notif.getType();
210                 
211                 try
212                 {
213                     if ( type.equals( MBeanServerNotification.REGISTRATION_NOTIFICATION ) )
214                     {
215                         listenToIfMatch( objectName );
216                     }
217                     else if ( type.equals( MBeanServerNotification.UNREGISTRATION_NOTIFICATION ) )
218                     {
219                         mListenees.remove( objectName );
220                     }
221                 }
222                 catch( Exception JavaDoc e )
223                 {
224                     // nothing can be done...
225
}
226             }
227         }
228     }
229     
230     /**
231         Reset everything so that no listening is occuring and
232         all lists are empty.
233      */

234         public synchronized void
235     cleanup()
236     {
237         try
238         {
239             if ( mDelegateListener != null )
240             {
241                 // it's crucial we listen for registration/unregistration events
242
// so that any patterns are maintained.
243
getConn().removeNotificationListener(
244                     JMXUtil.getMBeanServerDelegateObjectName(),
245                     mDelegateListener, null, null );
246                 mDelegateListener = null;
247             }
248             
249             for( final ObjectName JavaDoc objectName : mListenees )
250             {
251                 getConn().removeNotificationListener(
252                     objectName, this, mFilter, null);
253             }
254         }
255         catch( JMException JavaDoc e )
256         {
257         }
258         catch( IOException JavaDoc e )
259         {
260         }
261         
262         mListenees.clear();
263     }
264     
265     /**
266         @return a copy of the MBean currently being listened to.
267      */

268         public synchronized Set JavaDoc<ObjectName JavaDoc>
269     getListenees()
270     {
271         final Set JavaDoc<ObjectName JavaDoc> objectNames = new HashSet JavaDoc<ObjectName JavaDoc>();
272         
273         synchronized( mListenees )
274         {
275             objectNames.addAll( mListenees );
276         }
277         
278         return( objectNames );
279     }
280     
281     
282     /**
283         @return the MBeanServerConnection in use.
284         @throws an Exception if no longer alive ( isAlive() returns false).
285      */

286         public final MBeanServerConnection JavaDoc
287     getMBeanServerConnection()
288     {
289         return getConn();
290     }
291     
292         protected final MBeanServerConnection JavaDoc
293     getConn()
294     {
295         return mConn;
296     }
297     
298     
299         protected final void
300     checkAlive()
301         throws IOException JavaDoc
302     {
303         if ( ! isAlive() )
304         {
305             throw new IOException JavaDoc( "MBeanServerConnection failed" );
306         }
307     }
308     
309     /**
310         @return true if still listening and the connection is still alive
311      */

312         public boolean
313     isAlive()
314     {
315         boolean isAlive = true;
316         
317         if ( ! (mConn instanceof MBeanServer JavaDoc) )
318         {
319             // remote, check if it is alive
320
try
321             {
322                 mConn.isRegistered( JMXUtil.getMBeanServerDelegateObjectName() );
323             }
324             catch( Exception JavaDoc e )
325             {
326                 isAlive = false;
327             }
328         }
329         return isAlive;
330     }
331     
332 }
333
334
335
336
337
338
339
Popular Tags