donaldp     02/03/23 23:41:30

  Added:       baxter   .cvsignore BUILDING.txt README.txt
                        ant.properties.sample build.bat build.sh build.xml
                        project.properties
               baxter/examples README.txt
               baxter/src/java/org/apache/avalon/excalibur/baxter
                        AbstractMBean.java AttributeEntry.java
                        ConstructiveMBean.java JMXPermission.java
                        JavaBeanMBean.java OperationEntry.java
               baxter/src/test/org/apache/avalon/excalibur/baxter/test
                        BaxterTestSuite.java
  Log:
  Add in Baxter code from phoenix. Baxter is the MBean introspector stuff with 
all the javadocs fixed and all checkstyle violations fixed.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/baxter/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  ant.properties
  build
  checkstyle.cache
  distributions
  dist
  excalibur-*
  *.el
  *.ipr
  
  
  
  1.1                  jakarta-avalon-excalibur/baxter/BUILDING.txt
  
  Index: BUILDING.txt
  ===================================================================
  
                 Building The Component
                 ======================
  
  Building from CVS
  -----------------
  
  Assuming:
   - You have a JDK installed, $JAVA_HOME set and 'java -version' works
   - Your directory structure follows standard CVS layout:
  
  jakarta-avalon/                   # jakarta-avalon CVS module, containing Ant
  jakarta-avalon-excalibur/              # contains build.sh, build.bat
  jakarta-avalon-excalibur/<component>   # you are here
  
  Then to build, you need only customize ant.properties (see step 6 below) and
  type './build.sh' (Unix) or 'build' (DOS). The '-projecthelp' option will
  list the available targets.
  
  
  Building from source distribution
  ---------------------------------
  
  In order to build a binary distribution version of the component from a
  source  distribution,  you must have  a Java Development Kit (JDK)  for
  version  1.1 (or  later)  downloaded  and  installed  (version  1.3.1
  recommended), and do the following:
  
  (0) Download and Install a Java Development Kit
  
  * Download a Java Development Kit (JDK) release (version 1.1 or later)
    from:
  
      http://java.sun.com/j2se/
  
  * Install the JDK according to the instructions included with the release.
  
  * Set an environment variable JAVA_HOME to the pathname of the directory
    into which you installed the JDK release.
  
  
  (1) Download and Install the Ant Binary Distribution
  
  * Download a binary distribution of Ant 1.4.1 from:
  
      http://jakarta.apache.org/builds/jakarta-ant/release/v1.4.1/bin/
  
    On a Windows platform, you will need:
      jakarta-ant-1.4.1-bin.zip
      jakarta-ant-1.4.1-optional.jar
  
    On a Unix platform, you will need:
      jakarta-ant-1.4.1-bin.tar.gz
      jakarta-ant-1.4.1-optional.jar
  
  * Unpack the binary distribution into a convenient location so that the
    Ant release resides in its own directory (conventionally named
    "jakarta-ant-1.4.1").  For the purposes of the remainder of this document,
    the symbolic name "${ant.home}" is used to refer to the full pathname of
    the release directory.
  
  * Copy the file "jakarta-ant-1.4.1-optional.jar", downloaded above, into
    the directory "${ant.home}/lib".  This makes available several Ant
    extension commands that are commonly required when building Jakarta
    based projects.
  
  * Modify the PATH environment variable to include directory
    "${ant.home}/bin" in its list.  This makes the "ant" command line script
    available, which will be used to actually perform the build.
  
  (2) Download and Install the JUnit Testing Package (OPTIONAL)
  
  NOTE: This is only required if you wish to run the unit tests for
  this component
  
  * Download the JUnit unit test package (version 3.7 or later) from:
  
      http://www.junit.org/
  
  * Unpack the package into a convenient location so that it resides in its
    own subdirectory.
  
  * Copy the file "junit.jar", downloaded above, into the directory
    "${ant.home}/lib".  This makes available the unit testing tasks that are
    commonly required when building Jakarta based projects.
  
  (3) Download and Install the JDepend 2.2, Dependency Analysis Package 
(OPTIONAL)
  
  NOTE: This is only required if you wish to run dependency analysis for
  this component.
  
  * Download the JDepend package (version 2.2 or later) from:
  
      http://www.clarkware.com/software/JDepend.html
  
  * Unpack the package into a convenient location so that it resides in its
    own subdirectory.
  
  * Copy the file "jdepend.jar", downloaded above, into the directory
    "${ant.home}/lib".  This makes available the dependency analysis tasks.
  
  
  (4) Download and Install Checkstyle, 2.1 or later (OPTIONAL)
  
  NOTE: This is only required if you wish to generate reports regarding code 
