FileDocCategorySizeDatePackage
ProxyFactory.javaAPI DocGlassfish v2 API21677Fri May 04 22:30:32 BST 2007com.sun.appserv.management.client

ProxyFactory

public final class ProxyFactory extends Object implements NotificationListener
Factory for {@link AMX} proxies. Usually proxies are obtained by starting with the DomainRoot obtained via {@link AppserverConnectionSource#getDomainRoot}.
see
com.sun.appserv.management.client.AppserverConnectionSource

Fields Summary
private final com.sun.appserv.management.client.handler.ProxyCache
mProxyCache
private final com.sun.appserv.management.client.ConnectionSource
mConnectionSource
private final ObjectName
mDomainRootObjectName
private final com.sun.appserv.management.DomainRoot
mDomainRoot
private final String
mMBeanServerID
private static final com.sun.appserv.management.helper.AMXDebugHelper
mDebug
private static final Map
INSTANCES
private static final String
DOMAIN_ROOT_KEY
Constructors Summary
private ProxyFactory(com.sun.appserv.management.client.ConnectionSource connSource)

        mDebug.setEchoToStdOut( true );
        
		assert( connSource != null );
		
		mConnectionSource	= connSource;
		mProxyCache			= new ProxyCache();
		
		try
		{
			final MBeanServerConnection	conn	= getConnection();
			
			mMBeanServerID		= JMXUtil.getMBeanServerID( conn );
				
			mDomainRootObjectName	= initDomainRootObjectName();
			mDomainRoot				= initDomainRoot();
			
			// we should always be able to listen to MBeans--
			// but the http connector does not support listeners
			try
			{
				final MBeanServerNotificationFilter	filter	=
					new MBeanServerNotificationFilter();
				filter.enableAllObjectNames();
				filter.disableAllTypes();
				filter.enableType( MBeanServerNotification.UNREGISTRATION_NOTIFICATION );
				
				JMXUtil.listenToMBeanServerDelegate( conn, this, filter, null );
			}
			catch( Exception e )
			{
				warning( "ProxyFactory: connection does not support notifications: ",
                    mMBeanServerID, connSource);
			}
			
			// same idea as above, this time we want to listen to connection died
			// plus there may not be a JMXConnector involved
			final JMXConnector	connector	= connSource.getJMXConnector( false );
			if ( connector != null )
			{
				try
				{
					connector.addConnectionNotificationListener( this, null, null );
				}
				catch( Exception e )
				{
					warning("addConnectionNotificationListener failed: ",
                        mMBeanServerID, connSource, e);
				}
			}
		}
		catch( Exception e )
		{
			warning( "ProxyFactory.ProxyFactory:\n", e );
			throw new RuntimeException( e );
		}
	
Methods Summary
public booleancheckConnection()
Verify that the connection is still alive.

		boolean	connectionGood	= true;
		
		try
		{
			getConnection().isRegistered( JMXUtil.getMBeanServerDelegateObjectName() );
			connectionGood	= true;
		}
		catch( Exception e )
		{
			connectionBad();
		}
		
		return( connectionGood );
	
private voidconnectionBad()
The connection is bad. Tell each proxy its gone and remove it.

        final Set<AMX>   proxies  = new HashSet<AMX>();
        proxies.addAll( mProxyCache.values() );
        mProxyCache.clear();
        
        for( final AMX proxy : proxies )
        {
            ConverterHandlerUtil.connectionBad( proxy );
        }
	
public com.sun.appserv.management.DomainRootcreateDomainRoot()

	
		 
	 
		 
	
		return( mDomainRoot );
	
private com.sun.appserv.management.base.AMXcreateProxy(javax.management.ObjectName objectName)
Create a new proxy. When a new proxy is created, its parent is required, which could cause a chain of proxies to be created.

param
ObjectName

		AMX proxy				= null;
		
		try
		{
			String		proxyInterfaceName	= null;
			Class	proxyInterface		= null;
			
			proxyInterfaceName	= (String)
				getConnection().getAttribute( objectName, AMXAttributes.ATTR_INTERFACE_NAME );
			
			proxyInterface	= ClassUtil.getClassFromName( proxyInterfaceName );
					
			proxy	=  newProxyInstance( objectName, new Class[] { proxyInterface } );
		}
		catch( IllegalArgumentException e )
		{
            debug( "createProxy", e );
			throw e;
		}
		catch( Exception e )
		{
            debug( "createProxy", e );
			throw new RuntimeException( e );
		}
				
		return( proxy );
	
private com.sun.appserv.management.util.jmx.MBeanProxyHandlercreateProxyHandler(javax.management.ObjectName objectName)

	    return ConverterHandlerFactory.createHandler( mConnectionSource, objectName );
	
private static voiddebug(java.lang.Object args)

             mDebug.println( args ); 
public static synchronized com.sun.appserv.management.client.ProxyFactoryfindInstance(com.sun.appserv.management.client.ConnectionSource conn)

return
ProxyFactory corresponding to the ConnectionSource

		return( INSTANCES.get( conn ) );
	
public static synchronized com.sun.appserv.management.client.ProxyFactoryfindInstance(javax.management.MBeanServerConnection conn)

return
ProxyFactory corresponding to the MBeanServerConnection

		ProxyFactory	instance	= null;
		
		final Collection<ProxyFactory> values	= INSTANCES.values();
		for( final ProxyFactory factory : values )
		{
			if ( factory.getConnectionSource().getExistingMBeanServerConnection( ) == conn )
			{
				instance	= factory;
				break;
			}
		}
		return( instance );
	
public static synchronized com.sun.appserv.management.client.ProxyFactoryfindInstanceByID(java.lang.String mbeanServerID)

return
ProxyFactory corresponding to the MBeanServerID

		ProxyFactory	instance	= null;
		
		final Collection<ProxyFactory> values	= INSTANCES.values();
		for( final ProxyFactory factory : values )
		{
			if ( factory.getMBeanServerID().equals( mbeanServerID ) )
			{
				instance	= factory;
				break;
			}
		}
		
		return( instance );
	
protected javax.management.MBeanServerConnectiongetConnection()

return
MBeanServerConnection used by this factory

		return( getConnectionSource().getMBeanServerConnection( false ) );
	
public com.sun.appserv.management.client.ConnectionSourcegetConnectionSource()

return
the ConnectionSource used by this factory

		return( mConnectionSource );
	
public com.sun.appserv.management.DomainRootgetDomainRoot()
Return the DomainRoot. AMX may not yet be fully initialized; call getDomainRoot( true ) if AMX must be initialized upon return.

return
the DomainRoot for this factory.

		return getDomainRoot( false );
	
public com.sun.appserv.management.DomainRootgetDomainRoot(boolean waitReady)
If 'waitReady' is true, then upon return AMX is guaranteed to be fully loaded. Otherwise AMX MBeans may continue to initialize asynchronously.

param
waitReady
return
the DomainRoot for this factory.

	    if ( waitReady )
	    {
	        mDomainRoot.waitAMXReady();
	    }
	    
		return( mDomainRoot );
	
public javax.management.ObjectNamegetDomainRootObjectName()
Return the ObjectName for the DomainMBean.

		return( mDomainRootObjectName );
	
public static com.sun.appserv.management.client.ProxyFactorygetInstance(javax.management.MBeanServer server)
Get an instance of the ProxyFactory for the MBeanServer. Generally not applicable for remote clients.

param
server

		return( getInstance( new MBeanServerConnectionSource( server ), true ) );
	
public static com.sun.appserv.management.client.ProxyFactorygetInstance(javax.management.MBeanServerConnection conn)
Get an instance of the ProxyFactory for the MBeanServerConnection. Creates a ConnectionSource for it and calls getInstance( connSource, true ).

		return( getInstance( new MBeanServerConnectionConnectionSource( conn ), true ) );
	
public static com.sun.appserv.management.client.ProxyFactorygetInstance(com.sun.appserv.management.client.ConnectionSource conn)
Calls getInstance( connSource, true ).

	
		return( getInstance( conn, true ) );
	
public static synchronized com.sun.appserv.management.client.ProxyFactorygetInstance(com.sun.appserv.management.client.ConnectionSource connSource, boolean useMBeanServerID)
Get an instance. If 'useMBeanServerID' is false, and the ConnectionSource is not one that has been passed before, a new ProxyFactory is instantiated which will not share its proxies with any previously-instantiated ones. Such usage is discouraged, as it duplicates proxies. Pass 'true' unless there is an excellent reason to pass 'false'.

param
connSource the ConnectionSource
param
useMBeanServerID use the MBeanServerID to determine if it's the same server

		ProxyFactory	instance	= findInstance( connSource );
		
		if ( instance == null )
		{
			try
			{
				// match based on the MBeanServerConnection; different
				// ConnectionSource instances could wrap the same connection
				final MBeanServerConnection	conn =
					connSource.getMBeanServerConnection( false );
				
				instance	= findInstance( conn );
				
				// if not found, match based on MBeanServerID as requested, or if this
				// is an in-process MBeanServer
				if ( instance == null &&
					( useMBeanServerID  || connSource instanceof MBeanServerConnectionSource ) )
				{
					final String	id	= JMXUtil.getMBeanServerID( conn );
					instance	= findInstanceByID( id );
				}
			
				if ( instance == null )
				{
                    debug( "Creating new ProxyFactory for ConnectionSource / conn", connSource, conn );
					instance	= new ProxyFactory( connSource );
					INSTANCES.put( conn, instance );
				}
			}
			catch( Exception e )
			{
				warning( "ProxyFactory.getInstance: failure creating ProxyFactory: ", e );
				throw new RuntimeException( e );
			}
		}
		
		return( instance );
	
public java.lang.StringgetMBeanServerID()

return
the JMX MBeanServerID for the MBeanServer in which MBeans reside.

		return( mMBeanServerID );
	
public com.sun.appserv.management.base.AMXgetProxy(javax.management.ObjectName objectName)

return
an appropriate {@link AMX} interface for the ObjectName
deprecated
use versions that take a class as a parameter

	    return getProxy( objectName, true );
	
public com.sun.appserv.management.base.AMXgetProxy(javax.management.ObjectName objectName, boolean create)
Get any existing proxy, returning null if none exists and 'create' is false.

param
objectName ObjectName for which a proxy should be created
param
create true to create the proxy, false to return existing value
return
an appropriate {@link AMX} interface for the ObjectName
deprecated
use versions that take a class as a parameter

	    return getProxy( objectName, AMX.class, create );
	
public synchronized TgetProxy(javax.management.ObjectName objectName, java.lang.Class theInterface)
The actual interface(s) that the proxy implements are predetermined. Specifying the interface ties the return type to the interface at compile-time but has no effect on the actual interfaces that are implemented by the proxy.

return
an appropriate {@link AMX} interface for the ObjectName

		return getProxy( objectName, theInterface, true );
	
public synchronized TgetProxy(javax.management.ObjectName objectName, java.lang.Class theClass, boolean create)
Get any existing proxy, returning null if none exists and 'create' is false.

param
objectName ObjectName for which a proxy should be created
param
create true to create the proxy, false to return existing value
param
theClass class of returned proxy, avoids casts and compiler warnings
return
an appropriate {@link AMX} interface for the ObjectName

		AMX	proxy	= mProxyCache.getCachedProxy( objectName );
		
		if ( proxy == null && create )
		{
			proxy	= createProxy( objectName );
		}
		return theClass.cast( proxy );
	
public voidhandleNotification(javax.management.Notification notifIn, java.lang.Object handback)
Listens for MBeanServerNotification.UNREGISTRATION_NOTIFICATION and JMXConnectionNotification and takes appropriate action.
Used internally as callback for {@link javax.management.NotificationListener}. DO NOT CALL THIS METHOD.

		final String	type	= notifIn.getType();
		
		if ( type.equals( MBeanServerNotification.UNREGISTRATION_NOTIFICATION)  )
		{
			final MBeanServerNotification	notif	= (MBeanServerNotification)notifIn;
			final ObjectName	objectName	= notif.getMBeanName();
			final AMX proxy	= getProxy( objectName, AMX.class, false );
			mProxyCache.remove( objectName );
			ConverterHandlerUtil.targetUnregistered(proxy);
			
			//debug( "ProxyFactory.handleNotification: UNREGISTERED: ", objectName );
		}
		else if ( notifIn instanceof JMXConnectionNotification )
		{
			if ( type.equals( JMXConnectionNotification.CLOSED ) ||
				type.equals( JMXConnectionNotification.FAILED ) )
			{
                debug( "ProxyFactory.handleNotification: connection closed or failed: ", notifIn);
				connectionBad();
			}
			else if ( type.equals( JMXConnectionNotification.NOTIFS_LOST ) )
			{
                debug( "ProxyFactory.handleNotification: notifications lost: ", notifIn);
				notifsLost();
			}
		}
		else
		{
			debug( "ProxyFactory.handleNotification: UNKNOWN notification: ", notifIn );
		}
	
public com.sun.appserv.management.DomainRootinitDomainRoot()

		final ObjectName	domainRootObjectName	= getDomainRootObjectName( );
		
		final DomainRoot	domainRoot	= (DomainRoot)
			newProxyInstance(domainRootObjectName, new Class[] { DomainRoot.class });
		
		return( domainRoot );
	
private javax.management.ObjectNameinitDomainRootObjectName()

		final MBeanServerConnection	conn	= mConnectionSource.getMBeanServerConnection( false );
		
		final String	patternString	= "*:" +
							AMX.J2EE_TYPE_KEY + "=" + XTypes.DOMAIN_ROOT + ",*";
		
		ObjectName	pattern	= null;
		try
		{
			pattern	= new ObjectName( patternString );
		}
		catch ( MalformedObjectNameException e )
		{
            warning( "initDomainRootObjectName: impossible failure", e );
			assert( false );	// can't happen
			throw new RuntimeException( e );
		}
		
		final Set<ObjectName>	objectNames	= JMXUtil.queryNames( conn, pattern, null );
		if ( objectNames.size() != 1 )
		{
            warning( "Can't find DomainRoot MBean using pattern: ", pattern);
			throw new IllegalArgumentException( "Can't find DomainRoot MBean using pattern " + pattern );
		}

		final ObjectName	objectName	= GSetUtil.getSingleton( objectNames );
		
		return( objectName );
	
public com.sun.appserv.management.base.AMXnewProxyInstance(javax.management.ObjectName objectName, java.lang.Class[] interfaceClasses)
Instantiates a new proxy using the default AttributeNameMangler and with any desired number of interfaces. If you want NotificationBroadcaster as one of the interfaces, you must supply it in the list. Use of this routine is discouraged in favor of {@link #getProxy}

param
objectName the target MBean which will be invoked by the proxy
param
interfaceClasses all interfaces the proxy should implement
return
the new Proxy implementing the specified interface

		final MBeanProxyHandler	handler	= createProxyHandler( objectName );
		
		final ClassLoader		classLoader	= interfaceClasses[ 0 ].getClassLoader();
		
		final AMX proxy	= Util.asAMX(Proxy.newProxyInstance( classLoader, interfaceClasses, handler));
		if ( proxy != null )
		{
		    mProxyCache.remove( objectName );
			mProxyCache.cacheProxy( proxy );
		}
		
		return( proxy );
	
voidnotifsLost()

		// should probably check each proxy for validity, but not clear if it's important...
	
public java.util.ListtoProxyList(java.util.Collection objectNames)
Convert a Collection of ObjectName to a List of AMX.

return
a List of AMX from a List of ObjectName.

		final List<AMX>	list	= new ArrayList<AMX>();
		
		for( final ObjectName objectName : objectNames )
		{
			try
			{
				final AMX	proxy	= getProxy( objectName, AMX.class, true );
				list.add( proxy );
			}
			catch( final Exception e )
			{
			    debug( "ProxyFactory.toProxySet: exception for MBean ",
                    objectName, " = ", ExceptionUtil.getRootCause( e ) );
			}
		}
		
		return( list );
	
public java.util.MaptoProxyMap(java.util.Map objectNameMap)
Convert a Map of ObjectName, and convert it to a Map of AMX, with the same keys.

return
a Map of AMX from a Map of ObjectName.

		final Map<String,AMX> resultMap	= new HashMap<String,AMX>();
		
		final Set<String>   keys    = objectNameMap.keySet();
		
		for( final String key : keys )
		{
			final ObjectName	objectName	= objectNameMap.get( key );
			
			try
			{
				final AMX	proxy	= getProxy( objectName, AMX.class, true );
				resultMap.put( key, proxy );
			}
			catch( final Exception e )
			{
			    debug( "ProxyFactory.toProxySet: exception for MBean ",
                    objectName, " = ", ExceptionUtil.getRootCause( e ) );
			}
		}
		
		return( resultMap );
	
public java.util.SettoProxySet(java.util.Set objectNames)
Convert a Set of ObjectName to a Set of AMX.

return
a Set of AMX from a Set of ObjectName.

		final Set<AMX>	s	= new HashSet<AMX>();
		
		for( final ObjectName objectName : objectNames )
		{
			try
			{
				final AMX	proxy	= getProxy( objectName, AMX.class, true );
				assert( ! s.contains( proxy ) );
				s.add( proxy );
			}
			catch( final Exception e )
			{
			    debug( "ProxyFactory.toProxySet: exception for MBean ",
                    objectName, " = ", ExceptionUtil.getRootCause( e ) );
			}
		}
		
		return( s );
	
protected static java.lang.StringtoString(java.lang.Object o)

		return( com.sun.appserv.management.util.stringifier.SmartStringifier.toString( o ) );
	
private static voidwarning(java.lang.Object args)
Because ProxyFactory is used on both client and server, emitting anything to stdout or to the log is unacceptable in some circumstances. Warnings remain available if the AMX-DEBUG system property allows it.

    
                                                               
          
        
    
        debug( args );