FileDocCategorySizeDatePackage
AMXImplBase.javaAPI DocGlassfish v2 API78991Fri May 04 22:23:40 BST 2007com.sun.enterprise.management.support

AMXImplBase

public class AMXImplBase extends MBeanImplBase implements DynamicMBean, NotificationEmitter, com.sun.appserv.management.base.AMX, MBeanRegistration, DelegateOwner
Base class from which all AMX MBeans should derive (but not "must").

Note that even though this base class implements a number of interfaces, the actual MBean interface supplied by the subclass construction-time determines which of these is actually exposed in the MBeanInfo.

A subclass should generally not implement get/setAttribute(s) as these calls are processed in this base class--

If a subclass implements a getter or setter Method it will be invoked automatically. If there is no getter or setter Method, then the getAttributeManually() or setAttributeManually() methods will be invoked; the subclass should implement these methods instead.

Method invocation is also handled automatically. If a Method cannot be found, the invokeManually() method is called; the subclass should implement this method.

Note that various optimizations are possible, but not implemented. These include caching Methods for each Attribute and for operations as well. Careful testing should be done before complicating the code with such optimizations.

Fields Summary
protected static final String
GET
protected static final String
SET
private final Class
mInterface
The interface this MBean implements
private final MBeanInfo
mMBeanInterfaceMBeanInfo
The MBeanInfo
private ObjectName
mCachedContainerObjectName
The parent MBean for this MBean. No need to make volatile; a recompute is OK if one thread doesn't yet see it.
private final boolean
mEmitAttributeChangeNotifications
Flag to enable or disable whether AttributeChangeNotifications are emitted.
private volatile com.sun.appserv.management.base.QueryMgr
mQueryMgr
private volatile com.sun.appserv.management.base.AMX
mSelfProxy
private com.sun.appserv.management.client.ConnectionSource
mConnectionSource
private final Delegate
mSuppliedDelegate
An optional Delegate
private volatile Delegate
mDelegate
private com.sun.enterprise.management.support.AMXAttributeNameMapper
mAttributeNameMapper
private Map
mAttributeInfos
private String
mFullType
private final String
mJ2EEType
protected CoverageInfo
mCoverage
private static final Map
ATTRIBUTE_CLASSES
Maps a j2eeType to a Map which maps an Attribute name to a Class.
private static final MBeanNotificationInfo[]
EMPTY_NOTIFICATIONS
private static final Class[]
GETTER_SIG
Find a getXXX() method that matches the Attribute
protected static final String
GET_PREFIX
protected static final String
OBJECT_NAME_SUFFIX
protected static final String
OBJECT_NAME_MAP_SUFFIX
private static final Set
NO_AUTO_GET
protected static final Set
EMPTY_STRING_SET
private static final Set
AMX_NATIVE_ATTRIBUTES
private static final Set
NOT_SUPERFLUOUS
Constructors Summary
private AMXImplBase(String j2eeTypeIn, Class theInterface, Delegate delegate)
Construct a new implementation that implements the supplied mbeanInterface.

param
j2eeTypeIn (may be null) the j2eeType of this instance
param
theInterface (may be null) the public interface as seen on the client
param
delegate an MBean to which unknown requests are delegated

		super();
        
        mCoverage   = new CoverageInfoDummy();  // will change below...
        
		if ( delegate != null )
		{
			delegate.setOwner( this );
		}
		
		mJ2EEType	= j2eeTypeIn == null ? 
							deduceJ2EEType( getClass() ): j2eeTypeIn;
							
		if ( getAMXDebug() && j2eeTypeIn != null )
		{
			final String	deducedJ2EEType	= deduceJ2EEType( getClass() );
			
			if ( ! deducedJ2EEType.equals( mJ2EEType ) )
			{
				debug( "warning: deducedj2eeType " + deducedJ2EEType +
					" does not match: " + j2eeTypeIn );
			}
		}
		
		mInterface	= theInterface == null ? getInterface( mJ2EEType ) : theInterface;
		if ( mInterface == null )
		{
		    throw new Error( "AMXImplBase: can't get interface for j2eeType " + j2eeTypeIn  );
		}
		
		mCachedContainerObjectName	= null;
		mEmitAttributeChangeNotifications	= true;
		mQueryMgr			= null;
		mSelfProxy				= null;
		
		
		mSuppliedDelegate		= delegate;
		if ( mSuppliedDelegate instanceof DelegateBase )
		{
		    ((DelegateBase)mSuppliedDelegate).setDebugOutput( getDebugOutput() );
		}

        ATTRIBUTE_CLASSES.put( mJ2EEType,
            Collections.synchronizedMap( new HashMap<String,Class>() ) );
			
		// initialization of mDelegate is deferred until later; the supplied delegate
		// may not be in a position to run yet
		mDelegate				= null;
		mAttributeNameMapper	= null;
		
		mAttributeInfos	= null;
		mFullType		= null;
		
		mMBeanInterfaceMBeanInfo	= getInterfaceMBeanInfo( mInterface );
	
protected AMXImplBase(String j2eeType, Delegate delegate)

		this( j2eeType, null, delegate );
	
protected AMXImplBase()

		this( null, null, null );
	
protected AMXImplBase(Delegate delegate)

		this( null, null, delegate );
	
Methods Summary
protected voidaddCustomMappings(com.sun.enterprise.management.support.AMXAttributeNameMapper mapper)
Subclasses may choose to override any Attribute names by adding custom mappings that can't be handled algorithmically.

IMPORTANT: mappings for config delegates should use the same name as found in domain.xml, not the name found in the com.sun.appserv MBean. This is because a switchover to using ConfigAPI directly will only know the names found in domain.xml; we don't want to maintain two sets of custom mappings. The requisite mapping is handled internally, so even though the com.sun.appserv MBean might advertise "Id", using the domain.xml form "id" will work correctly.

Example: super.addCustomMappings( mapper ); mapper.matchName( "MyName", "YourName", "your-name" );

	
protected javax.management.MBeanInfoaddDebugMBeanInfo(javax.management.MBeanInfo origInfo)
Subclass may override, but should call super.addDebugMBeanInfo(). Add any additional debugging stuff to the MBeanInfo.

		final MBeanInfo debugInfo	=
			MBeanInfoConverter.getInstance().convert( AMXDebugStuff.class, null );
	
	    return JMXUtil.mergeMBeanInfos( origInfo, debugInfo );
	
protected java.lang.StringattributeNameToJ2EEType(java.lang.String attributeName)

        String  j2eeType   = null;
        
        if ( isObjectNameAttribute( attributeName ) )
        {
            j2eeType   = StringUtil.stripSuffix( attributeName, OBJECT_NAME_SUFFIX);
        }
        else if ( isObjectNameMapAttribute( attributeName ) )
        {
            j2eeType   = StringUtil.stripSuffix( attributeName, OBJECT_NAME_MAP_SUFFIX);
        }
        
        if ( ! J2EETypes.ALL_STD.contains( j2eeType ) )
        {
            j2eeType    = XTypes.PREFIX + j2eeType;
        }
            
        return j2eeType;
    
protected voidcheckAttributeSupportedInBuild(java.lang.String attributeName)

    
public java.lang.StringcheckInterfaceAgainstDelegate()
Verify that the Delegate's interface is consistent with the MBeanInfo for this MBean. Called by unit test code when AMX-DEBUG is enabled.

        final Delegate  delegate    = getDelegate();
        if ( ! ( getAMXDebug() && delegate != null) )
        {
            return null;
        }
        
        final String NEWLINE    = System.getProperty( "line.separator" );
        final String    result  = null;
        
        final MBeanInfo amxMBeanInfo    = getMBeanInfo();
        
        
        final Map<String,MBeanAttributeInfo> amxAttributeInfos   =
            JMXUtil.attributeInfosToMap( amxMBeanInfo.getAttributes() );
            
        // check that every Attribute in the Delegate exists in AMX
        final MBeanInfo delegateMBeanInfo    = delegate.getMBeanInfo();
        final MBeanAttributeInfo[] delegateAttributeInfos   = delegateMBeanInfo.getAttributes();
        
        //debug( "Delegate MBeanInfo: " + MBeanInfoStringifier.DEFAULT.stringify( delegateMBeanInfo ) );
        
        final StringBuilder builder = new StringBuilder();
        for( final MBeanAttributeInfo delegateAttrInfo : delegateAttributeInfos )
        {
            final String    delegateAttrName    = delegateAttrInfo.getName();
            assert( delegateAttrName != null ) :
                "delegate for " + getJ2EEType() + " supplied an MBeanAttributeInfo with a null name";
            
            try
            {
                final Object value  = delegateGetAttribute( delegateAttrName );
                // OK, we got the value.  Does AMX have it?
                if ( ! amxAttributeInfos.containsKey( delegateAttrName ) )
                {
                    builder.append( "Attribute " + quote( delegateAttrName ) +
                        " exists in Delegate, but not in AMX MBeanInfo" + NEWLINE );
                }
            }
            catch( Exception e )
            {
                builder.append( "Getting Attribute " +
                    quote( delegateAttrName ) +
                    " threw Exception: " + e + NEWLINE );
            }
        }
        
        // return empty string if nothing found
        return builder.length() == 0 ?
            "" : (getObjectName() + NEWLINE + builder.toString());
    