style.
  
  * Download the Checkstyle package (version 2.1 or later) from:
  
      http://checkstyle.sourceforge.net/
  
  * Unpack the package into a convenient location so that it resides in its
    own subdirectory.
  
  (5) Download and Install the Xalan, XSLT engine (OPTIONAL)
  
  NOTE: This is only required if you wish to generate reports for the dependency
  analysis, checkstyle and unit testing results.
  
  * Download the Xalan package (version 2.3.1 or later) from:
  
      http://xml.apache.org/xalan-j/
  
  * Unpack the package into a convenient location so that it resides in its
    own subdirectory.
  
  * Copy the files "xalan.jar", and "xml-apis.jar", downloaded above, into
    the directory "${ant.home}/lib".  This makes available the XSLT reporting
    capabilities.
  
  (6) Download and Install the JMX 1.0 Reference Implementation
  
  * Download the JMX Instrumentation and Agent Reference Implementation
    (version 1.0 or later) from
  
      http://java.sun.com/products/JavaManagement/download.html
  
  * Unpack the reference implementation into a convenient location so that
    it resides in its own subdirectory.
  
  (7) Customize Build Properties For This Subproject
  
  Most Jakarta subprojects allow you to customize Ant properties (with default
  values defined in the "build.xml" file.  This is done by creating a text file
  named "ant.properties" in the source distribution directory (for property
  definitions local to this subproject) and/or your user home directory (for
  property definitions shared across subprojects).  You can use the included
  "ant.properties.sample" file as a starting point for this.
  
  External dependencies are satisfied by configuring appropriate values in your
  ant.properties file.  The easiest way to satisfy these dependencies is to copy
  the "ant.properties.sample" file (in the top-level directory) to 
"ant.properties",
  and then edit it to suit your environment.  On Unix, this would be done as:
  
    cd @dist.name@
    cp ant.properties.sample ant.properties
    emacs ant.properties
  
  NOTE:  Be *sure* that you do not check "ant.properties" in to the CVS
  repository.  This file is local to your own development environment, and
  each developer will have their own version.
  
  (8) Build A Binary Distribution
  
  Open a command line shell, and issue the following commands:
  
    cd @dist.name@
    ant -projecthelp
  
  If everything is installed correctly, you should see a list of the Ant
  "targets" that represent different commands you might wish to build.  By
  convention, the "jar" target creates the jar of the component. To execute
  it, type the following commands:
  
    cd @dist.name@
    ant jar
  
  This will create a jar in the @dist.name@/build/lib directory that contains
  the component.
  
  
  
  1.1                  jakarta-avalon-excalibur/baxter/README.txt
  
  Index: README.txt
  ===================================================================
                    Avalons Excalibur Baxter
                    ------------------------
  
  Baxter is a set of base classes and utility classes that are enable
  rapid creation of MBeans via delegation and inheritance. These were
  originally derived from the Phoenix project.
  
  
  Getting Started:
  ----------------
  
  If you downloaded a source release of the component then you
  will need to build the component. Directions for building the
  component are located in BUILDING.txt
  
  If you downloaded a binary release, or a release with both binary
  and source then it is recomended you look over the documentation
  in docs/index.html - and then look into the examples/ directory
  for examples of the component in action.
  
  
  
  
  1.1                  jakarta-avalon-excalibur/baxter/ant.properties.sample
  
  Index: ant.properties.sample
  ===================================================================
  # 
-----------------------------------------------------------------------------
  # ant.properties.sample
  #
  # This is an example "ant.properties" file, used to customize building 
component
  # for your local environment.  It defines the location of all external
  # modules that the component depends on.  Copy this file to "ant.properties"
  # in the source directory, and customize it as needed.
  #
  # $Id: ant.properties.sample,v 1.1 2002/03/24 07:41:29 donaldp Exp $
  # 
-----------------------------------------------------------------------------
  
  
  # ----- Compile Control Flags -----
  build.debug=on
  build.optimize=off
  build.deprecation=off
  
  # ----- Base Directory in which all the packages are stored -----
  base.path=/opt
  
  # --------------------------------------------------
  #                REQUIRED LIBRARIES
  # --------------------------------------------------
  
  
  # ----- JUnit Unit Test Suite, version 3.7 or later -----
  junit.home=${base.path}/junit3.7
  junit.lib=${junit.home}
  junit.jar=${junit.lib}/junit.jar
  
  
  
  # --------------------------------------------------
  #                OPTIONAL LIBRARIES
  # --------------------------------------------------
  
  # ----- Checkstyle, version 2.1 or later -----
  
  # Uncomment the 'do.checkstyle' flag property to enable checkstyle
  # do.checkstyle=
  checkstyle.home=${base.path}/checkstyle-2.1
  checkstyle.lib=${checkstyle.home}
  checkstyle.jar=${checkstyle.lib}/checkstyle-all-2.1.jar
  
  # ----- Java Management Extensions (JMX) RI, version 1.0.1 or later -----
  jmx.home=${base.path}/jmx-ri_1.0.1/jmx
  jmx.lib=${jmx.home}/lib
  jmx.jar=${jmx.lib}/jmxri.jar
  
  
  
  1.1                  jakarta-avalon-excalibur/baxter/build.bat
  
  Index: build.bat
  ===================================================================
  @echo off
  
  set BASE=..
  call %BASE%\build.bat %1 %2 %3 %4 %5 %6 %7 %8
  
  
  
  1.1                  jakarta-avalon-excalibur/baxter/build.sh
  
  Index: build.sh
  ===================================================================
  #!/bin/sh
  
  BASE=`dirname $0`  # Directory containing this script. Not the same as $PWD.
  
  $BASE/../build.sh -f $BASE/build.xml
  
  
  
  1.1                  jakarta-avalon-excalibur/baxter/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <project name="Excalibur Baxter" default="main" basedir=".">
  
      <!-- load per-project properties -->
      <property file="project.properties"/>
  
      <!--
        Give user a chance to override without editing this file
        (and without typing -D each time he compiles it)
      -->
      <property file="ant.properties"/>
      <property file="../ant.properties"/>
      <property file="${user.home}/.ant.properties"/>
  
      <!-- Settings used to configure compile environment -->
      <property name="build.debug" value="on"/>
      <property name="build.optimize" value="off"/>
      <property name="build.deprecation" value="off"/>
      <property name="build.compress" value="false"/>
      <property name="junit.failonerror" value="false"/>
  
      <!-- location of intermediate products -->
      <property name="build.dir" value="build"/>
      <property name="build.lib" value="${build.dir}/lib"/>
      <property name="build.classes" value="${build.dir}/classes"/>
      <property name="build.tests" value="${build.dir}/tests"/>
      <property name="build.reports" value="${build.dir}/reports"/>
  
      <!-- Set the properties for source directories -->
      <property name="src.dir" value="src"/>
      <property name="java.dir" value="${src.dir}/java"/>
      <property name="test.dir" value="${src.dir}/test"/>
  
      <!-- Set the properties for distribution directories -->
      <property name="dist.dir" value="dist"/>
      <property name="dist.javadocs" value="${dist.dir}/docs/api"/>
  
      <!-- property to specify name of zip/jar files -->
      <property name="dist.name" value="excalibur-${name}-${version}"/>
  
      <!-- property indicating directory where all distribution archives are 
placed -->
      <property name="dist.base" value="distributions"/>
  
      <!-- Classpath for product -->
      <path id="project.class.path">
          <pathelement path="${java.class.path}"/>
          <pathelement location="${build.classes}"/>
          <pathelement location="${junit.jar}"/>
          <pathelement location="${jmx.jar}"/>
          <pathelement location="${checkstyle.jar}"/>
      </path>
  
      <target name="main" depends="dist" description="Build the project"/>
      <target name="rebuild" depends="clean,main" description="Rebuild the 
project"/>
  
      <!-- Compiles the source code -->
      <target name="compile" description="Compiles the source code">
  
          <mkdir dir="${build.classes}"/>
  
          <!-- Compile all classes including the tests. -->
          <javac srcdir="${java.dir}"
              destdir="${build.classes}"
              debug="${build.debug}"
              optimize="${build.optimize}"
              deprecation="${build.deprecation}"
              target="1.2">
              <classpath refid="project.class.path" />
              <src path="${test.dir}"/>
              <include name="**/*.java"/>
          </javac>
  
          <!-- copy resources to same location as .class files -->
          <copy todir="${build.classes}">
              <fileset dir="${java.dir}">
                  <exclude name="**/*.java"/>
              </fileset>
          </copy>
  
          <copy todir="${build.classes}">
              <fileset dir="${test.dir}">
                  <exclude name="**/*.java"/>
              </fileset>
          </copy>
  
      </target>
  
      <!-- Creates all the .jar file -->
      <target name="jar" depends="compile" description="Generates the jar 
files">
  
          <mkdir dir="${build.lib}"/>
  
          <jar jarfile="${build.lib}/${dist.name}.jar"
              basedir="${build.classes}"
              compress="${build.compress}">
              <exclude name="**/test/**"/>
              <zipfileset dir=".." prefix="META-INF/">
                  <include name="LICENSE.txt"/>
              </zipfileset>
          </jar>
      </target>
  
      <!-- Creates all the Javadocs -->
      <target name="javadocs" depends="compile" description="Generates the 
javadocs">
  
          <mkdir dir="${dist.javadocs}"/>
          <javadoc packagenames="org.apache.*"
              sourcepath="${java.dir}"
              destdir="${dist.javadocs}">
              <classpath refid="project.class.path" />
              <doclet name="com.sun.tools.doclets.standard.Standard">
                  <param name="-author"/>
                  <param name="-version"/>
                  <param name="-doctitle" value="${Name}"/>
                  <param name="-windowtitle" value="${Name} API"/>
                  <param name="-link" 
value="http://java.sun.com/j2se/1.4/docs/api/"/>
                  <param name="-link" 
value="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/"/>
                  <param name="-link" 
value="http://jakarta.apache.org/avalon/api/"/>
                  <param name="-bottom"
                      value="&quot;Copyright &#169; ${year} Apache Jakarta 
Project. All Rights Reserved.&quot;"/>
              </doclet>
          </javadoc>
      </target>
  
      <target name="test" depends="compile" description="Perform the unit 
tests">
  
          <echo message="Performing Unit Tests" />
  
          <mkdir dir="${build.tests}"/>
  
          <junit fork="true"
              haltonfailure="${junit.failonerror}"
              printsummary="yes"
              dir="${build.tests}">
              <classpath refid="project.class.path"/>
  
              <formatter type="xml"/>    <!-- xml reports for junitreport -->
              <formatter type="plain"/>  <!-- text reports for humans     -->
  
              <batchtest todir="${build.tests}">
                  <fileset dir="${build.classes}">
                      <include name="**/test/*TestCase.class"/>
                      <exclude name="**/Abstract*"/>
                  </fileset>
              </batchtest>
          </junit>
  
      </target>
  
      <target name="test-reports" depends="test" description="Generate Reports 
for the unit tests">
  
          <mkdir dir="${build.reports}/junit"/>
  
          <junitreport todir="${build.reports}/junit">
              <fileset dir="${build.tests}">
                  <include name="TEST-*.xml"/>
              </fileset>
              <report format="frames" todir="${build.reports}/junit"/>
          </junitreport>
  
          <!-- Clean up the xml reports used by the junitreport task -->
          <!--
          <delete>
              <fileset dir="${build.tests}" includes="TEST-*.xml"/>
              <fileset dir="${build.tests}" includes="TESTS-*.xml"/>
          </delete>
          -->
  
      </target>
  
      <target name="jdepend" if="do.jdepend" description="Generate Dependency 
Analysis Report">
  
          <!-- this invocation of jdepend requires the CVS version of ant for 
the xml format -->
          <!-- thats why you are required to define do.jdepend property to 
generate the report -->
          <jdepend outputfile="${build.dir}/jdepend-results.xml" format="xml" 
fork="yes">
              <classpath refid="project.class.path"/>
              <sourcespath>
                  <pathelement location="src/java" />
              </sourcespath>
          </jdepend>
  
          <mkdir dir="${build.reports}/jdepend"/>
          <style in="${build.dir}/jdepend-results.xml"
              processor="trax"
              out="${build.reports}/jdepend/delete-me.txt"
              style="${ant.home}/etc/jdepend-frames.xsl"/>
      </target>
  
      <target name="checkstyle" if="do.checkstyle" description="Checkstyle">
  
          <!-- this invocation of checkstyle requires that checkstyle be 
downloaded and setup -->
          <!-- thats why you are required to define do.checkstyle property to 
generate the report -->
          <taskdef name="checkstyle"
              classname="com.puppycrawl.tools.checkstyle.CheckStyleTask">
              <classpath refid="project.class.path"/>
          </taskdef>
          <checkstyle
              lcurlyType="nl"
              lcurlyMethod="nl"
              lcurlyOther="nl"
              rcurly="ignore"
              allowProtected="false"
              allowPackage="false"
              allowNoAuthor="false"
              maxLineLen="100"
              maxMethodLen="100"
              maxConstructorLen="100"
              memberPattern="^m_[a-z][a-zA-Z0-9]*$"
              staticPattern="^c_[a-z][a-zA-Z0-9]*$"
              constPattern="(^c_[a-z][a-zA-Z0-9]*$)|([A-Z_]*$)"
              ignoreImportLen="true"
              allowTabs="false"
              javadocScope="protected"
              ignoreWhitespace="true"
              cacheFile="checkstyle.cache"
              failOnViolation="false"
              ignoreCastWhitespace="true">
              <fileset dir="${java.dir}">
                  <include name="**/*.java"/>
              </fileset>
              <formatter type="plain"/>
              <formatter type="xml" toFile="build/checkstyle-results.xml"/>
          </checkstyle>
      </target>
  
      <target name="checkstyle-report"
          depends="checkstyle"
          if="do.checkstyle"
          description="Generate Checkstyle Report">
  
          <mkdir dir="${build.reports}/checkstyle"/>
          <style style="../tools/etc/checkstyle-frames.xsl" 
in="build/checkstyle-results.xml"
              out="${build.reports}/checkstyle/delete-me.html"/>
  
      </target>
  
      <!-- Creates the distribution -->
      <target name="dist"
          depends="jar, test-reports, jdepend, checkstyle-report, javadocs"
          description="Generates the jar files">
  
          <mkdir dir="${dist.dir}"/>
          <copy file="${build.lib}/${dist.name}.jar" todir="${dist.dir}"/>
          <copy file="../LICENSE.txt" todir="${dist.dir}"/>
          <copy file="../KEYS" todir="${dist.dir}"/>
          <copy file="README.txt" todir="${dist.dir}"/>
  
          <mkdir dir="${dist.base}"/>
  
          <zip zipfile="${dist.base}/${dist.name}-bin.zip" compress="true">
              <zipfileset dir="${dist.dir}" prefix="${dist.name}"/>
          </zip>
  
          <!--
            Not supported by released ant but when it is we should enable this 
across
            all of the products
          <tar longfile="gnu" tarfile="${dist.base}/${dist.name}-bin.tar">
            <tarfileset dir="${dist.dir}"
                        prefix="${dist.name}"
                        username="avalon"
                        group="avalon"/>
          </tar>
  
          <gzip zipfile="${dist.base}/${dist.name}-bin.tar.gz"
                src="${dist.name}-bin.tar"/>
          <bzip2 zipfile="${dist.base}/${dist.name}-bin.tar.gz"
                 src="${dist.name}-bin.tar"/>
  
          <delete file="${dist.base}/${dist.name}-bin.tar"/>
  
          <checksum fileext=".md5">
            <fileset dir="${dist.base}" />
          </checksum>
          -->
          <delete dir="${dist.dir}" />
  
      </target>
  
      <!-- Cleans up build and distribution directories -->
      <target name="clean" description="Cleans up the project">
          <delete file="checkstyle.cache"/>
          <delete dir="${build.dir}" />
          <delete dir="${dist.dir}" />
          <delete dir="test" /> <!-- unit testing output directory -->
          <delete>
              <fileset dir="." includes="**/*~" defaultexcludes="no"/>
          </delete>
      </target>
  
      <target name="real-clean" depends="clean" description="Cleans up the 
project, including distributions">
          <delete dir="${dist.base}" />
      </target>
  
  </project>
  
  
  
  1.1                  jakarta-avalon-excalibur/baxter/project.properties
  
  Index: project.properties
  ===================================================================
  name=baxter
  Name=Baxter
  version=1.0a
  year=2000-2002
  
  
  
  1.1                  jakarta-avalon-excalibur/baxter/examples/README.txt
  
  Index: README.txt
  ===================================================================
  This directory contains a number of examples for the component.
  They are;
  
  
  
  1.1                  
jakarta-avalon-excalibur/baxter/src/java/org/apache/avalon/excalibur/baxter/AbstractMBean.java
  
  Index: AbstractMBean.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.baxter;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import javax.management.Attribute;
  import javax.management.AttributeList;
  import javax.management.AttributeNotFoundException;
  import javax.management.DynamicMBean;
  import javax.management.InvalidAttributeValueException;
  import javax.management.MBeanAttributeInfo;
  import javax.management.MBeanException;
  import javax.management.MBeanInfo;
  import javax.management.MBeanNotificationInfo;
  import javax.management.MBeanOperationInfo;
  import javax.management.MBeanParameterInfo;
  import javax.management.NotificationBroadcasterSupport;
  import javax.management.ReflectionException;
  
  /**
   * This is an abstract class that can be used to support creation
   * of <code>DynamicMBean</code> objects. The developer is expected to
   * overide the create...() methods to provide useful elements for their
   * particular purpose.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a>
   * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/24 07:41:29 $
   */
  public abstract class AbstractMBean
      extends NotificationBroadcasterSupport
      implements DynamicMBean
  {
      private static final Object[] EMPTY_OBJ_ARRAY = new Object[ 0 ];
  
      /**
       * The object represented by this MBean
       */
      private final Object m_object;
  
      /**
       * The MBeanInfo object.
       */
      private MBeanInfo m_mBeanInfo;
  
      /**
       * The human readable description of the class.
       */
      private String m_description;
  
      /**
       * The MBean attribute entrys.
       */
      private AttributeEntry[] m_attributes;
  
      /**
       * The MBean operation entrys.
       */
      private OperationEntry[] m_operations;
  
      /**
       * The MBean notification descriptors.
       */
      private MBeanNotificationInfo[] m_notifications;
  
      /**
       * Constructor that takes object managed and description of object.
       *
       * @param object the object to be managed (may be this)
       */
      protected AbstractMBean( final Object object )
      {
          m_object = object;
      }
  
      /**
       * Retrieve NotificationInfo objects that this
       * MBean exports.
       *
       * <p>Note to change the notifications supported the user
       * should overide the createNotificationInfos() method.
       *
       * @return the MBeanNotificationInfo objects
       */
      public final MBeanNotificationInfo[] getNotificationInfo()
      {
          return m_notifications;
      }
  
      /**
       * Provides the exposed attributes and actions of the Dynamic MBean using 
an
       * MBeanInfo object.
       *
       * @return An instance of <code>MBeanInfo</code> allowing all attributes 
and
       *      actions exposed by this Dynamic MBean to be retrieved.
       */
      public synchronized MBeanInfo getMBeanInfo()
      {
          return m_mBeanInfo;
      }
  
      /**
       * Obtains the value of a specific attribute of the Dynamic MBean.
       *
       * @param attribute The name of attribute to retrieve
       * @return The Attribute value
       * @exception AttributeNotFoundException If no such attribute exists
       * @exception MBeanException if an error occurs retrieving attribute
       * @exception ReflectionException if a reflection error occurs
       */
      public Object getAttribute( final String attribute )
          throws AttributeNotFoundException, MBeanException, ReflectionException
      {
          final AttributeEntry entry = getAttributeEntry( attribute );
          final Method method = entry.getReadMethod();
  
          if( null == method )
          {
              throw new AttributeNotFoundException( attribute );
          }
  
          try
          {
              return method.invoke( getObject(), EMPTY_OBJ_ARRAY );
          }
          catch( final InvocationTargetException ite )
          {
              throw new MBeanException( ite );
          }
          catch( final Exception e )
          {
              throw new ReflectionException( e );
          }
      }
  
      /**
       * Enables the values of several attributes of the Dynamic MBean.
       *
       * @param names the names of attributes to get
       * @return The Attributes retrieved
       */
      public AttributeList getAttributes( final String[] names )
      {
          final AttributeList atributes = new AttributeList();
          for( int i = 0; i < names.length; i++ )
          {
              final String name = names[ i ];
              try
              {
                  final Object value = getAttribute( name );
                  final Attribute attribute = new Attribute( name, value );
                  atributes.add( attribute );
              }
              catch( final Exception e )
              {
                  //Not sure what todo here
              }
          }
          return atributes;
      }
  
      /**
       * Allows an action to be invoked on the Dynamic MBean.
       *
       * @param action The name of the action to be invoked.
       * @param params An array containing the parameters to be set when the
       *      action is invoked.
       * @param signature An array containing the signature of the action. The
       *      class objects will be loaded through the same class loader as the
       *      one used for loading the MBean on which the action is invoked.
       * @return The object returned by the action, which represents the result 
of
       *      invoking the action on the MBean specified.
       * @exception MBeanException Wraps a <code>java.lang.Exception</code> 
thrown
       *      by the MBean's invoked method.
       * @exception ReflectionException Wraps a <code>java.lang.Exception</code>
       *      thrown while trying to invoke the method
       */
      public Object invoke( final String action,
                            final Object[] params,
                            final String[] signature )
          throws MBeanException, ReflectionException
      {
          final OperationEntry entry = getOperationEntry( action, signature );
          final Method method = entry.getMethod();
          try
          {
              return method.invoke( getObject(), params );
          }
          catch( final InvocationTargetException ite )
          {
              throw new MBeanException( ite );
          }
          catch( final Exception e )
          {
              throw new ReflectionException( e );
          }
      }
  
      /**
       * Sets the value of a specific attribute of the Dynamic MBean
       *
       * @param attribute The new Attribute value
       * @exception AttributeNotFoundException if no such attribute exists
       * @exception InvalidAttributeValueException if provided value is invalid
       * @exception MBeanException if setting value raises exception
       * @exception ReflectionException if there is an error aquiring 
appropriate method
       */
      public void setAttribute( final Attribute attribute )
          throws AttributeNotFoundException, InvalidAttributeValueException,
          MBeanException, ReflectionException
      {
          final AttributeEntry entry = getAttributeEntry( attribute.getName() );
          final Method method = entry.getWriteMethod();
  
          if( null == method )
          {
              throw new AttributeNotFoundException( attribute.getName() );
          }
  
          try
          {
              method.invoke( getObject(), new Object[]{attribute.getValue()} );
          }
          catch( final IllegalArgumentException iae )
          {
              throw new InvalidAttributeValueException();
          }
          catch( final InvocationTargetException ite )
          {
              throw new MBeanException( ite );
          }
          catch( final Exception e )
          {
              throw new ReflectionException( e );
          }
      }
  
      /**
       * Sets the values of several attributes of the Dynamic MBean.
       *
       * @param input The new Attributes value
       * @return The attributes actually set
       */
      public AttributeList setAttributes( final AttributeList input )
      {
          final AttributeList atributes = new AttributeList();
          final int size = input.size();
          for( int i = 0; i < size; i++ )
          {
              try
              {
                  final Attribute attribute = (Attribute)input.get( i );
                  setAttribute( attribute );
                  atributes.add( attribute );
              }
              catch( final Exception e )
              {
                  //Not sure what todo here
              }
          }
          return atributes;
      }
  
      /**
       * Retrieve the underlying object that is being managed.
       *
       * @return the managed object
       */
      protected final Object getObject()
      {
          return m_object;
      }
  
      /**
       * Method that developer calls in subclass when they need to prepare the
       * object for use. This creates all the operation, attribute and
       * notification arrays and MBeanInfo by calling the respective create
       * methods.
       */
      protected synchronized void initialize()
      {
          m_description = createDescription();
          m_operations = createOperations();
          m_attributes = createAttributes();
          m_notifications = createNotificationInfos();
          m_mBeanInfo = createMBeanInfo();
      }
  
      /**
       * Utility method called by initialize to create description.
       * A developer should overide this method in subclasses to provide their 
own
       * description.
       *
       * @return the Description
       */
      protected synchronized String createDescription()
      {
          return null;
      }
  
      /**
       * Utility method called by initialize to create OperationEntry objects.
       * A developer should overide this method in subclasses to provide their 
own
       * operations.
       *
       * @return the OperationEntry objests
       */
      protected synchronized OperationEntry[] createOperations()
      {
          return new OperationEntry[ 0 ];
      }
  
      /**
       * Utility method called by initialize to create AttributeEntry objects.
       * A developer should overide this method in subclasses to provide their 
own
       * attributes.
       *
       * @return the AttributeEntry objests
       */
      protected synchronized AttributeEntry[] createAttributes()
      {
          return new AttributeEntry[ 0 ];
      }
  
      /**
       * Utility method called by initialize to create MBeanNotificationInfo 
objects.
       * A developer should overide this method in subclasses to provide their 
own
       * NotificationInfos.
       *
       * @return the MBeanNotificationInfo objests
       */
      protected synchronized MBeanNotificationInfo[] createNotificationInfos()
      {
          return new MBeanNotificationInfo[ 0 ];
      }
  
      /**
       * Helper method for get/setAttribute to retrieve AttributeEntry.
       *
       * @param name the name of attribute
       * @return the AttributeEntry
       * @exception AttributeNotFoundException if attribute not found
       */
      private synchronized AttributeEntry getAttributeEntry( final String name )
          throws AttributeNotFoundException
      {
          for( int i = 0; i < m_attributes.length; i++ )
          {
              final String other = m_attributes[ i ].getInfo().getName();
              if( other.equals( name ) )
              {
                  return m_attributes[ i ];
              }
          }
  
          throw new AttributeNotFoundException();
      }
  
      /**
       * Helper method for invoke() that finds the correct OperationEntry.
       *
       * @param action the name of operation
       * @param params the parameters of operation
       * @return the OperationEntry
       * @exception ReflectionException if can not find operation
       */
      private synchronized OperationEntry getOperationEntry( final String 
action,
                                                             final String[] 
params )
          throws ReflectionException
      {
          for( int i = 0; i < m_operations.length; i++ )
          {
              final MBeanOperationInfo info = m_operations[ i ].getInfo();
              final MBeanParameterInfo[] paramInfos = info.getSignature();
  
              //If operation doesn't have same name and
              //same number of parameters then it is
              //not the droids we are looking for
              if( !info.getName().equals( action ) ||
                  paramInfos.length != params.length )
              {
                  continue;
              }
  
              boolean found = true;
              for( int j = 0; j < paramInfos.length; j++ )
              {
                  final String param = paramInfos[ j ].getType();
                  if( !params[ j ].equals( param ) )
                  {
                      found = false;
                      break;
                  }
              }
  
              //If all the parameters have same
              //type then we have found a match
              //so return it
              if( found )
              {
                  return m_operations[ i ];
              }
          }
  
          throw new ReflectionException( new NoSuchMethodException( action ) );
      }
  
      /**
       * Utility method to create MBeanInfo.
       *
       * @return the new MBeanInfo
       */
      private synchronized MBeanInfo createMBeanInfo()
      {
          final MBeanAttributeInfo[] attributes =
              new MBeanAttributeInfo[ m_attributes.length ];
          for( int i = 0; i < attributes.length; i++ )
          {
              attributes[ i ] = m_attributes[ i ].getInfo();
          }
  
          final MBeanOperationInfo[] operations =
              new MBeanOperationInfo[ m_operations.length ];
          for( int i = 0; i < operations.length; i++ )
          {
              operations[ i ] = m_operations[ i ].getInfo();
          }
  
          return new MBeanInfo( getObject().getClass().getName(),
                                m_description,
                                attributes,
                                null,
                                operations,
                                m_notifications );
      }
  }
  
  
  
  1.1                  
jakarta-avalon-excalibur/baxter/src/java/org/apache/avalon/excalibur/baxter/AttributeEntry.java
  
  Index: AttributeEntry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.baxter;
  
  import java.lang.reflect.Method;
  import javax.management.IntrospectionException;
  import javax.management.MBeanAttributeInfo;
  
  class AttributeEntry
  {
      private MBeanAttributeInfo m_info;
      private Method m_readMethod;
      private Method m_writeMethod;
  
      protected AttributeEntry( final String name,
                                final String description,
                                final Method readMethod,
                                final Method writeMethod )
          throws IntrospectionException
      {
          m_info = new MBeanAttributeInfo( name, description, readMethod, 
writeMethod );
          m_readMethod = readMethod;
          m_writeMethod = writeMethod;
      }
  
      public MBeanAttributeInfo getInfo()
      {
          return m_info;
      }
  
      public Method getReadMethod()
      {
          return m_readMethod;
      }
  
      public Method getWriteMethod()
      {
          return m_writeMethod;
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-excalibur/baxter/src/java/org/apache/avalon/excalibur/baxter/ConstructiveMBean.java
  
  Index: ConstructiveMBean.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.baxter;
  
  import java.beans.Introspector;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.util.ArrayList;
  import javax.management.IntrospectionException;
  import javax.management.MBeanOperationInfo;
  import javax.management.MBeanParameterInfo;
  
  /**
   * Base Class to allow MBeans to be constructed programatically via
   * simple method calls. The attributes and operations of MBean are
   * verified by reflection,
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/24 07:41:30 $
   */
  public abstract class ConstructiveMBean
      extends AbstractMBean
  {
      private static final String[] EMPTY_STR_ARRAY = new String[ 0 ];
  
      /**
       * A constant for ACTION impact added for ease of use in sub-classes.
       *
       * @see MBeanOperationInfo#ACTION
       */
      protected static final int ACTION = MBeanOperationInfo.ACTION;
  
      /**
       * A constant for ACTION_INFO impact added for ease of use in sub-classes.
       *
       * @see MBeanOperationInfo#ACTION_INFO
       */
      protected static final int ACTION_INFO = MBeanOperationInfo.ACTION_INFO;
  
      /**
       * A constant for INFO impact added for ease of use in sub-classes.
       *
       * @see MBeanOperationInfo#INFO
       */
      protected static final int INFO = MBeanOperationInfo.INFO;
  
      /**
       * A constant for UNKNOWN impact added for ease of use in sub-classes.
       *
       * @see MBeanOperationInfo#UNKNOWN
       */
      protected static final int UNKNOWN = MBeanOperationInfo.UNKNOWN;
  
      /**
       * The temporary list of operations used to create operation list.
       */
      private ArrayList m_operations = new ArrayList();
  
      /**
       * The temporary list of attributes used to create attribute list.
       */
      private ArrayList m_attributes = new ArrayList();
  
      /**
       * Construct a MBean and check if permission is granted
       * to create specified MBean.
       *
       * @param object the object to adapt
       * @throws IllegalArgumentException if error introspecting bean
       */
      public ConstructiveMBean( final Object object )
          throws IllegalArgumentException
      {
          this( object, true );
      }
  
      /**
       * Construct a MBean and if secure is true then check if permission
       * is granted to create specified MBean.
       *
       * @param object the object to adapt
       * @param secure if true then check permission before creating Mbean
       * @throws IllegalArgumentException if error introspecting bean
       */
      public ConstructiveMBean( final Object object, final boolean secure )
          throws IllegalArgumentException
      {
          super( object );
  
          if( secure )
          {
              final SecurityManager sm = System.getSecurityManager();
              if( null != sm )
              {
                  final String classname = object.getClass().getName();
                  final JMXPermission permission = new JMXPermission( "create", 
classname );
                  sm.checkPermission( permission );
              }
          }
  
          defineObject();
  
          initialize();
  
          m_attributes.clear();
          m_operations.clear();
          m_attributes = null;
          m_operations = null;
      }
  
      /**
       * Utility method called to define manageable
       * objects attributes and operations.
       */
      protected abstract void defineObject();
  
      /**
       * Utility method to define an attribute with specified name.
       *
       * @param name the attribute name
       */
      protected final void addAttribute( final String name )
      {
          addAttribute( name, true );
      }
  
      /**
       * Utility method to define an attribute with specified name and
       * specify whether it is writeable.
       *
       * @param name the attribute name
       * @param isWriteable true if attribute is writeable, false
       *        otherwise
       */
      protected final void addAttribute( final String name,
                                         final boolean isWriteable )
      {
          addAttribute( name, isWriteable, null );
      }
  
      /**
       * Utility method to define an attribute with specified name and 
description.
       *
       * @param name the attribute name
       * @param isWriteable true if attribute is writeable, false otherwise
       * @param description the description
       */
      protected final void addAttribute( final String name,
                                         final boolean isWriteable,
                                         final String description )
      {
          final String property = Introspector.decapitalize( name );
          final String methodPropertyName =
              property.substring( 0, 1 ).toUpperCase() + property.substring( 1 
);
  
          final String getAccessorName = "get" + methodPropertyName;
          final String isAccessorName = "is" + methodPropertyName;
          final String mutatorName = "set" + methodPropertyName;
  
          Method accessor = null;
  
          final Class clazz = getObject().getClass();
          final Method[] methods = clazz.getMethods();
          for( int i = 0; i < methods.length; i++ )
          {
              final Method method = methods[ i ];
  
              if( 0 == ( Modifier.PUBLIC & method.getModifiers() ) )
              {
                  //If method is not public then skip it
                  continue;
              }
  
              //Look for a accessor
              if( 0 == method.getParameterTypes().length )
              {
                  if( method.getName().equals( getAccessorName ) ||
                      method.getName().equals( isAccessorName ) )
                  {
                      accessor = method;
                      break;
                  }
              }
          }
  
          if( null == accessor )
          {
              throw new IllegalArgumentException( "Unable to locate accessor 
for property " +
                                                  name );
          }
  
          Method mutator = null;
          if( isWriteable )
          {
              final Class[] params = new Class[]{accessor.getReturnType()};
              try
              {
                  mutator = clazz.getMethod( mutatorName, params );
              }
              catch( final NoSuchMethodException nsme )
              {
                  throw new IllegalArgumentException( "Unable to locate mutator 
for property " +
                                                      name );
              }
          }
  
          try
          {
              final AttributeEntry entry =
                  new AttributeEntry( name, description, accessor, mutator );
              m_attributes.add( entry );
          }
          catch( final IntrospectionException ie )
          {
              throw new IllegalArgumentException( "Unable to add attribute due 
to " + ie );
          }
      }
  
      /**
       * Utility method to define an operation with specified name and impact.
       * Operation is parameter method.
       *
       * @param name the operation name
       * @param impact the operation impact
       */
      protected final void addOperation( final String name, final int impact )
      {
          addOperation( name, impact, null );
      }
  
      /**
       * Utility method to define an operation with specified name, impact and 
description.
       *
       * @param name the operation name
       * @param impact the operation impact
       * @param description the description of operation
       */
      protected final void addOperation( final String name,
                                         final int impact,
                                         final String description )
      {
          addOperation( name, EMPTY_STR_ARRAY, impact, description, 
EMPTY_STR_ARRAY );
      }
  
      /**
       * Utility method to define an operation with specified
       * name, parameter types and impact.
       *
       * @param name the operation name
       * @param params the class names of parameters
       * @param impact the operation impact
       */
      protected final void addOperation( final String name,
                                         final String[] params,
                                         final int impact )
      {
  
          addOperation( name, params, impact, null );
      }
  
      /**
       * Utility method to define an operation with specified
       * name, parameter types, impact and description.
       *
       * @param name the operation name
       * @param params the class names of parameters
       * @param impact the operation impact
       * @param description the description of operation
       */
      protected final void addOperation( final String name,
                                         final String[] params,
                                         final int impact,
                                         final String description )
      {
          addOperation( name, params, impact, description, null );
      }
  
      /**
       * Utility method to define an operation with specified
       * name, parameter types, impact and description.
       *
       * @param name the operation name
       * @param params the class names of parameters
       * @param impact the operation impact
       * @param description the description of operation
       * @param paramNames the names of all the parameters
       */
      protected final void addOperation( final String name,
                                         final String[] params,
                                         final int impact,
                                         final String description,
                                         final String[] paramNames )
      {
          addOperation( name, params, impact, description, null, null );
      }
  
      /**
       * Utility method to define an operation with specified
       * name, parameter types, impact, description and parameter
       * descriptions.
       *
       * @param name the operation name
       * @param params the class names of parameters
       * @param impact the operation impact
       * @param description the description of operation
       * @param paramNames the names of all the parameters
       * @param paramsDescription the description of parameters
       */
      protected final void addOperation( final String name,
                                         final String[] params,
                                         final int impact,
                                         final String description,
                                         final String[] paramNames,
                                         final String[] paramsDescription )
      {
          if( null != paramNames && params.length != paramNames.length )
          {
              final String message = "Params length not match param names 
length";
              throw new IllegalArgumentException( message );
          }
  
          if( null != paramsDescription && params.length != 
paramsDescription.length )
          {
              final String message = "Params length not match params 
description length";
              throw new IllegalArgumentException( message );
          }
  
          final Class clazz = getObject().getClass();
          final ClassLoader classLoader = clazz.getClassLoader();
          final Class[] paramTypes = new Class[ params.length ];
          final MBeanParameterInfo[] paramInfos = new MBeanParameterInfo[ 
params.length ];
          for( int i = 0; i < params.length; i++ )
          {
              final String param = params[ i ];
              final String paramName =
                  ( null != paramNames ) ? paramNames[ i ] : "param" + i;
              final String paramDescription =
                  ( null != paramsDescription ) ? paramsDescription[ i ] : null;
  
              paramInfos[ i ] = new MBeanParameterInfo( paramName, param, 
paramDescription );
  
              try
              {
                  paramTypes[ i ] = classLoader.loadClass( param );
              }
              catch( final Exception e )
              {
                  throw new IllegalArgumentException( "error loading param type 
(" + param +
                                                      ") due to " + e );
              }
          }
  
          Method method = null;
          try
          {
              method = clazz.getMethod( name, paramTypes );
          }
          catch( final Exception e )
          {
              throw new IllegalArgumentException( "error retrieving method due 
to " + e );
          }
  
          final String type = method.getReturnType().getName();
          final MBeanOperationInfo info =
              new MBeanOperationInfo( name, description, paramInfos, type, 
impact );
          final OperationEntry entry = new OperationEntry( info, method );
          m_operations.add( entry );
      }
  
      /**
       * Utility method called by initialize to create OperationEntry objects.
       *
       * @return the OperationEntry objests
       */
      protected OperationEntry[] createOperations()
      {
          return (OperationEntry[])m_operations.toArray( new OperationEntry[ 0 
] );
      }
  
      /**
       * Utility method called by initialize to create AttributeEntry objects.
       *
       * @return the AttributeEntry objests
       */
      protected synchronized AttributeEntry[] createAttributes()
      {
          return (AttributeEntry[])m_attributes.toArray( new AttributeEntry[ 0 
] );
      }
  }
  
  
  
  1.1                  
jakarta-avalon-excalibur/baxter/src/java/org/apache/avalon/excalibur/baxter/JMXPermission.java
  
  Index: JMXPermission.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.baxter;
  
  import java.security.BasicPermission;
  
  /**
   * Permission used to check creation of <code>ConstructiveMBean</code> 
objects.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
   */
  public class JMXPermission
      extends BasicPermission
  {
      /**
       * Create a permission object with specified name and action.
       *
       * @param name the name of permission
       * @param action the action for permission (often name of class)
       */
      public JMXPermission( final String name, final String action )
      {
          super( name, action );
      }
  }
  
  
  
  1.1                  
jakarta-avalon-excalibur/baxter/src/java/org/apache/avalon/excalibur/baxter/JavaBeanMBean.java
  
  Index: JavaBeanMBean.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.baxter;
  
  import java.beans.BeanInfo;
  import java.beans.Introspector;
  import java.beans.MethodDescriptor;
  import java.beans.ParameterDescriptor;
  import java.beans.PropertyDescriptor;
  import java.lang.reflect.Method;
  import java.util.ArrayList;
  import javax.management.IntrospectionException;
  import javax.management.MBeanOperationInfo;
  
  /**
   * Class to automatically manage a JavaBean. A BeanInfo is created for the
   * object to be managed and its propertys are translated into attributes,
   * and it's Methods translated into operations.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a>
   * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/24 07:41:30 $
   */
  public class JavaBeanMBean
      extends AbstractMBean
  {
      /**
       * The BeanInfo representing this MBean
       */
      private BeanInfo m_beanInfo;
  
      /**
       * Methods for Operations that are allowed to operate on object.
       */
      private MethodDescriptor[] m_allowedOperations;
  
      /**
       * Propertys for Attributes that are allowed for object.
       */
      private PropertyDescriptor[] m_allowedAttributes;
  
      /**
       * Construct a MBean for specified object
       * addin all JavaBean properties as MBean properties and
       * JavaBean methods as MBean operations.
       *
       * @param object the object to adapt
       * @throws IllegalArgumentException if a non-JavaBean is passed in
       */
      public JavaBeanMBean( final Object object )
          throws IllegalArgumentException
      {
          this( object, null );
      }
  
  
      /**
       * Construct a MBean for specified object
       * Adding all JavaBean properties and JavaBean methods from the
       * specified interfaces as MBean properties and MBean operations.
       * If null is passed in as interfaces parameter then search through all
       * JavaBean proeprties and methods on object.
       *
       * @param object the object to adapt
       * @param interfaces the itnerfaces to use to generate operations and 
attributes of MBean
       * @throws IllegalArgumentException if a non-JavaBean is passed in
       */
      public JavaBeanMBean( final Object object, final Class[] interfaces )
          throws IllegalArgumentException
      {
          super( object );
  
          final Class clazz = object.getClass();
          try
          {
              m_beanInfo = Introspector.getBeanInfo( clazz );
          }
          catch( final Exception e )
          {
              throw new IllegalArgumentException( "Not a compliant javabean!" );
          }
  
          m_allowedOperations = getAllowedOperations( interfaces );
          m_allowedAttributes = getAllowedAttributes( interfaces );
  
          initialize();
  
          m_allowedOperations = null;
          m_allowedAttributes = null;
      }
  
      /**
       * Utility method called by initialize to create description.
       *
       * @return the Description
       */
      protected synchronized String createDescription()
      {
          return m_beanInfo.getBeanDescriptor().getShortDescription();
      }
  
      /**
       * Utility method called by initialize to create OperationEntry objects.
       *
       * @return the OperationEntry objests
       */
      protected OperationEntry[] createOperations()
      {
          final MethodDescriptor[] methods = m_beanInfo.getMethodDescriptors();
          final ArrayList entrys = new ArrayList();
  
          for( int i = 0; i < methods.length; i++ )
          {
              final MethodDescriptor descriptor = methods[ i ];
  
              //Skip disallowed operations
              if( !isAllowedOperation( descriptor ) )
              {
                  continue;
              }
  
              final Method method = descriptor.getMethod();
              final MBeanOperationInfo info =
                  new MBeanOperationInfo( descriptor.getShortDescription(),
                                          method );
  
              entrys.add( new OperationEntry( info, method ) );
          }
  
          return (OperationEntry[])entrys.toArray( new OperationEntry[ 0 ] );
      }
  
      /**
       * Utility method called by initialize to create AttributeEntry objects.
       *
       * @return the AttributeEntry objests
       * @throws IllegalArgumentException if error introspecting attributes
       */
      protected synchronized AttributeEntry[] createAttributes()
          throws IllegalArgumentException
      {
          final PropertyDescriptor[] propertys = 
m_beanInfo.getPropertyDescriptors();
          final ArrayList entrys = new ArrayList();
  
          for( int i = 0; i < propertys.length; i++ )
          {
              final PropertyDescriptor property = propertys[ i ];
  
              //Skip disallowed attributes
              if( !isAllowedAttribute( property ) )
              {
                  continue;
              }
  
              try
              {
                  final AttributeEntry attribute =
                      new AttributeEntry( property.getName(),
                                          property.getShortDescription(),
                                          property.getReadMethod(),
                                          property.getWriteMethod() );
                  entrys.add( attribute );
              }
              catch( final IntrospectionException ie )
              {
                  throw new IllegalArgumentException( "Error introspecting 
properties." );
              }
          }
  
          return (AttributeEntry[])entrys.toArray( new AttributeEntry[ 0 ] );
      }
  
      /**
       * Retrieve a list of allowed operations.
       * Allowed operations are based on interfaces passed in.
       */
      private MethodDescriptor[] getAllowedOperations( final Class[] interfaces 
)
          throws IllegalArgumentException
      {
          if( null == interfaces )
          {
              return null;
          }
  
          final ArrayList operations = new ArrayList();
  
          for( int i = 0; i < interfaces.length; i++ )
          {
              BeanInfo beanInfo = null;
              try
              {
                  beanInfo = Introspector.getBeanInfo( interfaces[ i ] );
              }
              catch( final Exception e )
              {
                  throw new IllegalArgumentException( "The supplied interfaces 
are " +
                                                      "not all valid 
javabeans!" );
              }
  
              final MethodDescriptor[] methods = 
beanInfo.getMethodDescriptors();
              for( int j = 0; j < methods.length; j++ )
              {
                  final MethodDescriptor descriptor = methods[ j ];
                  final Method method = descriptor.getMethod();
                  if( isMutator( method ) || isAccessor( method ) )
                  {
                      continue;
                  }
  
                  operations.add( methods[ j ] );
              }
          }
  
          return (MethodDescriptor[])operations.toArray( new MethodDescriptor[ 
0 ] );
      }
  
      private boolean isMutator( final Method method )
      {
          return
              Void.TYPE == method.getReturnType() &&
              method.getName().startsWith( "set" ) &&
              1 == method.getParameterTypes().length;
      }
  
      private boolean isAccessor( final Method method )
      {
          return
              Void.TYPE != method.getReturnType() &&
              method.getName().startsWith( "get" ) &&
              0 == method.getParameterTypes().length;
      }
  
      /**
       * Retrieve a list of allowed attributes.
       * Allowed attributes are based on interfaces passed in.
       */
      private PropertyDescriptor[] getAllowedAttributes( final Class[] 
interfaces )
          throws IllegalArgumentException
      {
          if( null == interfaces )
          {
              return null;
          }
  
          final ArrayList attributes = new ArrayList();
  
          for( int i = 0; i < interfaces.length; i++ )
          {
              BeanInfo beanInfo = null;
              try
              {
                  beanInfo = Introspector.getBeanInfo( interfaces[ i ] );
              }
              catch( final Exception e )
              {
                  throw new IllegalArgumentException( "The supplied interfaces 
are " +
                                                      "not all valid 
javabeans!" );
              }
  
              final PropertyDescriptor[] propertys = 
beanInfo.getPropertyDescriptors();
              for( int j = 0; j < propertys.length; j++ )
              {
                  attributes.add( propertys[ j ] );
              }
          }
  
          return (PropertyDescriptor[])attributes.toArray( new 
PropertyDescriptor[ 0 ] );
      }
  
      /**
       * Determine if specified descriptor describes an allowed operation.
       * If no interfaces were passed in then all operations are allowed.
       *
       * @param method the operation descriptor
       * @return true if allowed, false otherwise
       */
      private boolean isAllowedOperation( final MethodDescriptor method )
      {
          if( null == m_allowedOperations )
          {
              return true;
          }
  
          final ParameterDescriptor[] params = method.getParameterDescriptors();
  
          for( int i = 0; i < m_allowedOperations.length; i++ )
          {
              final MethodDescriptor other = m_allowedOperations[ i ];
              final ParameterDescriptor[] otherParams = 
other.getParameterDescriptors();
  
              //If operation doesn't have same name and
              //same number of parameters then it is
              //not the droids we are looking for
              if( !other.getName().equals( method.getName() ) )
              {
                  continue;
              }
              else if( null == params && null == otherParams )
              {
                  return true;
              }
              else if( otherParams.length != params.length )
              {
                  continue;
              }
  
              boolean found = true;
              for( int j = 0; j < otherParams.length; j++ )
              {
                  final String type = params[ j ].getName();
                  final String otherType = otherParams[ j ].getName();
                  if( !otherType.equals( type ) )
                  {
                      found = false;
                      break;
                  }
              }
  
              //If all the parameters have same
              //type then we have found a match
              //so return it
              if( found )
              {
                  return true;
              }
          }
  
          return false;
      }
  
      /**
       * Determine if specified descriptor describes an allowed attribute.
       * If no interfaces were passed in then all attributes are allowed.
       *
       * @param property the attribute descriptor
       * @return true if allowed, false otherwise
       */
      private boolean isAllowedAttribute( final PropertyDescriptor property )
      {
          if( null == m_allowedOperations )
          {
              return true;
          }
  
          for( int i = 0; i < m_allowedAttributes.length; i++ )
          {
              final PropertyDescriptor other = m_allowedAttributes[ i ];
  
              //If attribute has same name then we have a match
              if( other.getName().equals( property.getName() ) )
              {
                  return true;
              }
          }
  
          return false;
      }
  }
  
  
  
  1.1                  
jakarta-avalon-excalibur/baxter/src/java/org/apache/avalon/excalibur/baxter/OperationEntry.java
  
  Index: OperationEntry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.baxter;
  
  import java.lang.reflect.Method;
  import javax.management.MBeanOperationInfo;
  
  class OperationEntry
  {
      private MBeanOperationInfo m_info;
      private Method m_method;
  
      protected OperationEntry( final MBeanOperationInfo info,
                                final Method method )
      {
          m_info = info;
          m_method = method;
      }
  
      public MBeanOperationInfo getInfo()
      {
          return m_info;
      }
  
      public Method getMethod()
      {
          return m_method;
      }
  }
  
  
  
  
  1.1                  
jakarta-avalon-excalibur/baxter/src/test/org/apache/avalon/excalibur/baxter/test/BaxterTestSuite.java
  
  Index: BaxterTestSuite.java
  ===================================================================
  /*
   * Copyright  The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.baxter.test;
  
  import junit.framework.Test;
  import junit.framework.TestSuite;
  
  /**
   * A basic test suite that tests all the Baxter package.
   */
  public class BaxterTestSuite
  {
      public static Test suite()
      {
          final TestSuite suite = new TestSuite( "Baxter MBean Utilities" );
          return suite;
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to