Package com.sun.enterprise.management.monitor

Source Code of com.sun.enterprise.management.monitor.MonitoringStatsImplBase$OldMonitoringMBean

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package com.sun.enterprise.management.monitor;

import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Collections;
import java.io.Serializable;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;

import javax.management.ObjectName;
import javax.management.MBeanInfo;
import javax.management.MBeanAttributeInfo;
import javax.management.AttributeNotFoundException;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.OpenDataException;
import javax.management.InstanceNotFoundException;

import javax.management.j2ee.statistics.Statistic;
import javax.management.j2ee.statistics.*;
import com.sun.appserv.management.j2ee.statistics.StatsImpl;

import com.sun.appserv.management.base.AMXDebug;

import com.sun.appserv.management.monitor.MonitoringStats;

import com.sun.appserv.management.util.j2ee.J2EEUtil;
import com.sun.appserv.management.util.misc.ClassUtil;
import com.sun.appserv.management.util.jmx.JMXUtil;
import com.sun.appserv.management.util.misc.MapUtil;
import com.sun.appserv.management.util.misc.GSetUtil;
import com.sun.appserv.management.util.misc.StringUtil;
import com.sun.appserv.management.util.misc.ExceptionUtil;
import com.sun.appserv.management.util.misc.ArrayUtil;
import com.sun.appserv.management.j2ee.statistics.MapStatistic;
import com.sun.appserv.management.j2ee.statistics.MapStatisticImpl;
import com.sun.appserv.management.j2ee.statistics.StatisticImpl;
import com.sun.appserv.management.j2ee.statistics.StatisticFactory;

import com.sun.appserv.management.util.jmx.AttributeNameMapper;
import com.sun.appserv.management.util.jmx.AttributeNameMapperImpl;

import com.sun.enterprise.management.support.Delegate;
import com.sun.enterprise.management.support.DelegateToMBeanDelegate;

/**
  Base implementation class for Monitoring MBeans that provide Stats.
*/
public abstract class MonitoringStatsImplBase extends MonitoringImplBase
{
  private MBeanInfo          mMBeanInfo;
  private final AttributeNameMapper  mFieldNameMapper;
  private final AttributeNameMapper  mStatisticNameMapper;
 
  private Set<String>          mStatisticNames;
 
    public
  MonitoringStatsImplBase( final String j2eeType, final Delegate delegate )
  {
    super( j2eeType, delegate );
   
    mMBeanInfo  = null;
   
    mFieldNameMapper    = new AttributeNameMapperImpl();
    mStatisticNameMapper  = new AttributeNameMapperImpl();
   
    mStatisticNames  = null;
  }

    public
  MonitoringStatsImplBase( final String j2eeType )
  {
    this( j2eeType, null );
  }

  /**
    The interface available in underlying "old" MBean.
   */
  private static interface OldMonitoringMBean
  {
    public String[]    getStatisticNames();
    public Statistic[]  getStatistics();
  }
 
  /**
    Get the underlying Delegate.  Note that this proxy
    may not actually implement all the routines in MonitoringStats;
    we use only a few however, so that is OK.
   */
    protected OldMonitoringMBean
  getMonitoringMBeanDelegate()
  {
    return (OldMonitoringMBean)getDelegateProxy(OldMonitoringMBean.class);
  }
 
  /**
    The prefix of a getter method.
   */
  private static final String  GET  = "get";
 
  /**
    The delimiter between a Statistic name and its field value when
    exposed as an Attribute.
   */
  private static final String  STATISTIC_DELIM  = "_";
 
 
  static private final Set<String>   IGNORE_MISSING_SUFFIXES =
      Collections.unmodifiableSet( GSetUtil.newSet( new String[]
      {
          "current", "count", "description", "name",
          "lowwatermark", "highwatermark", "unit",
          "lastsampletime", "starttime",
          "lowerbound", "upperbound",
          "maxtime", "mintime", "totaltime", "average",
         
          "children",
      }));
     