protected voidcheckOperationSupportedInBuild(java.lang.String operationName, java.lang.Object[] args, java.lang.String[] types)

    
protected final voidcheckSuperfluousMethods()

	    final Set<String>   items = getSuperfluousMethods();
	    
	    items.removeAll( getNotSuperfluousMethods() );
	    
	    if ( items.size() != 0 )
	    {
	        final String    LINE_SEP    = System.getProperty( "line.separator" );
	        
            final String msg    = 
            "The following methods in " + getJ2EEType() +
            " are probably superfluous:" + LINE_SEP +
            CollectionUtil.toString( items, LINE_SEP ) + LINE_SEP;
	        
	        AMXDebug.getInstance().getOutput( "AMXImplBase.checkSuperfluousMethods" ).println( msg );
	        logFine( msg );
	    }
	
protected voidclearAttributeInfos()
Subclasses may need to force a refresh.

		mAttributeInfos	= null;
	
public final voidclearCoverageInfo()

        mCoverage.clear();
    
private java.lang.ObjectconvertToClass(java.lang.Object value, java.lang.Class theClass)

		Object	result	= value;
		
		if ( value instanceof String )
		{
			result	= ClassUtil.InstantiateFromString( theClass, (String)value );
		}
		else
		{
			getMBeanLogger().info( "convertToClass: don't know how to convert: " +
				value.getClass().getName() );
		}
		
		return( result );
	
protected booleancoverageActive()

        return ! (mCoverage instanceof CoverageInfoDummy);
    
protected final com.sun.enterprise.management.support.AMXAttributeNameMappercreateAttributeNameMapper()

		final AMXAttributeNameMapper   mapper  = new AMXAttributeNameMapperImpl();
		//mapper.setDebugOutput( getDebugOutput() );
		
		final Set<String>    myAttributeNames    = getMyAttributeMappingCandidates();
		
		final String[]    delegateAttributeNames  =
		    JMXUtil.getAttributeNames( mSuppliedDelegate.getMBeanInfo().getAttributes() );
		
	    mapper.matchNames(
	        GSetUtil.toStringArray( myAttributeNames ), delegateAttributeNames );
		addCustomMappings( mapper );
		
		if ( getAMXDebug() || false )
		{
		    // this is stuff helpful when implementing; leave here
		    // so it can be enabled
		    
    		final Set<String>   missingAttributeNames =
    		    GSetUtil.removeSet( myAttributeNames, mapper.getDerivedNames() );
    		if ( missingAttributeNames.size() != 0 )
    		{
    		    //handleMissingAttributeMappings( missingAttributeNames );
    		}
		
    		final Set<String>   missingOriginals  = mapper.getUnmappedOriginals();
    		missingOriginals.remove( "name" );  // special case, getName() always overides
    		missingOriginals.remove( "Name" );
    		if ( missingOriginals.size() != 0 )
    		{
    		    handleMissingOriginals( missingOriginals );
    		}
		}
		
		return mapper;
	
protected CoverageInfocreateCoverageInfo(boolean enable)

        final CoverageInfo info   = enable ?
            new CoverageInfoImpl( getMBeanInfo() ) : new CoverageInfoDummy();
        
        clearCoverageInfo();
        
        return info;
    
protected java.lang.StringdeduceJ2EEType(java.lang.Class c)

		// it may extend the interface in which case its type is readily available
		String	j2eeType	= (String)ClassUtil.getFieldValue( c, "J2EE_TYPE" );
		if ( j2eeType == null )
		{
			final String	strippedName	= StringUtil.stripSuffix(
												ClassUtil.stripPackageName( c.getName() ), "Impl" );
			
			if ( c.getPackage().getName().endsWith( ".j2ee" ) )
			{
				// j2ee standard type
				j2eeType	= strippedName;
			}
			else
			{
				j2eeType	= "X-" + strippedName;
			}
		}
		
		return( j2eeType );
	
public voiddelegateFailed(java.lang.Throwable t)

		// the delegate has fatally failed
	
protected java.lang.ObjectdelegateGetAttribute(java.lang.String name)

	    assert( name != null );
	    final Delegate  delegate    = getDelegate();
	    assert( delegate != null );
	    
		final Object	value	= delegate.getAttribute( name );
		
		Object result	= value;
		
		if ( value != null )
		{
			Class<?>	attrClass	= getAttributeClass( name );
			
			if ( attrClass != null )
			{
				if ( ClassUtil.IsPrimitiveClass( attrClass ) )
				{
					attrClass	= ClassUtil.PrimitiveClassToObjectClass( attrClass );
				}
					
				if ( ! attrClass.isAssignableFrom( value.getClass() ) )
				{
				    try
				    {
					    result	= convertToClass( value, attrClass );
					}
					catch( Exception e )
					{
					    // OK, there are a few exceptions
					    result  = value;
					}
				}
			}
			else
			{
				getMBeanLogger().warning( "AMXImplBase.delegateGetAttribute: " +
					"Can't find class for attribute: " + name + "=" + value +
					" in object " + getObjectName() );
                
                // add a null mapping
                ATTRIBUTE_CLASSES.get( getJ2EEType() ).put( name, null );
			}
		}
		
		return( result );
	
protected java.lang.ObjectdelegateGetAttributeNoThrow(java.lang.String name)

		try
		{
			final Object	value	= delegateGetAttribute( name );
			
			return( value );
		}
		catch( Exception e )
		{
			throw new RuntimeException( e );
		}
	
protected voiddelegateSetAttribute(java.lang.String name, java.lang.Object value)

		getDelegate().setAttribute( new Attribute( name, value ) );
	
protected voiddelegateSetAttributeNoThrow(java.lang.String name, java.lang.Object value)

		try
		{
			delegateSetAttribute( name, value );
		}
		catch( JMException e )
		{
		    debug( ExceptionUtil.toString( e ) );
			throw new RuntimeException( e );
		}
		catch( RuntimeException ee )
		{
		    debug( ExceptionUtil.toString( ee ) );
			throw ee;
		}
	
public booleanenableCoverageInfo(boolean enable)

        final boolean   wasEnabled    = ! ( mCoverage instanceof CoverageInfoDummy);
        
        if ( enable != wasEnabled )
        {
            mCoverage   = createCoverageInfo( enable );
        }

        return wasEnabled;
    
protected final java.lang.reflect.MethodfindGetter(java.lang.String name)

		  
	   
	
		final String	methodName	= GET + name;
		
		Method	m	= findMethod( methodName, GETTER_SIG );
		if ( m == null )
		{
			m	= findMethod( "is" + name, GETTER_SIG );
		}
		
		return( m );
	
protected final java.lang.reflect.MethodfindMethod(java.lang.String methodName, java.lang.Class[] sig)
Find a method.

param
methodName
param
sig
return
a Method or null if not found

		return( ClassUtil.findMethod( this.getClass(), methodName, sig ) );
	
protected final java.lang.reflect.MethodfindSetter(javax.management.Attribute attr)
Find a setXXX() method that matches the Attribute.

param
attr an Attribute for which a matching setter should be located
return
a Method or null if not found

		final Object	value		= attr.getValue();
		Class		valueClass  = null;
		if ( value == null )
		{
		    final MBeanAttributeInfo    info    = getAttributeInfos().get( attr.getName() );
		    if ( info != null )
		    {
		        try
		        {
		            valueClass  = ClassUtil.getClassFromName( info.getType() );
		        }
		        catch( Exception e )
		        {
		        }
		    }
		}
		else
		{
		    valueClass	= value.getClass();
		}
		
		if ( valueClass == null )
		{
		    return null;
		}
		
		final String	methodName	= SET + attr.getName();
		Class[]			sig			= new Class[]	{ valueClass };
		Method			setter		= findMethod( methodName, sig );
		
		final Class	primitiveClass	= ClassUtil.ObjectClassToPrimitiveClass( valueClass );
		if ( setter == null && primitiveClass != valueClass )
		{
			//trace( "findSetter: retrying for primitive class: " + primitiveClass );
			// the Attribute value is always an object.  But it may be
			// that the setter takes a primitive type.  So for example,
			// the Attribute may contain a value of type Boolean, but the setter
			// may required type boolean
			sig[ 0 ]	= primitiveClass;
			setter		= findMethod( methodName, sig );
		}
		
		return( setter );
	
protected java.lang.ObjectgetAttribute(javax.management.ObjectName objectName, java.lang.String name)

		return( getMBeanServer().getAttribute( objectName, name ) );
	
public java.lang.ObjectgetAttribute(java.lang.String name)
Get an Attribute value, first by looking for a getter method of the correct name and signature, then by looking for a delegate, and finally by calling getAttributeManually(), which a subclass is expected to override.

