FileDocCategorySizeDatePackage
NotificationListenerBase.javaAPI DocGlassfish v2 API10374Fri May 04 22:31:04 BST 2007com.sun.appserv.management.util.jmx

NotificationListenerBase

public abstract class NotificationListenerBase extends Object implements NotificationListener
Convenience base class for listening for Notifications from one or more MBeans, which may be specified as a specific MBean ObjectName, or an ObjectName pattern. If the ObjectName is a pattern, the list of listenees is dynamically maintained.

Caller should call {@link #cleanup} when done, because a listener is maintained on the MBeanServer delegate.

Fields Summary
private final String
mName
private final MBeanServerConnection
mConn
private final Set
mListenees
actual MBean ObjectNames, not patterns
private final ObjectName
mPattern
targets as specified by caller, may be a pattern or fixed ObjectName
private final NotificationFilter
mFilter
private final Object
mHandback
private RegistrationListener
mDelegateListener
private volatile boolean
mSetupListening
Constructors Summary
protected NotificationListenerBase(String name, MBeanServerConnection conn, ObjectName pattern)
Calls this( conn, listenTo, null, null ).

Instantiating code must call setupListening() in order to initiate listening

	    this( name, conn, pattern, null );
	
protected NotificationListenerBase(String name, MBeanServerConnection conn, ObjectName pattern, NotificationFilter filter)
Listen to all MBean(s) which match the pattern 'listenTo'.

Instantiating code must call setupListening() in order to initiate listening

param
listenerName arbitrary name of this listener
param
conn the MBeanServerConnection or MBeanServer
param
pattern an MBean ObjectName, or an ObjectName pattern
param
filter optional NotificationFilter

        mName           = name;
	    mConn           = conn;
		mPattern        = pattern;
		mFilter         = filter;
	    mHandback       = null;
	    mDelegateListener   = null;
        mSetupListening = false;
	    
		mListenees		= Collections.synchronizedSet( new HashSet<ObjectName>() );
		
	    // test connection for validity
	    if ( ! conn.isRegistered( JMXUtil.getMBeanServerDelegateObjectName() ) )
	    {
	        throw new IllegalArgumentException();
	    }
	
Methods Summary
protected final voidcheckAlive()

        if ( ! isAlive() )
        {
            throw new IOException( "MBeanServerConnection failed" );
        }
    
public synchronized voidcleanup()
Reset everything so that no listening is occuring and all lists are empty.

	    try
	    {
    	    if ( mDelegateListener != null )
    	    {
        		// it's crucial we listen for registration/unregistration events
        		// so that any patterns are maintained.
        		getConn().removeNotificationListener(
        		    JMXUtil.getMBeanServerDelegateObjectName(),
        			mDelegateListener, null, null );
        	    mDelegateListener   = null;
    	    }
    	    
    		for( final ObjectName objectName : mListenees )
    		{
        	    getConn().removeNotificationListener(
        	        objectName, this, mFilter, null);
    		}
		}
		catch( JMException e )
		{
		}
		catch( IOException e )
		{
		}
		
		mListenees.clear();
	
protected final javax.management.MBeanServerConnectiongetConn()

        return mConn;
    
public synchronized java.util.SetgetListenees()

return
a copy of the MBean currently being listened to.

		final Set<ObjectName>	objectNames	= new HashSet<ObjectName>();
		
		synchronized( mListenees )
		{
			objectNames.addAll( mListenees );
		}
		
		return( objectNames );
	
public final javax.management.MBeanServerConnectiongetMBeanServerConnection()

return
the MBeanServerConnection in use.
throws
an Exception if no longer alive ( isAlive() returns false).

        return getConn();
    
public final javax.management.NotificationFiltergetNotificationFilter(javax.management.ObjectName objectName)
Get the filter originally specified when constructing this object.

	    return mFilter;
	
public abstract voidhandleNotification(javax.management.Notification notif, java.lang.Object handback)
Subclass should implement this routine.

public booleanisAlive()

return
true if still listening and the connection is still alive

        boolean isAlive = true;
        
        if ( ! (mConn instanceof MBeanServer) )
        {
            // remote, check if it is alive
            try
            {
                mConn.isRegistered( JMXUtil.getMBeanServerDelegateObjectName() );
            }
            catch( Exception e )
            {
                isAlive = false;
            }
        }
        return isAlive;
    
protected synchronized voidlistenToIfMatch(javax.management.ObjectName objectName)

		if ( ! mListenees.contains( objectName ) )
		{
			final String	defaultDomain	= getConn().getDefaultDomain();
			
			if ( JMXUtil.matchesPattern( defaultDomain, mPattern, objectName ) )
			{
				listenToMBean( objectName );
			}
		}
	
protected synchronized voidlistenToMBean(javax.management.ObjectName objectName)

	    if ( ! mListenees.contains( objectName ) )
	    {
    	    mListenees.add( objectName );
    		getMBeanServerConnection().addNotificationListener(
    		    objectName, this, mFilter, null );
	    }
	
public synchronized voidstartListening()

        if ( mSetupListening )
        {
            throw new IllegalStateException( "setupListening() must be called exactly once" );
        }
        
	    if ( mPattern.isPattern() )
	    {
    		// it's crucial we listen for registration/unregistration events
    		// so that any patterns are maintained.
    		// do this BEFORE the code below, of we could
    		// miss a registration.
	        mDelegateListener   = new RegistrationListener();
    		JMXUtil.listenToMBeanServerDelegate( mConn,
    		    mDelegateListener, null, null );
	    }
	    
	    
		Set<ObjectName>	s	= null;
		
		if ( mPattern.isPattern() )
		{
			s	= JMXUtil.queryNames( getConn(), mPattern, null );
		}
		else
		{
			s	= GSetUtil.newSet( mPattern );
		}
		
		synchronized( this )
		{
    		for( final ObjectName objectName : s )
    		{
    		    listenToMBean( objectName );
    		}
		}
        
        mSetupListening = true;