  /**
      We don't map any of the Attributes derived from statistics.
   */
      protected void
  handleMissingOriginals( final Set<String> missingOriginals )
  {
      final Set<String>   stillMissing    = new HashSet<String>();
     
      for( final String name : missingOriginals )
      {
          final int idx   = name.lastIndexOf( '-' );
          final String suffix = name.substring( idx + 1, name.length() );
         
          if ( ! IGNORE_MISSING_SUFFIXES.contains( suffix ) )
          {
              stillMissing.add( name );
          }
      }
       
        super.handleMissingOriginals( stillMissing );
  }
 
 
    protected final AttributeNameMapper
  getFieldNameMapper()
  {
    return( mFieldNameMapper );
  }
    protected final AttributeNameMapper
  getStatisticNameMapper()
  {
    return( mStatisticNameMapper );
  }


  protected final static String[]  STD_FIELDS  = new String[]
  {
    // none, by default
  };
 
  /**
    Initialize the field-name mapping for any names that required
    special conversion.
   */
    protected void
  initFieldNameMapper()
  {
    final AttributeNameMapper  m  = getFieldNameMapper();
   
    assert( (STD_FIELDS.length % 2) == 0 );
    for( int i = 0; i < STD_FIELDS.length - 1; ++i )
    {
      m.addMapping( STD_FIELDS[ i ], STD_FIELDS[ i + 1 ] );
    }
  }
 
 
  protected final static String[]  STD_STATISTICS  = new String[]
  {
    "id", "ID",
    "Id", "ID",
  };
 
  /**
    Initialize the Statistic-name mapping for any names that required
    special conversion.
   */
    protected void
  initStatisticNameMapper()
  {
    final AttributeNameMapper  m  = getStatisticNameMapper();
   
    final String[]  mappings  = STD_STATISTICS;
   
    for( int i = 0; i < mappings.length -1; ++i )
    {
      m.addMapping( mappings[ i ], mappings[ i + 1 ] );
    }
  }
 
  /**
    Get an Attribute value by looking for a corresponding Statistic.
   
    @param statisticName as seen in the MBeanInfo of this MBean
    @param fieldName as seen in the MBeanInfo of this MBean
   */
    protected Object
  getAttributeFromStatistic(
    final String  statisticName,
    final String  fieldName )
    throws AttributeNotFoundException
  {
    try
    {
      final Statistic s  = getStatistic( statisticName );
      assert( s instanceof MapStatistic );
     
      final String  methodName  = JMXUtil.GET + fieldName;
      final Method  m  = s.getClass().getMethod( methodName, (Class[])null);
     
      //final MapStatisticImpl  ms  = new MapStatisticImpl( s );
      final Object result  = m.invoke( s, (Object[])null );
      return( result );
    }
    catch( Exception e )
    {
        debug( "getAttributeFromStatistic: exception getting statistic " +
            statisticName + e  + "\n" +
            ExceptionUtil.getStackTrace( ExceptionUtil.getRootCause( e ) ) );
      throw new AttributeNotFoundException( statisticName );
    }
  }
 
  /**
    Handle getting of artificial Attributes which are derived from Statistics.
   
    @param name the Attribute name
   */
    protected Object
  getAttributeManually( final String name )
    throws AttributeNotFoundException
  {
    final int  idx  = name.indexOf( STATISTIC_DELIM );
   
    Object  result  = null;
   
    if ( idx > 0 )
    {
      // Attribute name is of the form <statistic-name>_<field-name>
      final String  statisticName  = name.substring( 0, idx );
      final String  fieldName  = name.substring( idx + 1, name.length() );
     
      result  = getAttributeFromStatistic( statisticName, fieldName );
    }
    else
    {
        result  = super.getAttributeManually( name );
    }
   
    return( result );
  }
 