param
name name of the Attribute
return
value of the Attribute

		mCoverage.attributeWasRead( name );
		
		Object	result	= null;
		
		checkAttributeSupportedInBuild( name );
		
		if ( ! isLegalAttribute( name ) )
		{
		    mCoverage.attributeGetFailure( name );
		    
			debug( "getAttribute: unknown Attribute " + name + ", legal Attributes are: " +
				toString( getAttributeInfos().keySet() ) );
			throw new AttributeNotFoundException( name );
		}
		
		try
		{
			result	= getAttributeInternal( name );
		}
		catch( AttributeNotFoundException e)
		{
		    mCoverage.attributeGetFailure( name );
			throw e;
		}
		catch( Exception e )
		{
		    mCoverage.attributeGetFailure( name );
			throw new AttributeNotFoundException( name );
		}
		
		return( result );
	
protected java.lang.ObjectgetAttributeByMethod(java.lang.String attrName, java.lang.reflect.Method m)
Set an Attribute by invoking the supplied method.

		Object	result	= null;
		
		try
		{
			//trace( "getAttributeByMethod: " + attrName  );
			result	= m.invoke( this, (Object[])null );
		}
		catch( InvocationTargetException e )
		{
			trace( "InvocationTargetException: " + attrName + " by " + m );
			rethrowAttributeNotFound( e, attrName );
		}
		catch( IllegalAccessException e )
		{
			trace( "ILLEGAL ACCESS TO: " + attrName + " by " + m );
			rethrowAttributeNotFound( e, attrName );
		}
		catch( Exception e )
		{
			trace( "Exception: " + attrName + " by " + m );
			rethrowAttributeNotFound( e, attrName );
		}
		
		return( result );
	
private java.lang.ClassgetAttributeClass(java.lang.String attributeName)
Called every time an Attribute is obtained via delegateGetAttribute(), so make sure it's reasonably fast.

        final Map<String,Class> mappings    = ATTRIBUTE_CLASSES.get( getJ2EEType() );
        
        Class theClass = mappings.get( attributeName );
        // initialize only if the class is null and there isn't a mapping for to null
        if ( theClass == null && ! mappings.containsKey( attributeName ) )
        {
            // no need to synchronize; the Map is already so.
            // And if mappings were somehow 'put' twice, that's rare and of no importance
            final MBeanAttributeInfo[]	infos	= getMBeanInfo().getAttributes();
            
            // Map each Attribute to a Class
            for( int i = 0; i < infos.length; ++i )
            {
                final String attrName   = infos[ i ].getName();
                final Class c = ClassUtil.getClassFromName( infos[ i ].getType() );
                mappings.put( attrName, c );
            }
            
            theClass    = mappings.get( attributeName );
		}
        
		return( theClass );
	
protected javax.management.MBeanAttributeInfogetAttributeInfo(java.lang.String name)

		return( (MBeanAttributeInfo)getAttributeInfos().get( name ) );
	
protected synchronized java.util.MapgetAttributeInfos()

		if ( mAttributeInfos == null || ! getMBeanInfoIsInvariant() )
		{
			mAttributeInfos	= JMXUtil.attributeInfosToMap( getMBeanInfo().getAttributes() );
		}
		
		return( mAttributeInfos );
	
protected java.lang.ObjectgetAttributeInternal(java.lang.String name)

		Object	result	= null;
		boolean	handleManually	= false;
		
		// see if a getter exists
		final Method m	= findGetter( name );
		if ( m != null )
		{
			result	= getAttributeByMethod( name, m );
			debug( "getAttribute: " + name + " CALLED GETTER: " + m + " = " + result);
			handleManually	= false;
		}
		else if ( haveDelegate() )
		{
			trace( "getAttribute: " + name + " HAVE DELEGATE " );
				
			if ( getDelegate().supportsAttribute( name ) )
			{
				trace( "getAttribute: " + name + " CALLING DELEGATE " );
				try
				{
					result	= delegateGetAttribute( name );
				}
				catch( Exception e )
				{
					trace( "getAttribute: DELEGATE claims support, but fails: " + name  );
					handleManually	= true;
				}
			}
			else
			{
				trace( "getAttribute: " + name + " DELEGATE DOES NOT SUPPORT " );
				handleManually	= true;
			}
		}
		else
		{
			handleManually	= true;
		}
		
		if ( handleManually )
		{
			trace( "getAttribute: handle manually: " + name );
			try
			{
				result	= getAttributeManually( name );
			}
			catch( AttributeNotFoundException e )
			{
				trace( "getAttribute: " + name + " NOT FOUND " );
				throw e;
			}
		}
		
		return( result );
	
protected java.lang.ObjectgetAttributeManually(java.lang.String attributeName)
Subclasses should override this to handle getAttribute( attrName ). It will be called if no appropriate getter is found.

It generically handles all ObjectName() and ObjectNameMap Attributes.

	    Object  result  = null;
	    
	    AMXDebug.getInstance().getOutput( "getAttributeManually" ).println(
	        attributeName + " on " + getObjectName() );
	        
	    if ( isObjectNameAttribute( attributeName ) )
	    {
	        final String    j2eeType    = attributeNameToJ2EEType( attributeName );
	        debug( "getAttributeManually: attributeName " + attributeName + " => j2eeType " + j2eeType );
	        result  = getContaineeObjectName( j2eeType );
	    }
	    else if ( isObjectNameMapAttribute( attributeName  ) )
	    {
	        final String    j2eeType    = attributeNameToJ2EEType( attributeName );
	        debug( "invokeManually:  attributeName " + attributeName + " => j2eeType " + j2eeType );
	        result  = getContaineeObjectNameMap( j2eeType );
	    }
		else
		{
		    throw new AttributeNotFoundException( attributeName );
		}
		return result;
	
protected com.sun.enterprise.management.support.AMXAttributeNameMappergetAttributeNameMapper()

		return( mAttributeNameMapper );
	
public final java.lang.String[]getAttributeNames()

		return( GSetUtil.toStringArray( getAttributeInfos().keySet() ) );
	
protected java.lang.ObjectgetAttributeNoThrow(java.lang.String name)

		Object	result	= null;
		
		try
		{
			result	= getAttribute( name );
		}
		catch( Exception e )
		{
			throw new RuntimeException( new ThrowableMapper( e ).map() );
		}
		return( result );
	
protected java.lang.StringgetAttributeType(java.lang.String attrName)

		final MBeanAttributeInfo	info	=
			JMXUtil.getMBeanAttributeInfo( getMBeanInfo(), attrName );
		
		return( info.getType() );
	
protected javax.management.AttributeListgetAttributes(javax.management.ObjectName objectName, java.lang.String[] names)

		return( getMBeanServer().getAttributes( objectName, names ) );
	
public javax.management.AttributeListgetAttributes(java.lang.String[] names)
Bulk get. Note that is is important for this implementation to call getAttribute() for each name so that each may be processed appropriately; some Attributes may be in this MBean itself, and some may reside in a {@link Delegate}.

param
names array of Attribute names
return
AttributeList of Attributes successfully fetched

		trace( "AMXImplBase.getAttributes: " + SmartStringifier.toString( names ) );
		//trace( "AMXImplBase.getAttributes: delegate class = " + getDelegate().getClass().getName() );
		
		final AttributeList	attrs	= new AttributeList();
		
		for( int i = 0; i < names.length; ++i )
		{
			try
			{
				trace( "%%% calling getAttribute: " + names[ i ] + " on " + getObjectName() );
				final Object value	= getAttribute( names[ i ] );
				attrs.add( new Attribute( names[ i ], value ) );
			}
			catch( Exception e )
			{
				trace( "### AttributeNotFoundException: " + names[ i ] );
				// ignore, as per spec
			}
		}
		return( attrs );
	
public java.util.SetgetByNameContaineeObjectNameSet(java.util.Set j2eeTypes, java.lang.String name)

		final Iterator	iter	= getContaineeObjectNameSet( j2eeTypes ).iterator();
		final Set<ObjectName>		result	= new HashSet<ObjectName>();
		
		while ( iter.hasNext() )
		{
			final ObjectName	objectName	= (ObjectName)iter.next();
			
			if ( Util.getName( objectName ).equals( name ) )
			{
				result.add( objectName );
			}
		}
		return( result );
	
protected java.lang.StringgetChildJ2EEType()

		final Set<String>	types	= getChildJ2EETypes();
		if ( types.size() != 1 )
		{
			debug( "getChildJ2EEType failing on: ", getObjectName(),
				", got this many children: ", types.size() );
			throw new IllegalArgumentException(
						SmartStringifier.toString( types ) );
		}
		
		return( GSetUtil.getSingleton( types ) );
	
protected java.util.SetgetChildJ2EETypes()

		return( getSelfTypeInfo().getChildJ2EETypes() );
	
protected final java.lang.String[]getChildNames()

return
String[] containing names of all children of specified type

		return( getContaineeNamesOfType( getChildJ2EEType() ) );
	
public java.util.SetgetContaineeJ2EETypes()

		if ( ! isContainer() )
		{
			final Exception	e	=
				new AttributeNotFoundException( "ContaineeJ2EETypes" );
			
			throw new RuntimeException( e );
		}
		
		final Set<String>	fauxTypes		= getFauxChildTypes();
		final Set<String>	officialTypes	= getSelfTypeInfo().getContaineeJ2EETypes();

		return( fauxTypes.size() == 0 ? officialTypes : GSetUtil.newSet( fauxTypes, officialTypes ) );
	
