avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l...@apache.org
Subject cvs commit: jakarta-avalon-excalibur/instrument-manager/src/test README.txt
Date Tue, 26 Mar 2002 11:56:17 GMT
leif        02/03/26 03:56:17

  Added:       instrument-manager .cvsignore BUILDING.txt README.txt
                        ant.properties.sample build.xml project.properties
               instrument-manager/example .cvsignore ant.properties.sample
                        build.xml
               instrument-manager/example/bin cpappend.bat run.bat run.sh
               instrument-manager/example/conf components.xml
                        instrument.xml logkit.xml roles.xml
               instrument-manager/example/src/java/org/apache/avalon/excalibur/instrument/example
                        DefaultExampleInstrumentable.java
                        ExampleInstrumentable.java Main.java
               instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component
                        InstrumentComponentHandler.java
                        InstrumentComponentManager.java
                        InstrumentComponentSelector.java
                        InstrumentDefaultComponentFactory.java
               instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager
                        AbstractInstrumentSample.java
                        AbstractValueInstrumentSample.java
                        AverageValueInstrumentSample.java
                        CounterInstrumentSample.java
                        DefaultInstrumentManager.java
                        InstrumentDescriptorImpl.java
                        InstrumentManagerClientImpl.java
                        InstrumentProxy.java InstrumentSample.java
                        InstrumentSampleDescriptorImpl.java
                        InstrumentSampleFactory.java
                        InstrumentableDescriptorImpl.java
                        InstrumentableProxy.java
                        MaximumValueInstrumentSample.java
                        MinimumValueInstrumentSample.java
               instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/altrmi
                        InstrumentManagerAltrmiServer.java
               instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client
                        CounterInstrumentListener.java
                        InstrumentDescriptor.java InstrumentListener.java
                        InstrumentManagerClient.java
                        InstrumentSampleDescriptor.java
                        InstrumentSampleListener.java
                        InstrumentSampleSnapshot.java
                        InstrumentableDescriptor.java
                        NoSuchInstrumentException.java
                        NoSuchInstrumentSampleException.java
                        NoSuchInstrumentableException.java
                        ValueInstrumentListener.java
               instrument-manager/src/test README.txt
  Log:
  Check in new instrument-manager sub project.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/instrument-manager/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  ant.properties
  build
  checkstyle.cache
  distributions
  dist
  excalibur-*
  *.el
  *.ipr
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/BUILDING.txt
  
  Index: BUILDING.txt
  ===================================================================
  
                 Building The Component
                 ======================
  
  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) 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.
  
  (7) 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/instrument-manager/README.txt
  
  Index: README.txt
  ===================================================================
                 Avalons Excalibur Instrument
                 ----------------------------
  
  WARNING: Under Development--the API may change
  
  The instrument project provides an API for instrumenting
  components.
  
  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/instrument-manager/ant.properties.sample
  
  Index: ant.properties.sample
  ===================================================================
  # -----------------------------------------------------------------------------
  # Component ant.properties.sample
  #
  # This is an example "ant.properties" file, used to customize the building of
  # the component for your local environment.  It defines the location of all
  # external modules that this component depend on.  Copy this file to
  # "ant.properties" in the source directory, and customize it as needed.
  #
  # The ant.properties values in this directory apply only to this component, and
  # override the defaults in ../ant.properties.
  #
  # $Id: ant.properties.sample,v 1.1 2002/03/26 11:56:15 leif Exp $
  # -----------------------------------------------------------------------------
  
  # --------------------------------------------------
  #      COMPONENT-SPECIFIC REQUIRED LIBRARIES
  # --------------------------------------------------
  
  
  # ----- 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
  # --------------------------------------------------
  
  # ----- Logkit -----
  logkit.home=../../jakarta-avalon-logkit/build/lib
  logkit.jar=${logkit.home}/logkit.jar
  
  # ----- Avalon Framework -----
  avalon-framework.home=../../jakarta-avalon/build/lib
  avalon-framework.jar=${avalon-framework.home}/avalon-framework.jar
  
  # ----- Avalon Excalibur -----
  avalon-excalibur.home=../all/build/lib
  avalon-excalibur.jar=${avalon-excalibur.home}/avalon-excalibur.jar
  
  # ----- Excalibur Instrument -----
  excalibur-instrument.home=../instrument/build/lib
  excalibur-instrument.jar=${excalibur-instrument.home}/excalibur-instrument-0.1.jar
  
  # ----- Altrmi -----
  commons-altrmi.home=../../jakarta-commons-sandbox/altrmi/dist
  commons-altrmi-common.jar=${commons-altrmi.home}/commons-altrmi-common.jar
  commons-altrmi-server-impl.jar=${commons-altrmi.home}/commons-altrmi-server-impl.jar
  commons-altrmi-server-interfaces.jar=${commons-altrmi.home}/commons-altrmi-server-interfaces.jar
  
  # ----- 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
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <project name="Excalibur Instrument Manager" 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 name="dist-client.name" value="excalibur-${name}-client-${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="${logkit.jar}"/>
          <pathelement location="${avalon-framework.jar}"/>
          <pathelement location="${avalon-excalibur.jar}"/>
          <pathelement location="${excalibur-instrument.jar}"/>
          <pathelement location="${commons-altrmi-common.jar}"/>
          <pathelement location="${commons-altrmi-server-impl.jar}"/>
          <pathelement location="${commons-altrmi-server-interfaces.jar}"/>
          <pathelement location="${junit.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>
          
          <jar jarfile="${build.lib}/${dist-client.name}.jar"
              basedir="${build.classes}"
              compress="${build.compress}">
              <include name="**/client/**"/>
              <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="${build.lib}/${dist-client.name}.jar" todir="${dist.dir}"/>
          <copy file="../LICENSE.txt" todir="${dist.dir}"/>
          <copy file="../KEYS" 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>
  
          <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/instrument-manager/project.properties
  
  Index: project.properties
  ===================================================================
  name=instrument-manager
  Name=Instrument Manager
  version=0.1
  year=2002
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  build
  lib
  ant.properties
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/ant.properties.sample
  
  Index: ant.properties.sample
  ===================================================================
  # -----------------------------------------------------------------------------
  # Component ant.properties.sample
  #
  # This is an example "ant.properties" file, used to customize the building of
  # the component for your local environment.  It defines the location of all
  # external modules that this component depend on.  Copy this file to
  # "ant.properties" in the source directory, and customize it as needed.
  #
  # The ant.properties values in this directory apply only to this component, and
  # override the defaults in ../ant.properties.
  #
  # $Id: ant.properties.sample,v 1.1 2002/03/26 11:56:15 leif Exp $
  # -----------------------------------------------------------------------------
  
  # --------------------------------------------------
  #      COMPONENT-SPECIFIC REQUIRED LIBRARIES
  # --------------------------------------------------
  
  
  # ----- 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
  # --------------------------------------------------
  
  # ----- Xerces -----
  xerces.home=../../../jakarta-avalon/tools/lib/
  xerces.jar=${xerces.home}/xerces-1.4.4.jar
  
  # ----- XML-APIs -----
  xml-apis.home=../../../jakarta-avalon/tools/lib/
  xml-apis.jar=${xml-apis.home}/xml-apis.jar
  
  # ----- Xalan -----
  xalan.home=../../../jakarta-avalon/tools/lib/
  xalan.jar=${xalan.home}/xalan-2.2.0-D13.jar
  
  # ----- Logkit -----
  logkit.home=../../../jakarta-avalon-logkit/build/lib
  logkit.jar=${logkit.home}/logkit.jar
  
  # ----- Avalon Framework -----
  avalon-framework.home=../../../jakarta-avalon/build/lib
  avalon-framework.jar=${avalon-framework.home}/avalon-framework.jar
  
  # ----- Avalon Excalibur -----
  avalon-excalibur.home=../../all/build/lib
  avalon-excalibur.jar=${avalon-excalibur.home}/avalon-excalibur.jar
  
  # ----- Excalibur Instrument -----
  excalibur-instrument.home=../../instrument/build/lib
  excalibur-instrument.jar=${excalibur-instrument.home}/excalibur-instrument-0.1.jar
  
  # ----- Altrmi -----
  commons-altrmi.home=../../../jakarta-commons-sandbox/altrmi/dist
  commons-altrmi-common.jar=${commons-altrmi.home}/commons-altrmi-common.jar
  commons-altrmi-server-impl.jar=${commons-altrmi.home}/commons-altrmi-server-impl.jar
  commons-altrmi-server-interfaces.jar=${commons-altrmi.home}/commons-altrmi-server-interfaces.jar
  
  # ----- 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
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <!-- ======================================================================= -->
  <!-- Container Example build file!                                           -->
  <!-- ======================================================================= -->
  
  <project name="instrument-manager-example" default="main" basedir=".">
  
      <!--
        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"/>
  
      <!-- Directories build by ant -->
      <property name="build.dir"             value="${basedir}/build"/>
      <property name="build.classes.dir"     value="${build.dir}/classes"/>
      <property name="build.javadocs.dir"    value="${build.dir}/javadocs"/>
      <property name="lib.dir"               value="${basedir}/lib"/>
  
      <!-- Existing directories -->
      <property name="src.dir"               value="${basedir}/src"/>
      <property name="src.java.dir"          value="${src.dir}/java"/>
      <property name="commonlib.dir"         value="${basedir}/../commonlib"/>
  
      <!-- Define paths used by this project -->
      <path id="project.class.path">
          <fileset dir="${lib.dir}">
              <include name="**/*.jar"/>
              <exclude name="instrument-manager-example.jar"/>
          </fileset>
          <pathelement path="${build.classes.dir}" />
      </path>
  
      <!-- =================================================================== -->
      <!-- Help on usage                                                       -->
      <!-- =================================================================== -->
      <target name="usage">
          <echo message="Use the -projecthelp option instead"/>
      </target>
      <target name="help" depends="usage"/>
  
      <!-- =================================================================== -->
      <!-- Help on usage                                                       -->
      <!-- =================================================================== -->
      <target name="collect-jars">
          <!-- Xerces -->
          <copy file="${xerces.jar}" todir="${lib.dir}" preservelastmodified="yes"/>
          
          <!-- XML-APIs -->
          <copy file="${xml-apis.jar}" todir="${lib.dir}" preservelastmodified="yes"/>
          
          <!-- Xalan -->
          <copy file="${xalan.jar}" todir="${lib.dir}" preservelastmodified="yes"/>
          
          <!-- Logkit -->
          <copy file="${logkit.jar}" todir="${lib.dir}" preservelastmodified="yes"/>
          
          <!-- Avalon Framework -->
          <copy file="${avalon-framework.jar}" todir="${lib.dir}" preservelastmodified="yes"/>
          
          <!-- Avalon Excalibur -->
          <copy file="${avalon-excalibur.jar}" todir="${lib.dir}" preservelastmodified="yes"/>
          
          <!-- Avalon Excalibur Instrument -->
          <copy file="${excalibur-instrument.jar}"
              todir="${lib.dir}" preservelastmodified="yes"/>
          
          <!-- Avalon Excalibur Instrument Manager -->
          <copy file="../build/lib/excalibur-instrument-manager-0.1.jar"
              todir="${lib.dir}" preservelastmodified="yes"/>
          
          <!-- Altrmi Jars -->
          <copy file="${commons-altrmi-common.jar}"
              todir="${lib.dir}" preservelastmodified="yes"/>
          <copy file="${commons-altrmi-server-impl.jar}"
              todir="${lib.dir}" preservelastmodified="yes"/>
          <copy file="${commons-altrmi-server-interfaces.jar}"
              todir="${lib.dir}" preservelastmodified="yes"/>
      </target>
  
      <!-- =================================================================== -->
      <!-- Initialize custom tasks                                             -->
      <!-- =================================================================== -->
      <target name="init" depends="collect-jars">
      </target>
  
      <!-- =================================================================== -->
      <!-- Compiles the source code                                            -->
      <!-- =================================================================== -->
      <target name="compile" depends="init">
          <mkdir dir="${build.dir}"/>
          <mkdir dir="${build.classes.dir}"/>
  
          <!-- compile everything under src/java -->
          <javac srcdir="${src.java.dir}" destdir="${build.classes.dir}"
              deprecation="on"
              debug="on"
              optimize="off">
              <classpath refid="project.class.path" />
          </javac>
  
          <!-- copy image files to build directory -->
          <copy todir="${build.classes.dir}" >
              <fileset dir="${src.java.dir}" >
                  <include name="**/*.jpg" />
                  <include name="**/*.gif" />
              </fileset>
          </copy>
      </target>
  
      <!-- =================================================================== -->
      <!-- Creates the jar archive                                             -->
      <!-- =================================================================== -->
      <target name="jar" depends="compile" description="Builds the jar archive.">
          <mkdir dir="${lib.dir}"/>
  
          <jar jarfile="${lib.dir}/instrument-manager-example.jar"
              basedir="${build.classes.dir}"
              includes="**/*.class,**/*.properties,**/*.xml,**/*.jpg,**/*.gif,**/*.roles"
              />
      </target>
  
      <!-- =================================================================== -->
      <!-- Main target                                                         -->
      <!-- =================================================================== -->
      <target name="main" depends="jar" description="build the runnable application">
      </target>
  
      <!-- =================================================================== -->
      <!-- Creates the javadocs archive.                                       -->
      <!-- =================================================================== -->
      <target name="javadocs" description="Generates javadoc documentation">
          <mkdir dir="${build.javadocs.dir}"/>
  
          <javadoc packagenames="org.apache.*"
              sourcepath="${src.java.dir}"
              destdir="${build.javadocs.dir}">
              <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="-bottom"
                      value="&quot;Copyright &#169; 2001 Apache Jakarta Project. All Rights Reserved.&quot;"/>
              </doclet>
          </javadoc>
      </target>
  
      <!-- =================================================================== -->
      <!-- Builds everything.                                                  -->
      <!-- =================================================================== -->
      <target name="all" depends="main, javadocs" description="Build everything"/>
  
      <!-- =================================================================== -->
      <!-- Cleans up compiled classes and generated XMLC source.               -->
      <!-- =================================================================== -->
      <target name="clean" description="cleans up the directory">
          <delete dir="${build.dir}"/>
      </target>
  </project>
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/bin/cpappend.bat
  
  Index: cpappend.bat
  ===================================================================
  set _LIBJARS=%_LIBJARS%;%1
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/bin/run.bat
  
  Index: run.bat
  ===================================================================
  @echo off
  rem
  rem Example start script.
  rem
  rem Author: Leif Mortenson [leif@silveregg.co.jp]
  
  rem
  rem Determine if JAVA_HOME is set and if so then use it
  rem
  if not "%JAVA_HOME%"=="" goto found_java
  
  set EXAMPLE_JAVACMD=java
  goto file_locate
  
  :found_java
  set EXAMPLE_JAVACMD=%JAVA_HOME%\bin\java
  
  :file_locate
  
  rem
  rem Locate where the example is in filesystem
  rem
  if not "%OS%"=="Windows_NT" goto start
  
  rem %~dp0 is name of current script under NT
  set EXAMPLE_HOME=%~dp0
  
  rem : operator works similar to make : operator
  set EXAMPLE_HOME=%EXAMPLE_HOME:\bin\=%
  
  :start
  
  if not "%EXAMPLE_HOME%" == "" goto example_home
  
  echo.
  echo Warning: EXAMPLE_HOME environment variable is not set.
  echo   This needs to be set for Win9x as it's command prompt 
  echo   scripting bites
  echo.
  goto end
  
  :example_home
  rem
  rem build the runtime classpath
  rem
  set CP=
  
  
  set _LIBJARS=
  for %%i in (%EXAMPLE_HOME%\lib\*.jar) do call %EXAMPLE_HOME%\bin\cpappend.bat %%i
  if not "%_LIBJARS%" == "" goto run
  
  echo Unable to set CLASSPATH dynamically.
  goto end
  
  :run
  set CP=%CP%%_LIBJARS%
  
  rem Run the example application
  %EXAMPLE_JAVACMD% -Djava.compiler="NONE" -classpath "%CP%" org.apache.avalon.excalibur.instrument.example.Main %1 %2 %3 %4 %5 %6 %7 %8 %9
  
  :end
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/bin/run.sh
  
  Index: run.sh
  ===================================================================
  #!/bin/bash 
  #
  # Startup script.
  #
  
  #
  # Determine if JAVA_HOME is set and if so then use it
  #
  if [ -z "$JAVA_HOME" ] ;  then
    JAVA=`which java`
    if [ -z "$JAVA" ] ; then
      echo "Cannot find JAVA. Please set your PATH."
      exit 1
    fi
    JAVA_BINDIR=`dirname $JAVA`
    JAVA_HOME=$JAVA_BINDIR/..
  fi
  
  if [ "$JAVACMD" = "" ] ; then
     # it may be defined in env - including flags!!
     JAVACMD=$JAVA_HOME/bin/java
  fi
  
  # Main.java has hard coded config values so this script must be run from 
  # altprofile/bin (any better ideas ?)
  EXAMPLE_HOME=../..
  
  #
  # Build the runtime classpath
  #
  for i in ${EXAMPLE_HOME}/commonlib/*.jar ; do
      CP=${CP}:$i
  done
  
  CP=${CP}:../lib/altprofile.jar
  
  #echo $CP
  
  # Run the example application
  $JAVACMD -classpath $CP org.apache.avalon.examples.altprofile.Main $@
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/conf/components.xml
  
  Index: components.xml
  ===================================================================
  <components logger="cm">
      <!-- =============================================================== -->
      <!-- Application components.                                         -->
      <!-- =============================================================== -->
      <example-instrumentable logger="app"/>
  </components>
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/conf/instrument.xml
  
  Index: instrument.xml
  ===================================================================
  <instrument logger="im">
      <state-file interval="60000" use-compact-samples="true">../data/instrument.sampledata</state-file>
      
      <instrumentables>
          <!-- The profiler Profilable is the ProfilerManager itself. -->
          <instrumentable name="instrument-manager" description="Instrument Manager">
              <instrument name="active-thread-count" description="Active Thread Count">
                  <sample type="max" interval="1000" size="600" description="Maximum each second."/>
              </instrument>
              
              <instrument name="total-memory" description="Total Memory">
                  <sample type="max" interval="1000" size="600" description="Maximum each second."/>
              </instrument>
              
              <instrument name="free-memory" description="Free Memory">
                  <sample type="min" interval="1000" size="600" description="Minimum each second."/>
              </instrument>
              
              <instrument name="memory" description="In-Use Memory">
                  <sample type="max" interval="1000" size="600" description="Maximum each second."/>
              </instrument>
          </instrumentable>
          
          <!-- ExampleProfilable. -->
          <instrumentable name="example-instrumentable" description="Example Instrumentable">
              <!-- Note that any number of samples are possible for each profile point. -->
              <instrument name="random-quick" description="Random Values at a quick rate.">
                  <sample type="maximum" interval="1000" size="600" description="Maximum each second."/>
                  <sample type="minimum" interval="1000" size="600" description="Minimum each second."/>
                  <sample type="average" interval="1000" size="600" description="Average each second."/>
              </instrument>
              
              <instrument name="random-slow" description="Random Values at a slow rate.">
                  <sample type="maximum" interval="1000" size="600" description="Maximum each second."/>
                  <sample type="minimum" interval="1000" size="600" description="Minimum each second."/>
                  <sample type="average" interval="1000" size="600" description="Average each second."/>
              </instrument>
              
              <instrument name="random-random" description="Random Values at a random rate.">
                  <sample type="maximum" interval="1000" size="600" description="Maximum each second."/>
                  <sample type="minimum" interval="1000" size="600" description="Minimum each second."/>
                  <sample type="average" interval="1000" size="600" description="Average each second."/>
              </instrument>
              
              <instrument name="counter-quick" description="Count of actions at a quick rate.">
                  <sample type="counter" interval="100" size="600" description="Count per 100ms."/>
                  <sample type="counter" interval="1000" size="600" description="Count per second."/>
                  <sample type="counter" interval="60000" size="60" description="Count per minute."/>
              </instrument>
              
              <instrument name="counter-slow" description="Count of actions at a slow rate.">
                  <sample type="counter" interval="1000" size="600" description="Count per second."/>
                  <sample type="counter" interval="60000" size="60" description="Count per minute."/>
              </instrument>
              
              <instrument name="counter-random" description="Count of actions at a random rate.">
                  <sample type="counter" interval="1000" size="600" description="Count per second."/>
                  <sample type="counter" interval="60000" size="60" description="Count per minute."/>
              </instrument>
              
              <instrument name="doaction-counter" description="Number of times doAction is called.">
                  <sample type="counter" interval="1000" size="600" description="Count per second."/>
                  <sample type="counter" interval="60000" size="60" description="Count per minute."/>
              </instrument>
          </instrumentable>
      </instrumentables>
  </instrument>
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/conf/logkit.xml
  
  Index: logkit.xml
  ===================================================================
  <logkit logger="lm" log-level="INFO">
      <factories>
          <factory type="stream" 
                   class="org.apache.avalon.excalibur.logger.factory.StreamTargetFactory"/>
          <factory type="file" 
                   class="org.apache.avalon.excalibur.logger.factory.FileTargetFactory"/>
          <factory type="priority-filter" 
                   class="org.apache.avalon.excalibur.logger.factory.PriorityFilterTargetFactory"/>
      </factories>
      <targets>
          <stream id="console">
              <stream>System.out</stream>
              <format type="avalon">
  %19.19{time:yyyy-MM-dd'T'HH:mm:ss.SSS} %5.5{priority} [%15.15{category}]: %{message}\n%{throwable}
              </format>
          </stream>
      </targets>
      <categories>
          <!-- Profiler Manager Logger -->
          <category name="im" log-level="INFO">
              <log-target id-ref="console"/>
              
              <!-- The values child logger can dump out a lot of data. -->
              <category name="values" 
                        log-level="INFO">
                  <log-target id-ref="console"/>
              </category>
          </category>
          
          <!-- Role Manager Logger -->
          <category name="rm" log-level="INFO">
              <log-target id-ref="console"/>
          </category>
          
          <!-- Component Manager Logger -->
          <category name="cm" log-level="INFO">
              <log-target id-ref="console"/>
          </category>
          
          <!-- Application Loggers -->
          <category name="app" log-level="INFO">
              <log-target id-ref="console"/>
          </category>
      </categories>
  </logkit>
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/conf/roles.xml
  
  Index: roles.xml
  ===================================================================
  <role-list logger="rm">
      <!-- =================================================================== -->
      <!-- Application roles.                                                  -->
      <!-- =================================================================== -->
      <role name="org.apache.avalon.excalibur.instrument.example.ExampleInstrumentable"
            shorthand="example-instrumentable"
            default-class="org.apache.avalon.excalibur.instrument.example.DefaultExampleInstrumentable"/>
  </role-list>
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/src/java/org/apache/avalon/excalibur/instrument/example/DefaultExampleInstrumentable.java
  
  Index: DefaultExampleInstrumentable.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.instrument.example;
  
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.sql.Timestamp;
  
  import org.apache.avalon.excalibur.instrument.CounterInstrument;
  import org.apache.avalon.excalibur.instrument.Instrumentable;
  import org.apache.avalon.excalibur.instrument.Instrument;
  import org.apache.avalon.excalibur.instrument.ValueInstrument;
  
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  /**
   * This example application creates a component which registers several
   *  Instruments for the example.
   *
   * Note, this code ignores exceptions to keep the code simple.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class DefaultExampleInstrumentable
      extends AbstractLogEnabled
      implements ExampleInstrumentable, Startable, Runnable, Instrumentable
  {
      public static final String INSTRUMENT_RANDOM_QUICK_NAME   = "random-quick";
      public static final String INSTRUMENT_RANDOM_SLOW_NAME    = "random-slow";
      public static final String INSTRUMENT_RANDOM_RANDOM_NAME  = "random-random";
      public static final String INSTRUMENT_COUNTER_QUICK_NAME  = "counter-quick";
      public static final String INSTRUMENT_COUNTER_SLOW_NAME   = "counter-slow";
      public static final String INSTRUMENT_COUNTER_RANDOM_NAME = "counter-random";
      public static final String INSTRUMENT_DOACTION_NAME       = "doaction-counter";
  
      /** Instrumentable Name assigned to this Instrumentable */
      private String m_instrumentableName;
  
      /** Instrument used to profile random values with lots of updates. */
      private ValueInstrument m_randomQuickInstrument;
  
      /** Instrument used to profile random values with few of updates. */
      private ValueInstrument m_randomSlowInstrument;
  
      /** Instrument used to profile random values with updates at a random rate. */
      private ValueInstrument m_randomRandomInstrument;
  
      /** Instrument used to profile random actions with lots of updates. */
      private CounterInstrument m_counterQuickInstrument;
  
      /** Instrument used to profile random actions with few of updates. */
      private CounterInstrument m_counterSlowInstrument;
  
      /** Instrument used to profile random actions with updates at a random rate. */
      private CounterInstrument m_counterRandomInstrument;
  
      /** Instrument used to count the number of times that doAction is called. */
      private CounterInstrument m_doActionInstrument;
  
      /** Thread which is used to send profile data to the random instruments. */
      private Thread m_runner;
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      public DefaultExampleInstrumentable()
      {
          // Initialize the Instrumentable elements.
          m_randomQuickInstrument   = new ValueInstrument( INSTRUMENT_RANDOM_QUICK_NAME );
          m_randomSlowInstrument    = new ValueInstrument( INSTRUMENT_RANDOM_SLOW_NAME );
          m_randomRandomInstrument  = new ValueInstrument( INSTRUMENT_RANDOM_RANDOM_NAME );
          m_counterQuickInstrument  = new CounterInstrument( INSTRUMENT_COUNTER_QUICK_NAME );
          m_counterSlowInstrument   = new CounterInstrument( INSTRUMENT_COUNTER_SLOW_NAME );
          m_counterRandomInstrument = new CounterInstrument( INSTRUMENT_COUNTER_RANDOM_NAME );
          m_doActionInstrument      = new CounterInstrument( INSTRUMENT_DOACTION_NAME );
      }
  
      /*---------------------------------------------------------------
       * ExampleInstrumentable Methods
       *-------------------------------------------------------------*/
      /**
       * Example action method.
       */
      public void doAction()
      {
          getLogger().info( "ExampleInstrumentable.doAction() called." );
  
          // Notify the profiler.
          m_doActionInstrument.increment();
      }
  
      /*---------------------------------------------------------------
       * Startable Methods
       *-------------------------------------------------------------*/
      /**
       * Start the component.
       */
      public void start()
      {
          if ( m_runner == null )
          {
              m_runner = new Thread( this, "ExampleInstrumentableRunner" );
              m_runner.start();
          }
      }
  
      /**
       * Stop the component.
       */
      public void stop()
      {
          if ( m_runner != null )
          {
              m_runner.interrupt();
              m_runner = null;
          }
      }
  
      /*---------------------------------------------------------------
       * Runnable Methods
       *-------------------------------------------------------------*/
      /**
       * Runner thread which is responsible for sending data to the Profiler via
       *  the various random Profile Points.
       */
      public void run()
      {
          int counter = 0;
          while ( m_runner != null )
          {
              // Add some delay to the loop.
              try
              {
                  Thread.sleep( 100 );
              }
              catch ( InterruptedException e )
              {
                  if ( m_runner == null )
                  {
                      return;
                  }
              }
  
              // Handle the quick Profile Points
              m_randomQuickInstrument.setValue( (int)(Math.random() * 100) );
              m_counterQuickInstrument.increment();
  
              // Handle the slow Profile Points
              counter++;
              if ( counter >= 20 )
              {
                  m_randomSlowInstrument.setValue( (int)(Math.random() * 100) );
                  m_counterSlowInstrument.increment();
                  counter = 0;
              }
  
              // Handle the random Profile Points.  Fire 10% of the time.
              if ( 100 * Math.random() < 10 )
              {
                  m_randomRandomInstrument.setValue( (int)(Math.random() * 100) );
                  m_counterRandomInstrument.increment();
              }
          }
      }
  
      /*---------------------------------------------------------------
       * Instrumentable Methods
       *-------------------------------------------------------------*/
      /**
       * Sets the name for the Instrumentable.  The Instrumentable Name is used
       *  to uniquely identify the Instrumentable during the configuration of
       *  the InstrumentManager and to gain access to an InstrumentableDescriptor
       *  through the InstrumentManager.  The value should be a string which does
       *  not contain spaces or periods.
       * <p>
       * This value may be set by a parent Instrumentable, or by the
       *  InstrumentManager using the value of the 'instrumentable' attribute in
       *  the configuration of the component.
       *
       * @param name The name used to identify a Instrumentable.
       */
      public void setInstrumentableName( String name )
      {
          m_instrumentableName = name;
      }
  
      /**
       * Gets the name of the Instrumentable.
       *
       * @return The name used to identify a Instrumentable.
       */
      public String getInstrumentableName()
      {
          return m_instrumentableName;
      }
  
      /**
       * Obtain a reference to all the Instruments that the Instrumentable object
       *  wishes to expose.  All sampling is done directly through the
       *  Instruments as opposed to the Instrumentable interface.
       *
       * @return An array of the Instruments available for profiling.  Should
       *         never be null.  If there are no Instruments, then
       *         EMPTY_INSTRUMENT_ARRAY can be returned.  This should never be
       *         the case though unless there are child Instrumentables with
       *         Instruments.
       */
      public Instrument[] getInstruments()
      {
          return new Instrument[]
          {
              m_randomQuickInstrument,
              m_randomSlowInstrument,
              m_randomRandomInstrument,
              m_counterQuickInstrument,
              m_counterSlowInstrument,
              m_counterRandomInstrument,
              m_doActionInstrument
          };
      }
  
      /**
       * Any Object which implements Instrumentable can also make use of other
       *  Instrumentable child objects.  This method is used to tell the
       *  InstrumentManager about them.
       *
       * @return An array of child Instrumentables.  This method should never
       *         return null.  If there are no child Instrumentables, then
       *         EMPTY_INSTRUMENTABLE_ARRAY can be returned.
       */
      public Instrumentable[] getChildInstrumentables()
      {
          // This instrumentable does not have any children.
          return Instrumentable.EMPTY_INSTRUMENTABLE_ARRAY;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/src/java/org/apache/avalon/excalibur/instrument/example/ExampleInstrumentable.java
  
  Index: ExampleInstrumentable.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.instrument.example;
  
  import org.apache.avalon.framework.component.Component;
  
  /**
   * This example application creates a component which registers several
   *  Instruments for the example.
   *
   * Note, this code ignores exceptions to keep the code simple.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public interface ExampleInstrumentable
      extends Component
  {
      String ROLE = ExampleInstrumentable.class.getName();
      
      /**
       * Example action method.
       */
      void doAction();
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/example/src/java/org/apache/avalon/excalibur/instrument/example/Main.java
  
  Index: Main.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.instrument.example;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.InputStreamReader;
  
  import org.apache.avalon.excalibur.component.DefaultRoleManager;
  import org.apache.avalon.excalibur.instrument.component.InstrumentComponentManager;
  import org.apache.avalon.excalibur.instrument.manager.DefaultInstrumentManager;
  import org.apache.avalon.excalibur.instrument.manager.altrmi.InstrumentManagerAltrmiServer;
  import org.apache.avalon.excalibur.logger.DefaultLogKitManager;
  import org.apache.avalon.excalibur.concurrent.ThreadBarrier;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.context.DefaultContext;
  import org.apache.avalon.framework.logger.LogKitLogger;
  
  import org.apache.log.Hierarchy;
  import org.apache.log.Logger;
  import org.apache.log.Priority;
  
  /**
   * This example application loads a component which publishes a series
   *  of Instruments.  An InstrumentManager is created to collect and
   *  manage the Instrument data.  And an Altrmi based InstrumentManagerInterface
   *  is registered.  A client may connect to InstrumentManager later.
   * <p>
   * Note, this code ignores exceptions to keep the code simple.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class Main
  {
      private static InstrumentComponentManager           m_componentManager;
      private static DefaultInstrumentManager             m_instrumentManager;
      private static InstrumentManagerAltrmiServer        m_altrmiServer;
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      private Main() {}
  
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Creates and initializes the component manager using config files.
       */
      private static void createComponentManager()
          throws Exception
      {
          // Create a context to use.
          DefaultContext context = new DefaultContext();
          // Add any context variables here.
          context.makeReadOnly();
  
          // Create a ConfigurationBuilder to parse the config files.
          DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
  
          // Load in the configuration files
          Configuration logKitConfig     = builder.build( "../conf/logkit.xml" );
          Configuration instrumentConfig = builder.build( "../conf/instrument.xml" );
          Configuration rolesConfig      = builder.build( "../conf/roles.xml" );
          Configuration componentsConfig = builder.build( "../conf/components.xml" );
  
          // Setup the LogKitManager
          DefaultLogKitManager logManager = new DefaultLogKitManager();
          Logger lmLogger = Hierarchy.getDefaultHierarchy().
              getLoggerFor( logKitConfig.getAttribute( "logger", "lm" ) );
          lmLogger.setPriority(
              Priority.getPriorityForName( logKitConfig.getAttribute( "log-level", "INFO" ) ) );
          logManager.setLogger( lmLogger );
          logManager.configure( logKitConfig );
  
          // Set up the Instrument Manager
          m_instrumentManager = new DefaultInstrumentManager( "instrument-manager-example" );
          m_instrumentManager.enableLogging( new LogKitLogger( logManager.getLogger( instrumentConfig.getAttribute( "logger", "pm" ) ) ) );
          m_instrumentManager.configure( instrumentConfig );
          m_instrumentManager.initialize();
  
          // Setup the RoleManager
          DefaultRoleManager roleManager = new DefaultRoleManager();
          roleManager.setLogger(
              logManager.getLogger( rolesConfig.getAttribute( "logger", "rm" ) ) );
          roleManager.configure( rolesConfig );
  
          // Set up the ComponentManager
          m_componentManager = new InstrumentComponentManager();
          m_componentManager.setLogger(
              logManager.getLogger( componentsConfig.getAttribute( "logger", "cm" ) ) );
          m_componentManager.setLogKitManager( logManager );
          m_componentManager.contextualize( context );
          m_componentManager.setInstrumentManager( m_instrumentManager ); // <-- Set the instrument manager.
          m_componentManager.setRoleManager( roleManager );
          m_componentManager.configure( componentsConfig );
          m_componentManager.initialize();
  
          // Set up the InstrumentManagerAltrmiServer so clients can connect.
          m_altrmiServer = new InstrumentManagerAltrmiServer( m_instrumentManager );
          
          /*
          m_instrumentFrame = new InstrumentFrame( m_instrumentManager, "Example Instrument" );
          m_instrumentFrame.setVisible( true );
  
          try
          {
              File desktopFile = new File( "../conf/instrument.desktop" );
              m_instrumentFrame.loadDesktopStateFromFile( desktopFile, false );
          }
          catch ( Exception e )
          {
              System.out.println( "Unable to load desktop file: " + e );
          }
          */
      }
  
      /*---------------------------------------------------------------
       * Main method
       *-------------------------------------------------------------*/
      /**
       * All of the guts of this example exist in the main method.
       */
      public static void main( String[] args )
          throws Exception
      {
          System.out.println( "Running the AltProfile Example Application" );
  
          // Create the ComponentManager
          createComponentManager();
  
          // Get a reference to the example component.
          ExampleInstrumentable instrumentable =
              (ExampleInstrumentable)m_componentManager.lookup( ExampleInstrumentable.ROLE );
          try
          {
              boolean quit = false;
              while ( !quit )
              {
                  System.out.println( "Enter the number of times that exampleAction should be called, or 'q' to quit." );
                  BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) );
                  System.out.print( " : " );
                  String cntStr = in.readLine();
  
                  // Can get a null if CTRL-C is hit.
                  if ( ( cntStr == null ) || ( cntStr.equalsIgnoreCase( "q" ) ) )
                  {
                      quit = true;
                  }
                  else if ( ( cntStr.equalsIgnoreCase( "gc" ) ) )
                  {
                      System.gc();
                  }
                  else
                  {
                      try
                      {
                          int concurrent = 100;
                          ThreadBarrier barrier = new ThreadBarrier( concurrent );
                          int cnt = Integer.parseInt( cntStr );
                          int average = Math.max(cnt / concurrent, 1);
  
                          while (cnt > 0)
                          {
                              Thread t = new Thread( new ActionRunner( instrumentable,
                                                            Math.min(average, cnt),
                                                            barrier) );
                              t.start();
  
                              if (cnt > 0)
                              {
                                  cnt -= average;
                              }
  
                              if (cnt < 0)
                              {
                                  cnt = 0;
                              }
                          }
                      }
                      catch ( NumberFormatException e ) {}
                  }
              }
          }
          finally
          {
              // Release the component
              m_componentManager.release( instrumentable );
              instrumentable = null;
              
              // Dispose the InstrumentManagerAltrmiServer
              m_altrmiServer.dispose();
              m_altrmiServer = null;
  
              /*
              // Hide the frame
              m_instrumentFrame.setVisible( false );
              m_instrumentFrame.dispose();
              m_instrumentFrame = null;
              */
  
              // Dispose the ComponentManager
              m_componentManager.dispose();
              m_componentManager = null;
  
              // Dispose the InstrumentManager
              m_instrumentManager.dispose();
              m_instrumentManager = null;
          }
  
          System.out.println();
          System.out.println( "Exiting..." );
          System.exit(0);
      }
  
      private final static class ActionRunner implements Runnable
      {
          private final int m_numIterations;
          private final ExampleInstrumentable m_instrumentable;
          private final ThreadBarrier m_barrier;
  
          protected ActionRunner( ExampleInstrumentable instrumentable, int numIterations, ThreadBarrier barrier )
          {
              m_numIterations = numIterations;
              m_instrumentable = instrumentable;
              m_barrier = barrier;
          }
  
          public void run()
          {
              for ( int i = 0; i < m_numIterations; i++ )
              {
                  m_instrumentable.doAction();
              }
  
              try
              {
                  m_barrier.barrierSynchronize();
              }
              catch (Exception e) {}
          }
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentHandler.java
  
  Index: InstrumentComponentHandler.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.instrument.component;
  
  import org.apache.avalon.excalibur.instrument.InstrumentManager;
  import org.apache.avalon.excalibur.component.ComponentHandler;
  import org.apache.avalon.excalibur.component.DefaultComponentFactory;
  import org.apache.avalon.excalibur.component.DefaultComponentHandler;
  import org.apache.avalon.excalibur.component.PoolableComponentHandler;
  import org.apache.avalon.excalibur.component.RoleManager;
  import org.apache.avalon.excalibur.component.ThreadSafeComponentHandler;
  import org.apache.avalon.excalibur.logger.LogKitManager;
  import org.apache.avalon.excalibur.pool.Poolable;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.thread.SingleThreaded;
  import org.apache.avalon.framework.thread.ThreadSafe;
  
  /**
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public abstract class InstrumentComponentHandler
      extends ComponentHandler
  {
      /*---------------------------------------------------------------
       * Static Methods
       *-------------------------------------------------------------*/
      /**
       *
       *
       * @param componentClass Class of the component for which the handle is
       *                       being requested.
       * @param configuration The configuration for this component.
       * @param componentManager The ComponentManager which will be managing
       *                         the Component.
       * @param context The current context object.
       * @param roleManager The current RoleManager.
       * @param logkitManager The current LogKitManager.
       * @param instrumentManager The current InstrumentManager.
       *
       * @throws Exception If there were any problems obtaining a ComponentHandler
       */
      public static ComponentHandler getComponentHandler(
          final Class componentClass,
          final Configuration config,
          final ComponentManager componentManager,
          final Context context,
          final RoleManager roleManager,
          final LogKitManager logkitManager,
          final InstrumentManager instrumentManager )
          throws Exception
      {
          int numInterfaces = 0;
  
          if( SingleThreaded.class.isAssignableFrom( componentClass ) )
          {
              numInterfaces++;
          }
  
          if( ThreadSafe.class.isAssignableFrom( componentClass ) )
          {
              numInterfaces++;
          }
  
          if( Poolable.class.isAssignableFrom( componentClass ) )
          {
              numInterfaces++;
          }
  
          if( numInterfaces > 1 )
          {
              throw new Exception( "[CONFLICT] lifestyle interfaces: " + componentClass.getName() );
          }
  
          // Create the factory to use to create the instances of the Component.
          DefaultComponentFactory factory =
              new InstrumentDefaultComponentFactory( componentClass,
                                                     config,
                                                     componentManager,
                                                     context,
                                                     roleManager,
                                                     logkitManager,
                                                     instrumentManager );
  
          if( Poolable.class.isAssignableFrom( componentClass ) )
          {
              return new PoolableComponentHandler( factory, config );
          }
          else if( ThreadSafe.class.isAssignableFrom( componentClass ) )
          {
              return new ThreadSafeComponentHandler( factory, config );
          }
          else // This is a SingleThreaded component
          {
              return new DefaultComponentHandler( factory, config );
          }
      }
  
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new InstrumentComponentHandler.
       */
      public InstrumentComponentHandler()
      {
      }
  
      /*---------------------------------------------------------------
       * ComponentHandler Methods
       *-------------------------------------------------------------*/
  
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentManager.java
  
  Index: InstrumentComponentManager.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.instrument.component;
  
  import org.apache.avalon.excalibur.instrument.InstrumentManageable;
  import org.apache.avalon.excalibur.instrument.InstrumentManager;
  import org.apache.avalon.excalibur.component.ComponentHandler;
  import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
  import org.apache.avalon.excalibur.component.RoleManager;
  import org.apache.avalon.excalibur.logger.LogKitManager;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.context.Context;
  
  /**
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class InstrumentComponentManager
      extends ExcaliburComponentManager
      implements InstrumentManageable
  {
      private InstrumentManager m_instrumentManager;
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new InstrumentComponentManager.
       */
      public InstrumentComponentManager()
      {
          super();
      }
  
      /**
       * Creates a new InstrumentComponentManager which will use the specified
       *  class loader to load all of its components.
       */
      public InstrumentComponentManager( ClassLoader classLoader )
      {
          super( classLoader );
      }
  
      /*---------------------------------------------------------------
       * ExcaliburComponentManager Methods
       *-------------------------------------------------------------*/
      /**
       * Obtain a new ComponentHandler for the specified component.  This method
       *  allows classes which extend the ExcaliburComponentManager to use their
       *  own ComponentHandlers.
       *
       * @param componentClass Class of the component for which the handle is
       *                       being requested.
       * @param configuration The configuration for this component.
       * @param context The current context object.
       * @param roleManager The current RoleManager.
       * @param logkitManager The current LogKitManager.
       *
       * @throws Exception If there were any problems obtaining a ComponentHandler
       */
      protected ComponentHandler getComponentHandler( final Class componentClass,
                                                      final Configuration configuration,
                                                      final Context context,
                                                      final RoleManager roleManager,
                                                      final LogKitManager logkitManager )
          throws Exception
      {
          if( m_instrumentManager == null )
          {
              throw new IllegalStateException( "The InstrumentManager was not yet set." );
          }
  
          return InstrumentComponentHandler.getComponentHandler( componentClass,
                                                                 configuration,
                                                                 this,
                                                                 context,
                                                                 roleManager,
                                                                 logkitManager,
                                                                 m_instrumentManager );
      }
  
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Sets the InstrumentManager for child components.  Can be for special
       * purpose components, however it is used mostly internally.
       *
       * @param instrumentManager The InstrumentManager for the component to use.
       */
      public void setInstrumentManager( InstrumentManager instrumentManager )
      {
          m_instrumentManager = instrumentManager;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentComponentSelector.java
  
  Index: InstrumentComponentSelector.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.instrument.component;
  
  import org.apache.avalon.excalibur.instrument.InstrumentManageable;
  import org.apache.avalon.excalibur.instrument.InstrumentManager;
  import org.apache.avalon.excalibur.component.ComponentHandler;
  import org.apache.avalon.excalibur.component.ExcaliburComponentSelector;
  import org.apache.avalon.excalibur.component.RoleManager;
  import org.apache.avalon.excalibur.logger.LogKitManager;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.context.Context;
  
  /**
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class InstrumentComponentSelector
      extends ExcaliburComponentSelector
      implements InstrumentManageable
  {
      private InstrumentManager m_instrumentManager;
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new InstrumentComponentSelector.
       */
      public InstrumentComponentSelector()
      {
          super();
      }
  
      /**
       * Creates a new InstrumentComponentSelector which will use the specified
       *  class loader to load all of its components.
       */
      public InstrumentComponentSelector( ClassLoader classLoader )
      {
          super( classLoader );
      }
  
      /*---------------------------------------------------------------
       * ExcaliburComponentSelector Methods
       *-------------------------------------------------------------*/
      /**
       * Obtain a new ComponentHandler for the specified component.  This method
       *  allows classes which extend the ExcaliburComponentSelector to use their
       *  own ComponentHandlers.
       *
       * @param componentClass Class of the component for which the handle is
       *                       being requested.
       * @param configuration The configuration for this component.
       * @param componentManager The ComponentManager which will be managing
       *                         the Component.
       * @param context The current context object.
       * @param roleManager The current RoleManager.
       * @param logkitManager The current LogKitManager.
       *
       * @throws Exception If there were any problems obtaining a ComponentHandler
       */
      protected ComponentHandler getComponentHandler( final Class componentClass,
                                                      final Configuration configuration,
                                                      final ComponentManager componentManager,
                                                      final Context context,
                                                      final RoleManager roleManager,
                                                      final LogKitManager logkitManager )
          throws Exception
      {
          return InstrumentComponentHandler.getComponentHandler( componentClass,
                                                                 configuration,
                                                                 componentManager,
                                                                 context,
                                                                 roleManager,
                                                                 logkitManager,
                                                                 m_instrumentManager );
      }
  
      /*---------------------------------------------------------------
       * InstrumentManageable Methods
       *-------------------------------------------------------------*/
      /**
       * Sets the InstrumentManager for child components.  Can be for special
       * purpose components, however it is used mostly internally.
       *
       * @param instrumentManager The InstrumentManager for the component to use.
       */
      public void setInstrumentManager( final InstrumentManager instrumentManager )
      {
          m_instrumentManager = instrumentManager;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/component/InstrumentDefaultComponentFactory.java
  
  Index: InstrumentDefaultComponentFactory.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.instrument.component;
  
  import org.apache.avalon.excalibur.instrument.Instrumentable;
  import org.apache.avalon.excalibur.instrument.InstrumentManageable;
  import org.apache.avalon.excalibur.instrument.InstrumentManager;
  import org.apache.avalon.excalibur.component.DefaultComponentFactory;
  import org.apache.avalon.excalibur.component.RoleManager;
  import org.apache.avalon.excalibur.logger.LogKitManager;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.context.Context;
  
  /**
   * Factory for Avalon Instrumentable components.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.0
   */
  public class InstrumentDefaultComponentFactory
      extends DefaultComponentFactory
  {
      private InstrumentManager m_instrumentManager;
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Construct a new component factory for the specified component.
       *
       * @param componentClass the class to instantiate (must have a default constructor).
       * @param configuration the <code>Configuration</code> object to pass to new instances.
       * @param componentManager the component manager to pass to <code>Composable</code>s.
       * @param context the <code>Context</code> to pass to <code>Contexutalizable</code>s.
       * @param roles the <code>RoleManager</code> to pass to <code>DefaultComponentSelector</code>s.
       * @param instrumentManager the <code>InstrumentManager</code> to register the component with if
       *        it is a Instrumentable.
       */
      public InstrumentDefaultComponentFactory( final Class componentClass,
                                                final Configuration configuration,
                                                final ComponentManager componentManager,
                                                final Context context,
                                                final RoleManager roles,
                                                final LogKitManager logkit,
                                                final InstrumentManager instrumentManager )
  
      {
          super( componentClass, configuration, componentManager, context, roles, logkit );
  
          m_instrumentManager = instrumentManager;
      }
  
  
      /*---------------------------------------------------------------
       * DefaultComponentFactory Methods
       *-------------------------------------------------------------*/
      /**
       * Called after a new component is initialized, but before it is started.  This was added
       *  to make it possible to implement the InstrumentComponentFactory without too much duplicate
       *  code.  WARNING:  Do not take advantage of this method as it will most likely be removed.
       */
      protected void postLogger( Object component, Configuration configuration )
          throws Exception
      {
          if( component instanceof InstrumentManageable )
          {
              ( (InstrumentManageable)component ).setInstrumentManager( m_instrumentManager );
          }
      }
  
      /**
       * Called after a new component is initialized, but before it is started.  This was added
       *  to make it possible to implement the InstrumentComponentFactory without too much duplicate
       *  code.  WARNING:  Do not take advantage of this method as it will most likely be removed.
       */
      protected void postInitialize( Object component, Configuration configuration )
          throws Exception
      {
          if( component instanceof Instrumentable )
          {
              getLogger().debug( "Doing instrument setup for: " + component );
              
              String instrumentName = configuration.getAttribute( "instrumentable", configuration.getName() );
              
              m_instrumentManager.registerInstrumentable( (Instrumentable)component, instrumentName );
          }
      }
  
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/AbstractInstrumentSample.java
  
  Index: AbstractInstrumentSample.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.instrument.manager;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.StringTokenizer;
  
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleListener;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleSnapshot;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  /**
   * An AbstractInstrumentSample contains all of the functionality common to all
   *  InstrumentSamples.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  abstract class AbstractInstrumentSample
      extends AbstractLogEnabled
      implements InstrumentSample
  {
      /** The name of the new InstrumentSample. */
      private String m_name;
      
      /** The sample interval of the new InstrumentSample. */
      private long m_interval;
      
      /** The number of samples to store as history. */
      private int m_size;
      
      /** The description of the new InstrumentSample. */
      private String m_description;
      
      /** The Descriptor for the InstrumentSample. */
      private InstrumentSampleDescriptor m_descriptor;
      
      /** 
       * The maximum amount of time between updates before history will be
       * wiped clean.
       */
      private long m_maxAge;
      
      /** The UNIX time of the beginning of the sample. */
      protected long m_time;
      
      /** The Index into the history arrays. */
      private int m_historyIndex;
      
      /** The Old half of the history array. */
      private int[] m_historyOld;
      
      /** The New half of the history array. */
      private int[] m_historyNew;
      
      /** Array of registered InstrumentSampleListeners. */
      private InstrumentSampleListener[] m_listeners;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new AbstractInstrumentSample
       *
       * @param name The name of the new InstrumentSample.
       * @param interval The sample interval of the new InstrumentSample.
       * @param size The number of samples to store as history.  Assumes that size is at least 1.
       * @param description The description of the new InstrumentSample.
       */
      protected AbstractInstrumentSample( String name, long interval, int size, String description )
      {
          if ( interval < 1 )
          {
              throw new IllegalArgumentException( "interval must be at least 1." );
          }
          if ( size < 1 )
          {
              throw new IllegalArgumentException( "size must be at least 1." );
          }
          
          m_name = name;
          m_interval = interval;
          m_size = size;
          m_description = description;
          
          // Calculate the maxAge
          m_maxAge = m_size * m_interval;
          
          init();
          
          // Create the descriptor
          m_descriptor = new InstrumentSampleDescriptorImpl( this );
      }
      
      /*---------------------------------------------------------------
       * InstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * Returns true if the Instrument was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      public boolean isConfigured()
      {
          //return m_configured;
          return true;
      }
      
      /**
       * Returns the name of the sample.
       *
       * @return The name of the sample.
       */
      public final String getName()
      {
          return m_name;
      }
      
      /**
       * Returns the sample interval.  The period of each sample in millisends.
       *
       * @return The sample interval.
       */
      public final long getInterval()
      {
          return m_interval;
      }
      
      /**
       * Returns the number of samples in the sample history.
       *
       * @return The size of the sample history.
       */
      public final int getSize()
      {
          return m_size;
      }
      
      /**
       * Returns the description of the sample.
       *
       * @return The description of the sample.
       */
      public final String getDescription()
      {
          return m_description;
      }
      
      /**
       * Returns a Descriptor for the InstrumentSample.
       *
       * @return A Descriptor for the InstrumentSample.
       */
      public InstrumentSampleDescriptor getDescriptor()
      {
          return m_descriptor;
      }
      
      /**
       * Obtain the value of the sample.  All samples are integers, so the profiled
       * objects must measure quantity (numbers of items), rate (items/period), time in
       * milliseconds, etc.
       *
       * @return The sample value.
       */
      public final int getValue()
      {
          boolean update;
          int value;
          long time;
          
          synchronized(this)
          {
              long now = System.currentTimeMillis();
              update = update( now );
              value = getValueInner();
              time = m_time;
          }
          
          if ( update )
          {
              updateListeners( value, time );
          }
          return value;
      }
      
      /**
       * Obtain the UNIX time of the beginning of the sample.
       *
       * @return The UNIX time of the beginning of the sample.
       */
      public final long getTime()
      {
          boolean update;
          int value;
          long time;
          
          synchronized(this)
          {
              long now = System.currentTimeMillis();
              update = update( now );
              value = getValueInner();
              time = m_time;
          }
          
          if ( update )
          {
              updateListeners( value, time );
          }
          return time;
      }
      
      /**
       * Obtains a static snapshot of the InstrumentSample.
       *
       * @return A static snapshot of the InstrumentSample.
       */
      public final InstrumentSampleSnapshot getSnapshot()
      {
          synchronized(this)
          {
              long time = System.currentTimeMillis();
              update( time );
              
              return new InstrumentSampleSnapshot(
                  m_name,
                  m_interval,
                  m_size,
                  m_time,
                  getHistorySnapshot() );
          }
      }
      
      /**
       * Registers a InstrumentSampleListener with a InstrumentSample given a name.
       *
       * @param listener The listener which should start receiving updates from the
       *                 InstrumentSample.
       */
      public void addInstrumentSampleListener( InstrumentSampleListener listener )
      {
          if ( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "A InstrumentSampleListener was added to sample, " + m_name + " : " +
                  listener.getClass().getName() );
          }
          
          synchronized(this)
          {
              // Store the listeners in an array.  This makes it possible to
              //  avoid synchronization while propagating events.  Never change
              //  the contents of the listener array once it has been set to the
              //  m_listeners field.
              InstrumentSampleListener[] oldListeners = m_listeners;
              InstrumentSampleListener[] newListeners;
              if ( oldListeners == null )
              {
                  newListeners = new InstrumentSampleListener[] { listener };
              }
              else
              {
                  newListeners = new InstrumentSampleListener[ oldListeners.length + 1 ];
                  System.arraycopy( oldListeners, 0, newListeners, 0, oldListeners.length );
                  newListeners[ oldListeners.length ] = listener;
              }
              
              // Update the m_listeners field.
              m_listeners = newListeners;
          }
      }
      
      /**
       * Unregisters a InstrumentSampleListener from a InstrumentSample given a name.
       *
       * @param listener The listener which should stop receiving updates from the
       *                 InstrumentSample.
       */
      public void removeInstrumentSampleListener( InstrumentSampleListener listener )
      {
          if ( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "A InstrumentSampleListener was removed from sample, " + m_name +
                  " : " + listener.getClass().getName() );
          }
          
          synchronized(this)
          {
              // Store the listeners in an array.  This makes it possible to
              //  avoid synchronization while propagating events.  Never change
              //  the contents of the listener array once it has been set to the
              //  m_listeners field.
              InstrumentSampleListener[] oldListeners = m_listeners;
              InstrumentSampleListener[] newListeners;
              if ( oldListeners == null )
              {
                  // Means that this method should not have been called, but
                  //  don't throw an error.
                  newListeners = null;
              }
              else if ( oldListeners.length == 1 )
              {
                  if ( oldListeners[0] == listener )
                  {
                      newListeners = null;
                  }
                  else
                  {
                      // The listener was not in the list.
                      newListeners = oldListeners;
                  }
              }
              else
              {
                  // Look for the listener in the array.
                  int pos = -1;
                  for ( int i = 0; i < oldListeners.length; i++ )
                  {
                      if ( oldListeners[i] == listener )
                      {
                          pos = i;
                          break;
                      }
                  }
                  
                  if ( pos < 0 )
                  {
                      // The listener was not in the list.
                      newListeners = oldListeners;
                  }
                  else
                  {
                      newListeners = new InstrumentSampleListener[ oldListeners.length - 1 ];
                      if ( pos > 0 )
                      {
                          // Copy the head of the array
                          System.arraycopy( oldListeners, 0, newListeners, 0, pos );
                      }
                      if ( pos < oldListeners.length - 1 )
                      {
                          // Copy the tail of the array
                          System.arraycopy( oldListeners, pos + 1, 
                              newListeners, pos, oldListeners.length - 1 - pos );
                      }
                  }
              }
              
              // Update the m_listeners field.
              m_listeners = newListeners;
          }
      }
      
      /**
       * Notifies any listeners of a change.
       * <p>
       * Make sure that this is called OUTSIDE of a synchrinization block.
       *
       * @param value The new value.
       * @param time The time that the new value was set.
       */
      protected void updateListeners( int value, long time )
      {
          // Get a local reference to the listeners, so that synchronization can be avoided.
          InstrumentSampleListener[] listeners = m_listeners;
          if ( listeners != null )
          {
              for ( int i = 0; i < listeners.length; i++ )
              {
                  listeners[i].setValue( getName(), value, time );
              }
          }
      }
      
      /**
       * Saves the current state into a Configuration.
       *
       * @param useCompactSamples Flag for whether or not InstrumentSample data
       *                          should be saved in compact format or not.
       *
       * @return The state as a Configuration.
       */
      public final Configuration saveState( boolean useCompactSamples )
      {
          synchronized(this)
          {
              DefaultConfiguration state = new DefaultConfiguration( "profile-sample", "-" );
              state.addAttribute( "name", m_name );
              state.addAttribute( "time", Long.toString( m_time ) );
              
              // Save the history samples so that the newest is first.
              DefaultConfiguration samples = new DefaultConfiguration( "history", "-" );
              int[] history = getHistorySnapshot();
              if ( useCompactSamples )
              {
                  StringBuffer sb = new StringBuffer();
                  
                  // Store the first value outside the loop to simplify the loop.
                  sb.append( history[ history.length - 1 ] );
                  for ( int i = history.length - 2; i >= 0; i-- )
                  {
                      sb.append( ',' );
                      sb.append( history[ i ] );
                  }
                  
                  samples.setValue( sb.toString() );
              }
              else
              {
                  for ( int i = history.length - 1; i >= 0; i-- )
                  {
                      DefaultConfiguration sample = new DefaultConfiguration( "sample", "-" );
                      sample.setValue( Integer.toString( history[i] ) );
                      samples.addChild( sample );
                  }
              }
              state.addChild( samples );
              
              saveState( state );
              
              return state;
          }
      }
      
      /**
       * Loads the state into the InstrumentSample.
       *
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      public final void loadState( Configuration state ) throws ConfigurationException
      {
          synchronized( this )
          {
              // Set the time
              long savedTime = m_time = state.getAttributeAsLong( "time" );
              
              // Set the history index.
              m_historyIndex = 0;
              
              // Read in the samples, don't trust that the number will be correct.
              //  First sample is the current value, following sames go back in
              //   time from newest to oldest.
              Configuration history = state.getChild( "history" );
              
              Configuration samples[] = history.getChildren( "sample" );
              int[] sampleValues;
              if ( samples.length == 0 )
              {
                  // No sample children.  The data may be stored in compact form
                  String compactSamples = history.getValue();
                  
                  // Sample values are stored in newest to oldest order.
                  StringTokenizer st = new StringTokenizer( compactSamples, "," );
                  sampleValues = new int[st.countTokens()];
                  
                  for ( int i = 0; i < sampleValues.length; i++ )
                  {
                      try
                      {
                          sampleValues[i] = Integer.parseInt( st.nextToken() );
                      }
                      catch ( NumberFormatException e )
                      {
                          throw new ConfigurationException( "The compact sample data could not be " +
                              "loaded, because of a number format problem, for InstrumentSample: " +
                              m_name ); 
                      }
                  }
              }
              else
              {
                  // Sample data stored as individual elements
                  sampleValues = new int[ samples.length ];
                  
                  // Sample values are stored in newest to oldest order.
                  for ( int i = 0; i < samples.length; i++ )
                  {
                      sampleValues[i] = samples[ i ].getValueAsInteger();
                  }
              }
              
              // Get the current value
              int value;
              if ( sampleValues.length > 0 )
              {
                  value = sampleValues[0];
                  
                  for ( int i = 0; i < m_size - 1; i++ )
                  {
                      if ( i < sampleValues.length - 1 )
                      {
                          m_historyOld[ m_size - 2 - i ] = sampleValues[ i + 1 ];
                      }
                      else
                      {
                          m_historyOld[ m_size - 2 - i ] = 0;
                      }
                  }
              }
              else
              {
                  value = 0;
              }
              
              loadState( value, state );
  
              if ( calculateSampleTime( System.currentTimeMillis() ) > savedTime )
              {
                  // The sample period changed since the save.
                  //  This will usually happen, but not always for long
                  //  intervals.
                  postSaveNeedsReset();
              }
          }
      }
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Initializes the sample
       */
      private void init()
      {
          // Calculate an interval time based on the current time by removing the modulous
          //  value of the current time. This will allign the intervals to the start of computer
          //  time.
          m_time = calculateSampleTime( System.currentTimeMillis() );
          
          // Create the arrays which will hold the history points.
          // History is build with m_value holding the current value and all previous values
          // spanning accross 2 arrays that switch places as time progresses.  This completely
          // removes the need to manage large lists or do array copies.
          // All history values are 0 initially.
          m_historyIndex = 0;
          m_historyOld = new int[ m_size - 1 ];
          m_historyNew = new int[ m_size - 1 ];
      }
      
      /**
       * Allow subclasses to add information into the saved state.
       *
       * @param state State configuration.
       */
      protected void saveState( DefaultConfiguration state ) {}
      
      /**
       * Used to load the state, called from AbstractInstrumentSample.loadState();
       * <p>
       * Should only be called when synchronized.
       *
       * @param value Current value loaded from the state.
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      protected abstract void loadState( int value, Configuration state )
          throws ConfigurationException;
      
      /**
       * Called after a state is loaded if the sample period is not the same
       *  as the last period saved.
       */
      protected abstract void postSaveNeedsReset();
      
      /**
       * Calculates the time of the sample which contains the specified time.
       *
       * @param time Time whose sample time is requested.
       */
      private long calculateSampleTime( long time )
      {
          return ( time / m_interval ) * m_interval;
      }
      
      /**
       * Gets the current value.  Does not update.
       * <p>
       * Should only be called when synchronized.
       *
       * @return The current value.
       */
      protected abstract int getValueInner();
      
      /**
       * The current sample has already been stored.  Reset the current sample
       *  and move on to the next.
       * <p>
       * Should only be called when synchronized.
       */
      protected abstract void advanceToNextSample();
      
      /**
       * Brings the InstrumentSample's time up to date so that a new value can be added.
       * <p>
       * Should only be called when synchronized.
       *
       * @param time The time to which the InstrumentSample should be brought up to date.
       *
       * @return True if listeners should be notified.
       */
      protected boolean update( long time )
      {
          //System.out.println("update(" + time + ")");
          // See if we are already up to date.
          if ( time - m_time >= m_interval )
          {
              // Needs to move to a new sample.
              if ( time - m_time >= m_maxAge )
              {
                  // The history is too old, reset the sample.
                  advanceToNextSample();
                  init();
              }
              else
              {
                  // Advance the history index.
                  while ( time - m_time >= m_interval )
                  {
                      // Store the current value into the end of the history.
                      m_historyNew[ m_historyIndex ] = getValueInner();
                      
                      // Advance to the next sample.
                      m_time += m_interval;
                      advanceToNextSample();
                      m_historyIndex++;
                      
                      if ( m_historyIndex >= m_size - 1 )
                      {
                          // Need to swap the history arrays
                          int[] tmp = m_historyOld;
                          m_historyOld = m_historyNew;
                          m_historyNew = tmp;
                          
                          // Reset the history index
                          m_historyIndex = 0;
                      }
                  }
              }
              return true;
          } else {
              return false;
          }
      }
      
      /**
       * Gets a snapshot of the samples.
       * <p>
       * Should only be called after an update when synchronized.
       *
       * @return A snapshot of the samples in the InstrumentSample.
       */
      private int[] getHistorySnapshot()
      {
          // Create a new array to hold the snapshot of the history data.
          // This method is a little slow but normal collection of sample points is
          // extremely fast.
          int[] history = new int[m_size];
          
          int sizem1 = m_size - 1;
          
          if ( m_size > 1 )
          {
              // Copy samples from the old history first.
              if ( m_historyIndex < sizem1 )
              {
                  // Copy the last (size - 1 - historyIndex) samples from the old history.
                  System.arraycopy( m_historyOld, m_historyIndex, history, 0, sizem1 - m_historyIndex );
              }
              
              if ( m_historyIndex > 0 )
              {
                  // Copy the first (historyIndex) samples from the new history.
                  System.arraycopy( m_historyNew, 0, history, sizem1 - m_historyIndex, m_historyIndex );
              }
          }
          // Get the final sample from the current sample value.
          history[ m_size - 1] = getValueInner();
          
          return history;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/AbstractValueInstrumentSample.java
  
  Index: AbstractValueInstrumentSample.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.instrument.manager;
  
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentManagerClient;
  import org.apache.avalon.excalibur.instrument.manager.client.ValueInstrumentListener;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  
  /**
   * An AbstractValueInstrumentSample contains all of the functionality common
   *  to all InstrumentSamples which represent a fixed value.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  abstract class AbstractValueInstrumentSample
      extends AbstractInstrumentSample
      implements ValueInstrumentListener
  {
      /** The sample value. */
      protected int m_value;
      
      /** The number of times that the value has been changed in this sample period. */
      protected int m_valueCount;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new AbstractValueInstrumentSample
       *
       * @param name The name of the new InstrumentSample.
       * @param interval The sample interval of the new InstrumentSample.
       * @param size The number of samples to store as history.  Assumes that size is at least 1.
       * @param description The description of the new InstrumentSample.
       */
      protected AbstractValueInstrumentSample( String name, long interval, int size, String description )
      {
          super( name, interval, size, description );
          
          // Set the current value to 0 initially.
          m_value = 0;
      }
      
      /*---------------------------------------------------------------
       * InstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * Returns the Type of the Instrument which can use the sample.  This
       *  should be the same for all instances of a class.
       * <p>
       * This InstrumentSample returns InstrumentManager.PROFILE_POINT_TYPE_VALUE
       *
       * @return The Type of the Instrument which can use the sample.
       */
      public final int getInstrumentType()
      {
          return InstrumentManagerClient.INSTRUMENT_TYPE_VALUE;
      }
      
      /**
       * Obtain the value of the sample.  All samples are integers, so the profiled
       * objects must measure quantity (numbers of items), rate (items/period), time in
       * milliseconds, etc.
       * <p>
       * Should only be called when synchronized.
       *
       * @return The sample value.
       */
      public int getValueInner()
      {
          return m_value;
      }
  
      /*---------------------------------------------------------------
       * AbstractInstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * Allow subclasses to add information into the saved state.
       *
       * @param state State configuration.
       */
      protected void saveState( DefaultConfiguration state )
      {
          super.saveState( state );
          
          state.setAttribute( "value-count", Integer.toString( m_valueCount ) );
      }
      
      /**
       * Used to load the state, called from AbstractInstrumentSample.loadState();
       * <p>
       * Should only be called when synchronized.
       *
       * @param value Current value loaded from the state.
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      protected void loadState( int value, Configuration state )
          throws ConfigurationException
      {
          m_value = value;
          m_valueCount = state.getAttributeAsInteger( "value-count" );
      }
      
      /**
       * Called after a state is loaded if the sample period is not the same
       *  as the last period saved.
       */
      protected void postSaveNeedsReset()
      {
          m_value = 0;
          m_valueCount = 0;
      }
      
      /*---------------------------------------------------------------
       * ValueInstrumentListener Methods
       *-------------------------------------------------------------*/
      /**
       * Called by a ValueInstrument whenever its value is set.
       *
       * @param instrumentName The key of Instrument whose value was set.
       * @param value Value that was set.
       * @param time The time that the Instrument was incremented.
       *
       * ValueInstrument
       */
      public void setValue( String instrumentName, int value, long time )
      {
          //System.out.println("AbstractValueInstrumentSample.setValue(" + instrumentName + ", " + value + ", " + time + ") : " + getName());
          setValueInner( value, time );
      }
      
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Sets the current value of the sample.
       *
       * @param value New sample value.
       * @param time Time that the new sample arrives.
       */
      protected abstract void setValueInner( int value, long time );
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/AverageValueInstrumentSample.java
  
  Index: AverageValueInstrumentSample.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.instrument.manager;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  
  /**
   * A InstrumentSample which stores the average value set during the sample
   *  period.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  class AverageValueInstrumentSample
      extends AbstractValueInstrumentSample
  {
      /** Total of all values seen during the sample period. */
      private long m_valueTotal;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new AverageValueInstrumentSample
       *
       * @param name The name of the new InstrumentSample.
       * @param interval The sample interval of the new InstrumentSample.
       * @param size The number of samples to store as history.  Assumes that size is at least 1.
       * @param description The description of the new InstrumentSample.
       */
      AverageValueInstrumentSample( String name, long interval, int size, String description )
      {
          super( name, interval, size, description );
      }
      
      /*---------------------------------------------------------------
       * AbstractInstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * The current sample has already been stored.  Reset the current sample
       *  and move on to the next.
       * <p>
       * Should only be called when synchronized.
       */
      protected void advanceToNextSample()
      {
          // Leave the value as is so that it will propagate to the next sample
          //  if needed.  But reset the value count so that new values will not
          //  be affected by the old.
          m_valueCount = 0;
      }
      
      /**
       * Allow subclasses to add information into the saved state.
       *
       * @param state State configuration.
       */
      protected void saveState( DefaultConfiguration state )
      {
          super.saveState( state );
          
          state.setAttribute( "value-total", Long.toString( m_valueTotal ) );
      }
      
      /**
       * Used to load the state, called from AbstractInstrumentSample.loadState();
       * <p>
       * Should only be called when synchronized.
       *
       * @param value Current value loaded from the state.
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      protected void loadState( int value, Configuration state )
          throws ConfigurationException
      {
          super.loadState( value, state );
          
          m_valueTotal = state.getAttributeAsLong( "value-total" );
      }
      
      /**
       * Called after a state is loaded if the sample period is not the same
       *  as the last period saved.
       */
      protected void postSaveNeedsReset()
      {
          super.postSaveNeedsReset();
          
          m_valueTotal = 0;
      }
      
      /*---------------------------------------------------------------
       * AbstractValueInstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * Sets the current value of the sample.  The value will be set as the
       *  average of the new value and other values seen during the sample period.
       *
       * @param value New sample value.
       * @param time Time that the new sample arrives.
       */
      protected void setValueInner( int value, long time )
      {
          int sampleValue;
          long sampleTime;
          
          synchronized(this)
          {
              update( time );
              
              if ( m_valueCount > 0 )
              {
                  // Additional sample
                  m_valueCount++;
                  m_valueTotal += value;
                  m_value = (int)(m_valueTotal / m_valueCount);
              }
              else
              {
                  // First value of this sample.
                  m_valueCount = 1;
                  m_valueTotal = m_value = value;
              }
              sampleValue = m_value;
              sampleTime = m_time;
          }
          
          updateListeners( sampleValue, sampleTime );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/CounterInstrumentSample.java
  
  Index: CounterInstrumentSample.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.instrument.manager;
  
  import org.apache.avalon.excalibur.instrument.manager.client.CounterInstrumentListener;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentManagerClient;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  
  /**
   * A InstrumentSample which stores the number of times that increment has been
   *  called during the sample period.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  class CounterInstrumentSample
      extends AbstractInstrumentSample
      implements CounterInstrumentListener
  {
      /** The count. */
      protected int m_count;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new CounterInstrumentSample
       *
       * @param name The name of the new InstrumentSample.
       * @param interval The sample interval of the new InstrumentSample.
       * @param size The number of samples to store as history.  Assumes that size is at least 1.
       * @param description The description of the new InstrumentSample.
       */
      CounterInstrumentSample( String name, long interval, int size, String description )
      {
          super( name, interval, size, description );
          
          // Set the current value to 0 initially.
          m_count = 0;
      }
      
      /*---------------------------------------------------------------
       * InstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * Returns the Type of the Instrument which can use the sample.  This
       *  should be the same for all instances of a class.
       * <p>
       * This InstrumentSample returns InstrumentManager.PROFILE_POINT_TYPE_COUNTER
       *
       * @return The Type of the Instrument which can use the sample.
       */
      public final int getInstrumentType()
      {
          return InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER;
      }
      
      /**
       * Obtain the value of the sample.  All samples are integers, so the profiled
       * objects must measure quantity (numbers of items), rate (items/period), time in
       * milliseconds, etc.
       *
       * @return The sample value.
       */
      public int getValueInner()
      {
          return m_count;
      }
      
      /*---------------------------------------------------------------
       * AbstractInstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * The current sample has already been stored.  Reset the current sample
       *  and move on to the next.
       * <p>
       * Should only be called when synchronized.
       */
      protected void advanceToNextSample()
      {
          // Counts do not propagate, so always reset the count to 0.
          m_count = 0;
      }
      
      /**
       * Used to load the state, called from AbstractInstrumentSample.loadState();
       * <p>
       * Should only be called when synchronized.
       *
       * @param value Current value loaded from the state.
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      protected void loadState( int value, Configuration state )
          throws ConfigurationException
      {
          m_count = value;
      }
      
      /**
       * Called after a state is loaded if the sample period is not the same
       *  as the last period saved.
       */
      protected void postSaveNeedsReset()
      {
          m_count = 0;
      }
      
      /*---------------------------------------------------------------
       * CounterInstrumentListener Methods
       *-------------------------------------------------------------*/
      /**
       * Called by a CounterInstrument whenever its value is incremented.
       *
       * @param instrumentName The name of Instrument which was incremented.
       * @param time The time that the Instrument was incremented.
       */
      public void increment( String instrumentName, long time )
      {
          //System.out.println("CounterInstrumentSample.increment(" + instrumentName + ", " + time + ") : " + getName() );
          increment( time );
      }
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Increments the count.
       *
       * @param time Time that the count is incremented.
       */
      private void increment( long time )
      {
          int sampleValue;
          long sampleTime;
          
          synchronized(this)
          {
              update( time );
              
              m_count++;
              
              sampleValue = m_count;
              sampleTime = m_time;
          }
          
          updateListeners( sampleValue, sampleTime );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/DefaultInstrumentManager.java
  
  Index: DefaultInstrumentManager.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.instrument.manager;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.util.HashMap;
  
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentableDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentManagerClient;
  import org.apache.avalon.excalibur.instrument.manager.client.NoSuchInstrumentableException;
  
  import org.apache.avalon.excalibur.instrument.AbstractInstrument;
  import org.apache.avalon.excalibur.instrument.CounterInstrument;
  import org.apache.avalon.excalibur.instrument.Instrument;
  import org.apache.avalon.excalibur.instrument.Instrumentable;
  import org.apache.avalon.excalibur.instrument.InstrumentManager;
  import org.apache.avalon.excalibur.instrument.ValueInstrument;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  /**
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class DefaultInstrumentManager
      extends AbstractLogEnabled
      implements Configurable, Initializable, Disposable, InstrumentManager,
          Instrumentable, Runnable
  {
      public static final String INSTRUMENT_TOTAL_MEMORY = "total-memory";
      public static final String INSTRUMENT_FREE_MEMORY = "free-memory";
      public static final String INSTRUMENT_MEMORY = "memory";
      public static final String INSTRUMENT_ACTIVE_THREAD_COUNT = "active-thread-count";
      
      /** The name used to identify this InstrumentManager. */
      private String m_name;
  
      /** The description of this InstrumentManager. */
      private String m_description;
      
      /** Configuration for the InstrumentManager */
      private Configuration m_configuration;
  
      /** State file. */
      private File m_stateFile;
  
      /** Save state interval. */
      private long m_stateInterval;
  
      /** Use a compact format when saving profile sample data. */
      private boolean m_stateCompactSamples;
  
      /** Last time that the state was saved. */
      private long m_lastStateSave;
  
      /** Semaphore for actions which must be synchronized */
      private Object m_semaphore = new Object();
  
      /** HashMap of all of the registered InstrumentableProxies by their keys. */
      private HashMap m_instrumentableProxies = new HashMap();
  
      /** Optimized array of the InstrumentableProxies. */
      private InstrumentableProxy[] m_instrumentableProxyArray;
  
      /** Optimized array of the InstrumentableDescriptors. */
      private InstrumentableDescriptor[] m_instrumentableDescriptorArray;
  
      /**
       * Thread used to keep the instruments published by the InstrumentManager
       *  up to date.
       */
      private Thread m_runner;
  
      /** Instrumentable Name assigned to this Instrumentable */
      private String m_instrumentableName = "instrument-manager";
  
      /** Instrument used to profile the total memory. */
      private ValueInstrument m_totalMemoryInstrument;
  
      /** Instrument used to profile the free memory. */
      private ValueInstrument m_freeMemoryInstrument;
  
      /** Instrument used to profile the in use memory. */
      private ValueInstrument m_memoryInstrument;
  
      /** Instrument used to profile the active thread count of the JVM. */
      private ValueInstrument m_activeThreadCountInstrument;
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new DefaultInstrumentManager.
       *
       * @param name The name used to identify this InstrumentManager.  Should not
       *             contain any spaces or periods.
       */
      public DefaultInstrumentManager( String name )
      {
          m_name = name;
          // The description defaults to the name.
          m_description = name;
          
          // Initialize the Instrumentable elements.
          m_totalMemoryInstrument = new ValueInstrument( INSTRUMENT_TOTAL_MEMORY );
          m_freeMemoryInstrument = new ValueInstrument( INSTRUMENT_FREE_MEMORY );
          m_memoryInstrument = new ValueInstrument( INSTRUMENT_MEMORY );
          m_activeThreadCountInstrument = new ValueInstrument( INSTRUMENT_ACTIVE_THREAD_COUNT );
      }
  
      /*---------------------------------------------------------------
       * Configurable Methods
       *-------------------------------------------------------------*/
      /**
       * Initializes the configured instrumentables.
       *
       * @param configuration InstrumentManager configuration.
       *
       * @throws ConfigurationException If there are any configuration problems.
       */
      public void configure( Configuration configuration )
          throws ConfigurationException
      {
          synchronized( m_semaphore )
          {
              m_configuration = configuration;
  
              // Configure the instrumentables.
              Configuration instrumentablesConf =
                  configuration.getChild( "instrumentables" );
              Configuration[] instrumentableConfs =
                  instrumentablesConf.getChildren( "instrumentable" );
              for( int i = 0; i < instrumentableConfs.length; i++ )
              {
                  Configuration instrumentableConf = instrumentableConfs[ i ];
                  String instrumentableName = instrumentableConf.getAttribute( "name" );
  
                  InstrumentableProxy instrumentableProxy =
                      new InstrumentableProxy( instrumentableName );
                  instrumentableProxy.enableLogging( getLogger() );
                  instrumentableProxy.configure( instrumentableConf );
                  m_instrumentableProxies.put( instrumentableName, instrumentableProxy );
  
                  // Clear the optimized arrays
                  m_instrumentableProxyArray = null;
                  m_instrumentableDescriptorArray = null;
              }
  
              // Configure the state file.
              Configuration stateFileConf = configuration.getChild( "state-file" );
              m_stateInterval = stateFileConf.getAttributeAsLong( "interval", 60000 );
              m_stateCompactSamples =
                  stateFileConf.getAttributeAsBoolean( "use-compact-samples", true );
  
              String stateFile = stateFileConf.getValue( null );
              if( stateFile != null )
              {
                  m_stateFile = new File( stateFile );
                  if( m_stateFile.exists() )
                  {
                      /*
                      try
                      {
                          loadStateFromFile( m_stateFile );
                      }
                      catch( Exception e )
                      {
                          getLogger().error(
                              "Unable to load the instrument manager state.  The configuration " +
                              "may have been corruptped.  A backup may have been made in the same " +
                              "directory when it was saved.", e );
                      }
                      */
                  }
              }
          }
      }
  
      /*---------------------------------------------------------------
       * Initializable Methods
       *-------------------------------------------------------------*/
      /**
       * Initializes the InstrumentManager.
       *
       * @throws Exception If there were any problems initializing the object.
       */
      public void initialize()
          throws Exception
      {
          // Register the InstrumentManager as an Instrumentable.
          registerInstrumentable( this, getInstrumentableName() );
  
          if( m_runner == null )
          {
              m_runner = new Thread( this, "InstrumentManagerRunner" );
              m_runner.start();
          }
      }
  
      /*---------------------------------------------------------------
       * Disposable Methods
       *-------------------------------------------------------------*/
      /**
       * Disposes the InstrumentManager.
       */
      public void dispose()
      {
          if( m_runner != null )
          {
              m_runner = null;
          }
  
          saveState();
      }
  
      /*---------------------------------------------------------------
       * InstrumentManager Methods
       *-------------------------------------------------------------*/
      /**
       * Instrumentable to be registered with the instrument manager.  Should be
       *  called whenever an Instrumentable is created.
       *
       * @param instrumentable Instrumentable to register with the InstrumentManager.
       * @param instrumentableName The name to use when registering the Instrumentable.
       *
       * @throws Exception If there were any problems registering the Instrumentable.
       */
      public void registerInstrumentable( Instrumentable instrumentable, String instrumentableName )
          throws Exception
      {
          getLogger().debug( "Registering Instrumentable: " + instrumentableName );
  
          synchronized( m_semaphore )
          {
              // If the instrumentable does not implement ThreadSafe, then it is possible that
              //  another one of its instance was already registered.  If so, then the
              //  Instruments will all be the same.  The new instances still need to be
              //  registered however.
              InstrumentableProxy instrumentableProxy =
                  (InstrumentableProxy)m_instrumentableProxies.get( instrumentableName );
              if( instrumentableProxy == null )
              {
                  // This is a Instrumentable that has not been seen before.
                  instrumentableProxy = new InstrumentableProxy( instrumentableName );
                  instrumentableProxy.enableLogging( getLogger() );
                  // Do not call configure here because there is no configuration
                  //  for discovered instrumentables.
                  m_instrumentableProxies.put( instrumentableName, instrumentableProxy );
  
                  // Recursively register all the Instruments in this and any child Instrumentables.
                  registerInstruments( instrumentable, instrumentableProxy, instrumentableName );
              }
              else
              {
                  // Additional Instrumentable instance.  Possible that new Instruments could be found.
                  registerInstruments( instrumentable, instrumentableProxy, instrumentableName );
              }
          }
      }
  
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Returns the name used to identify this InstrumentManager.
       *
       * @return The name used to identify this InstrumentManager.
       */
      public String getName()
      {
          return m_name;
      }
      
      /**
       * Returns the description of this InstrumentManager.
       *
       * @return The description of this InstrumentManager.
       */
      public String getDescription()
      {
          return m_description;
      }
      
      /**
       * Returns an InstrumentableDescriptor based on its name or the name of any
       *  of its children.
       *
       * @param instrumentableName Name of the Instrumentable being requested.
       *
       * @return A Descriptor of the requested Instrumentable.
       *
       * @throws NoSuchInstrumentableException If the specified Instrumentable
       *                                       does not exist.
       */
      public InstrumentableDescriptor getInstrumentableDescriptor( String instrumentableName )
          throws NoSuchInstrumentableException
      {
          InstrumentableProxy proxy = getInstrumentableProxy( instrumentableName );
          if( proxy == null )
          {
              throw new NoSuchInstrumentableException(
                  "No instrumentable can be found using name: " + instrumentableName );
          }
  
          return proxy.getDescriptor();
      }
  
      /**
       * Returns an array of Descriptors for the Instrumentables managed by this
       *  InstrumentManager.
       *
       * @return An array of Descriptors for the Instrumentables managed by this
       *  InstrumentManager.
       */
      public InstrumentableDescriptor[] getInstrumentableDescriptors()
      {
          InstrumentableDescriptor[] descriptors = m_instrumentableDescriptorArray;
          if( descriptors == null )
          {
              descriptors = updateInstrumentableDescriptorArray();
          }
          return descriptors;
      }
      
      /**
       * Invokes garbage collection.
       */
      public void invokeGarbageCollection()
      {
          System.gc();
      }
      
      
  
      /**
       * Loads the profiler state from the specified file.
       *
       * @param stateFile File to read the profiler's state from.
       *
       * @throws Exception if there are any problems loading the state.
       */
      /*
      public void loadInstrumentStateFromFile( File stateFile )
          throws Exception
      {
          long now = System.currentTimeMillis();
          getLogger().debug( "Loading profiler state from: " + stateFile.getAbsolutePath() );
  
          FileInputStream is = new FileInputStream( stateFile );
          try
          {
              loadInstrumentStateFromStream( is );
          }
          finally
          {
              is.close();
          }
  
          getLogger().debug( "Loading profiler state took " +
                             ( System.currentTimeMillis() - now ) + "ms." );
      }
      */
  
      /**
       * Loads the profiler state from the specified stream.
       *
       * @param is Stream to read the profiler's state from.
       *
       * @throws Exception if there are any problems loading the state.
       */
      /*
      public void loadInstrumentStateFromStream( InputStream is )
          throws Exception
      {
          // Ride on top of the Configuration classes to load the state.
          DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
          Configuration stateConfig = builder.build( is );
  
          loadInstrumentStateFromConfiguration( stateConfig );
      }
      */
  
      /**
       * Loads the profiler state from the specified Configuration.
       *
       * @param state Configuration object to load the state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      /*
      public void loadInstrumentStateFromConfiguration( Configuration state )
          throws ConfigurationException
      {
          Configuration[] instrumentableConfs = state.getChildren( "instrumentable" );
          for( int i = 0; i < instrumentableConfs.length; i++ )
          {
              Configuration instrumentableConf = instrumentableConfs[ i ];
              String name = instrumentableConf.getAttribute( "name" );
              InstrumentableProxy proxy = getInstrumentableProxy( name );
              if( proxy == null )
              {
                  getLogger().warn( "Instrumentable entry ignored while loading state because the " +
                                    "instrumentable does not exist: " + name );
              }
              else
              {
                  proxy.loadState( instrumentableConf );
              }
          }
      }
      */
  
      /**
       * Saves the Instrument's state to the specified file.
       *
       * @param stateFile File to write the profiler's state to.
       *
       * @throws Exception if there are any problems saving the state.
       */
      /*
      public void saveInstrumentStateToFile( File stateFile )
          throws Exception
      {
          long now = System.currentTimeMillis();
          getLogger().debug( "Saving profiler state to: " + stateFile.getAbsolutePath() );
  
          FileOutputStream os = new FileOutputStream( stateFile );
          try
          {
              saveInstrumentStateToStream( os );
          }
          finally
          {
              os.close();
          }
  
          getLogger().debug( "Saving profiler state took " +
                             ( System.currentTimeMillis() - now ) + "ms." );
      }
      */
  
      /**
       * Saves the Instrument's state to the specified output stream.
       *
       * @param os Stream to write the profiler's state to.
       *
       * @throws Exception if there are any problems saving the state.
       */
      /*
      public void saveInstrumentStateToStream( OutputStream os )
          throws Exception
      {
          Configuration stateConfig = saveInstrumentStateToConfiguration();
  
          // Ride on top of the Configuration classes to save the state.
          DefaultConfigurationSerializer serializer = new DefaultConfigurationSerializer();
          serializer.setIndent( true );
          serializer.serialize( os, stateConfig );
      }
      */
  
      /**
       * Returns the desktop state as a Configuration object.
       *
       * @return The desktop state as a Configuration object.
       */
      /*
      public Configuration saveInstrumentStateToConfiguration()
      {
  
          DefaultConfiguration state = new DefaultConfiguration( "profiler-state", "-" );
  
          InstrumentableProxy[] instrumentableProxies = m_instrumentableProxyArray;
          if( instrumentableProxies == null )
          {
              instrumentableProxies = updateInstrumentableProxyArray();
          }
  
          for( int i = 0; i < instrumentableProxies.length; i++ )
          {
              // Only save configured instrumentables as they are the only ones
              //  that will contain profile samples.
              if( instrumentableProxies[ i ].isConfigured() )
              {
                  state.addChild( instrumentableProxies[ i ].saveState( m_stateCompactSamples ) );
              }
          }
  
          return state;
      }
      */
  
  
      /*---------------------------------------------------------------
       * Instrumentable Methods
       *-------------------------------------------------------------*/
      /**
       * Sets the name for the Instrumentable.  The Instrumentable Name is used
       *  to uniquely identify the Instrumentable during the configuration of
       *  the InstrumentManager and to gain access to an InstrumentableDescriptor
       *  through the InstrumentManager.  The value should be a string which does
       *  not contain spaces or periods.
       * <p>
       * This value may be set by a parent Instrumentable, or by the
       *  InstrumentManager using the value of the 'instrumentable' attribute in
       *  the configuration of the component.
       *
       * @param name The name used to identify a Instrumentable.
       */
      public void setInstrumentableName( String name )
      {
          m_instrumentableName = name;
      }
  
      /**
       * Gets the name of the Instrumentable.
       *
       * @return The name used to identify a Instrumentable.
       */
      public String getInstrumentableName()
      {
          return m_instrumentableName;
      }
  
      /**
       * Obtain a reference to all the Instruments that the Instrumentable object
       *  wishes to expose.  All sampling is done directly through the
       *  Instruments as opposed to the Instrumentable interface.
       *
       * @return An array of the Instruments available for profiling.  Should
       *         never be null.  If there are no Instruments, then
       *         EMPTY_INSTRUMENT_ARRAY can be returned.  This should never be
       *         the case though unless there are child Instrumentables with
       *         Instruments.
       */
      public Instrument[] getInstruments()
      {
          return new Instrument[]
          {
              m_totalMemoryInstrument,
              m_freeMemoryInstrument,
              m_memoryInstrument,
              m_activeThreadCountInstrument
          };
      }
  
      /**
       * Any Object which implements Instrumentable can also make use of other
       *  Instrumentable child objects.  This method is used to tell the
       *  InstrumentManager about them.
       *
       * @return An array of child Instrumentables.  This method should never
       *         return null.  If there are no child Instrumentables, then
       *         EMPTY_INSTRUMENTABLE_ARRAY can be returned.
       */
      public Instrumentable[] getChildInstrumentables()
      {
          return Instrumentable.EMPTY_INSTRUMENTABLE_ARRAY;
      }
  
      /*---------------------------------------------------------------
       * Runnable Methods
       *-------------------------------------------------------------*/
      public void run()
      {
          while( m_runner != null )
          {
              try
              {
                  Thread.sleep( 1000 );
  
                  memoryInstruments();
                  threadInstruments();
  
                  // Handle the state file if it is set
                  long now = System.currentTimeMillis();
                  if( now - m_lastStateSave >= m_stateInterval )
                  {
                      saveState();
                  }
              }
              catch( Throwable t )
              {
                  getLogger().error( "Encountered an unexpected error.", t );
              }
          }
      }
  
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Saves the state to the current state file if configured.
       */
      private void saveState()
      {
          long now = System.currentTimeMillis();
  
          // Always set the time even if the save fails so that we don't thrash
          m_lastStateSave = now;
  
          if( m_stateFile == null )
          {
              return;
          }
  
          // Rename the old file in case there is a problem
          File renameFile = null;
          boolean success = false;
          if( m_stateFile.exists() )
          {
              renameFile = new File( m_stateFile.getAbsolutePath() + "." + now + ".backup" );
              m_stateFile.renameTo( renameFile );
          }
  
          try
          {
              /*
              try
              {
                  saveInstrumentStateToFile( m_stateFile );
                  success = true;
              }
              catch( Exception e )
              {
                  getLogger().error( "Unable to save the profiler state.", e );
              }
              */
          }
          finally
          {
              // Clean up after the renamed file.
              if( renameFile != null )
              {
                  if( success )
                  {
                      renameFile.delete();
                  }
                  else
                  {
                      m_stateFile.delete();
                      renameFile.renameTo( m_stateFile );
                  }
              }
          }
      }
  
      /**
       * Returns a InstrumentableDescriptor based on its name or the name of any
       *  of its children.
       *
       * @param instrumentableName Name of the Instrumentable being requested.
       *
       * @return A Proxy of the requested Instrumentable or null if not found.
       */
      private InstrumentableProxy getInstrumentableProxy( String instrumentableName )
      {
          String name = instrumentableName;
          while( true )
          {
              InstrumentableProxy proxy = (InstrumentableProxy)m_instrumentableProxies.get( name );
              if( proxy != null )
              {
                  return proxy;
              }
  
              // Assume this is a child name and try looking with the parent name.
              int pos = name.lastIndexOf( '.' );
              if( pos > 0 )
              {
                  name = name.substring( 0, pos );
              }
              else
              {
                  return null;
              }
          }
      }
  
      /**
       * Updates the Memory based Profile Points published by the InstrumentManager.
       */
      private void memoryInstruments()
      {
          // Avoid doing unneeded work if profile points are not being used.
          Runtime runtime = null;
          long totalMemory = -1;
          long freeMemory = -1;
  
          // Total Memory
          if( m_totalMemoryInstrument.isActive() )
          {
              runtime = Runtime.getRuntime();
              totalMemory = runtime.totalMemory();
              m_totalMemoryInstrument.setValue( (int)totalMemory );
          }
  
          // Free Memory
          if( m_freeMemoryInstrument.isActive() )
          {
              if( runtime == null )
              {
                  runtime = Runtime.getRuntime();
              }
              freeMemory = runtime.freeMemory();
              m_freeMemoryInstrument.setValue( (int)freeMemory );
          }
  
          // In use Memory
          if( m_memoryInstrument.isActive() )
          {
              if( runtime == null )
              {
                  runtime = Runtime.getRuntime();
              }
              if( totalMemory < 0 )
              {
                  totalMemory = runtime.totalMemory();
              }
              if( freeMemory < 0 )
              {
                  freeMemory = runtime.freeMemory();
              }
              m_memoryInstrument.setValue( (int)( totalMemory - freeMemory ) );
          }
      }
  
      /**
       * Updates the Thread based Profile Points published by the InstrumentManager.
       */
      private void threadInstruments()
      {
          if( m_activeThreadCountInstrument.isActive() )
          {
              // Get the top level thread group.
              ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
              ThreadGroup parent;
              while( ( parent = threadGroup.getParent() ) != null )
              {
                  threadGroup = parent;
              }
  
              m_activeThreadCountInstrument.setValue( threadGroup.activeCount() );
          }
      }
  
      /**
       * Updates the cached array of InstrumentableProxies taking
       *  synchronization into account.
       *
       * @return An array of the InstrumentableProxies.
       */
      private InstrumentableProxy[] updateInstrumentableProxyArray()
      {
          synchronized( m_semaphore )
          {
              m_instrumentableProxyArray = new InstrumentableProxy[ m_instrumentableProxies.size() ];
              m_instrumentableProxies.values().toArray( m_instrumentableProxyArray );
  
              return m_instrumentableProxyArray;
          }
      }
  
      /**
       * Updates the cached array of InstrumentableDescriptors taking
       *  synchronization into account.
       *
       * @return An array of the InstrumentableDescriptors.
       */
      private InstrumentableDescriptor[] updateInstrumentableDescriptorArray()
      {
          synchronized( m_semaphore )
          {
              if( m_instrumentableProxyArray == null )
              {
                  updateInstrumentableProxyArray();
              }
  
              m_instrumentableDescriptorArray =
                  new InstrumentableDescriptor[ m_instrumentableProxyArray.length ];
              for( int i = 0; i < m_instrumentableProxyArray.length; i++ )
              {
                  m_instrumentableDescriptorArray[ i ] = m_instrumentableProxyArray[ i ].getDescriptor();
              }
  
              return m_instrumentableDescriptorArray;
          }
      }
  
      /**
       * Examines a instrumentable and Registers all of its Instruments.
       * <p>
       * Only called when m_semaphore is locked.
       */
      private void registerInstruments( Instrumentable instrumentable,
                                          InstrumentableProxy instrumentableProxy,
                                          String instrumentableName )
          throws Exception
      {
          // Loop over the Instruments published by this Instrumentable
          Instrument[] profilePoints = instrumentable.getInstruments();
          for( int i = 0; i < profilePoints.length; i++ )
          {
              Instrument profilePoint = profilePoints[ i ];
              String profilePointName =
                  instrumentableName + "." + profilePoint.getInstrumentName();
  
              getLogger().debug( "Registering Instrument: " + profilePointName );
  
              // See if a proxy exists for the Instrument yet.
              InstrumentProxy proxy = instrumentableProxy.getInstrumentProxy( profilePointName );
              if( proxy == null )
              {
                  proxy = new InstrumentProxy( profilePointName );
  
                  // Set the type of the new InstrumentProxy depending on the
                  //  class of the actual Instrument.
                  if( profilePoint instanceof CounterInstrument )
                  {
                      proxy.setType( InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER );
                  }
                  else if( profilePoint instanceof ValueInstrument )
                  {
                      proxy.setType( InstrumentManagerClient.INSTRUMENT_TYPE_VALUE );
                  }
                  else
                  {
                      throw new ComponentException( "Encountered an unknown Instrument type for " +
                                                    "the Instrument with key, " + profilePointName + ": " +
                                                    profilePoint.getClass().getName() );
                  }
  
                  // Store a reference to the proxy in the Instrument.
                  ( (AbstractInstrument)profilePoint ).setInstrumentProxy( proxy );
  
                  instrumentableProxy.addInstrumentProxy( proxy );
              }
              else
              {
                  // Register the existing proxy with the Instrument.  Make sure that the
                  //  type didn't change on us.
                  if( profilePoint instanceof CounterInstrument )
                  {
                      switch( proxy.getType() )
                      {
                          case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER:
                              // Type is the same.
                              // Store a reference to the proxy in the Instrument.
                              ( (AbstractInstrument)profilePoint ).setInstrumentProxy( proxy );
                              break;
  
                          case InstrumentManagerClient.INSTRUMENT_TYPE_NONE:
                              // Not yet set.  Created in configuration.
                              proxy.setType( InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER );
  
                              // Store a reference to the proxy in the Instrument.
                              ( (AbstractInstrument)profilePoint ).setInstrumentProxy( proxy );
                              break;
  
                          default:
                              throw new ComponentException(
                                  "Instruments of more than one type are assigned to name: " +
                                  profilePointName );
                      }
                  }
                  else if( profilePoint instanceof ValueInstrument )
                  {
                      switch( proxy.getType() )
                      {
                          case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE:
                              // Type is the same.
                              // Store a reference to the proxy in the Instrument.
                              ( (AbstractInstrument)profilePoint ).setInstrumentProxy( proxy );
                              break;
  
                          case InstrumentManagerClient.INSTRUMENT_TYPE_NONE:
                              // Not yet set.  Created in configuration.
                              proxy.setType( InstrumentManagerClient.INSTRUMENT_TYPE_VALUE );
  
                              // Store a reference to the proxy in the Instrument.
                              ( (AbstractInstrument)profilePoint ).setInstrumentProxy( proxy );
                              break;
  
                          default:
                              throw new ComponentException(
                                  "Instruments of more than one type are assigned to name: " +
                                  profilePointName );
                      }
                  }
                  else
                  {
                      throw new ComponentException( "Encountered an unknown Instrument type for " +
                                                    "the Instrument with name, " + profilePointName + ": " +
                                                    profilePoint.getClass().getName() );
                  }
              }
          }
  
          // Loop over the child Instrumentables and register their Instruments as well.
          Instrumentable[] childInstrumentables = instrumentable.getChildInstrumentables();
          for( int i = 0; i < childInstrumentables.length; i++ )
          {
              // Make sure that the child instrumentable name is set.
              if( childInstrumentables[ i ].getInstrumentableName() == null )
              {
                  String msg = "The getInstrumentableNAme of a child Instrumentable returned null.  " +
                      "Instance of " + instrumentable.getClass().getName();
                  getLogger().debug( msg );
                  throw new ComponentException( msg );
              }
  
              String instrumentableChildName = instrumentableName + "." +
                  childInstrumentables[ i ].getInstrumentableName();
  
              registerInstruments( childInstrumentables[ i ], instrumentableProxy, instrumentableChildName );
          }
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/InstrumentDescriptorImpl.java
  
  Index: InstrumentDescriptorImpl.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.instrument.manager;
  
  import org.apache.avalon.excalibur.instrument.manager.client.CounterInstrumentListener;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.NoSuchInstrumentSampleException;
  import org.apache.avalon.excalibur.instrument.manager.client.ValueInstrumentListener;
  
  /**
   * Describes a Instrument and acts as a Proxy to protect the original
   *  Instrument.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class InstrumentDescriptorImpl
      implements InstrumentDescriptor
  {
      /** InstrumentProxy being described. */
      private InstrumentProxy m_instrumentProxy;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new InstrumentDescriptor.
       *
       * @param instrumentProxy InstrumentProxy being described.
       */
      InstrumentDescriptorImpl( InstrumentProxy instrumentProxy )
      {
          m_instrumentProxy = instrumentProxy;
      }
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Returns true if the Instrument was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      public boolean isConfigured()
      {
          return m_instrumentProxy.isConfigured();
      }
      
      /**
       * Gets the name for the Instrument.  The Instrument Name is used to
       *  uniquely identify the Instrument during the configuration of the
       *  Profiler.  The value should be a string which does not contain spaces
       *  or periods.
       *
       * @return The name used to identify a Instrument.
       */
      public String getName() 
      {
          return m_instrumentProxy.getName();
      }
      
      /**
       * Gets the description of the Instrument.
       *
       * @return The description of the Instrument.
       */
      public String getDescription()
      {
          return m_instrumentProxy.getDescription();
      }
      
      /**
       * Returns the type of the Instrument.
       *
       * @return The type of the Instrument.
       */
      public int getType()
      {
          return m_instrumentProxy.getType();
      }
      
      /**
       * Adds a CounterInstrumentListener to the list of listeners which will
       *  receive updates of the value of the Instrument.
       *
       * @param listener CounterInstrumentListener which will start receiving
       *                 profile updates.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.PROFILE_POINT_TYPE_COUNTER.
       */
      public void addCounterInstrumentListener( CounterInstrumentListener listener )
      {
          m_instrumentProxy.addCounterInstrumentListener( listener );
      }
      
      /**
       * Removes a InstrumentListener from the list of listeners which will
       *  receive profile events.
       *
       * @param listener InstrumentListener which will stop receiving profile
       *                 events.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.PROFILE_POINT_TYPE_COUNTER.
       */
      public void removeCounterInstrumentListener( CounterInstrumentListener listener )
      {
          m_instrumentProxy.removeCounterInstrumentListener( listener );
      }
      
      /**
       * Adds a ValueInstrumentListener to the list of listeners which will
       *  receive updates of the value of the Instrument.
       *
       * @param listener ValueInstrumentListener which will start receiving
       *                 profile updates.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.PROFILE_POINT_TYPE_VALUE.
       */
      public void addValueInstrumentListener( ValueInstrumentListener listener )
      {
          m_instrumentProxy.addValueInstrumentListener( listener );
      }
          
      /**
       * Removes a InstrumentListener from the list of listeners which will
       *  receive profile events.
       *
       * @param listener InstrumentListener which will stop receiving profile
       *                 events.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.PROFILE_POINT_TYPE_VALUE.
       */
      public void removeValueInstrumentListener( ValueInstrumentListener listener )
      {
          m_instrumentProxy.removeValueInstrumentListener( listener );
      }
      
      /**
       * Returns a InstrumentSampleDescriptor based on its name.
       *
       * @param InstrumentSampleName Name of the InstrumentSample being requested.
       *
       * @return A Descriptor of the requested InstrumentSample.
       *
       * @throws NoSuchInstrumentSampleException If the specified InstrumentSample
       *                                      does not exist.
       */
      public InstrumentSampleDescriptor getInstrumentSampleDescriptor( String InstrumentSampleName )
          throws NoSuchInstrumentSampleException
      {
          InstrumentSample InstrumentSample =
              m_instrumentProxy.getInstrumentSample( InstrumentSampleName );
          if ( InstrumentSample == null )
          {
              throw new NoSuchInstrumentSampleException(
                  "No instrument sample can be found using name: " + InstrumentSampleName );
          }
          
          return InstrumentSample.getDescriptor();
      }
      
      /**
       * Returns an array of Descriptors for the InstrumentSamples configured for this
       *  Instrument.
       *
       * @return An array of Descriptors for the InstrumentSamples configured for this
       *  Instrument.
       */
      public InstrumentSampleDescriptor[] getInstrumentSampleDescriptors()
      {
          return m_instrumentProxy.getInstrumentSampleDescriptors();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/InstrumentManagerClientImpl.java
  
  Index: InstrumentManagerClientImpl.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.instrument.manager;
  
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentableDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentManagerClient;
  import org.apache.avalon.excalibur.instrument.manager.client.NoSuchInstrumentableException;
  
  import org.apache.avalon.framework.configuration.Configuration;
  
  /**
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class InstrumentManagerClientImpl
      implements InstrumentManagerClient
  {
      private DefaultInstrumentManager m_manager;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      public InstrumentManagerClientImpl( DefaultInstrumentManager manager )
      {
          m_manager = manager;
      }
      
      /*---------------------------------------------------------------
       * InstrumentManagerClient Methods
       *-------------------------------------------------------------*/
      /**
       * Returns the name used to identify this InstrumentManager.
       *
       * @return The name used to identify this InstrumentManager.
       */
      public String getName()
      {
          return m_manager.getName();
      }
      
      /**
       * Returns the description of this InstrumentManager.
       *
       * @return The description of this InstrumentManager.
       */
      public String getDescription()
      {
          return m_manager.getDescription();
      }
      
      /**
       * Returns a InstrumentableDescriptor based on its name or the name of any
       *  of its children.
       *
       * @param instrumentableName Name of the Instrumentable being requested.
       *
       * @return A Descriptor of the requested Instrumentable.
       *
       * @throws NoSuchInstrumentableException If the specified Instrumentable does
       *                                   not exist.
       */
      public InstrumentableDescriptor getInstrumentableDescriptor( String instrumentableName )
          throws NoSuchInstrumentableException
      {
          return m_manager.getInstrumentableDescriptor( instrumentableName );
      }
  
      /**
       * Returns an array of Descriptors for the Instrumentables managed by this
       *  InstrumentManager.
       *
       * @return An array of Descriptors for the Instrumentables managed by this
       *  InstrumentManager.
       */
      public InstrumentableDescriptor[] getInstrumentableDescriptors()
      {
          return m_manager.getInstrumentableDescriptors();
      }
      
      /**
       * Invokes garbage collection.
       */
      public void invokeGarbageCollection()
      {
          m_manager.invokeGarbageCollection();
      }
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/InstrumentProxy.java
  
  Index: InstrumentProxy.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.instrument.manager;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  
  import org.apache.avalon.excalibur.instrument.manager.client.CounterInstrumentListener;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentListener;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentManagerClient;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.ValueInstrumentListener;
  
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.Logger;
  
  /**
   * Instrumentables which do not implement ThreadSafe may have multiple instances
   *  created by the ComponentManager.  Each of these Instruments will share
   *  a common key and are profiled as a group.  The InstrumentProxy is used
   *  make it easy for the InstrumentManager to control groups of Instruments
   *  as one.
   * <p>
   * The type of a Instrument can not be determined at configuration time.
   *  It is resolved when the Instrumentable actually registers the Instrument.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class InstrumentProxy
      extends AbstractLogEnabled
      implements org.apache.avalon.excalibur.instrument.InstrumentProxy, Configurable
  {
      /** Configured flag. */
      private boolean m_configured;
      
      /** The name used to identify a Instrument. */
      private String m_name;
      
      /** The description of the Instrumente. */
      private String m_description;
      
      /** The Descriptor for the Instrument. */
      private InstrumentDescriptor m_descriptor;
      
      /** Type of the Instrument */
      private int m_type;
      
      /** Array of registered Counter/ValueInstrumentListeners. */
      private InstrumentListener[] m_listeners;
      
      /** Map of the maintained InstrumentSamples. */
      private HashMap m_samples = new HashMap();
      
      /** Optimized array of the InstrumentSamples. */
      private InstrumentSample[] m_sampleArray;
      
      /** Optimized array of the InstrumentSampleDescriptors. */
      private InstrumentSampleDescriptor[] m_sampleDescriptorArray;
      
      /** Child logger to use for logging of new values. */
      private Logger m_valueLogger;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new InstrumentProxy.
       *
       * @param name The name used to identify a Instrument.
       */
      InstrumentProxy( String name )
      {
          // Default description equals the name in case it is not set later.
          m_description = m_name = name;
          
          // Create the descriptor
          m_descriptor = new InstrumentDescriptorImpl( this );
      }
      
      /*---------------------------------------------------------------
       * LogEnabled Methods
       *-------------------------------------------------------------*/
      public void enableLogging( Logger logger )
      {
          super.enableLogging( logger );
          
          // Create a child logger for logging setValue and increment calls so
          //  that they can be filtered out.
          m_valueLogger = logger.getChildLogger( "values" );
      }
      
      /*---------------------------------------------------------------
       * Configurable Methods
       *-------------------------------------------------------------*/
      /**
       * Configures the Instrument.  Called from the InstrumentManager's
       *  configure method.  The class does not need to be configured to
       *  function correctly.
       *
       * @param configuration Instrument configuration element from the
       *                      InstrumentManager's configuration.
       *
       * @throws ConfigurationException If there are any configuration problems.
       */
      public void configure( Configuration configuration )
          throws ConfigurationException
      {
          synchronized(this)
          {
              // The description is optional
              m_description = configuration.getAttribute( "description", m_name );
              
              if ( getLogger().isDebugEnabled() )
              {
                  getLogger().debug( "Configuring Instrument: " + m_name + " as \"" +
                      m_description + "\"" );
              }
              
              m_configured = true;
              
              // Configure any Samples
              Configuration[] sampleConfs = configuration.getChildren( "sample" );
              for ( int i = 0; i < sampleConfs.length; i++ )
              {
                  Configuration sampleConf = sampleConfs[i];
                  
                  String sampleType = sampleConf.getAttribute( "type" );
                  long sampleInterval = sampleConf.getAttributeAsLong( "interval" );
                  int sampleSize = sampleConf.getAttributeAsInteger( "size", 1 );
                  
                  // Build the sample name from its attributes.  This makes it
                  //  possible to avoid forcing the user to maintain a name as well.
                  String sampleName = m_name + "." + sampleType + "." + 
                      sampleInterval + "." + sampleSize;
                  
                  String sampleDescription = sampleConf.getAttribute( "description", sampleName );
                  
                  if ( getLogger().isDebugEnabled() )
                  {
                      getLogger().debug( "Configuring InstrumentSample: " + sampleName + 
                          " as \"" + sampleDescription + "\"" );
                  }
                  
                  InstrumentSample InstrumentSample = InstrumentSampleFactory.getInstrumentSample(
                      sampleType, sampleName, sampleInterval, sampleSize, sampleDescription );
                  InstrumentSample.enableLogging( getLogger() );
                  
                  addInstrumentSample( InstrumentSample );
              }
          }
      }
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Returns true if the Instrument was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      boolean isConfigured()
      {
          return m_configured;
      }
      
      /**
       * Gets the name for the Instrument.  The Instrument Name is used to
       *  uniquely identify the Instrument during the configuration of the
       *  Profiler and to gain access to a InstrumentDescriptor through a
       *  InstrumentManager.
       *
       * @return The name used to identify a Instrumentable.
       */
      String getName() 
      {
          return m_name;
      }
      
      /**
       * Sets the description for the Instrument.  This description will
       *  be set during the configuration of the profiler if a configuration
       *  exists for this Instrument.
       *
       * @param description The description of the Instrument.
       */
      void setDescription( String description )
      {
          m_description = description;
      }
      
      /**
       * Gets the description of the Instrument.
       *
       * @return The description of the Instrument.
       */
      String getDescription()
      {
          return m_description;
      }
      
      /**
       * Returns a Descriptor for the Instrument.
       *
       * @return A Descriptor for the Instrument.
       */
      InstrumentDescriptor getDescriptor()
      {
          return m_descriptor;
      }
      
      /**
       * Set the type of the Instrument.  Once set, the type can not be changed.
       *
       * @param type Type of the Instrument.
       */
      void setType( int type )
      {
          synchronized(this)
          {
              if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_NONE )
              {
                  throw new IllegalStateException( "Type already set." );
              }
              switch ( type )
              {
              case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER:
              case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE:
                  m_type = type;
                  break;
              default:
                  throw new IllegalStateException( type + " is not a valid type." );
              }
          }
      }
      
      /**
       * Returns the type of the Instrument.
       *
       * @return The type of the Instrument.
       */
      int getType()
      {
          return m_type;
      }
      
      /**
       * Used by classes being profiles so that they can avoid unnecessary
       *  code when the data from a Instrument is not being used.
       *
       * @returns True if listeners are registered with the Instrument.
       */
      public boolean isActive() {
          return m_listeners != null;
      }
      
      /**
       * Adds a CounterInstrumentListener to the list of listeners which will
       *  receive updates of the value of the Instrument.
       *
       * @param listener CounterInstrumentListener which will start receiving
       *                 profile updates.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.INSTRUMENT_TYPE_COUNTER.
       */
      void addCounterInstrumentListener( CounterInstrumentListener listener )
      {
          if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER )
          {
              // Type is not correct.
              throw new IllegalStateException(
                  "The proxy is not configured to handle CounterInstruments." );
          }
          
          if ( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "A CounterInstrumentListener was added to Instrument, " +
                  m_name + " : " + listener.getClass().getName() );
          }
          
          addInstrumentListener( listener );
      }
      
      /**
       * Removes a InstrumentListener from the list of listeners which will
       *  receive profile events.
       *
       * @param listener InstrumentListener which will stop receiving profile
       *                 events.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.INSTRUMENT_TYPE_COUNTER.
       */
      void removeCounterInstrumentListener( CounterInstrumentListener listener )
      {
          if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER )
          {
              // Type is not correct.
              throw new IllegalStateException(
                  "The proxy is not configured to handle CounterInstruments." );
          }
          
          if ( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "A CounterInstrumentListener was removed from Instrument, " + 
                  m_name + " : " + listener.getClass().getName() );
          }
          
          removeInstrumentListener( listener );
      }
      
      /*
       * Increments the Instrument.  This method is optimized to be extremely
       *  light weight when there are no registered CounterInstrumentListeners.
       */
      public void increment()
      {
          if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER )
          {
              // Type is not correct.
              throw new IllegalStateException(
                  "The proxy is not configured to handle CounterInstruments." );
          }
          
          // Get a local reference to the listeners, so that synchronization can be avoided.
          InstrumentListener[] listeners = m_listeners;
          if ( listeners != null )
          {
              if ( m_valueLogger.isDebugEnabled() )
              {
                  m_valueLogger.debug( "increment() called for Instrument, " + m_name );
              }
              
              long time = System.currentTimeMillis();
              for ( int i = 0; i < listeners.length; i++ )
              {
                  CounterInstrumentListener listener =
                      (CounterInstrumentListener)listeners[i];
                  listener.increment( getName(), time );
              }
          }
      }
      
      /**
       * Adds a ValueInstrumentListener to the list of listeners which will
       *  receive updates of the value of the Instrument.
       *
       * @param listener ValueInstrumentListener which will start receiving
       *                 profile updates.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.INSTRUMENT_TYPE_VALUE.
       */
      void addValueInstrumentListener( ValueInstrumentListener listener )
      {
          if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_VALUE )
          {
              // Type is not correct.
              throw new IllegalStateException(
                  "The proxy is not configured to handle ValueInstruments." );
          }
          
          if ( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "A ValueInstrumentListener was added to Instrument, " + m_name +
                  " : " + listener.getClass().getName() );
          }
          
          addInstrumentListener( listener );
      }
      
      /**
       * Removes a InstrumentListener from the list of listeners which will
       *  receive profile events.
       *
       * @param listener InstrumentListener which will stop receiving profile
       *                 events.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.INSTRUMENT_TYPE_VALUE.
       */
      void removeValueInstrumentListener( ValueInstrumentListener listener )
      {
          if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_VALUE )
          {
              // Type is not correct.
              throw new IllegalStateException(
                  "The proxy is not configured to handle ValueInstruments." );
          }
          
          if ( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "A ValueInstrumentListener was removed from Instrument, " + m_name +
                  " : " + listener.getClass().getName() );
          }
          
          removeInstrumentListener( listener );
      }
      
      /**
       * Sets the current value of the Instrument.  This method is optimized
       *  to be extremely light weight when there are no registered
       *  ValueInstrumentListeners.
       *
       * @param value The new value for the Instrument.
       */
      public void setValue( int value )
      {
          if ( m_type != InstrumentManagerClient.INSTRUMENT_TYPE_VALUE )
          {
              // Type is not correct.
              throw new IllegalStateException(
                  "The proxy is not configured to handle ValueInstruments." );
          }
          
          // Get a local reference to the listeners, so that synchronization can be avoided.
          InstrumentListener[] listeners = m_listeners;
          if ( listeners != null )
          {
              if ( m_valueLogger.isDebugEnabled() )
              {
                  m_valueLogger.debug( "setValue( " + value + " ) called for Instrument, " + m_name );
              }
              
              long time = System.currentTimeMillis();
              for ( int i = 0; i < listeners.length; i++ )
              {
                  ValueInstrumentListener listener =
                      (ValueInstrumentListener)listeners[i];
                  listener.setValue( getName(), value, time );
              }
          }
      }
      
      /**
       * Add a InstrumentSample to the Instrument.
       *
       * @param InstrumentSample InstrumentSample to be added.
       *
       * @throws ConfigurationException If there are any configuration problems
       *                                with the InstrumentSample.
       */
      public void addInstrumentSample( InstrumentSample InstrumentSample )
          throws ConfigurationException
      {
          synchronized(this)
          {
              // If the type has not been set, set it.  If it has been set, make sure this sample has
              //  the same type.
              if ( m_type == InstrumentManagerClient.INSTRUMENT_TYPE_NONE )
              {
                  setType( InstrumentSample.getInstrumentType() );
              }
              else if ( m_type != InstrumentSample.getInstrumentType() )
              {
                  // The type is different.
                  throw new ConfigurationException( "The sample '" + InstrumentSample.getName() + 
                      "' had its type set to " + getTypeName( m_type ) + 
                      " by another sample.  This sample has a type of " + 
                      getTypeName( InstrumentSample.getInstrumentType() ) + " and is not compatible." );
              }
              
              // Make sure that a sample with the same name has not already been set.
              String sampleName = InstrumentSample.getName();
              if ( m_samples.get( sampleName ) != null )
              {
                  throw new ConfigurationException( "More than one sample with the same name, '" +
                      sampleName + "', can not be configured." );
              }
          
              // Sample is safe to add.
              m_samples.put( sampleName, InstrumentSample );
              
              // Clear the optimized arrays
              m_sampleArray = null;
              m_sampleDescriptorArray = null;
              
              // Add the sample as a listener for this Instrument.
              switch ( m_type )
              {
              case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER:
                  addCounterInstrumentListener( (CounterInstrumentSample)InstrumentSample );
                  break;
                  
              case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE:
                  addValueInstrumentListener( (AbstractValueInstrumentSample)InstrumentSample );
                  break;
                  
              default:
                  throw new IllegalStateException(
                      "Don't know how to deal with the type: " + m_type );
              }
          }
      }
      
      /**
       * Returns a InstrumentSample based on its name.
       *
       * @param InstrumentSampleName Name of the InstrumentSample being requested.
       *
       * @return The requested InstrumentSample or null if does not exist.
       */
      InstrumentSample getInstrumentSample( String InstrumentSampleName )
      {
          synchronized(this)
          {
              return (InstrumentSample)m_samples.get( InstrumentSampleName );
          }
      }
      
      /**
       * Returns an array of the InstrumentSamples in the Instrument.
       *
       * @return An array of the InstrumentSamples in the Instrument.
       */
      InstrumentSample[] getInstrumentSamples()
      {
          InstrumentSample[] samples = m_sampleArray;
          if ( samples == null )
          {
              samples = updateInstrumentSampleArray();
          }
          return samples;
      }
      
      /**
       * Returns an array of Descriptors for the InstrumentSamples in the
       *  Instrument.
       *
       * @return An array of Descriptors for the InstrumentSamples in the
       *         Instrument.
       */
      InstrumentSampleDescriptor[] getInstrumentSampleDescriptors()
      {
          InstrumentSampleDescriptor[] descriptors = m_sampleDescriptorArray;
          if ( descriptors == null )
          {
              descriptors = updateInstrumentSampleDescriptorArray();
          }
          return descriptors;
      }
      
      /**
       * Common code to add a listener to the list of listeners which will
       *  receive updates of the value of the Instrument.
       *
       * @param listener InstrumentListener which will start receiving
       *                 profile updates.
       */
      private void addInstrumentListener( InstrumentListener listener )
      {
          synchronized(this)
          {
              // Store the listeners in an array.  This makes it possible to
              //  avoid synchronization while propagating events.  Never change
              //  the contents of the listener array once it has been set to the
              //  m_listeners field.
              InstrumentListener[] oldListeners = m_listeners;
              InstrumentListener[] newListeners;
              if ( oldListeners == null )
              {
                  newListeners = new InstrumentListener[] { listener };
              }
              else
              {
                  newListeners = new InstrumentListener[ oldListeners.length + 1 ];
                  System.arraycopy( oldListeners, 0, newListeners, 0, oldListeners.length );
                  newListeners[ oldListeners.length ] = listener;
              }
              
              // Update the m_listeners field.
              m_listeners = newListeners;
          }
      }
      
      /**
       * Common code to remove a listener from the list of listeners which will
       *  receive updates of the value of the Instrument.
       *
       * @param listener InstrumentListener which will stop receiving
       *                 profile updates.
       */
      private void removeInstrumentListener( InstrumentListener listener )
      {
          synchronized(this)
          {
              // Store the listeners in an array.  This makes it possible to
              //  avoid synchronization while propagating events.  Never change
              //  the contents of the listener array once it has been set to the
              //  m_listeners field.
              InstrumentListener[] oldListeners = m_listeners;
              InstrumentListener[] newListeners;
              if ( oldListeners == null )
              {
                  // Means that this method should not have been called, but
                  //  don't throw an error.
                  newListeners = null;
              }
              else if ( oldListeners.length == 1 )
              {
                  if ( oldListeners[0] == listener )
                  {
                      newListeners = null;
                  }
                  else
                  {
                      // The listener was not in the list.
                      newListeners = oldListeners;
                  }
              }
              else
              {
                  // Look for the listener in the array.
                  int pos = -1;
                  for ( int i = 0; i < oldListeners.length; i++ )
                  {
                      if ( oldListeners[i] == listener )
                      {
                          pos = i;
                          break;
                      }
                  }
                  
                  if ( pos < 0 )
                  {
                      // The listener was not in the list.
                      newListeners = oldListeners;
                  }
                  else
                  {
                      newListeners = new InstrumentListener[ oldListeners.length - 1 ];
                      if ( pos > 0 )
                      {
                          // Copy the head of the array
                          System.arraycopy( oldListeners, 0, newListeners, 0, pos );
                      }
                      if ( pos < oldListeners.length - 1 )
                      {
                          // Copy the tail of the array
                          System.arraycopy( oldListeners, pos + 1, 
                              newListeners, pos, oldListeners.length - 1 - pos );
                      }
                  }
              }
              
              // Update the m_listeners field.
              m_listeners = newListeners;
          }
      }
      
      /**
       * Updates the cached array of InstrumentSamples taking synchronization into
       *  account.
       *
       * @return An array of the InstrumentSamples.
       */
      private InstrumentSample[] updateInstrumentSampleArray()
      {
          synchronized(this)
          {
              m_sampleArray = new InstrumentSample[ m_samples.size() ];
              m_samples.values().toArray( m_sampleArray );
              
              return m_sampleArray;
          }
      }
      
      /**
       * Updates the cached array of InstrumentSampleDescriptors taking
       *  synchronization into account.
       *
       * @return An array of the InstrumentSampleDescriptors.
       */
      private InstrumentSampleDescriptor[] updateInstrumentSampleDescriptorArray()
      {
          synchronized(this)
          {
              if ( m_sampleArray == null )
              {
                  updateInstrumentSampleArray();
              }
              
              m_sampleDescriptorArray =
                  new InstrumentSampleDescriptor[ m_sampleArray.length ];
              for ( int i = 0; i < m_sampleArray.length; i++ )
              {
                  m_sampleDescriptorArray[i] = m_sampleArray[i].getDescriptor();
              }
              
              return m_sampleDescriptorArray;
          }
      }
      
      /**
       * Saves the current state into a Configuration.
       *
       * @param useCompactSamples Flag for whether or not InstrumentSample data
       *                          should be saved in compact format or not.
       *
       * @return The state as a Configuration.
       */
      Configuration saveState( boolean useCompactSamples )
      {
          DefaultConfiguration state = new DefaultConfiguration( "instrument", "-" );
          state.addAttribute( "name", m_name );
          
          InstrumentSample[] samples = getInstrumentSamples();
          for ( int i = 0; i < samples.length; i++ )
          {
              state.addChild( samples[i].saveState( useCompactSamples ) );
          }
          
          return state;
      }
      
      /**
       * Loads the state into the Instrument.
       *
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      void loadState( Configuration state ) throws ConfigurationException
      {
          synchronized( this )
          {
              Configuration[] InstrumentSampleConfs = state.getChildren( "sample" );
              for ( int i = 0; i < InstrumentSampleConfs.length; i++ )
              {
                  Configuration InstrumentSampleConf = InstrumentSampleConfs[i];
                  String name = InstrumentSampleConf.getAttribute( "name" );
                  InstrumentSample sample = getInstrumentSample( name );
                  if ( sample == null )
                  {
                      getLogger().warn( "InstrumentSample entry ignored while loading state because the " +
                          "sample does not exist: " + name );
                  }
                  else
                  {
                      sample.loadState( InstrumentSampleConf );
                  }
              }
          }
      }
      
      /**
       * Returns the name of a Instrument type.
       *
       * @param type Type whose name is wanted.
       *
       * @return The name of a Instrument type.
       */
      public static String getTypeName( int type )
      {
          switch ( type )
          {
          case InstrumentManagerClient.INSTRUMENT_TYPE_NONE:
              return "none";
          case InstrumentManagerClient.INSTRUMENT_TYPE_COUNTER:
              return "counter";
          case InstrumentManagerClient.INSTRUMENT_TYPE_VALUE:
              return "value";
          default:
              throw new IllegalArgumentException( type + " is not a known Instrument type." );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/InstrumentSample.java
  
  Index: InstrumentSample.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.instrument.manager;
  
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleListener;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleSnapshot;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.logger.LogEnabled;
  
  /**
   * InstrumentSamples are used to provide an Instrument with state.  Samples
   *  have a sample interval, which is the period over which data is grouped.
   * <p>
   * InstrmentSamples can be created when the InstrumentManager is created as
   *  part of the configuration process, or as a result of a request from an
   *  InstrumentClient.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public interface InstrumentSample
      extends LogEnabled
  {
      /**
       * Returns true if the InstrumentSample was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      boolean isConfigured();
      
      /**
       * Returns the name of the sample.
       *
       * @return The name of the sample.
       */
      String getName();
      
      /**
       * Returns the sample interval.  The period of each sample in millisends.
       *
       * @return The sample interval.
       */
      long getInterval();
      
      /**
       * Returns the number of samples in the sample history.
       *
       * @return The size of the sample history.
       */
      int getSize();
      
      /**
       * Returns the description of the sample.
       *
       * @return The description of the sample.
       */
      String getDescription();
      
      /**
       * Returns a Descriptor for the InstrumentSample.
       *
       * @return A Descriptor for the InstrumentSample.
       */
      InstrumentSampleDescriptor getDescriptor();
      
      /**
       * Obtain the value of the sample.  All samples are integers, so the profiled
       * objects must measure quantity (numbers of items), rate (items/period), time in
       * milliseconds, etc.
       *
       * @return The sample value.
       */
      int getValue();
      
      /**
       * Obtain the UNIX time of the beginning of the sample.
       *
       * @return The UNIX time of the beginning of the sample.
       */
      long getTime();
      
      /**
       * Returns the Type of the Instrument which can use the sample.  This
       *  should be the same for all instances of a class.
       * <p>
       * Should be one of the following: InstrumentManager.PROFILE_POINT_TYPE_COUNTER
       *  or InstrumentManager.PROFILE_POINT_TYPE_VALUE
       *
       * @return The Type of the Instrument which can use the sample.
       */
      int getInstrumentType();
      
      /**
       * Obtains a static snapshot of the InstrumentSample.
       *
       * @return A static snapshot of the InstrumentSample.
       */
      InstrumentSampleSnapshot getSnapshot();
      
      /**
       * Registers a InstrumentSampleListener with a InstrumentSample given a name.
       *
       * @param listener The listener which should start receiving updates from the
       *                 InstrumentSample.
       */
      void addInstrumentSampleListener( InstrumentSampleListener listener );
      
      /**
       * Unregisters a InstrumentSampleListener from a InstrumentSample given a name.
       *
       * @param listener The listener which should stop receiving updates from the
       *                 InstrumentSample.
       */
      void removeInstrumentSampleListener( InstrumentSampleListener listener );
      
      /**
       * Saves the current state into a Configuration.
       *
       * @param useCompactSamples Flag for whether or not InstrumentSample data
       *                          should be saved in compact format or not.
       *
       * @return The state as a Configuration.
       */
      Configuration saveState( boolean useCompactSamples );
      
      /**
       * Loads the state into the InstrumentSample.
       *
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      void loadState( Configuration state ) throws ConfigurationException;
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/InstrumentSampleDescriptorImpl.java
  
  Index: InstrumentSampleDescriptorImpl.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.instrument.manager;
  
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleListener;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleSnapshot;
  
  /**
   * Describes an InstrumentSample and acts as a Proxy to protect the original
   *  InstrumentSample object.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class InstrumentSampleDescriptorImpl
      implements InstrumentSampleDescriptor
  {
      /** The InstrumentSample. */
      private InstrumentSample m_instrumentSample;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new InstrumentSampleDescriptor.
       *
       * @param InstrumentSample InstrumentSample being described.
       */
      InstrumentSampleDescriptorImpl( InstrumentSample InstrumentSample )
      {
          m_instrumentSample = InstrumentSample;
      }
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Returns true if the InstrumentSample was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      public boolean isConfigured()
      {
          return m_instrumentSample.isConfigured();
      }
      
      /**
       * Returns the name of the sample.
       *
       * @return The name of the sample.
       */
      public String getName()
      {
          return m_instrumentSample.getName();
      }
      
      /**
       * Returns the sample interval.  The period of each sample in millisends.
       *
       * @return The sample interval.
       */
      public long getInterval()
      {
          return m_instrumentSample.getInterval();
      }
      
      /**
       * Returns the number of samples in the sample history.
       *
       * @return The size of the sample history.
       */
      public int getSize()
      {
          return m_instrumentSample.getSize();
      }
      
      /**
       * Returns the description of the sample.
       *
       * @return The description of the sample.
       */
      public String getDescription()
      {
          return m_instrumentSample.getDescription();
      }
      
      /**
       * Obtain the value of the sample.  All samples are integers, so the profiled
       * objects must measure quantity (numbers of items), rate (items/period), time in
       * milliseconds, etc.
       *
       * @return The sample value.
       */
      public int getValue()
      {
          return m_instrumentSample.getValue();
      }
      
      /**
       * Obtain the UNIX time of the beginning of the sample.
       *
       * @return The UNIX time of the beginning of the sample.
       */
      public long getTime()
      {
          return m_instrumentSample.getTime();
      }
      
      /**
       * Returns the Type of the Instrument which can use the sample.  This
       *  should be the same for all instances of a class.
       * <p>
       * Should be one of the following: InstrumentManager.PROFILE_POINT_TYPE_COUNTER
       *  or InstrumentManager.PROFILE_POINT_TYPE_VALUE
       *
       * @return The Type of the Instrument which can use the sample.
       */
      public int getInstrumentType()
      {
          return m_instrumentSample.getInstrumentType();
      }
      
      /**
       * Obtains a static snapshot of the InstrumentSample.
       *
       * @return A static snapshot of the InstrumentSample.
       */
      public InstrumentSampleSnapshot getSnapshot()
      {
          return m_instrumentSample.getSnapshot();
      }
      
      /**
       * Registers a InstrumentSampleListener with a InstrumentSample given a name.
       *
       * @param listener The listener which should start receiving updates from the
       *                 InstrumentSample.
       */
      public void addInstrumentSampleListener( InstrumentSampleListener listener )
      {
          m_instrumentSample.addInstrumentSampleListener( listener );
      }
      
      /**
       * Unregisters a InstrumentSampleListener from a InstrumentSample given a name.
       *
       * @param listener The listener which should stop receiving updates from the
       *                 InstrumentSample.
       */
      public void removeInstrumentSampleListener( InstrumentSampleListener listener )
      {
          m_instrumentSample.removeInstrumentSampleListener( listener );
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/InstrumentSampleFactory.java
  
  Index: InstrumentSampleFactory.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.instrument.manager;
  
  import org.apache.avalon.framework.configuration.ConfigurationException;
  
  /**
   * The InstrumentSample represents a single data sample in a ProfileDataSet.
   * Access to InstrumentSamples are synchronized through the ProfileDataSet.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  class InstrumentSampleFactory
  {
      /**
       * A Profile Sample Type loaded in from a Configuration.
       *
       * @param type Type of the InstrumentSample to create.  Accepted values are:
       *              "max", "maximum", "min", "minimum", "avg", "average", 
       *              "ctr", and "counter".
       * @param name The name of the new InstrumentSample.
       * @param interval The sample interval of the new InstrumentSample.
       * @param size The number of samples to store as history.
       * @param description The description of the new InstrumentSample.
       */
      static InstrumentSample getInstrumentSample( String type,
                                             String name,
                                             long interval,
                                             int size,
                                             String description )
          throws ConfigurationException
      {
          if ( type.equalsIgnoreCase( "max" ) || type.equalsIgnoreCase( "maximum" ) )
          {
              return new MaximumValueInstrumentSample( name, interval, size, description );
          }
          else if ( type.equalsIgnoreCase( "min" ) || type.equalsIgnoreCase( "minimum" ) )
          {
              return new MinimumValueInstrumentSample( name, interval, size, description );
          }
          else if ( type.equalsIgnoreCase( "avg" ) || type.equalsIgnoreCase( "average" ) )
          {
              return new AverageValueInstrumentSample( name, interval, size, description );
          }
          else if ( type.equalsIgnoreCase( "ctr" ) || type.equalsIgnoreCase( "counter" ) )
          {
              return new CounterInstrumentSample( name, interval, size, description );
          }
          else
          {
              throw new ConfigurationException( "'" + type + "' is not a valid sample type." );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/InstrumentableDescriptorImpl.java
  
  Index: InstrumentableDescriptorImpl.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.instrument.manager;
  
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentableDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.NoSuchInstrumentException;
  
  /**
   * Describes a Instrumentable and acts as a Proxy to protect the original
   *  Instrumentable.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  public class InstrumentableDescriptorImpl
      implements InstrumentableDescriptor
  {
      /** InstrumentableProxy being described. */
      private InstrumentableProxy m_instrumentableProxy;
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new InstrumentableDescriptorImpl.
       *
       * @param instrumentableProxy InstrumentableProxy being described.
       */
      InstrumentableDescriptorImpl( InstrumentableProxy instrumentableProxy )
      {
          m_instrumentableProxy = instrumentableProxy;
      }
  
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Returns true if the Instrumentable was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      public boolean isConfigured()
      {
          return m_instrumentableProxy.isConfigured();
      }
  
      /**
       * Gets the name for the Instrumentable.  The Instrumentable Name is used to
       *  uniquely identify the Instrumentable during the configuration of the
       *  Profiler and to gain access to a InstrumentableDescriptor through a
       *  ProfilerManager.
       *
       * @return The name used to identify a Instrumentable.
       */
      public String getName()
      {
          return m_instrumentableProxy.getName();
      }
  
      /**
       * Gets the description of the Instrumentable.
       *
       * @return The description of the Instrumentable.
       */
      public String getDescription()
      {
          return m_instrumentableProxy.getDescription();
      }
  
      /**
       * Returns a InstrumentDescriptor based on its name.
       *
       * @param instrumentName Name of the Instrument being requested.
       *
       * @return A Descriptor of the requested Instrument.
       *
       * @throws NoSuchInstrumentException If the specified Instrument does
       *                                     not exist.
       */
      public InstrumentDescriptor getInstrumentDescriptor( String instrumentName )
          throws NoSuchInstrumentException
      {
          InstrumentProxy instrumentProxy =
              m_instrumentableProxy.getInstrumentProxy( instrumentName );
          if( instrumentProxy == null )
          {
              throw new NoSuchInstrumentException(
                  "No instrument can be found using name: " + instrumentName );
          }
  
          return instrumentProxy.getDescriptor();
      }
  
      /**
       * Returns an array of Descriptors for the Instruments registered by this
       *  Instrumentable.
       *
       * @return An array of Descriptors for the Instruments registered by this
       *  Instrumentable.
       */
      public InstrumentDescriptor[] getInstrumentDescriptors()
      {
          return m_instrumentableProxy.getInstrumentDescriptors();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/InstrumentableProxy.java
  
  Index: InstrumentableProxy.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.instrument.manager;
  
  import java.util.HashMap;
  
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentableDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.NoSuchInstrumentException;
  
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  /**
   * A InstrumentableProxy makes it easy for the InstrumentManager to manage
   *  Instrumentables and their Instruments.
   * <p>
   * Not Synchronized.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  class InstrumentableProxy
      extends AbstractLogEnabled
      implements Configurable
  {
      /** Configured flag. */
      private boolean m_configured;
  
      /** The name used to identify a Instrumentable. */
      private String m_name;
  
      /** The description of the Instrumentable. */
      private String m_description;
  
      /** The Descriptor for the Instrumentable. */
      private InstrumentableDescriptorImpl m_descriptor;
  
      /** Map of the InstrumentProxies owned by this InstrumentableProxy. */
      private HashMap m_instrumentProxies = new HashMap();
  
      /** Optimized array of the InstrumentProxies. */
      private InstrumentProxy[] m_instrumentProxyArray;
  
      /** Optimized array of the InstrumentDescriptors. */
      private InstrumentDescriptor[] m_instrumentDescriptorArray;
  
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new InstrumentableProxy.
       *
       * @param name The name used to identify a Instrumentable.
       */
      InstrumentableProxy( String name )
      {
          // Default description equals the name in case it is not set later.
          m_description = m_name = name;
  
          // Create the descriptor
          m_descriptor = new InstrumentableDescriptorImpl( this );
      }
  
      /*---------------------------------------------------------------
       * Configurable Methods
       *-------------------------------------------------------------*/
      /**
       * Configures the Instrumentable.  Called from the ProfilerManager's
       *  configure method.  The class does not need to be configured to
       *  function correctly.
       *
       * @param configuration Instrumentable configuration element from the
       *                      ProfilerManager's configuration.
       *
       * @throws ConfigurationException If there are any configuration problems.
       */
      public void configure( Configuration configuration )
          throws ConfigurationException
      {
          synchronized( this )
          {
              // The description is optional
              m_description = configuration.getAttribute( "description", m_name );
  
              if( getLogger().isDebugEnabled() )
              {
                  getLogger().debug( "Configuring Instrumentable: " + m_name + " as \"" +
                                     m_description + "\"" );
              }
  
              m_configured = true;
              
              // Configure any Instruments
              Configuration[] instrumentConfs = configuration.getChildren( "instrument" );
              for( int i = 0; i < instrumentConfs.length; i++ )
              {
                  Configuration instrumentConf = instrumentConfs[ i ];
                  String instrumentName = m_name + "." + instrumentConf.getAttribute( "name" );
  
                  InstrumentProxy instrumentProxy = new InstrumentProxy( instrumentName );
                  instrumentProxy.enableLogging( getLogger() );
                  instrumentProxy.configure( instrumentConf );
                  m_instrumentProxies.put( instrumentName, instrumentProxy );
  
                  // Clear the optimized arrays
                  m_instrumentProxyArray = null;
                  m_instrumentDescriptorArray = null;
              }
          }
      }
  
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Returns true if the instrumentable was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      boolean isConfigured()
      {
          return m_configured;
      }
  
      /**
       * Gets the name for the Instrumentable.  The Instrumentable Name is used to
       *  uniquely identify the Instrumentable during the configuration of the
       *  Profiler and to gain access to a InstrumentableDescriptor through a
       *  ProfilerManager.
       *
       * @return The name used to identify a Instrumentable.
       */
      String getName()
      {
          return m_name;
      }
  
      /**
       * Sets the description for the instrumentable object.  This description will
       *  be set during the configuration of the profiler if a configuration
       *  exists for this Instrumentable.
       *
       * @param description The description of the Instrumentable.
       */
      void setDescription( String description )
      {
          m_description = description;
      }
  
      /**
       * Gets the description of the Instrumentable.
       *
       * @return The description of the Instrumentable.
       */
      String getDescription()
      {
          return m_description;
      }
  
      /**
       * Returns a Descriptor for the Instrumentable.
       *
       * @return A Descriptor for the Instrumentable.
       */
      InstrumentableDescriptor getDescriptor()
      {
          return m_descriptor;
      }
  
      /**
       * Adds a InstrumentProxy to the Instrumentable.  This method will be
       *  called during the configuration phase of the Profiler if an element
       *  defining the Instrument exists, or if the Instrument registers
       *  itself with the ProfilerManager as it is running.
       * <p>
       * This method should never be called for Instruments which have already
       *  been added.
       *
       * @param instrumentProxy InstrumentProxy to be added.
       */
      void addInstrumentProxy( InstrumentProxy instrumentProxy )
      {
          synchronized( this )
          {
              m_instrumentProxies.put( instrumentProxy.getName(), instrumentProxy );
  
              // Clear the optimized arrays
              m_instrumentProxyArray = null;
              m_instrumentDescriptorArray = null;
          }
      }
  
      /**
       * Returns a InstrumentProxy based on its name or the name of any
       *  of its children.
       *
       * @param instrumentName Name of the Instrument being requested.
       *
       * @return The requested InstrumentProxy or null if does not exist.
       */
      InstrumentProxy getInstrumentProxy( String instrumentName )
      {
          synchronized( this )
          {
              String name = instrumentName;
              while( true )
              {
                  InstrumentProxy proxy = (InstrumentProxy)m_instrumentProxies.get( name );
                  if( proxy != null )
                  {
                      return proxy;
                  }
  
                  // Assume this is a child name and try looking with the parent name.
                  int pos = name.lastIndexOf( '.' );
                  if( pos > 0 )
                  {
                      name = name.substring( 0, pos );
                  }
                  else
                  {
                      return null;
                  }
              }
          }
      }
  
      /**
       * Returns an array of Proxies to the Instruments in the Instrumentable.
       *
       * @return An array of Proxies to the Instruments in the Instrumentable.
       */
      InstrumentProxy[] getInstrumentProxies()
      {
          InstrumentProxy[] proxies = m_instrumentProxyArray;
          if( proxies == null )
          {
              proxies = updateInstrumentProxyArray();
          }
          return proxies;
      }
  
      /**
       * Returns an array of Descriptors for the Instruments in the Instrumentable.
       *
       * @return An array of Descriptors for the Instruments in the Instrumentable.
       */
      InstrumentDescriptor[] getInstrumentDescriptors()
      {
          InstrumentDescriptor[] descriptors = m_instrumentDescriptorArray;
          if( descriptors == null )
          {
              descriptors = updateInstrumentDescriptorArray();
          }
          return descriptors;
      }
  
      /**
       * Updates the cached array of InstrumentProxies taking
       *  synchronization into account.
       *
       * @return An array of the InstrumentProxies.
       */
      private InstrumentProxy[] updateInstrumentProxyArray()
      {
          synchronized( this )
          {
              m_instrumentProxyArray = new InstrumentProxy[ m_instrumentProxies.size() ];
              m_instrumentProxies.values().toArray( m_instrumentProxyArray );
  
              return m_instrumentProxyArray;
          }
      }
  
      /**
       * Updates the cached array of InstrumentDescriptors taking
       *  synchronization into account.
       *
       * @return An array of the InstrumentDescriptors.
       */
      private InstrumentDescriptor[] updateInstrumentDescriptorArray()
      {
          synchronized( this )
          {
              if( m_instrumentProxyArray == null )
              {
                  updateInstrumentProxyArray();
              }
  
              m_instrumentDescriptorArray =
                  new InstrumentDescriptor[ m_instrumentProxyArray.length ];
              for( int i = 0; i < m_instrumentProxyArray.length; i++ )
              {
                  m_instrumentDescriptorArray[ i ] = m_instrumentProxyArray[ i ].getDescriptor();
              }
  
              return m_instrumentDescriptorArray;
          }
      }
  
      /**
       * Saves the current state into a Configuration.
       *
       * @param useCompactSamples Flag for whether or not ProfileSample data
       *                          should be saved in compact format or not.
       *
       * @return The state as a Configuration.
       */
      /*
      Configuration saveState( boolean useCompactSamples )
      {
          DefaultConfiguration state = new DefaultConfiguration( "instrumentable", "-" );
          state.addAttribute( "name", m_name );
  
          InstrumentProxy[] proxies = getInstrumentProxies();
          for( int i = 0; i < proxies.length; i++ )
          {
              // Only save configured instrumentables as they are the only ones
              //  that will contain profile samples.
              if( proxies[ i ].isConfigured() )
              {
                  state.addChild( proxies[ i ].saveState( useCompactSamples ) );
              }
          }
  
          return state;
      }
      */
  
      /**
       * Loads the state into the Instrumentable.
       *
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      /*
      void loadState( Configuration state ) throws ConfigurationException
      {
          synchronized( this )
          {
              Configuration[] instrumentConfs = state.getChildren( "profile-point" );
              for( int i = 0; i < instrumentConfs.length; i++ )
              {
                  Configuration instrumentConf = instrumentConfs[ i ];
                  String name = instrumentConf.getAttribute( "name" );
                  InstrumentProxy proxy = getInstrumentProxy( name );
                  if( proxy == null )
                  {
                      getLogger().warn( "Instrument entry ignored while loading state because the " +
                                        "profile point does not exist: " + name );
                  }
                  else
                  {
                      proxy.loadState( instrumentConf );
                  }
              }
          }
      }
      */
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/MaximumValueInstrumentSample.java
  
  Index: MaximumValueInstrumentSample.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.instrument.manager;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  
  /**
   * A InstrumentSample which stores the maximum value set during the sample
   *  period.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  class MaximumValueInstrumentSample
      extends AbstractValueInstrumentSample
  {
      /** Last value set to the sample for use for sample periods where no value is set. */
      private int m_lastValue;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new MaximumValueInstrumentSample
       *
       * @param name The name of the new InstrumentSample.
       * @param interval The sample interval of the new InstrumentSample.
       * @param size The number of samples to store as history.  Assumes that size is at least 1.
       * @param description The description of the new InstrumentSample.
       */
      MaximumValueInstrumentSample( String name, long interval, int size, String description )
      {
          super( name, interval, size, description );
      }
      
      /*---------------------------------------------------------------
       * AbstractInstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * The current sample has already been stored.  Reset the current sample
       *  and move on to the next.
       * <p>
       * Should only be called when synchronized.
       */
      protected void advanceToNextSample()
      {
          // Reset the value count and set the value to the last known value.
          m_value = m_lastValue;
          m_valueCount = 0;
      }
      
      /**
       * Allow subclasses to add information into the saved state.
       *
       * @param state State configuration.
       */
      protected void saveState( DefaultConfiguration state )
      {
          super.saveState( state );
          
          state.setAttribute( "last-value", Integer.toString( m_lastValue ) );
      }
      
      /**
       * Used to load the state, called from AbstractInstrumentSample.loadState();
       * <p>
       * Should only be called when synchronized.
       *
       * @param value Current value loaded from the state.
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      protected void loadState( int value, Configuration state )
          throws ConfigurationException
      {
          super.loadState( value, state );
          
          m_lastValue = state.getAttributeAsInteger( "last-value" );
      }
      
      /**
       * Called after a state is loaded if the sample period is not the same
       *  as the last period saved.
       */
      protected void postSaveNeedsReset()
      {
          super.postSaveNeedsReset();
          
          m_lastValue = 0;
      }
      
      /*---------------------------------------------------------------
       * AbstractValueInstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * Sets the current value of the sample.  The value will be set as the
       *  sample value if it is the largest value seen during the sample period.
       *
       * @param value New sample value.
       * @param time Time that the new sample arrives.
       */
      protected void setValueInner( int value, long time )
      {
          boolean update;
          int sampleValue;
          long sampleTime;
          
          synchronized(this)
          {
              update = update( time );
              
              // Always store the last value to use for samples where a value is not set.
              m_lastValue = value;
              
              if ( m_valueCount > 0 )
              {
                  // Additional sample
                  m_valueCount++;
                  if ( value > m_value )
                  {
                      m_value = value;
                      update = true;
                  }
              }
              else
              {
                  // First value of this sample.
                  m_valueCount = 1;
                  m_value = value;
                  update = true;
              }
              
              sampleValue = m_value;
              sampleTime = m_time;
          }
          
          if ( update )
          {
              updateListeners( sampleValue, sampleTime );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/MinimumValueInstrumentSample.java
  
  Index: MinimumValueInstrumentSample.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.instrument.manager;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  
  /**
   * A InstrumentSample which stores the minimum value set during the sample
   *  period.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:16 $
   * @since 4.1
   */
  class MinimumValueInstrumentSample
      extends AbstractValueInstrumentSample
  {
      /** Last value set to the sample for use for sample periods where no value is set. */
      private int m_lastValue;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Creates a new MinimumValueInstrumentSample
       *
       * @param name The name of the new InstrumentSample.
       * @param interval The sample interval of the new InstrumentSample.
       * @param size The number of samples to store as history.  Assumes that size is at least 1.
       * @param description The description of the new InstrumentSample.
       */
      MinimumValueInstrumentSample( String name, long interval, int size, String description )
      {
          super( name, interval, size, description );
      }
      
      /*---------------------------------------------------------------
       * AbstractInstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * The current sample has already been stored.  Reset the current sample
       *  and move on to the next.
       * <p>
       * Should only be called when synchronized.
       */
      protected void advanceToNextSample()
      {
          // Reset the value count and set the value to the last known value.
          m_value = m_lastValue;
          m_valueCount = 0;
      }
      
      /**
       * Allow subclasses to add information into the saved state.
       *
       * @param state State configuration.
       */
      protected void saveState( DefaultConfiguration state )
      {
          super.saveState( state );
          
          state.setAttribute( "last-value", Integer.toString( m_lastValue ) );
      }
      
      /**
       * Used to load the state, called from AbstractInstrumentSample.loadState();
       * <p>
       * Should only be called when synchronized.
       *
       * @param value Current value loaded from the state.
       * @param state Configuration object to load state from.
       *
       * @throws ConfigurationException If there were any problems loading the
       *                                state.
       */
      protected void loadState( int value, Configuration state )
          throws ConfigurationException
      {
          super.loadState( value, state );
          
          m_lastValue = state.getAttributeAsInteger( "last-value" );
      }
      
      /**
       * Called after a state is loaded if the sample period is not the same
       *  as the last period saved.
       */
      protected void postSaveNeedsReset()
      {
          super.postSaveNeedsReset();
          
          m_lastValue = 0;
      }
      
      /*---------------------------------------------------------------
       * AbstractValueInstrumentSample Methods
       *-------------------------------------------------------------*/
      /**
       * Sets the current value of the sample.  The value will be set as the
       *  sample value if it is the smallest value seen during the sample period.
       *
       * @param value New sample value.
       * @param time Time that the new sample arrives.
       */
      protected void setValueInner( int value, long time )
      {
          boolean update;
          int sampleValue;
          long sampleTime;
          
          synchronized(this)
          {
              update( time );
              
              // Always store the last value to use for samples where a value is not set.
              m_lastValue = value;
              
              if ( m_valueCount > 0 )
              {
                  // Additional sample
                  m_valueCount++;
                  if ( value < m_value )
                  {
                      m_value = value;
                      update = true;
                  }
              }
              else
              {
                  // First value of this sample.
                  m_valueCount = 1;
                  m_value = value;
              }
              
              sampleValue = m_value;
              sampleTime = m_time;
                  update = true;
          }
          
          if ( update )
          {
              updateListeners( sampleValue, sampleTime );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/altrmi/InstrumentManagerAltrmiServer.java
  
  Index: InstrumentManagerAltrmiServer.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.instrument.manager.altrmi;
  
  import org.apache.avalon.excalibur.instrument.manager.DefaultInstrumentManager;
  import org.apache.avalon.excalibur.instrument.manager.InstrumentManagerClientImpl;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentableDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentDescriptor;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentManagerClient;
  import org.apache.avalon.excalibur.instrument.manager.client.InstrumentSampleDescriptor;
  
  import org.apache.avalon.framework.activity.Disposable;
  
  import org.apache.commons.altrmi.server.AltrmiServerException;
  import org.apache.commons.altrmi.server.PublicationDescription;
  import org.apache.commons.altrmi.server.PublicationException;
  import org.apache.commons.altrmi.server.impl.AbstractServer;
  import org.apache.commons.altrmi.server.impl.socket.CompleteSocketObjectStreamServer;
  
  /**
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public class InstrumentManagerAltrmiServer
      implements Disposable
  {
      /** The default port. */
      public static final int DEFAULT_PORT = 15555;
      
      private int m_port;
      private AbstractServer m_server;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      public InstrumentManagerAltrmiServer( DefaultInstrumentManager manager )
          throws AltrmiServerException, PublicationException
      {
          this( manager, DEFAULT_PORT );
      }
      
      public InstrumentManagerAltrmiServer( DefaultInstrumentManager manager, int port )
          throws AltrmiServerException, PublicationException
      {
          m_port = port;
          
          InstrumentManagerClientImpl client = new InstrumentManagerClientImpl( manager );
          
          System.out.println( "Creating CompleteSocketObjectStreamServer..." );
          m_server = new CompleteSocketObjectStreamServer( port );
          
          System.out.println( "Publishing InstrumentManagerClient..." );
          
          Class[] additionalFacadeClasses = new Class[]
          {
              InstrumentableDescriptor.class,
              InstrumentDescriptor.class,
              InstrumentSampleDescriptor.class
          };
          
          m_server.publish( client, "InstrumentManagerClient", 
              new PublicationDescription( InstrumentManagerClient.class, additionalFacadeClasses ) );
          
          System.out.println( "Starting CompleteSocketObjectStreamServer..." );
          m_server.start();
          System.out.println( "Started on port: " + port );
      }
      
      /*---------------------------------------------------------------
       * Disposable Methods
       *-------------------------------------------------------------*/
      public void dispose()
      {
          m_server.stop();
          m_server = null;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/CounterInstrumentListener.java
  
  Index: CounterInstrumentListener.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.instrument.manager.client;
  
  /**
   * Objects which implement the CounterInstrumentListener interface can
   *  register themselves with Instrument instances to receive updates when
   *  it is incremented.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public interface CounterInstrumentListener
      extends InstrumentListener
  {
      /**
       * Called by a CounterInstrument whenever its value is incremented.
       *
       * @param instrumentName The name of Instrument which was incremented.
       * @param time The time that the Instrument was incremented.
       */
      void increment( String instrumentName, long time );
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/InstrumentDescriptor.java
  
  Index: InstrumentDescriptor.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.instrument.manager.client;
  
  /**
   * Describes a Instrument and acts as a Proxy to protect the original
   *  Instrument.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public interface InstrumentDescriptor
  {
      /**
       * Returns true if the Instrument was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      boolean isConfigured();
      
      /**
       * Gets the name for the Instrument.  The Instrument Name is used to
       *  uniquely identify the Instrument during the configuration of the
       *  Profiler.  The value should be a string which does not contain spaces
       *  or periods.
       *
       * @return The name used to identify a Instrument.
       */
      String getName();
      
      /**
       * Gets the description of the Instrument.
       *
       * @return The description of the Instrument.
       */
      String getDescription();
      
      /**
       * Returns the type of the Instrument.
       *
       * @return The type of the Instrument.
       */
      int getType();
      
      /**
       * Adds a CounterInstrumentListener to the list of listeners which will
       *  receive updates of the value of the Instrument.
       *
       * @param listener CounterInstrumentListener which will start receiving
       *                 profile updates.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.PROFILE_POINT_TYPE_COUNTER.
       */
      void addCounterInstrumentListener( CounterInstrumentListener listener );
      
      /**
       * Removes a InstrumentListener from the list of listeners which will
       *  receive profile events.
       *
       * @param listener InstrumentListener which will stop receiving profile
       *                 events.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.PROFILE_POINT_TYPE_COUNTER.
       */
      void removeCounterInstrumentListener( CounterInstrumentListener listener );
      
      /**
       * Adds a ValueInstrumentListener to the list of listeners which will
       *  receive updates of the value of the Instrument.
       *
       * @param listener ValueInstrumentListener which will start receiving
       *                 profile updates.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.PROFILE_POINT_TYPE_VALUE.
       */
      void addValueInstrumentListener( ValueInstrumentListener listener );
          
      /**
       * Removes a InstrumentListener from the list of listeners which will
       *  receive profile events.
       *
       * @param listener InstrumentListener which will stop receiving profile
       *                 events.
       *
       * @throws IllegalStateException If the Instrument's type is not
       *         InstrumentManager.PROFILE_POINT_TYPE_VALUE.
       */
      void removeValueInstrumentListener( ValueInstrumentListener listener );
      
      /**
       * Returns a InstrumentSampleDescriptor based on its name.
       *
       * @param InstrumentSampleName Name of the InstrumentSample being requested.
       *
       * @return A Descriptor of the requested InstrumentSample.
       *
       * @throws NoSuchInstrumentSampleException If the specified InstrumentSample
       *                                      does not exist.
       */
      InstrumentSampleDescriptor getInstrumentSampleDescriptor( String InstrumentSampleName )
          throws NoSuchInstrumentSampleException;
      
      /**
       * Returns an array of Descriptors for the InstrumentSamples configured for this
       *  Instrument.
       *
       * @return An array of Descriptors for the InstrumentSamples configured for this
       *  Instrument.
       */
      InstrumentSampleDescriptor[] getInstrumentSampleDescriptors();
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/InstrumentListener.java
  
  Index: InstrumentListener.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.instrument.manager.client;
  
  /**
   * Root interface for InstrumentListeners.  This interface should not be
   *  be implemented directly.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public interface InstrumentListener
  {
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/InstrumentManagerClient.java
  
  Index: InstrumentManagerClient.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.instrument.manager.client;
  
  import org.apache.avalon.excalibur.instrument.Instrumentable;
  
  import org.apache.avalon.framework.configuration.Configuration;
  
  /**
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public interface InstrumentManagerClient
  {
      /** Type which specifies that the type of a Instrument has not yet been determined. */
      int INSTRUMENT_TYPE_NONE = 0;
      
      /** Type which identifies CounterInstruments. */
      int INSTRUMENT_TYPE_COUNTER = 1;
      
      /** Type which identifies ValueInstruments. */
      int INSTRUMENT_TYPE_VALUE   = 2;
      
      /**
       * Returns the name used to identify this InstrumentManager.
       *
       * @return The name used to identify this InstrumentManager.
       */
      String getName();
      
      /**
       * Returns the description of this InstrumentManager.
       *
       * @return The description of this InstrumentManager.
       */
      String getDescription();
      
      /**
       * Returns a InstrumentableDescriptor based on its name or the name of any
       *  of its children.
       *
       * @param instrumentableName Name of the Instrumentable being requested.
       *
       * @return A Descriptor of the requested Instrumentable.
       *
       * @throws NoSuchInstrumentableException If the specified Instrumentable does
       *                                   not exist.
       */
      InstrumentableDescriptor getInstrumentableDescriptor( String instrumentableName )
          throws NoSuchInstrumentableException;
  
      /**
       * Returns an array of Descriptors for the Instrumentables managed by this
       *  InstrumentManager.
       *
       * @return An array of Descriptors for the Instrumentables managed by this
       *  InstrumentManager.
       */
      InstrumentableDescriptor[] getInstrumentableDescriptors();
      
      /**
       * Invokes garbage collection.
       */
      void invokeGarbageCollection();
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/InstrumentSampleDescriptor.java
  
  Index: InstrumentSampleDescriptor.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.instrument.manager.client;
  
  /**
   * Describes an InstrumentSample and acts as a Proxy to protect the original
   *  InstrumentSample object.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public interface InstrumentSampleDescriptor
  {
      /**
       * Returns true if the InstrumentSample was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      boolean isConfigured();
      
      /**
       * Returns the name of the sample.
       *
       * @return The name of the sample.
       */
      String getName();
      
      /**
       * Returns the sample interval.  The period of each sample in millisends.
       *
       * @return The sample interval.
       */
      long getInterval();
      
      /**
       * Returns the number of samples in the sample history.
       *
       * @return The size of the sample history.
       */
      int getSize();
      
      /**
       * Returns the description of the sample.
       *
       * @return The description of the sample.
       */
      String getDescription();
      
      /**
       * Obtain the value of the sample.  All samples are integers, so the profiled
       * objects must measure quantity (numbers of items), rate (items/period), time in
       * milliseconds, etc.
       *
       * @return The sample value.
       */
      int getValue();
      
      /**
       * Obtain the UNIX time of the beginning of the sample.
       *
       * @return The UNIX time of the beginning of the sample.
       */
      long getTime();
      
      /**
       * Returns the Type of the Instrument which can use the sample.  This
       *  should be the same for all instances of a class.
       * <p>
       * Should be one of the following: InstrumentManager.PROFILE_POINT_TYPE_COUNTER
       *  or InstrumentManager.PROFILE_POINT_TYPE_VALUE
       *
       * @return The Type of the Instrument which can use the sample.
       */
      int getInstrumentType();
      
      /**
       * Obtains a static snapshot of the InstrumentSample.
       *
       * @return A static snapshot of the InstrumentSample.
       */
      InstrumentSampleSnapshot getSnapshot();
      
      /**
       * Registers a InstrumentSampleListener with a InstrumentSample given a name.
       *
       * @param listener The listener which should start receiving updates from the
       *                 InstrumentSample.
       */
      void addInstrumentSampleListener( InstrumentSampleListener listener );
      
      /**
       * Unregisters a InstrumentSampleListener from a InstrumentSample given a name.
       *
       * @param listener The listener which should stop receiving updates from the
       *                 InstrumentSample.
       */
      void removeInstrumentSampleListener( InstrumentSampleListener listener );
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/InstrumentSampleListener.java
  
  Index: InstrumentSampleListener.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.instrument.manager.client;
  
  /**
   * Objects which implement the InstrumentSampleListener interface can register
   *  themselves with InstrumentSample instances to receive updates on their value.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public interface InstrumentSampleListener
  {
      /**
       * Called by a InstrumentSample whenever its value is changed.
       *
       * @param InstrumentSampleName The name of the InstrumentSample whose value was changed.
       * @param value The new value.
       * @param time The time that the InstrumentSample value was changed.
       */
      void setValue( String InstrumentSampleName, int value, long time );
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/InstrumentSampleSnapshot.java
  
  Index: InstrumentSampleSnapshot.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.instrument.manager.client;
  
  import java.io.Serializable;
  
  /**
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public class InstrumentSampleSnapshot
      implements Serializable
  {
      /** The name used to reference the InstrumentSample. */
      private String m_InstrumentSampleName;
      
      /** The interval between each sample. */
      private long m_interval;
      
      /** The number of samples in the InstrumentSample. */
      private int m_size;
      
      /** The time that the last sample starts. */
      private long m_time;
      
      /** The samples as an array of integers. */
      private int[] m_samples;
      
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * @param InstrumentSampleName The name used to reference the InstrumentSample.
       * @param interval The interval between each sample.
       * @param size The number of samples in the InstrumentSample.
       * @param time The time that the last sample starts.
       * @param samples The samples as an array of integers.
       */
      public InstrumentSampleSnapshot( String InstrumentSampleName,
                             long interval,
                             int size,
                             long time,
                             int[] samples )
      {
          m_InstrumentSampleName = InstrumentSampleName;
          m_interval = interval;
          m_size = size;
          m_time = time;
          m_samples = samples;
      }
      
      /*---------------------------------------------------------------
       * Methods
       *-------------------------------------------------------------*/
      /**
       * Returns the name used to reference the InstrumentSample.
       *
       * @return The name used to reference the InstrumentSample.
       */
      public String getInstrumentSampleName()
      {
          return m_InstrumentSampleName;
      }
      
      /**
       * Returns the interval, in milliseconds, between each sample.
       *
       * @return The interval between each sample.
       */
      public long getInterval()
      {
          return m_interval;
      }
      
      /**
       * Returns the number of samples in the InstrumentSample.
       *
       * @return The number of samples in the InstrumentSample.
       */
      public int getSize()
      {
          return m_size;
      }
      
      /**
       * Returns the time that the last sample starts.
       *
       * @return The time that the last sample starts.
       */
      public long getTime()
      {
          return m_time;
      }
      
      /**
       * Returns the samples as an array of integers.  The sample at index 0
       *  will be the oldest.  The end of the array is the newest.
       *
       * @return The samples as an array of integers.
       */
      public int[] getSamples()
      {
          return m_samples;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/InstrumentableDescriptor.java
  
  Index: InstrumentableDescriptor.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.instrument.manager.client;
  
  /**
   * Describes a Instrumentable and acts as a Proxy to protect the original
   *  Instrumentable.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public interface InstrumentableDescriptor
  {
      /**
       * Returns true if the Instrumentable was configured in the instrumentables
       *  section of the configuration.
       *
       * @return True if configured.
       */
      boolean isConfigured();
  
      /**
       * Gets the name for the Instrumentable.  The Instrumentable Name is used to
       *  uniquely identify the Instrumentable during the configuration of the
       *  Profiler and to gain access to a InstrumentableDescriptor through a
       *  ProfilerManager.
       *
       * @return The name used to identify a Instrumentable.
       */
      String getName();
  
      /**
       * Gets the description of the Instrumentable.
       *
       * @return The description of the Instrumentable.
       */
      String getDescription();
  
      /**
       * Returns a InstrumentDescriptor based on its name.
       *
       * @param instrumentName Name of the Instrument being requested.
       *
       * @return A Descriptor of the requested Instrument.
       *
       * @throws NoSuchInstrumentException If the specified Instrument does
       *                                     not exist.
       */
      InstrumentDescriptor getInstrumentDescriptor( String instrumentName )
          throws NoSuchInstrumentException;
  
      /**
       * Returns an array of Descriptors for the Instruments registered by this
       *  Instrumentable.
       *
       * @return An array of Descriptors for the Instruments registered by this
       *  Instrumentable.
       */
      InstrumentDescriptor[] getInstrumentDescriptors();
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/NoSuchInstrumentException.java
  
  Index: NoSuchInstrumentException.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.instrument.manager.client;
  
  /**
   * Thrown when a Instrument can not be found.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public class NoSuchInstrumentException
      extends RuntimeException
  {
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Construct a new NoSuchInstrumentException instance.
       *
       * @param message The detail message for this exception.
       */
      public NoSuchInstrumentException( String message )
      {
          super( message );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/NoSuchInstrumentSampleException.java
  
  Index: NoSuchInstrumentSampleException.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.instrument.manager.client;
  
  /**
   * Thrown when a InstrumentSample can not be found.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public class NoSuchInstrumentSampleException
      extends RuntimeException
  {
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Construct a new NoSuchInstrumentSampleException instance.
       *
       * @param message The detail message for this exception.
       */
      public NoSuchInstrumentSampleException( String message )
      {
          super( message );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/NoSuchInstrumentableException.java
  
  Index: NoSuchInstrumentableException.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.instrument.manager.client;
  
  /**
   * Thrown when a Instrumentable can not be found.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public class NoSuchInstrumentableException
      extends RuntimeException
  {
      /*---------------------------------------------------------------
       * Constructors
       *-------------------------------------------------------------*/
      /**
       * Construct a new NoSuchInstrumentableException instance.
       *
       * @param message The detail message for this exception.
       */
      public NoSuchInstrumentableException( String message )
      {
          super( message );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/java/org/apache/avalon/excalibur/instrument/manager/client/ValueInstrumentListener.java
  
  Index: ValueInstrumentListener.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.instrument.manager.client;
  
  /**
   * Objects which implement the InstrumentListener interface can register
   *  themselves with Instrument instances to receive updates on the
   *  Profile Point's value.
   *
   * @author <a href="mailto:leif@silveregg.co.jp">Leif Mortenson</a>
   * @version CVS $Revision: 1.1 $ $Date: 2002/03/26 11:56:17 $
   * @since 4.1
   */
  public interface ValueInstrumentListener
      extends InstrumentListener
  {
      /**
       * Called by a ValueInstrument whenever its value is set.
       *
       * @param instrumentName The name of Instrument whose value was set.
       * @param value Value that was set.
       * @param time The time that the Instrument was incremented.
       *
       * ValueInstrument
       */
      void setValue( String instrumentName, int value, long time );
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/instrument-manager/src/test/README.txt
  
  Index: README.txt
  ===================================================================
  No tests yet.
  This file keeps the directory here until they are added.
  
  
  
  

--
To unsubscribe, e-mail:   <mailto:avalon-cvs-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@jakarta.apache.org>


Mime
View raw message