  /**
    A bug in the underlying MBeans is present.
   */
  private static final boolean  BUG_STATISTIC_NAMES  = true;
 
 
    private String[]
  originalToDerivedStatisticNames( final String[] names )
  {
    final String[]  derived  = new String[ names.length ];
   
    for( int i = 0; i < names.length; ++i )
    {
      derived[ i = originalToDerivedStatisticName( names[ i ] );
    }
   
    return( derived );
  }
 
 
    private void
  checkUnderlyingMBean()
  {
    assert( BUG_STATISTIC_NAMES );
               
    if ( BUG_STATISTIC_NAMES  /* && ! getJ2EEType().equals( "X-BeanMethodMonitor" ) */ )
    {
        final Delegate  delegate    = getDelegate();
       
            if ( delegate == null) return;
           
      final String[]  claimedNames  = getMonitoringMBeanDelegate().getStatisticNames();
      if ( claimedNames == null )
      {
          throw new RuntimeException( "Delegate " +
              " used by AMX MBean " + getObjectName() +
              " returned null StatisticNames array" );
      }
      else if ( claimedNames.length == 0 )
      {
          throw new RuntimeException( "Delegate " +
              " used by AMX MBean " + getObjectName() +
              " returned empty StatisticNames array" );
      }

      final Statistic[]  statistics  = getMonitoringMBeanDelegate().getStatistics();
      if ( statistics == null )
      {
          throw new RuntimeException( "Delegate " +
              " used by AMX MBean " + getObjectName() +
              " returned null Statistics array" );
      }
      else if ( statistics.length == 0 )
      {
          throw new RuntimeException( "Delegate " +
              " used by AMX MBean " + getObjectName() +
              " returned empty Statistics array" );
      }
        
      try
      {
        final Set<String>    actualSet  = new HashSet<String>();
       
        final String[]  namesFromGetStatistics  = new String[ statistics.length ];
       
        for( int i = 0; i < statistics.length; ++i )
        {
          final String  name  = StringUtil.upperCaseFirstLetter( statistics[ i ].getName() );
          namesFromGetStatistics[ i = name;
         
          if ( ! actualSet.contains( name ) )
          {
            actualSet.add( name );
          }
          else
          {
            logWarning( "MBean delegate " +
                " for " + getObjectName() +
              " returns Statistic with duplicate name: " + name +
              " from getStatistics() call.\n" );
          }
        }
       
        final Set<String>  claimedSet  = GSetUtil.newStringSet( claimedNames );
        if ( ! claimedSet.equals( actualSet ) )
        {
          final Set<String>  missing  = new HashSet<String>( claimedSet );
          missing.removeAll( actualSet );
         
          // assume workarounds are in place
          final String msg = "\nMBean delegate " + " for " + getObjectName() +
            " does not provide Statistic(s): " + missing + " from getStatistics() call, " +
          "\ngetStatisticNames() = " + toString( claimedSet ) +
          "\nnames from getStatistics() = " + toString( namesFromGetStatistics ) + "\n";
         
                  AMXDebug.getInstance().getOutput(
                      "MonitoringStatsImplBase.checkUnderlyingMBean" ).println( msg );
          logFine( msg );
        }
      }
      catch( Exception e )
      {
        final Throwable rootCause  = ExceptionUtil.getRootCause( e );
        logWarning( "MBean delegate " +
            " doesn't work, used by AMX MBean: " +
          getObjectName() + "\n" +
          rootCause.getClass().getName() + "\n" +
          ExceptionUtil.getStackTrace( rootCause ) );
      }
    }
  }
 
 
    private final String[]
  initStatisticNames()
  {
    String[]  names  = null;
   
    if ( BUG_STATISTIC_NAMES )
    {
      names  = getStats().getStatisticNames();
      if ( names == null || names.length == 0 )
      {
          throw new RuntimeException( "Stats are null or empty for: " + getObjectName());
      }
    }
    else
    {
      names  = originalToDerivedStatisticNames( getMonitoringMBeanDelegate().getStatisticNames() );
    }
   
    return( names );
  }
 
  /**
    Gets the names of all the Statistics.
    @return a String[] of statistic names
  */
    public String[]
  getStatisticNames()
  {
    return( GSetUtil.toStringArray( mStatisticNames ) );
  }

    public CompositeDataSupport
  getOpenStatistic(String name)
  {
    final Statistic statistic = getStatistic( name );
   
    try
    {
      return J2EEUtil.statisticToCompositeData(statistic);
    }
    catch(OpenDataException e)
    {
      throw new RuntimeException(e);
    }
  }

    public CompositeDataSupport[]
  getOpenStatistics( final String[] names)
  {
    final CompositeDataSupport[] result  = new CompositeDataSupport[names.length];
   
    for(int i = 0; i < names.length; i++)
    {
      result[ i ] = getOpenStatistic( names[ i ] );
    }
    return result;
  }

    public CompositeDataSupport
  getOpenStats()
  {
    final Stats  stats  = getStats();
   
    CompositeDataSupport  result  = null;
    // can't make a CompositeDataSupport if there are no Statistics
    if ( stats.getStatisticNames().length != 0 )
    {
      try
      {
        result  = J2EEUtil.statsToCompositeData( stats );
      }
      catch(OpenDataException e)
      {
        throw new RuntimeException(e);
      }
    }
    else
    {
      logWarning( "No Statistics available for: " + getObjectName() );
    }
   
    return( result );
  }

    public Statistic
  getStatistic( final String name)
  {
    final Stats    stats = getStats();
   
    return stats.getStatistic( name );
  }

    public Statistic[]
  getStatistics(final String[] desiredNames)
  {
    final Stats      stats  = getStats();
    final Statistic[]  result  = new Statistic[ desiredNames.length ];
   
    for( int i = 0; i < desiredNames.length; ++i )
    {
      final Statistic  statistic  = stats.getStatistic( desiredNames[ i ] );
     
      // OK to return null if not found--see Javadoc
      result[ i = statistic;
    }
   
    return( result );
  }

  /**
    Convert a Statistic-name from its underlying name to the one we expose.
   
    @param underlyingName
   */
    protected String
  originalToDerivedStatisticName( final String underlyingName )
  {
    String    result  = getStatisticNameMapper().originalToDerived( underlyingName );
    result  = StringUtil.upperCaseFirstLetter( result );
   
    return( result );
  }
 
    protected String
  derivedToOriginalStatisticName( final String derivedName )
  {
    return( getStatisticNameMapper().derivedToOriginal( derivedName ) );
  }
 
    protected final Statistic[]
  getStatisticsFromDelegate()
  {
      if ( getDelegate() == null )
      {
          throw new NullPointerException();
      }
    return( getStatisticsFromDelegate( getDelegate() ) );
  }

    protected final Statistic[]
  checkDuplicateStatistics(
    final Delegate d,
    final Statistic[] statistics)
  {
    // check to see if any names are duplicated
    final Set<String>  actualNames  = new HashSet<String>();
    for ( int i = 0; i < statistics.length; ++i )
    {
      final String  name  = statistics[ i ].getName();
     
      if ( actualNames.contains( name ) )
      {
        throw new RuntimeException(
          "MonitoringStatsImplBase.checkDuplicateStatistics: " +
          getObjectName() +
            "Statistic " + StringUtil.quote( name ) + " is duplicated in getStatistics(): " +
             " as supplied from Delegate of " + StringUtil.quote( getObjectName() )+
             ", please see bug #6179364"  );
      }
      else
      {
        actualNames.add( name );
      }
    }
   
    if ( actualNames.size() != statistics.length )
    {
      final String[] claimedNames = (String[])d.invoke( "getStatisticNames", null,  null );
   
      final Set<String>  missingNames  = GSetUtil.newStringSet( claimedNames );
      missingNames.removeAll( actualNames );
     
      throw new RuntimeException(
        "MonitoringStatsImplBase.getStatisticsFromDelegateRaw: " + missingNames.size() +
        " Statistic names as found in Statistics from getStatistics() are missing: {" +
        toString( missingNames ) +
         "} from Delegate of " + StringUtil.quote( getObjectName() ) + ", please see bug #6179364" );
    }
   
    return( statistics );
  }

    protected Statistic[]
  getStatisticsFromDelegateRaw( final Delegate d )
  {
      try
      {
        final Statistic[] statistics = (Statistic[])d.invoke( "getStatistics", null,  null );
       
        checkDuplicateStatistics( d, statistics );
       
        return( statistics );
    }
    catch( Exception e )
    {
        final Throwable rootCause   = ExceptionUtil.getRootCause( e );
       
        logWarning( "MonitoringStatsImplBase: the com.sun.appserv Delegate MBean for AMX MBean " +
            getObjectName() + " threw an exception: " + rootCause +
        ", stack = \n" + ExceptionUtil.getStackTrace( rootCause ) );
    }
    return new Statistic[0];
  }


  private void
  debug( String s )
  {
    System.out.println( s );
  }
 
 
  /**
    Get all Statistics from the delegate (our only available call API).
    Statistic names are translated appropriately.
   */
    protected Statistic[]
  getStatisticsFromDelegate( final Delegate d )
  {
    try
    {
      final Statistic[] statistics = getStatisticsFromDelegateRaw( d );
     
      // translate the names to be the ones we expose in MBeanInfo
      for( int i = 0; i < statistics.length; ++i )
      {
        final Statistic  origStatistic  = statistics[ i ];
     
        final MapStatistic  m  = new MapStatisticImpl( origStatistic );
       
        final String  convertedName  = originalToDerivedStatisticName( origStatistic.getName() );
        if ( ! convertedName.equals( origStatistic.getName() ) )
        {
          m.setName( convertedName );
        }
       
        final Class<? extends Statistic> theClass  =
            StatisticFactory.getInterface( origStatistic );
        assert( theClass != null );
       
        // this will create one which implements the requisite interfaces
        statistics[ i = StatisticFactory.create( theClass, m.asMap() );
       
        assert( theClass.isAssignableFrom( statistics[ i ].getClass() ));
      }
     
      return( statistics );
    }
    catch (Exception e)
    {
      final Throwable  rootCause  = ExceptionUtil.getRootCause( e );
     
      if ( ! ( rootCause instanceof InstanceNotFoundException ) )
      {
        // don't rethrow--will make MBeanServer unuseable as it has a bug if we throw
        // an exception of of getMBeanInfo() which halts any further processing of the query
        //NOTE: WARNING_CHANGED_TO_FINE 
        logWarning( "Can't get Statistics from delegate for " + getObjectName() +
          "\n" + rootCause.getMessage() + "\n" + ExceptionUtil.getStackTrace( rootCause ) );
      }
      throw new RuntimeException( e );
    }
  }
 
  // default interface implemented by Stats that we return
  private final Class[]  STATS_IMPL_INTERFACES  = new Class[]
  {
    Serializable.class,
    Stats.class,
  };
 
  /**
    Get the specific type of Stats interface (if any) that should be implemented
    by a Stats returned from getStats().
   
    @return an interface, or null if the interface is generic Stats
   */
  protected abstract Class  getStatsInterface();
 
 
    protected StatsImpl
  createStatsImpl()
  {
    return new StatsImpl( getStatisticsFromDelegate() );
  }
 
  /*
    protected void
  serializeTest( final Object toSerialize )
    throws java.io.IOException, ClassNotFoundException
  {
    final java.io.ByteArrayOutputStream  os  = new java.io.ByteArrayOutputStream( 2048 );
   
    final java.io.ObjectOutputStream  oos  = new java.io.ObjectOutputStream( os );
   
    oos.writeObject( toSerialize );
    oos.close();
   
    final byte[]  bytes  = os.toByteArray();
   
    final java.io.ObjectInputStream  is  = new java.io.ObjectInputStream( new java.io.ByteArrayInputStream( bytes ) );
   
    final Object  result  = is.readObject();
   
    if ( ! result.equals( toSerialize ) )
    {
      assert( false ):
        "statistics not equal: " + toSerialize + " != " + result;
    }
  }
  */
 
 
    public String
  getStatsInterfaceName()
  {
    return( getStatsInterface().getName() );
  }
 
    public Stats
  getStats()
  {
    final Class  statsInterface  = getStatsInterface();
    assert( statsInterface == null || Stats.class.isAssignableFrom( statsInterface ) );
   
    Class[] implementedInterfaces  = null;
    if ( statsInterface == null )
    {
      implementedInterfaces  = STATS_IMPL_INTERFACES;
      logInfo( "getStats: no Stats interface found for " + getObjectName() );
    }
    else
    {
      implementedInterfaces  = (Class[])
        ArrayUtil.newArray( STATS_IMPL_INTERFACES, statsInterface );
    }
   
    final StatsImpl      impl  = createStatsImpl();
    final ClassLoader    classLoader  = this.getClass().getClassLoader();
   
    final Stats stats  = (Stats)
      Proxy.newProxyInstance( classLoader, implementedInterfaces, impl );
 
 
  /*try
  {
    serializeTest( stats );
  } catch( Throwable t )
  {
    System.out.println( "getStats: Stats proxy serialization FAILED for " + getObjectName() );
    ExceptionUtil.getRootCause( t ).printStackTrace();
  }
  */
   
    return( stats );
  }

 
    public final boolean
  refresh()
  {
    mMBeanInfo  = null;
    clearAttributeInfos();
   
    return( true );
  }
 
  /**
    Given a Statistic-name and a field-name, create an Attribute name.
   
    @param statisticName  Statistic-name
    @param fieldName
    @return a name suitable for an Attribute
   */
    private String
  makeAttributeName(
    final String   statisticName,
    final String  fieldName )
  {
    final String  attributeName  = statisticName + STATISTIC_DELIM + fieldName;

    return( attributeName );
  }
 
  /**
    JSR 77 defines these fields as having type "long", so we must define them that
    way as well, in spite of the underlying bug in the old monitoring MBeans, which
    declares them all as Strings.
   */
  private static final Set<String> LONG_FIELDS = GSetUtil.newUnmodifiableStringSet(
     "Count", "LastSampleTime", "StartTime", "LowerBound", "UpperBound",
     "HighWaterMark", "LowWaterMark", "MaxTime", "MinTime", "TotalTime" );
 
  /**
    Determine the Java class of a field.
   */
    private Class
  determineFieldType(
    final String  fieldName,
    final Object  value )
  {
    Class  theClass  = String.class;
   
    if ( value != null )
    {
      theClass  = ClassUtil.ObjectClassToPrimitiveClass( value.getClass() );
    }
    else if ( LONG_FIELDS.contains( fieldName ) )
    {
      theClass  = long.class;
    }
   
    return( theClass );
  }
 
  /**
    Convert a single Statistic to MBeanAttributeInfo.
   
    @return a Map, keyed by the Attribute name, value of MBeanAttributeInfo
   */
    private Map<String,MBeanAttributeInfo>
  statisticToMBeanAttributeInfos( final Statistic s )
  {
    final Map<String,Object>  src  = new MapStatisticImpl( s ).asMap();
   
    final String  statisticName  = s.getName();
   
    final Map<String,MBeanAttributeInfo>  result  = new HashMap<String,MBeanAttributeInfo>();
    for( final String fieldName : src.keySet() )
    {
      final Object  value  = src.get( fieldName );
      // if the value is null, always make it a String
      final String  type  = determineFieldType( fieldName, value ).getName();
     
      final String  attributeName  = makeAttributeName( statisticName, fieldName );
     
      final MBeanAttributeInfo  attributeInfo  = new MBeanAttributeInfo( attributeName, type, "",
                        true, false, false );
      result.put( attributeName, attributeInfo );
    }
    return( result );
  }
 
  /**
    Create MBeanInfo by taking default MBeanInfo and adding Attributes to it corresponding
    to all available Statistics.
   */
    private synchronized MBeanInfo
  createMBeanInfo()
  {
    final MBeanInfo  baseMBeanInfo  = super.getMBeanInfo();
   
    MBeanInfo  mbeanInfo  = baseMBeanInfo;
   
    if ( getMBeanServer() != null && getDelegate() != null )
    {
      assert( getDelegate() != null ) : "null delegate for: " + getObjectName();
     
      final Map<String,MBeanAttributeInfo>
          newAttrs  = new HashMap<String,MBeanAttributeInfo>();
     
      final Statistic[]  statistics  = getStats().getStatistics();
      for( int i = 0; i < statistics.length; ++i )
      {
        final Map<String,MBeanAttributeInfo> attrInfos  =
            statisticToMBeanAttributeInfos( statistics[ i ] );
       
        newAttrs.putAll( attrInfos );
      }
     
      final MBeanAttributeInfo[]  dynamicAttrInfos  =
        new MBeanAttributeInfo[ newAttrs.keySet().size() ];
      newAttrs.values().toArray( dynamicAttrInfos );
     
      final MBeanAttributeInfo[]  attrInfos  =
        JMXUtil.mergeMBeanAttributeInfos( dynamicAttrInfos, baseMBeanInfo.getAttributes() );
     
      mbeanInfo  = JMXUtil.newMBeanInfo( baseMBeanInfo, attrInfos );
    }
   
    return( mbeanInfo );
  }
 
    protected ObjectName
  preRegisterHook( final ObjectName   objectName )
  {
    initFieldNameMapper();
    initStatisticNameMapper();
   
    // ensure that it gets generated anew now that we are registered and can access everything
    refresh();
   
    assert( MonitoringStats.class.isAssignableFrom( getInterface() )  ) :
      "MBean extends MonitoringStatsImpl but does not have MonitoringStats interface: " + getObjectName();
   
    if ( BUG_STATISTIC_NAMES )
    {
      checkUnderlyingMBean();
    }
   
    mStatisticNames  = GSetUtil.newUnmodifiableStringSet( initStatisticNames() );
     
      return objectName;
  }
 
  private static final MBeanInfo  EMPTY_MBEAN_INFO  =
    new MBeanInfo( "Empty", "Failed to create MBeanInfo", null, null, null, null);
   
    public synchronized MBeanInfo
  getMBeanInfo()
  {
    if ( mMBeanInfo == null )
    {
      try
      {
        mMBeanInfo  = createMBeanInfo();
      }
      catch( Throwable t )
      {
        // if we throw an exception, it will kill the MBeanServer's ability
        // to function
        final Throwable rootCause  = ExceptionUtil.getRootCause( t );
       
        // when an old mbean gets unregistered, this object does too,
        // but the MBeanServer calls getMBeanInfo() before unregistering us,
        // putting this MBean in the awkward position of supplying MBeanInfo
        // from a delegate that has disappeared.
        if ( ! ( rootCause instanceof InstanceNotFoundException) )
        {
          getMBeanLogger().warning( "can't create MBeanInfo for: " + getObjectName() +
            "\n" + rootCause.getClass() + ": " + rootCause.getMessage() + ":\n" +
            ExceptionUtil.getStackTrace( rootCause ) );
        }
       
        mMBeanInfo  = EMPTY_MBEAN_INFO;
      }
    }
   
    return( mMBeanInfo );
  }
}























TOP

Related Classes of com.sun.enterprise.management.monitor.MonitoringStatsImplBase$OldMonitoringMBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.