protected final java.lang.String[]getContaineeNamesOfType(java.lang.String j2eeType)

return
String[] containing names of all children of specified type

		final Set<ObjectName> objectNames	= getContaineeObjectNameSet( j2eeType );
				
		return( getNamePropertyValues( objectNames ) );
	
public final javax.management.ObjectNamegetContaineeObjectName(java.lang.String j2eeType)
There must be 0 or 1 children of the specified type or an exception will be thrown.

return
ObjectName for child of specified type

		final Set<ObjectName>	children	= getContaineeObjectNameSet( j2eeType );
		
		ObjectName	result	= null;
		
		if ( children.size() == 1 )
		{
			result	= GSetUtil.getSingleton( children );
		}
		else if ( children.size() == 0 )
		{
			trace( "AMXImplBase.getContaineeObjectName: no children of type " + j2eeType );
			result	= null;
		}
		else
		{
			trace( "AMXImplBase.getContaineeObjectName: " + j2eeType + " impossible");
			impossible( new UnsupportedOperationException( "getContaineeObjectName" ) );
		}
				
		return( result );
	
public final javax.management.ObjectNamegetContaineeObjectName(java.lang.String j2eeType, java.lang.String name)

		final Set<ObjectName>	candidates	= getContaineeObjectNameSet( j2eeType );
		
		final Set<ObjectName> matching	=
		    JMXUtil.findByProperty( candidates, NAME_KEY, name );
		
		final ObjectName	result	= (matching.size() == 0) ?
			null : GSetUtil.getSingleton( matching );
		
		return( result );
	
public final java.util.MapgetContaineeObjectNameMap(java.lang.String j2eeType)

		if ( ! getContaineeJ2EETypes().contains( j2eeType ) )
		{
			throw new IllegalArgumentException( getObjectName() +
				" does not contain j2eeType: " + j2eeType );
		}

		final Set<ObjectName>	objectNames	= getContaineeObjectNameSet( j2eeType );
		
		Map<String,ObjectName>	result	= Collections.emptyMap();
		
		if ( objectNames.size() != 0 )
		{
			result	= Util.createObjectNameMap( objectNames );
		}
		assert( result.keySet().size() == objectNames.size() );
		
		return( result );
	
public final java.util.SetgetContaineeObjectNameSet()
Get the names of all child objects, which may be of more than one type.

return
Set containing all child ObjectNames

		final String		selfType	= getSelfJ2EEType();
		
		final Set<ObjectName>	allChildren	= new HashSet<ObjectName>();
		
		final Set<String>	containedTypes	=
			GSetUtil.newSet( getChildJ2EETypes(), getContaineeJ2EETypes() );
		
		for( final String	childJ2eeType : containedTypes )
		{
			final Set<ObjectName>	childrenOfType	= getContaineeObjectNameSet( childJ2eeType );
			
			allChildren.addAll( childrenOfType );
		}
		
		return( allChildren );
	
public java.util.SetgetContaineeObjectNameSet(java.lang.String childJ2EEType)

		final TypeInfos	infos	= TypeInfos.getInstance();
		final TypeInfo	info	= infos.getInfo( childJ2EEType );
		
		String	props	= Util.makeJ2EETypeProp( childJ2EEType );
		
		QueryExp expr	= null;
		if ( info.isSubType() )
		{
			final String	selfFullType	= getFullType();
			final String	childFullType	= makeType( selfFullType, childJ2EEType );
			
			final String	selfProps	= Util.getFullTypeProps( getObjectName(), getFullType() );
			
			props	= Util.concatenateProps( props, selfProps );
			expr	= Query.eq(Query.attr( AMXAttributes.ATTR_FULL_TYPE ), Query.value( childFullType ));
		}
		else
		{
			// not a sub-type; nothing else to add
			expr	= null;
		}
		
        final ObjectName	pattern	=
         	JMXUtil.newObjectNamePattern( getObjectName().getDomain(), props );
		final Set<ObjectName>	candidates	= JMXUtil.queryNames( getMBeanServer(), pattern, expr);
		
		return( candidates );
	
public final java.util.SetgetContaineeObjectNameSet(java.util.Set j2eeTypes)

		final Set<ObjectName>	all	= new HashSet<ObjectName>();

        final Set<String>   actualTypes =
            j2eeTypes == null ? getContaineeJ2EETypes() : j2eeTypes;
            
		for( final String j2eeType : actualTypes )
		{
			final Set<ObjectName>	objectNames	= getContaineeObjectNameSet( j2eeType );
			
			all.addAll( objectNames );
		}
				
		return( all );
	
public final com.sun.appserv.management.base.ContainergetContainer()

		final ObjectName	objectName	= getContainerObjectName( getObjectName() );
		
		return(  getProxyFactory().getProxy( objectName, Container.class) );
	
public final javax.management.ObjectNamegetContainerObjectName()

		return( getContainerObjectName( getObjectName() ) );
	
protected synchronized javax.management.ObjectNamegetContainerObjectName(javax.management.ObjectName selfObjectName)

		if ( mCachedContainerObjectName == null &&
			! getSelfJ2EEType().equals( XTypes.DOMAIN_ROOT ) )
		{
			try
			{
				mCachedContainerObjectName	=
					getObjectNames().getContainerObjectName( getMBeanServer(), selfObjectName );
			}
			catch( InstanceNotFoundException e )
			{
			    debug( ExceptionUtil.getStackTrace( e ) );
				throw new RuntimeException( e );
			}
		}

		return( mCachedContainerObjectName );
	
public final CoverageInfogetCoverageInfo()

        mCoverage.setMBeanInfo( getMBeanInfo() );
        return mCoverage;
    
protected java.lang.StringgetDebugID()

        return ClassUtil.stripPackageName( this.getClass().getName() );
    
public DelegategetDelegate()

		return( mDelegate );
	
protected java.lang.ObjectgetDelegateProxy(java.lang.Class theInterface)

		return( DelegateInvocationHandler.newProxyInstance( getDelegate(), theInterface ) );
	
public final com.sun.appserv.management.DomainRootgetDomainRoot()

		return( getProxyFactory().getDomainRoot() );
	
public final javax.management.ObjectNamegetDomainRootObjectName()

		return( Util.getObjectName( getDomainRoot() ) );
	
public com.sun.appserv.management.base.ContainergetFactoryContainer()

		return( Container.class.cast( getSelf() ) );
	
protected java.util.SetgetFauxChildTypes()
Certain special cases are present (eg standalone ejb/web modules) where a parent as described by the FullType (TypeInfos) does not exist. In this case, the actual parent must contain these items.


			         		          		         	 
		 
	
	
		return( EMPTY_STRING_SET );
	
protected java.util.SetgetFauxContaineeObjectNameSet(java.lang.String childJ2EEType, java.lang.String nullProps)

		assert getFauxChildTypes().contains( childJ2EEType );
		
		final String selfProp	= Util.makeProp( getJ2EEType(), getSelfName() );
		
		final String	childJ2EETypeProp	= Util.makeJ2EETypeProp( childJ2EEType );
		final String	props	= Util.concatenateProps( selfProp, nullProps, childJ2EETypeProp );
		
		final Set<AMX>	candidates	= getQueryMgr().queryPropsSet( props );
		final Set<ObjectName>	objectNames	= Util.toObjectNames( candidates );
		
		return( objectNames );
	
protected static java.lang.StringgetFullType(javax.management.ObjectName partialSelfObjectName)

param
partialSelfObjectName the ObjectName, lacking the type property
return
the fully qualified type as required by AMX.FULL_TYPE

		final String	selfJ2EEType	= Util.getJ2EEType( partialSelfObjectName );
		
		final TypeInfos	typeInfos	= TypeInfos.getInstance();
		final TypeInfo	info	= typeInfos.getInfo( selfJ2EEType );
		
		final String[]	chain	= typeInfos.getJ2EETypeChain( partialSelfObjectName );
		
		final String	fullType	= ArrayStringifier.stringify( chain, "." );
		
		return( fullType );
	
public final java.lang.StringgetFullType()

		assert( mFullType != null ) : "******************************************************";
		return( mFullType );
	
public java.lang.StringgetGroup()
Classes of MBeans should override this.

		return( GROUP_OTHER );
	
public java.lang.StringgetImplString(boolean verbose)

	    final String NEWLINE    = System.getProperty( "line.separator" );
	    
	    String s = this.getClass().getName() + NEWLINE +
	        MBeanInfoStringifier.DEFAULT.stringify( getMBeanInfo() ) + NEWLINE;
	    
	    if ( verbose )
	    {
	        final AttributeList attrs   = getAttributes( getAttributeNames() );
	        final Map<String,Object>    m   = JMXUtil.attributeListToValueMap( attrs );
	        s   = NEWLINE + s + MapUtil.toString( m, NEWLINE + NEWLINE ) + NEWLINE;
	    }
	    
	    return s;
	
protected java.lang.ClassgetInterface(java.lang.String j2eeType)

	
		 
	    
	
		return( AllTypesMapper.getInstance().getInterfaceForType( j2eeType ) );
	
public final java.lang.ClassgetInterface()

		return( mInterface );
	
private synchronized javax.management.MBeanInfogetInterfaceMBeanInfo(java.lang.Class theInterface)

		MBeanInfo info	= TypeInfos.getInstance().getMBeanInfoForInterface( theInterface );
        if ( false || getAMXDebug() )
        {
            debug( "Interface " + mInterface.getName() +
                " has MBeanInfo:\n" +
                MBeanInfoStringifier.DEFAULT.stringify( info ) );
                
            info   = addDebugMBeanInfo( info );
        }
        
        return info;
    
public final java.lang.StringgetInterfaceName()

		return( getInterface().getName() );
	
public java.lang.StringgetJ2EEType()

		return( Util.getJ2EEType( getObjectName() ) );
	
protected java.lang.StringgetKeyProperty(java.lang.String key)
Get the value of a property within this MBean's ObjectName.

return
the value of the specified property, or null if not found.

		return( getObjectName().getKeyProperty( key ) );
	
public final LoaderMBeangetLoader()

		return( Loader.getLoader( getMBeanServer() ) );
	
public java.util.logging.LoggergetLogger()

		return( getMBeanLogger() );
	
public javax.management.MBeanInfogetMBeanInfo()
By default, the MBeanInfo is derived once from the MBean interface. Then certain items are removed, and optional debugging is added. This method should not cache the MBeanInfo because it may change dynamically. The client-side proxies cache the MBeanInfo if getMBeanInfoIsInvariant() returns true.

		MBeanInfo	mbeanInfo	= null;
	
		try
		{
			mbeanInfo	= getMBeanInfoFromInterface();
			
			final MBeanNotificationInfo[]    notifs  = getNotificationInfo();
			if ( notifs != null && notifs.length != 0 )
			{
			    mbeanInfo   = JMXUtil.addNotificationInfos( mbeanInfo, notifs );
			}
		}
		catch( Exception e )
		{
			e.printStackTrace();
			throw new RuntimeException( e );
		}
		
		mbeanInfo   = removeUnsupportedMBeanInfo( mbeanInfo );
		mbeanInfo   = modifyMBeanInfo( mbeanInfo );
		
		return( mbeanInfo );
	
protected javax.management.MBeanInfogetMBeanInfoFromInterface()

		return( mMBeanInterfaceMBeanInfo );
	
public booleangetMBeanInfoIsInvariant()
Almost all MBeans don't change their MBeanInfo once it's created, making it possible to cache it on the client side.

		return( true );
	
protected com.sun.appserv.management.client.ConnectionSourcegetMBeanServerConnectionSource()

		return( mConnectionSource );
	
public java.util.MapgetMultiContaineeObjectNameMap(java.util.Set j2eeTypesIn)

		// if Set is null, it means all types
		final Set<String>	j2eeTypes	= j2eeTypesIn == null ?
			getContaineeJ2EETypes() : j2eeTypesIn;
			
		final Map<String,Map<String,ObjectName>>	m	=
		    new HashMap<String,Map<String,ObjectName>>();
		
		for( final String j2eeType : j2eeTypes )
		{
			final Map<String,ObjectName>	nameMap	= getContaineeObjectNameMap( j2eeType );
			if ( nameMap.keySet().size() != 0 )
			{
				m.put( j2eeType, nameMap );
			}
		}
		
		return( m );
	
private java.util.SetgetMyAttributeMappingCandidates()
An optimization to not bother with all the names that are native to AMX and not mapped to a Delegate Attribute.

	    
	
			          		         	 
	     
    
    
		final Set<String>    candidates    = GSetUtil.newSet( getAttributeNames() );
		
		candidates.removeAll( AMX_NATIVE_ATTRIBUTES );
		
		// now remove all Attributes that end appropriately
		final Set<String>   toRemove    = new HashSet<String>();
		for( final String name : candidates )
		{
		    if ( name.endsWith( "ObjectNameMap" ) ||
		         name.endsWith( "ObjectNameSet" ) ||
		         name.endsWith( "ObjectName" ) ||
		         name.endsWith( "Stats" )
		        )
		    {
		        toRemove.add( name );
		    }
		}
		
		candidates.removeAll( toRemove );
		
		return candidates;
    
public java.lang.StringgetName()

		return( Util.getName( getObjectName() ) );
	
protected final java.lang.String[]getNamePropertyValues(java.util.Set objectNameSet)
Extract the value of the "name" key for each ObjectName and place it into an array.

return
String[] containing values of "name" property, one for each ObjectName

		return( JMXUtil.getKeyProperty( NAME_KEY, objectNameSet ) );
	
protected final javax.management.ObjectNamegetNamedChildObjectName(java.lang.String name)

		trace( "\nAMXImplBase.getNamedContaineeObjectName: " +
			"Looking for " + name + " in " + quote( getObjectName() ) );
		
		return( getContaineeObjectName( getChildJ2EEType(), name ) );
	
protected java.util.SetgetNotSuperfluousMethods()

return
any non-superflous methods that are the exception to the default assumptions

            
    
                            
		 
	
	
	    return NOT_SUPERFLUOUS;
	
public javax.management.MBeanNotificationInfo[]getNotificationInfo()
Defined by NotificationBroadcaster.

return
an empty array Subclass may wish to override this.

	
 	 	       	    		    		      	
		 
	
	
		return( EMPTY_NOTIFICATIONS );
	
public final javax.management.ObjectNamegetObjectNamePattern()
Use the ObjectName with which this MBean was registered in combination with its j2eeType and its parent keys to determine the ObjectName pattern that uniquely identifies it.

		final ObjectName	selfObjectName	= getObjectName();
		final Set<String>	requiredKeys	= Util.getPatternKeys( getFullType() );
		
		final String		requiredProps	= JMXUtil.getProps( selfObjectName, requiredKeys, true );
		final ObjectName	pat	= Util.newObjectNamePattern( selfObjectName.getDomain(), requiredProps );
		
		return( pat );
	
protected com.sun.enterprise.management.support.ObjectNamesgetObjectNames()

    	return ObjectNames.getInstance( getJMXDomain() );
    
protected booleangetOffline()

	    return BootUtil.getInstance().getOffline();
	
public com.sun.enterprise.management.support.oldconfig.OldConfigProxiesgetOldConfigProxies()

		return( OldConfigProxies.getInstance( getMBeanServer() ) );
	
protected javax.management.ObjectNamegetOnlyChildObjectName()
Get the name of a child MBean, assuming there is only one kind, and there is never more than one.

return
ObjectName of child, or null if not found

		return( getContaineeObjectName( getChildJ2EEType() ) );
	
protected javax.management.ObjectNamegetProgenyObjectName(java.lang.String j2eeType, java.lang.String name)
Our container is the one that actually holds the MBeans we created. Ask it for the ObjectName.

		final Container	container	= getContainer();
		
		final AMX	containee	= container.getContainee( j2eeType, name );
		if ( containee == null )
		{
			throw new IllegalArgumentException( "Not containee found: " + j2eeType + "=" + name );
		}
		
		return( Util.getObjectName( containee ) );
	
public TgetProxy(javax.management.ObjectName objectName, java.lang.Class theClass)

	    return getProxyFactory().getProxy( objectName, theClass );
	
public com.sun.appserv.management.client.ProxyFactorygetProxyFactory()

		assert( mConnectionSource != null );
		return( ProxyFactory.getInstance( mConnectionSource, true ) );
	
protected final com.sun.appserv.management.base.QueryMgrgetQueryMgr()

        // this relies on mQueryMgr being 'volatile'
		if ( mQueryMgr != null )
            return mQueryMgr;
        
        final ObjectName	objectName	= getQueryMgrObjectName();
        if ( objectName != null )
        {
            // it doesn't matter if two thread do this; the same proxy will be returned.
            mQueryMgr	= getProxyFactory().getProxy( objectName, QueryMgr.class);
        }
    
		return( mQueryMgr );
	
public javax.management.ObjectNamegetQueryMgrObjectName()
The QueryMgr is a special-case; all the other types rely on it.

		ObjectName	objectName	= null;
		
		if ( mQueryMgr != null )
		{
			// do it the fast way if we already have the proxy
			objectName	= Util.getObjectName( mQueryMgr );
		}
		else
		{
			final MBeanServer	server		= getMBeanServer();
			final String		domainName	= getObjectName().getDomain();
			
			objectName	= QueryMgrImpl.querySingletonJ2EETypeObjectName( server,
							domainName, QueryMgr.J2EE_TYPE );
		}
	
		assert( objectName != null ) : "getQueryMgrObjectName failed";
		return( objectName );
	
protected final synchronized com.sun.appserv.management.base.AMXgetSelf()

		if ( mSelfProxy == null )
		{
			final ObjectName	selfObjectName	= getObjectName();
			assert( selfObjectName != null );
			
			mSelfProxy	= getProxyFactory().getProxy( selfObjectName, AMX.class );
			assert( mSelfProxy != null );
		}
		return( mSelfProxy );
	
protected java.lang.StringgetSelfJ2EEType()

		return( mJ2EEType );
	
protected java.lang.StringgetSelfName()

		return( Util.getName( getObjectName() ) );
	
protected com.sun.enterprise.management.support.TypeInfogetSelfTypeInfo()

		return( getTypeInfo( getSelfJ2EEType() ) );
	
protected java.util.SetgetSuperfluousMethods()

return
all method names that appear superfluous

	    final Set<String>   items   = new HashSet<String>();
	    
	    final Method[]  methods = this.getClass().getMethods();
	    for( final Method m : methods )
	    {
            if ( JMXUtil.isGetter( m ) )
            {
	            final String    name    = m.getName();
	        
                final String attributeName  = StringUtil.stripPrefix( name, GET );
                if ( isObjectNameAttribute( attributeName ) ||
                    isObjectNameMapAttribute( attributeName ) )
                {
                    items.add( name );
                }
            }
	    }
	    
	    items.removeAll( NOT_SUPERFLUOUS );
	    
	    return items;
	
protected com.sun.enterprise.management.support.TypeInfogetTypeInfo(java.lang.String j2eeType)

		return( TypeInfos.getInstance().getInfo( j2eeType ) );
	
protected booleangetterNameMatches(java.lang.String operationName, java.lang.String suffix)

        return operationNameMatches( operationName, GET_PREFIX, suffix );
    
protected voidhandleException(java.lang.Exception e)

		final ThrowableMapper	mapper	= new ThrowableMapper( e );
		final Throwable			mapped	= mapper.map();
		
		if ( mapped instanceof ReflectionException )
		{
			throw (ReflectionException)mapped;
		}
		else if ( mapped instanceof MBeanException )
		{
			throw (MBeanException)mapped;
		}
		else if ( ! (mapped instanceof Exception) )
		{
			// wrap the Throwable in an Exception
			final Exception	wrapper	= new Exception( mapped );
			throw new MBeanException( wrapper );
		}
		else
		{
			throw new MBeanException( (Exception)mapped );
		}
	
protected voidhandleGetAttributeException(java.lang.Exception e)

		if ( e instanceof AttributeNotFoundException )
		{
			// AttributeNotFoundException can never contain anything non-standard
			throw (AttributeNotFoundException)e;
		}
		else
		{
			handleException( e );
		}
	
protected voidhandleInvokeThrowable(java.lang.Exception e)

		handleException( e );
	
protected voidhandleMissingAttributeMappings(java.util.Set missing)
Mapping of Attributes names is done. But some of our Attributes don't map to anything in the Delegate.

		if ( missing.size() != 0 )
		{
    		final String msg    = getJ2EEType() +
    		    ": AMX Attributes have no corresponding delegate Attribute: " +
    		    CollectionUtil.toString( missing, ", " );
    		    
	        AMXDebug.getInstance().getOutput( "AMXImplBase.handleMissingAttributeMappings" ).println( msg );
		    logInfo( msg );
        }
	
protected voidhandleMissingOriginals(java.util.Set missingOriginals)
Mapping of Attributes names is done. But there are still names in the Delegate which don't map to anything in this AMX MBean. This may be OK; some delegates contain a bunch of extra stuff not used by AMX.

		if ( missingOriginals.size() != 0 )
		{
    		final String msg    = getJ2EEType() +
    		    ": Delegate Attributes have no matching AMX Attribute: " +
    		    CollectionUtil.toString( missingOriginals, ", " ) +
    		    "--(this may or may not be an error; if necessary override handleMissingOriginals()";
    		
	        AMXDebug.getInstance().getOutput( "AMXImplBase.handleMissingOriginals" ).println( msg );
		    logFine( msg );
        }
	
protected static booleanhasElementName(java.lang.Class mbeanInterface)

		return( NamedConfigElement.class.isAssignableFrom( mbeanInterface ) );
	
protected booleanhaveDelegate()

		return( getDelegate() != null );
	
protected voidimplCheck()

		final boolean	isContainer	= isContainer();
		final String	j2eeType	= getSelfJ2EEType();
		final TypeInfo	selfInfo	= TypeInfos.getInstance().getInfo( j2eeType );
		
		final Set<String>	nonChildren	= selfInfo.getNonChildJ2EETypes();
		final Set<String>	children	= selfInfo.getChildJ2EETypes();
		
		if ( isContainer )
		{
			assert( nonChildren.size() != 0 || children.size() != 0 ) :
				"ERROR: is Container but contains no children or containees " + j2eeType;
		}
		else
		{
			assert( nonChildren.size() == 0 ) :
				"ERROR: not a Container: " + j2eeType + " but contains types: " + toString( nonChildren );
				
			assert( children.size() == 0 ) :
				"ERROR: not a Container: " + j2eeType + " but contains children: " + toString( children );
		}
		
	    checkSuperfluousMethods();
	
protected final voidimpossible(java.lang.Throwable t)
The impossible has happened.

		logSevere( "AMXImplBase.impossible: " + t.getMessage() );
		assert( false );
		throw new RuntimeException( t );
	
public final java.lang.Objectinvoke(java.lang.String operationName, java.lang.Object[] args, java.lang.String[] types)
Generic handling of invoke(). Converts the types[] to a Class[], then attempts to locate a suitable Method. If a suitable Method is found, it is invoked. If not found the subclass is expected to handle it in invokeManually();

	    mCoverage.operationWasInvoked( operationName, types );
	    
		Object	result	= null;
		boolean	unimplemented	= false;
		
		try
		{
		    checkOperationSupportedInBuild( operationName, args, types );
		
			final Class[]	signature	= ClassUtil.signatureFromClassnames( types );
			final Method	m	= findMethod( operationName, signature );
			if ( m != null )
			{
				debugMethod( "invoking method: " + operationName, args );
				result	= m.invoke( this, args );
			}
			else if ( haveDelegate() &&
				getDelegate().supportsOperation( operationName, args, types ) )
			{
				debug( "AMXImplBase.invoke: calling delegate for ", operationName );
				result	= getDelegate().invoke( operationName, args, types );

			}
			else
			{
				result	= invokeManually( operationName, args, types );
			}
		}
		catch( Exception e )
		{
	        mCoverage.operationFailed( operationName, types );
		    debug( ExceptionUtil.toString( e ) );
			handleInvokeThrowable( e );
		}
		
		return( result );
	
protected java.lang.ObjectinvokeManually(java.lang.String operationName, java.lang.Object[] args, java.lang.String[] types)
An operation is being invoked manually, meaning that it is missing as a method. invokeManually() will be called only if no appropriate Method is found.

Subclasses may override this to handle invoke(), though usually it's just easier to write the appropriate method directly, which will be found and called if present.

	    final int   numArgs = args == null ? 0 : args.length;
	    
	    Object  result  = null;
	    
	    boolean handled = false;
	    
	    final boolean   ALLOW_GETTERS   = true;
	    
	    if ( ALLOW_GETTERS &&
	        numArgs == 0 &&
	        operationName.startsWith( GET )  )
	    {
    	    final String    attributeName   = StringUtil.stripPrefix( operationName, GET );
    	    
	        if ( getAttributeInfos().get( attributeName ) != null )
	        {
    	        result  = getAttribute( attributeName );
    	        handled = true;
	        }
	    }
	    else if ( operationName.equals( "toString" ) && numArgs == 0 )
	    {
	        result  = toString();
	    }
	    
	    if ( ! handled )
	    {
    	    debugMethod( operationName, args );
    		throw new NoSuchMethodException( "no operation " + operationName +
    		    toString( types ) + " in " + getObjectName() );
		}
		
		return result;
	
private booleanisContainer()

		return( Container.class.isAssignableFrom( getInterface() ) );
	
public booleanisDAS()

	    return getLoader().isDAS();
	
protected booleanisLegalAttribute(java.lang.String name)

		return( getAttributeInfos().keySet().contains( name ) );
	
protected booleanisObjectNameAttribute(java.lang.String attributeName)

           
        
      
    
        return attributeName.endsWith( OBJECT_NAME_SUFFIX ) &&
            ! NO_AUTO_GET.contains( attributeName );
    
protected booleanisObjectNameGetter(java.lang.String operationName, java.lang.Object[] args, java.lang.String[] types)

        final int   numArgs = args == null ? 0 : args.length;
        return numArgs == 0 && isObjectNameGetter( operationName );
    
protected booleanisObjectNameGetter(java.lang.String operationName)

        return getterNameMatches( operationName, OBJECT_NAME_SUFFIX );
    
protected booleanisObjectNameMapAttribute(java.lang.String attributeName)

        return attributeName.endsWith( OBJECT_NAME_MAP_SUFFIX ) &&
            ! NO_AUTO_GET.contains( attributeName );
    
protected booleanisObjectNameMapGetter(java.lang.String operationName, java.lang.Object[] args, java.lang.String[] types)

        final int   numArgs = args == null ? 0 : args.length;
        return numArgs == 0 && isObjectNameMapGetter( operationName );
    
protected booleanisObjectNameMapGetter(java.lang.String operationName)

        return getterNameMatches( operationName, OBJECT_NAME_MAP_SUFFIX );
    
protected booleanisOfflineCapable(com.sun.enterprise.management.support.TypeInfo childInfo)

	    final Class c   = childInfo.getInterface();
	    
	    return  AMXConfig.class.isAssignableFrom( c ) || 
	            Utility.class.isAssignableFrom( c ) ||
	            c == DomainRoot.class;
	
protected booleanisReadOnlyAttribute(java.lang.String name)

		return( ! getAttributeInfo( name ).isWritable() );
	
protected static booleanisSingletonMBean(java.lang.Class mbeanInterface)

		return( Singleton.class.isAssignableFrom( mbeanInterface ) );
	
protected static booleanisUtilityMBean(java.lang.Class mbeanInterface)

		return( Utility.class.isAssignableFrom( mbeanInterface ) );
	
protected java.lang.Stringj2eeTypeToSimpleClassname(java.lang.String j2eeType)

        return StringUtil.stripPrefix( j2eeType, XTypes.PREFIX );
    
private static java.lang.StringmakeType(java.lang.String parentType, java.lang.String subType)

param
parentType
param
subType

		String	result	= null;
		
		if ( parentType == null || parentType.length() == 0 )
		{
			result	= subType;
		}
		else
		{
			result	= parentType + AMX.FULL_TYPE_DELIM + subType;
		}

		return( result  );
	
protected javax.management.MBeanInfomodifyMBeanInfo(javax.management.MBeanInfo info)
Hook for subclass to modify anything in MBeanInfo.

		return( info );
	
protected booleanoperationNameMatches(java.lang.String operationName, java.lang.String prefix, java.lang.String suffix)

    
         
    
          
          
           
    
        return operationName.startsWith( prefix ) &&
	        operationName.endsWith( suffix );
    
protected java.lang.StringoperationNameToJ2EEType(java.lang.String operationName)

        String  j2eeType   = null;
        
        if ( isObjectNameGetter( operationName ) )
        {
            j2eeType   =
                StringUtil.stripPrefixAndSuffix( operationName, GET_PREFIX, OBJECT_NAME_SUFFIX);
        }
        else if ( isObjectNameMapGetter( operationName ) )
        {
            j2eeType   =
                StringUtil.stripPrefixAndSuffix( operationName, GET_PREFIX, OBJECT_NAME_MAP_SUFFIX);
        }
        
        if ( ! J2EETypes.ALL_STD.contains( j2eeType ) )
        {
            j2eeType    = XTypes.PREFIX + j2eeType;
        }
            
        return j2eeType;
    
public voidpostDeregister()

	    super.postDeregister();
	    
	    postDeregisterHook();
	
protected voidpostDeregisterHook()

	
public final synchronized voidpostRegister(java.lang.Boolean registrationSucceeded)

		super.postRegister( registrationSucceeded );
		
		postRegisterHook( registrationSucceeded );
	
public voidpostRegisterHook(java.lang.Boolean registrationSucceeded)

	    if ( registrationSucceeded.booleanValue() )
		{
		    enableCoverageInfo( getAMXDebug() );
		}
	
public final voidpreDeregister()

	    super.preDeregister();
	    
	    preDeregisterHook();
	
protected voidpreDeregisterHook()

	    unregisterMisc();
		unregisterSelfMgrChildren( );
	
public final synchronized javax.management.ObjectNamepreRegister(javax.management.MBeanServer server, javax.management.ObjectName nameIn)

		final ObjectName	nameFromSuper	= super.preRegister( server, nameIn );

		mConnectionSource	= new MBeanServerConnectionSource( server );
		
		if ( mSuppliedDelegate != null )
		{
			mDelegate	= wrapSuppliedDelegate( mSuppliedDelegate );
		}
        
		mSelfObjectName	= preRegisterModifyName( server, nameFromSuper );
		
		if ( getAMXDebug() )
		{
		    implCheck();
		}
		
		mSelfObjectName = preRegisterHook( mSelfObjectName );
		
		registerSpecialContainees();
		
		preRegisterDone();
		return( mSelfObjectName );
	
protected voidpreRegisterDone()

		debug( "AMXImplBase.preRegister() done for: ", getObjectName() );
		
		mCoverage.setMBeanInfo( getMBeanInfo() );
    
protected javax.management.ObjectNamepreRegisterHook(javax.management.ObjectName selfObjectName)
This is an opportunity for a subclass to do initialization and optionally to modify the ObjectName one last time.

        // subclass may do something
        return selfObjectName;
    
protected javax.management.ObjectNamepreRegisterModifyName(javax.management.MBeanServer server, javax.management.ObjectName nameIn)
O the ObjectName by adding to it:
  • adding AMX.FULL_TYPE_KEY property

		mFullType		= getFullType( nameIn );
		
		// now ensure that certain singleton ancestors have a name
		String	ancestorProps	= "";
		final String[]	fullTypeArray	= Util.getTypeArray( mFullType );
		for( int i = 0; i < fullTypeArray.length - 1; ++i )
		{
			final String	key	= fullTypeArray[ i ];
			
			if ( nameIn.getKeyProperty( key ) == null )
			{
				final String	name	= ObjectNames.getSingletonName( key );
				final String	prop	= Util.makeProp( key, name );
				
				ancestorProps	= Util.concatenateProps( ancestorProps, prop );
			} 
		}
		
		final String	props	=  ancestorProps;
		
		final String	newName	=
			Util.concatenateProps( nameIn.toString(), props );
		
		final ObjectName	nameOut	= Util.newObjectName( newName );

		return( nameOut );
	
protected javax.management.ObjectNameregisterMBean(java.lang.Object mbean, javax.management.ObjectName name)

		return getMBeanServer().registerMBean( mbean, name ).getObjectName();
	
protected voidregisterMisc()

		// nothing by default
	
protected voidregisterSelfMgrChild(com.sun.enterprise.management.support.TypeInfo childInfo)
Register a child MBean which is a manager.

		final String	childJ2EEType	= childInfo.getJ2EEType( );
		
	    if ( ( ! getOffline() ) || isOfflineCapable( childInfo ) )
	    {
    		final Class		implClass	= childInfo.getImplClass();
    		
    		final ObjectName	childObjectName	=
    			getObjectNames().buildContaineeObjectName( getObjectName(), getFullType(), childJ2EEType );
    		if ( ! getMBeanServer().isRegistered ( childObjectName ) )
    		{
    		    final Object	impl	= implClass.newInstance();
    		
    		    registerMBean( impl, childObjectName );
    		}
	    }
	    else
	    {
	        debug( "Not loading child in offline mode: " + childJ2EEType );
	    }
	
protected voidregisterSelfMgrChildren()

		final TypeInfo		selfInfo		= getSelfTypeInfo();
		final Set<String> childTypesSet	=	selfInfo.getContaineeJ2EETypes();

		debug( "registerSelfMgrChildren for ", getSelfJ2EEType(), ": ", toString( childTypesSet ) );
		
		if ( childTypesSet.size() != 0 )
		{
			debug( "registerSelfMgrChildren: child types = ", toString( childTypesSet ) );
		}
		else
		{
			debug( "no child types for: ", quote( getObjectName() ) );
		}
		
		final String[]	childTypes	= GSetUtil.toStringArray( childTypesSet );
		for( int i = 0; i < childTypes.length; ++i )
		{
			final String		childType	= childTypes[ i ];
			debug( "registerSelfMgrChildren: processing type: ", childType);
			
			final TypeInfo	childInfo	= getTypeInfo( childType );
	
			final Class	childInterface	= childInfo.getInterface();
		
			if ( 	isSingletonMBean( childInterface ) ||
					isUtilityMBean( childInterface )
					)
			{
				try
				{
					registerSelfMgrChild( childInfo );
				}
				catch( InstantiationException e )
				{
					trace( "InstantiationException for child of type: " + childInfo.getJ2EEType() +
						" = " + e.getMessage() );
					e.printStackTrace();
					
					final Throwable	t	= ExceptionUtil.getRootCause( e );
					if ( t != e && t != null )
					{
						trace( "InstantiationException: root cause msg =" + t.getMessage() );
						trace( ExceptionUtil.getStackTrace( t ) );
					}
					else
					{
						trace( ExceptionUtil.getStackTrace(  ExceptionUtil.getRootCause( e ) ));
					}
				}
				catch( Exception e )
				{
					trace( "Can't create child, info = " + childInfo + "\n" + e + "\n\n" );
					debug( ExceptionUtil.getStackTrace( e ) );
				}
			}
			else
			{
				trace( "registerSelfMgrChildren: skipping: " + childInterface.getName() );
			}
		}
	
protected final voidregisterSpecialContainees()
Register special containee MBeans. Usually this should only be done for child MBeans that otherwise would not come into existence.

		registerSelfMgrChildren( );
		registerMisc();
	
protected javax.management.MBeanInforemoveUnsupportedMBeanInfo(javax.management.MBeanInfo info)

		return( info );
	
private final voidrethrowAttributeNotFound(java.lang.Throwable t, java.lang.String attrName)

		final Throwable rootCause	= ExceptionUtil.getRootCause( t );
		if ( rootCause instanceof AttributeNotFoundException )
		{
			throw (AttributeNotFoundException)rootCause;
		}
		
		final String msg = "Attribute not found: " + StringUtil.quote(attrName) + " [" + rootCause.getMessage() + "]";;
		throw new AttributeNotFoundException( msg );
	
protected synchronized voidsendAttributeChangeNotification(java.lang.String msg, java.lang.String attrType, java.lang.Object oldValue, javax.management.Attribute newAttr)

		final AttributeChangeNotificationBuilder builder	=
		(AttributeChangeNotificationBuilder)
			getNotificationBuilder( AttributeChangeNotification.ATTRIBUTE_CHANGE );
		
		final AttributeChangeNotification	n	= 
			builder.buildAttributeChange( msg, newAttr.getName(), attrType, oldValue, newAttr.getValue() );
			
		sendNotification( n );
	
protected voidsetAttribute(javax.management.ObjectName objectName, javax.management.Attribute attr)

		getMBeanServer().setAttribute( objectName, attr );
	
public voidsetAttribute(javax.management.Attribute attr)

	    final String    name    = attr.getName();
	    
		mCoverage.attributeWasWritten( name );
		    
		if ( isReadOnlyAttribute( name ) )
		{
		    mCoverage.attributeSetFailure( name );
			throw new IllegalArgumentException( "Attribute is read-only: " + attr.getName() );
		}
		
		boolean failure = true;
		
		try
		{
			setAttributeInternal( attr );
			failure = false;
		}
		catch( AttributeNotFoundException e )
		{
			throw e;
		}
		catch( InvalidAttributeValueException e )
		{
			throw e;
		}
		catch( RuntimeException e )
		{
			throw (RuntimeException)e;
		}
		catch( Exception e )
		{
			throw new RuntimeException( e );
		}
		finally
		{
		    if ( failure )
		    {
		        mCoverage.attributeSetFailure( name );
		    }
		}
	
protected voidsetAttributeByMethod(javax.management.Attribute attr, java.lang.reflect.Method m)

		try
		{
			// trace( "setAttributeByMethod: " + m );
			m.invoke( this, new Object[] { attr.getValue() } );
		}
		catch( InvocationTargetException e )
		{
			trace( "setAttributeByMethod: InvocationTargetException: " + e );
		
			final Throwable t	= ExceptionUtil.getRootCause( e );
			if ( t instanceof InvalidAttributeValueException)
			{
				throw (InvalidAttributeValueException)t;
			}

			rethrowAttributeNotFound( e, attr.getName() );
		}
		catch( IllegalAccessException e )
		{
			trace( "setAttributeByMethod: IllegalAccessException: " + e );
			rethrowAttributeNotFound( e, attr.getName()  );
		}
		catch( Exception e )
		{
			trace( "setAttributeByMethod: Exception: " + e );
			rethrowAttributeNotFound( e, attr.getName()  );
		}
	
protected voidsetAttributeInternal(javax.management.Attribute attr)
Set an Attribute value, first by looking for a setter method of the correct name and signature, then by looking for a delegate, and finally by calling setAttributeManually(), which a subclass is expected to override.

param
attr the Attribute

		trace( "setAttribute: " + attr.getName() + " = " + attr.getValue() );
		
		boolean			handleManually	= false;
		final Method	m	= findSetter( attr );
		
		final boolean	shouldEmitNotifications	= shouldEmitNotifications();
		// note that this will fail if an Attribute is write-only
		final Object	oldValue	= shouldEmitNotifications ?
						getAttribute( attr.getName() ) : null;
		
		if ( m != null )
		{
			setAttributeByMethod( attr, m );
		}
		else if ( haveDelegate() )
		{
			if ( getDelegate().supportsAttribute( attr.getName() ) )
			{
				try
				{
					getDelegate().setAttribute( attr );
				}
				catch( JMException e )
				{
					handleManually	= true;
				}
			}
			else
			{
				handleManually	= true;
			}
		}
		else
		{
			handleManually	= true;
		}
		
		if ( handleManually )
		{
			setAttributeManually( attr );
		}
		
		if ( shouldEmitNotifications )
		{
			final String	attrType	= getAttributeType( attr.getName() );
			
			sendAttributeChangeNotification( "", attrType, oldValue, attr );
		}
	
protected voidsetAttributeManually(javax.management.Attribute attr)
Subclasses should override this to handle setAttribute( attr ). It will be called if no appropriate setter is found.

		throw new AttributeNotFoundException( attr.getName() );
	
protected javax.management.AttributeListsetAttributes(javax.management.ObjectName objectName, javax.management.AttributeList attrs)

		return( getMBeanServer().setAttributes( objectName, attrs ) );
	
public javax.management.AttributeListsetAttributes(javax.management.AttributeList attrs)
Bulk get. Note that is is important for this implementation to call setAttribute() for each name so that each may be processed appropriately; some Attributes may be in this MBean itself, and some may reside in a {@link Delegate}.

param
attrs attributes to be set
return
AttributeList containing Attributes successfully set

		trace( "AMXImplBase.setAttributes = " + SmartStringifier.toString( attrs ) );
		
		final int			numAttrs	= attrs.size();
		final AttributeList	successList	= new AttributeList();
		
		for( int i = 0; i < numAttrs; ++i )
		{
			final Attribute attr	= (Attribute)attrs.get( i );
			trace( "setAttributes: " + attr.getName() );
			try
			{
				setAttribute( attr );
				
				successList.add( attr );
			}
			catch( Exception e )
			{
				// ignore, as per spec
			}
		}
		return( successList );
	
protected voidsetDelegate(Delegate delegate)

		mDelegate	= delegate;
	
protected final booleanshouldEmitNotifications()

		return( mEmitAttributeChangeNotifications && getListenerCount() != 0 );
	
protected booleanshouldOmitObjectNameForDebug()

		return super.shouldOmitObjectNameForDebug() ||
		    getObjectName().getKeyProperty( "name" ).equals( AMX.NO_NAME );
	
protected java.lang.Stringstringify(java.lang.Object o)

		return( SmartStringifier.toString( o ) );
	
public java.lang.StringtoString()

	    return getImplString( false );
	
protected final java.lang.ObjectunimplementedAttribute(java.lang.String attrName)
An Attribute has not been implemented.

	    final String msg = "UNIMPLEMENTED ATTRIBUTE: " + attrName + " in " + getObjectName();
		logInfo( msg );
				
		return( null );
	
protected final voidunimplementedOperation(java.lang.String operation)
An operation has not been implemented. Deal with appropriately.

	    final String msg = "UNIMPLEMENTED OPERATION: " + operation + " in " + getObjectName();
		
		logInfo( msg );
		
		throw new UnsupportedOperationException( operation );
	
protected voidunregisterMisc()

		// nothing by default
	
protected voidunregisterSelfMgrChildren()

		final TypeInfo		selfInfo		=	getSelfTypeInfo();
		final Set<String>	childTypesSet	=	selfInfo.getContaineeJ2EETypes();
		final String[]		childTypes		=	GSetUtil.toStringArray( childTypesSet );
		final MBeanServer	mbeanServer		=	getMBeanServer();
		for( int i = 0; i < childTypes.length; ++i )
		{
			final String		childType	= childTypes[ i ];
			debug( "unregisterSelfMgrChildren: processing type: ", childType);

			final TypeInfo	childInfo	= getTypeInfo( childType );
	
			final Class	childInterface	= childInfo.getInterface();

			if ( 	//isConfigMgrMBean( childInterface ) ||
					isSingletonMBean( childInterface ) ||
					isUtilityMBean( childInterface )
				)
			{
				final ObjectName containeeObjectName = 
					getContaineeObjectName( childType );
			    if ( containeeObjectName != null )
			    {
    				try
    				{
    					mbeanServer.unregisterMBean( containeeObjectName );
    					debug( "unregisterSelfMgrChildren: ", containeeObjectName,
    						" is unregistered" );
    				}
    				catch ( InstanceNotFoundException infe )
    				{
    					logWarning( "unregisterSelfMgrChildren: " + infe.getMessage() );
    				}
    				catch ( Exception e )
    				{
    					logSevere( "unregisterSelfMgrChildren: " + 
    						ExceptionUtil.getRootCause(e).getMessage() );
    				}
    				}
			}
			else
			{
				debug( "unregisterSelfMgrChildren: skipping: ", childInterface.getName() );
			}
		}
	
protected final DelegatewrapSuppliedDelegate(Delegate delegate)
Wrap the supplied delegate (if one was supplied) with a MappedDelegate which will be created by calling createAttributeNameMapper()

		mAttributeNameMapper	= createAttributeNameMapper();
		
		final MappedDelegate result	= new MappedDelegate( mSuppliedDelegate, mAttributeNameMapper );
		result.setDebugOutput( getDebugOutput() );
		
		return( result );