Return-Path: Delivered-To: apmail-jakarta-avalon-cvs-archive@apache.org Received: (qmail 85822 invoked from network); 6 Aug 2002 16:28:45 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 6 Aug 2002 16:28:45 -0000 Received: (qmail 11791 invoked by uid 97); 6 Aug 2002 16:29:09 -0000 Delivered-To: qmlist-jakarta-archive-avalon-cvs@jakarta.apache.org Received: (qmail 11763 invoked by uid 97); 6 Aug 2002 16:29:08 -0000 Mailing-List: contact avalon-cvs-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon CVS List" Reply-To: "Avalon Developers List" Delivered-To: mailing list avalon-cvs@jakarta.apache.org Received: (qmail 11747 invoked by uid 97); 6 Aug 2002 16:29:08 -0000 X-Antivirus: nagoya (v4198 created Apr 24 2002) Date: 6 Aug 2002 16:28:38 -0000 Message-ID: <20020806162838.9567.qmail@icarus.apache.org> From: leif@apache.org To: jakarta-avalon-excalibur-cvs@apache.org Subject: cvs commit: jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component AbstractDualLogEnabledInstrumentable.java ComponentHandler.java DefaultComponentFactory.java ExcaliburComponentManager.java ExcaliburComponentSelector.java PoolableComponentHandler.java ThreadSafeComponentHandler.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N leif 2002/08/06 09:28:38 Modified: component/src/java/org/apache/avalon/excalibur/component ComponentHandler.java DefaultComponentFactory.java ExcaliburComponentManager.java ExcaliburComponentSelector.java PoolableComponentHandler.java ThreadSafeComponentHandler.java Added: component/examples/instrument-manager .cvsignore ant.properties.sample build.xml default.properties component/examples/instrument-manager/bin cpappend.bat run.bat run.sh component/examples/instrument-manager/conf components.xml instrument.xml logkit.xml roles.xml component/examples/instrument-manager/src/java/org/apache/avalon/excalibur/component/example_im DefaultExampleInstrumentable.java ExampleInstrumentable.java Main.java component/src/java/org/apache/avalon/excalibur/component AbstractDualLogEnabledInstrumentable.java Log: Merge the ICM into the ECM. Revision Changes Path 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/.cvsignore Index: .cvsignore =================================================================== build data lib ant.properties 1.1 jakarta-avalon-excalibur/component/examples/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/08/06 16:28:37 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-2.0.1.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.3.1.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 # ----- Excalibur Concurrent ----- excalibur-concurrent.home=../../../concurrent/build/lib excalibur-concurrent.jar=${excalibur-concurrent.home}/excalibur-concurrent-1.0.jar # ----- Excalibur Collections ----- excalibur-collections.home=../../../collections/build/lib excalibur-collections.jar=${excalibur-collections.home}/excalibur-collections-1.0.jar # ----- Excalibur Component ----- excalibur-component.home=../../../component/build/lib excalibur-component.jar=${excalibur-component.home}/excalibur-component-1.0.jar # ----- Excalibur Logger ----- excalibur-logger.home=../../../logger/build/lib excalibur-logger.jar=${excalibur-logger.home}/excalibur-logger-1.0.jar # ----- Excalibur Pool ----- excalibur-pool.home=../../../pool/build/lib excalibur-pool.jar=${excalibur-pool.home}/excalibur-pool-1.0.jar # ----- Excalibur Instrument ----- excalibur-instrument.home=../../../instrument/build/lib excalibur-instrument.jar=${excalibur-instrument.home}/excalibur-instrument-0.3.jar excalibur-instrument-manager.jar=${excalibur-instrument.home}/excalibur-instrument-manager-0.3.jar excalibur-instrument-manager-interfaces.jar=${excalibur-instrument.home}/excalibur-instrument-manager-interfaces-0.3.jar # ----- Altrmi ----- excalibur-altrmi.home=../../../altrmi/build/lib excalibur-altrmi-common.jar=${excalibur-altrmi.home}/excalibur-altrmi-common.jar excalibur-altrmi-server-impl.jar=${excalibur-altrmi.home}/excalibur-altrmi-server-impl.jar excalibur-altrmi-server-interfaces.jar=${excalibur-altrmi.home}/excalibur-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/component/examples/instrument-manager/build.xml Index: build.xml =================================================================== 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/default.properties Index: default.properties =================================================================== # ------------------------------------------------------------------- # B U I L D P R O P E R T I E S # ------------------------------------------------------------------- # Specifies default property values # Overridden by ../default.properties and all ant.properties # Not user-editable; use ant.properties files instead # -------------------------------------------------- # REQUIRED LIBRARIES # -------------------------------------------------- excalibur.dir=${basedir}/../../.. avalon-framework.home=${excalibur.dir}/../jakarta-avalon # ----- Xerces ----- xerces.jar=${tools.dir}/lib/xerces-2.0.1.jar # ----- XML Apis ----- xml-apis.jar=${tools.dir}/lib/xml-apis.jar # ----- Xalan ----- xalan.jar=${tools.dir}/lib/xalan-2.3.1.jar # ----- Logkit ----- logkit.home=${excalibur.dir}/../jakarta-avalon-logkit logkit.lib=${logkit.home}/build/lib logkit.jar=${logkit.lib}/logkit.jar # ----- Avalon Framework ----- avalon-framework.lib=${avalon-framework.home}/build/lib avalon-framework.jar=${avalon-framework.lib}/avalon-framework.jar # ----- Excalibur Concurrent ----- excalibur-concurrent.home=${excalibur.dir}/concurrent/dist excalibur-concurrent.jar=${excalibur-concurrent.home}/excalibur-concurrent-1.0.jar # ----- Excalibur Collections ----- excalibur-collections.home=${excalibur.dir}/collections/dist excalibur-collections.jar=${excalibur-collections.home}/excalibur-collections-1.0.jar # ----- Excalibur Component ----- excalibur-component.home=${excalibur.dir}/component/dist excalibur-component.jar=${excalibur-component.home}/excalibur-component-1.0.jar # ----- Excalibur Logger ----- excalibur-logger.home=${excalibur.dir}/logger/dist excalibur-logger.jar=${excalibur-logger.home}/excalibur-logger-1.0.jar # ----- Excalibur Pool ----- excalibur-pool.home=${excalibur.dir}/pool/dist excalibur-pool.jar=${excalibur-pool.home}/excalibur-pool-1.0.jar # ----- Excalibur Instrument ----- excalibur-instrument.home=${excalibur.dir}/instrument/dist excalibur-instrument.jar=${excalibur-instrument.home}/excalibur-instrument-0.3.jar excalibur-instrument-manager.jar=${excalibur-instrument.home}/excalibur-instrument-manager-0.3.jar excalibur-instrument-manager-interfaces.jar=${excalibur-instrument.home}/excalibur-instrument-manager-interfaces-0.3.jar # ----- Altrmi ----- excalibur-altrmi.home=${excalibur.dir}/altrmi/dist excalibur-altrmi-common.jar=${excalibur-altrmi.home}/excalibur-altrmi-common.jar excalibur-altrmi-server-impl.jar=${excalibur-altrmi.home}/excalibur-altrmi-server-impl.jar excalibur-altrmi-server-interfaces.jar=${excalibur-altrmi.home}/excalibur-altrmi-server-interfaces.jar # -------------------------------------------------- # OPTIONAL LIBRARIES # -------------------------------------------------- # -------------------------------------------------- # Settings used to configure compile environment build.debug = on build.optimize = off build.deprecation = off build.compress = false junit.failonerror = false # location of intermediate products build.dir = ${basedir}/build build.testsrc = ${build.dir}/testsrc build.testclasses = ${build.dir}/testclasses build.lib = ${build.dir}/lib build.conf = ${build.dir}/conf build.classes = ${build.dir}/classes build.tests = ${build.dir}/tests build.reports = ${build.dir}/reports build.genjava="${build.dir}/genjava # Set the properties for source directories src.dir = ${basedir}/src java.dir = ${src.dir}/java conf.dir = ${src.dir}/conf test.dir = ${src.dir}/test manager.dir = ${src.dir}/manager client.dir = ${src.dir}/client # needed by Cocoon build.context = ${build.dir}/documentation build.docs = ${build.dir}/docs build.xdocs = ${build.dir}/xdocs context.dir = ${avalon-framework.home}/src/documentation tools.dir = ${avalon-framework.home}/tools tools.jar = ${java.home}/../lib/tools.jar docs.dir = docs xdocs.dir = ${src.dir}/xdocs # Set the properties for distribution directories dist.dir = ${basedir}/dist dist.javadocs = ${dist.dir}/docs/api # name of .zip/.tar.gz/.bz2 files and their top-level directory dist.name = ${name}-${version} # name of jar file jar.name = ${name}-${version}.jar client.jar.name = ${client.name}-${version}.jar manager.jar.name = ${manager.name}-${version}.jar # property indicating directory where all distribution archives are placed dist.base = distributions depchecker.prefix=../../../ 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/bin/cpappend.bat Index: cpappend.bat =================================================================== set _LIBJARS=%_LIBJARS%;%1 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/bin/run.bat Index: run.bat =================================================================== @echo off rem rem Example start script. rem rem Author: Leif Mortenson [leif@tanukisoftware.com] 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.component.example_im.Main %1 %2 %3 %4 %5 %6 %7 %8 %9 :end 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/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}/lib/*.jar ; do CP=${CP}:$i done #echo $CP # Run the example application $JAVACMD -classpath $CP org.apache.avalon.excalibur.component.example_im.Main $@ 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/conf/components.xml Index: components.xml =================================================================== 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/conf/instrument.xml Index: instrument.xml =================================================================== example-instrument-manager ECM Example Instrument Application ../data/instrument.sampledata 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/conf/logkit.xml Index: logkit.xml =================================================================== System.out %19.19{time:yyyy-MM-dd'T'HH:mm:ss.SSS} %5.5{priority} [%15.15{category}]: %{message}\n%{throwable} 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/conf/roles.xml Index: roles.xml =================================================================== 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/src/java/org/apache/avalon/excalibur/component/example_im/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.component.example_im; import org.apache.excalibur.instrument.CounterInstrument; import org.apache.excalibur.instrument.Instrumentable; import org.apache.excalibur.instrument.Instrument; import org.apache.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 Leif Mortenson * @version CVS $Revision: 1.1 $ $Date: 2002/08/06 16:28:37 $ * @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. *

* 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/component/examples/instrument-manager/src/java/org/apache/avalon/excalibur/component/example_im/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.component.example_im; 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 Leif Mortenson * @version CVS $Revision: 1.1 $ $Date: 2002/08/06 16:28:37 $ * @since 4.1 */ public interface ExampleInstrumentable extends Component { String ROLE = ExampleInstrumentable.class.getName(); /** * Example action method. */ void doAction(); } 1.1 jakarta-avalon-excalibur/component/examples/instrument-manager/src/java/org/apache/avalon/excalibur/component/example_im/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.component.example_im; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import org.apache.avalon.excalibur.component.DefaultRoleManager; import org.apache.avalon.excalibur.component.ExcaliburComponentManager; import org.apache.avalon.excalibur.logger.LogKitLoggerManager; 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.excalibur.instrument.manager.DefaultInstrumentManager; 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. *

* Note, this code ignores exceptions to keep the code simple. * * @author Leif Mortenson * @version CVS $Revision: 1.1 $ $Date: 2002/08/06 16:28:37 $ * @since 4.1 */ public class Main { private static ExcaliburComponentManager m_componentManager; private static DefaultInstrumentManager m_instrumentManager; /*--------------------------------------------------------------- * 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" ); // Create the default logger for the Logger Manager. Logger lmLogger = Hierarchy.getDefaultHierarchy(). getLoggerFor( logKitConfig.getAttribute( "logger", "lm" ) ); lmLogger.setPriority( Priority.getPriorityForName( logKitConfig.getAttribute( "log-level", "INFO" ) ) ); // Setup the LogKitLoggerManager LogKitLoggerManager logManager = new LogKitLoggerManager( null, Hierarchy.getDefaultHierarchy(), new LogKitLogger( lmLogger ) ); logManager.contextualize( context ); logManager.configure( logKitConfig ); // Set up the Instrument Manager DefaultInstrumentManager instrumentManager = new DefaultInstrumentManager(); instrumentManager.enableLogging( logManager.getLoggerForCategory( instrumentConfig.getAttribute( "logger", "im" ) ) ); instrumentManager.configure( instrumentConfig ); instrumentManager.initialize(); m_instrumentManager = instrumentManager; // Setup the RoleManager DefaultRoleManager roleManager = new DefaultRoleManager(); roleManager.enableLogging( logManager.getLoggerForCategory( rolesConfig.getAttribute( "logger", "rm" ) ) ); roleManager.configure( rolesConfig ); // Set up the ComponentManager ExcaliburComponentManager componentManager = new ExcaliburComponentManager(); componentManager.enableLogging( logManager.getLoggerForCategory( componentsConfig.getAttribute( "logger", "cm" ) ) ); componentManager.setLoggerManager( logManager ); componentManager.contextualize( context ); componentManager.setInstrumentManager( m_instrumentManager ); componentManager.setRoleManager( roleManager ); componentManager.configure( componentsConfig ); componentManager.initialize(); m_componentManager = componentManager; } /*--------------------------------------------------------------- * 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 InstrumentManager 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 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 static final 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.4 +127 -38 jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/ComponentHandler.java Index: ComponentHandler.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/ComponentHandler.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ComponentHandler.java 2 Jun 2002 06:03:01 -0000 1.3 +++ ComponentHandler.java 6 Aug 2002 16:28:37 -0000 1.4 @@ -8,6 +8,7 @@ package org.apache.avalon.excalibur.component; import org.apache.avalon.excalibur.pool.Poolable; + import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.component.Component; @@ -17,30 +18,101 @@ import org.apache.avalon.framework.thread.SingleThreaded; import org.apache.avalon.framework.thread.ThreadSafe; +import org.apache.excalibur.instrument.CounterInstrument; +import org.apache.excalibur.instrument.Instrumentable; +import org.apache.excalibur.instrument.InstrumentManager; +import org.apache.excalibur.instrument.ValueInstrument; + /** * This class acts like a Factory to instantiate the correct version * of the ComponentHandler that you need. * * @author Berin Loritsch * @author Ryan Shaw - * @author Leif Mortenson + * @author Leif Mortenson * @version CVS $Revision$ $Date$ * @since 4.0 */ public abstract class ComponentHandler - extends AbstractDualLogEnabled + extends AbstractDualLogEnabledInstrumentable implements Initializable, Disposable { private Object m_referenceSemaphore = new Object(); private int m_references = 0; - public static ComponentHandler getComponentHandler( - final Class componentClass, - final Configuration config, - final ComponentManager manager, - final Context context, - final RoleManager roles, - final LogkitLoggerManager logkit ) + /** Instrument used to profile the number of outstanding references. */ + private ValueInstrument m_referencesInstrument; + + /** Instrument used to profile the number of gets. */ + private CounterInstrument m_getsInstrument; + + /** Instrument used to profile the number of puts. */ + private CounterInstrument m_putsInstrument; + + /*--------------------------------------------------------------- + * Static Methods + *-------------------------------------------------------------*/ + /** + * Looks up and returns a component handler for a given component class. + * + * @param componentClass Class of the component for which the handle is + * being requested. + * @param configuration The configuration for this component. + * @param componentManager The ComponentLocator which will be managing + * the Component. + * @param context The current context object. + * @param roleManager The current RoleManager. + * @param loggerManager The current LogKitLoggerManager. + * @param instrumentManager The current InstrumentManager. + * @param instrumentableName The name of the handler. + * + * @throws Exception If there were any problems obtaining a ComponentHandler + * + * @deprecated This method has been deprecated in favor of the version below which + * handles instrumentation. + */ + public static ComponentHandler getComponentHandler( final Class componentClass, + final Configuration configuration, + final ComponentManager componentManager, + final Context context, + final RoleManager roleManager, + final LogkitLoggerManager loggerManager ) + throws Exception + { + return ComponentHandler.getComponentHandler( componentClass, + configuration, + componentManager, + context, + roleManager, + loggerManager, + null, + "N/A" ); + } + + /** + * Looks up and returns a component handler for a given component class. + * + * @param componentClass Class of the component for which the handle is + * being requested. + * @param configuration The configuration for this component. + * @param componentManager The ComponentLocator which will be managing + * the Component. + * @param context The current context object. + * @param roleManager The current RoleManager. + * @param loggerManager The current LogKitLoggerManager. + * @param instrumentManager The current InstrumentManager (May be null). + * @param instrumentableName The name of the handler. + * + * @throws Exception If there were any problems obtaining a ComponentHandler + */ + public static ComponentHandler getComponentHandler( final Class componentClass, + final Configuration configuration, + final ComponentManager componentManager, + final Context context, + final RoleManager roleManager, + final LogkitLoggerManager loggerManager, + final InstrumentManager instrumentManager, + final String instrumentableName ) throws Exception { int numInterfaces = 0; @@ -65,33 +137,35 @@ throw new Exception( "[CONFLICT] lifestyle interfaces: " + componentClass.getName() ); } + // Create the factory to use to create the instances of the Component. + DefaultComponentFactory factory = + new DefaultComponentFactory( componentClass, + configuration, + componentManager, + context, + roleManager, + loggerManager, + instrumentManager, + instrumentableName ); + + ComponentHandler handler; if( Poolable.class.isAssignableFrom( componentClass ) ) { - return new PoolableComponentHandler( componentClass, - config, - manager, - context, - roles, - logkit ); + handler = new PoolableComponentHandler( factory, configuration ); } else if( ThreadSafe.class.isAssignableFrom( componentClass ) ) { - return new ThreadSafeComponentHandler( componentClass, - config, - manager, - context, - roles, - logkit ); + handler = new ThreadSafeComponentHandler( factory, configuration ); } else // This is a SingleThreaded component { - return new DefaultComponentHandler( componentClass, - config, - manager, - context, - roles, - logkit ); + handler = new DefaultComponentHandler( factory, configuration ); } + + // Set the instrumentable name of the handler. + ((Instrumentable)handler).setInstrumentableName( instrumentableName ); + + return handler; } public static ComponentHandler getComponentHandler( @@ -122,7 +196,24 @@ return new ThreadSafeComponentHandler( componentInstance ); } + + /*--------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------*/ + /** + * Creates a new ComponentHandler. + */ + public ComponentHandler() + { + // Initialize the Instrumentable elements. + addInstrument( m_referencesInstrument = new ValueInstrument( "references" ) ); + addInstrument( m_getsInstrument = new CounterInstrument( "gets" ) ); + addInstrument( m_putsInstrument = new CounterInstrument( "puts" ) ); + } + /*--------------------------------------------------------------- + * Methods + *-------------------------------------------------------------*/ /** * Get an instance of the type of component handled by this handler. *

@@ -142,6 +233,10 @@ { m_references++; } + + // Notify the instrument manager + m_getsInstrument.increment(); + m_referencesInstrument.setValue( m_references ); return component; } @@ -170,6 +265,10 @@ { m_references--; } + + // Notify the instrument manager + m_putsInstrument.increment(); + m_referencesInstrument.setValue( m_references ); try { @@ -203,16 +302,6 @@ { // This method is not abstract to make the class backwards compatible. throw new IllegalStateException( "This method must be overridden." ); - } - - /** - * Returns the current number of references. - * - * @return The current number of references. - */ - protected int getReferences() - { - return m_references; } /** 1.7 +117 -63 jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/DefaultComponentFactory.java Index: DefaultComponentFactory.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/DefaultComponentFactory.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- DefaultComponentFactory.java 16 Jul 2002 12:35:45 -0000 1.6 +++ DefaultComponentFactory.java 6 Aug 2002 16:28:37 -0000 1.7 @@ -9,9 +9,11 @@ import java.util.ArrayList; import java.util.Collection; + import org.apache.avalon.excalibur.collections.BucketMap; import org.apache.avalon.excalibur.logger.LogKitManageable; import org.apache.avalon.excalibur.pool.ObjectFactory; + import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.activity.Startable; @@ -32,12 +34,17 @@ import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.Serviceable; +import org.apache.excalibur.instrument.Instrumentable; +import org.apache.excalibur.instrument.InstrumentManageable; +import org.apache.excalibur.instrument.InstrumentManager; + /** * Factory for Avalon components. * * @author Berin Loritsch * @author Paul Russell * @author Ryan Shaw + * @author Leif Mortenson * @version CVS $Revision$ $Date$ * @since 4.0 */ @@ -68,13 +75,22 @@ /** The LogkitLoggerManager for child ComponentSelectors */ - private LogkitLoggerManager m_logkit; + private LogkitLoggerManager m_loggerManager; /** Components created by this factory, and their associated ComponentLocator * proxies, if they are Composables. */ private final BucketMap m_components = new BucketMap(); + /** Instrument Manager to register objects created by this factory with (May be null). */ + private InstrumentManager m_instrumentManager; + + /** Instrumentable Name assigned to objects created by this factory. */ + private String m_instrumentableName; + + /*--------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------*/ /** * Construct a new component factory for the specified component. * @@ -83,22 +99,64 @@ * @param componentManager the component manager to pass to Composables. * @param context the Context to pass to Contexutalizables. * @param roles the RoleManager to pass to DefaultComponentSelectors. + * + * @deprecated This constructor has been deprecated in favor of the version below which + * handles instrumentation. + */ + public DefaultComponentFactory( final Class componentClass, + final Configuration configuration, + final ComponentManager componentManager, + final Context context, + final RoleManager roles, + final LogkitLoggerManager loggerManager ) + { + this( componentClass, + configuration, + componentManager, + context, + roles, + loggerManager, + null, + "N/A" ); + } + + /** + * Construct a new component factory for the specified component. + * + * @param componentClass the class to instantiate (must have a default constructor). + * @param configuration the Configuration object to pass to new instances. + * @param componentManager the component manager to pass to Composables. + * @param context the Context to pass to Contexutalizables. + * @param roles the RoleManager to pass to + * DefaultComponentSelectors. + * @param instrumentManager the InstrumentManager to register the component + * with if it is a Instrumentable (May be null). + * @param instrumentableName The instrument name to assign the component if + * it is Initializable. */ public DefaultComponentFactory( final Class componentClass, final Configuration configuration, final ComponentManager componentManager, final Context context, final RoleManager roles, - final LogkitLoggerManager logkit ) + final LogkitLoggerManager loggerManager, + final InstrumentManager instrumentManager, + final String instrumentableName ) + { m_componentClass = componentClass; m_configuration = configuration; m_componentManager = componentManager; m_context = context; m_roles = roles; - m_logkit = logkit; + m_loggerManager = loggerManager; + m_instrumentManager = instrumentManager; + m_instrumentableName = instrumentableName; } - + + /*--------------------------------------------------------------- + * ObjectFactory Methods + *-------------------------------------------------------------*/ public Object newInstance() throws Exception { @@ -112,7 +170,7 @@ if( component instanceof LogEnabled ) { - if( null == m_logkit || null == m_configuration ) + if( null == m_loggerManager || null == m_configuration ) { ( (LogEnabled)component ).enableLogging( getLogger() ); } @@ -127,14 +185,14 @@ else { getLogger().debug( "logger attribute is " + logger ); - ( (LogEnabled)component ).enableLogging( m_logkit.getLoggerForCategory( logger ) ); + ( (LogEnabled)component ).enableLogging( m_loggerManager.getLoggerForCategory( logger ) ); } } } if( component instanceof Loggable ) { - if( null == m_logkit || null == m_configuration ) + if( null == m_loggerManager || null == m_configuration ) { ( (Loggable)component ).setLogger( getLogkitLogger() ); } @@ -149,15 +207,15 @@ else { getLogger().debug( "logger attribute is " + logger ); - ( (Loggable)component ).setLogger( m_logkit.getLogKitLoggerForCategory( logger ) ); + ( (Loggable)component ).setLogger( m_loggerManager.getLogKitLoggerForCategory( logger ) ); } } } - // This was added to make it possible to implement a ProfilerComponentFactory without - // code duplication. Once the issues there are worked out, this will most likely be - // removed as it is rather hackish. - postLogger( component, m_configuration ); + if( ( component instanceof InstrumentManageable ) && ( m_instrumentManager != null ) ) + { + ( (InstrumentManageable)component ).setInstrumentManager( m_instrumentManager ); + } if( component instanceof Contextualizable ) { @@ -191,7 +249,7 @@ if( component instanceof LogKitManageable ) { - ( (LogKitManageable)component ).setLogKitManager( m_logkit.getLogKitManager() ); + ( (LogKitManageable)component ).setLogKitManager( m_loggerManager.getLogKitManager() ); } if( component instanceof Configurable ) @@ -210,10 +268,17 @@ ( (Initializable)component ).initialize(); } - // This was added to make it possible to implement a ProfilerComponentFactory without - // code duplication. Once the issues there are worked out, this will most likely be - // removed as it is rather hackish. - postInitialize( component, m_configuration ); + if( component instanceof Instrumentable ) + { + Instrumentable instrumentable = (Instrumentable)component; + + instrumentable.setInstrumentableName( m_instrumentableName ); + if ( m_instrumentManager != null ) + { + m_instrumentManager.registerInstrumentable( + (Instrumentable)component, m_instrumentableName ); + } + } if( component instanceof Startable ) { @@ -225,56 +290,11 @@ return component; } - /** - * Called after a new component is initialized, but before it is started. This was added - * to make it possible to implement the ProfilerComponentFactory 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 - { - // Do nothing in this version. - } - - /** - * Called after a new component is initialized, but before it is started. This was added - * to make it possible to implement the ProfilerComponentFactory 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 - { - // Do nothing in this version. - } - public final Class getCreatedClass() { return m_componentClass; } - public final void dispose() - { - Component[] components = new Component[ m_components.keySet().size() ]; - - m_components.keySet().toArray( components ); - - for( int i = 0; i < components.length; i++ ) - { - try - { - decommission( components[ i ] ); - } - catch( final Exception e ) - { - if( getLogger().isWarnEnabled() ) - { - getLogger().warn( "Error decommissioning component: " + - getCreatedClass().getName(), e ); - } - } - } - } - public final void decommission( final Object component ) throws Exception { @@ -309,6 +329,40 @@ m_components.remove( component ); } + /*--------------------------------------------------------------- + * Disposable Methods + *-------------------------------------------------------------*/ + public final void dispose() + { + Component[] components = new Component[ m_components.keySet().size() ]; + + m_components.keySet().toArray( components ); + + for( int i = 0; i < components.length; i++ ) + { + try + { + decommission( components[ i ] ); + } + catch( final Exception e ) + { + if( getLogger().isWarnEnabled() ) + { + getLogger().warn( "Error decommissioning component: " + + getCreatedClass().getName(), e ); + } + } + } + } + + /*--------------------------------------------------------------- + * ThreadSafe Methods + *-------------------------------------------------------------*/ + // No methods + + /*--------------------------------------------------------------- + * Methods + *-------------------------------------------------------------*/ /** * Proxy ComponentLocator class to maintain references to * components looked up within a Composable instance created 1.11 +109 -13 jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/ExcaliburComponentManager.java Index: ExcaliburComponentManager.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/ExcaliburComponentManager.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- ExcaliburComponentManager.java 6 Aug 2002 14:02:12 -0000 1.10 +++ ExcaliburComponentManager.java 6 Aug 2002 16:28:37 -0000 1.11 @@ -8,12 +8,15 @@ package org.apache.avalon.excalibur.component; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; + import org.apache.avalon.excalibur.collections.BucketMap; import org.apache.avalon.excalibur.logger.LogKitManageable; import org.apache.avalon.excalibur.logger.LogKitManager; import org.apache.avalon.excalibur.logger.LoggerManager; + import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.component.Component; @@ -26,6 +29,11 @@ import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.Contextualizable; +import org.apache.excalibur.instrument.Instrument; +import org.apache.excalibur.instrument.Instrumentable; +import org.apache.excalibur.instrument.InstrumentManageable; +import org.apache.excalibur.instrument.InstrumentManager; + /** * Default component manager for Avalon's components. * @@ -44,7 +52,9 @@ Initializable, Disposable, RoleManageable, - LogKitManageable + LogKitManageable, + InstrumentManageable, + Instrumentable { /** The parent ComponentLocator */ private final ComponentManager m_parentManager; @@ -78,6 +88,12 @@ /** Is the Manager initialized? */ private boolean m_initialized; + /** Instrument Manager being used by the Component Manager. */ + private InstrumentManager m_instrumentManager; + + /** Instrumentable Name assigned to this Instrumentable */ + private String m_instrumentableName = "component-manager"; + /*--------------------------------------------------------------- * Constructors *-------------------------------------------------------------*/ @@ -468,6 +484,11 @@ public void initialize() throws Exception { + if ( m_instrumentManager != null ) + { + m_instrumentManager.registerInstrumentable( this, m_instrumentableName ); + } + synchronized( this ) { m_initialized = true; @@ -598,6 +619,86 @@ } /*--------------------------------------------------------------- + * 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( InstrumentManager instrumentManager ) + { + m_instrumentManager = instrumentManager; + } + + /*--------------------------------------------------------------- + * 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. + *

+ * 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 Instrumentable.EMPTY_INSTRUMENT_ARRAY; + } + + /** + * 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() + { + // Get the values. This set is created for this call and thus thread safe. + Collection values = m_componentHandlers.values(); + Instrumentable[] children = new Instrumentable[ values.size() ]; + values.toArray( children ); + + return children; + } + + /*--------------------------------------------------------------- * Methods *-------------------------------------------------------------*/ private void removeDisposedHandlers( List disposed ) @@ -643,22 +744,17 @@ final LogkitLoggerManager logkitManager ) throws Exception { + String instrumentableName = + configuration.getAttribute( "instrumentable", configuration.getName() ); + return ComponentHandler.getComponentHandler( componentClass, configuration, this, context, roleManager, - logkitManager ); - } - - /** - * Makes the ComponentHandlers available to subclasses. - * - * @return A collection of the reference to the componentHandler Map. - */ - protected BucketMap getComponentHandlers() - { - return m_componentHandlers; + logkitManager, + m_instrumentManager, + instrumentableName ); } /** 1.11 +284 -148 jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/ExcaliburComponentSelector.java Index: ExcaliburComponentSelector.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/ExcaliburComponentSelector.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- ExcaliburComponentSelector.java 28 Jun 2002 03:34:25 -0000 1.10 +++ ExcaliburComponentSelector.java 6 Aug 2002 16:28:38 -0000 1.11 @@ -8,12 +8,15 @@ package org.apache.avalon.excalibur.component; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; + import org.apache.avalon.excalibur.collections.BucketMap; import org.apache.avalon.excalibur.logger.LogKitManageable; import org.apache.avalon.excalibur.logger.LogKitManager; import org.apache.avalon.excalibur.logger.LoggerManager; + import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.component.Component; @@ -28,11 +31,17 @@ import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.thread.ThreadSafe; +import org.apache.excalibur.instrument.Instrument; +import org.apache.excalibur.instrument.Instrumentable; +import org.apache.excalibur.instrument.InstrumentManageable; +import org.apache.excalibur.instrument.InstrumentManager; + /** * Default component selector for Avalon's components. * * @author Berin Loritsch * @author Paul Russell + * @author Leif Mortenson * @version CVS $Revision$ $Date$ * @since 4.0 */ @@ -46,7 +55,9 @@ ThreadSafe, Disposable, RoleManageable, - LogKitManageable + LogKitManageable, + InstrumentManageable, + Instrumentable { /** The classloader used for this system. */ private final ClassLoader m_loader; @@ -95,6 +106,15 @@ */ private LogkitLoggerManager m_logkit; + /** Instrument Manager to register objects created by this selector with (May be null). */ + private InstrumentManager m_instrumentManager; + + /** Instrumentable Name assigned to this Instrumentable */ + private String m_instrumentableName; + + /*--------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------*/ /** Create the ComponentSelector */ public ExcaliburComponentSelector() { @@ -114,6 +134,9 @@ } } + /*--------------------------------------------------------------- + * Contextualizable Methods + *-------------------------------------------------------------*/ /** Provide the application Context. */ public void contextualize( final Context context ) @@ -124,108 +147,9 @@ } } - /** Compose the ComponentSelector so that we know what the parent ComponentLocator is. - */ - public void compose( final ComponentManager componentManager ) - throws ComponentException - { - //HACK: Is this necessary??? - if( null == m_componentManager ) - { - m_componentManager = componentManager; - } - } - - /** Properly initialize of the Child handlers. - */ - public void initialize() - { - synchronized( this ) - { - m_initialized = true; - - List keys = new ArrayList( m_componentHandlers.keySet() ); - - for( int i = 0; i < keys.size(); i++ ) - { - final Object key = keys.get( i ); - final ComponentHandler handler = - (ComponentHandler)m_componentHandlers.get( key ); - - try - { - handler.initialize(); - } - catch( Exception e ) - { - if( getLogger().isDebugEnabled() ) - { - getLogger().debug( "Caught an exception trying to initialize " + - "of the component handler.", e ); - } - } - - } - } - } - - /** - * Tests for existence of a component. - */ - public boolean hasComponent( final Object hint ) - { - if( !m_initialized ) return false; - if( m_disposed ) return false; - - boolean exists = false; - - try - { - ComponentHandler handler = (ComponentHandler)m_componentHandlers.get( hint ); - exists = (handler != null); - } - catch( Throwable t ) - { - // We can safely ignore all exceptions - } - - return exists; - } - - /** - * Properly dispose of all the ComponentHandlers. - */ - public void dispose() - { - synchronized( this ) - { - Iterator keys = m_componentHandlers.keySet().iterator(); - List keyList = new ArrayList(); - - while( keys.hasNext() ) - { - Object key = keys.next(); - ComponentHandler handler = - (ComponentHandler)m_componentHandlers.get( key ); - - handler.dispose(); - - keyList.add( key ); - } - - keys = keyList.iterator(); - - while( keys.hasNext() ) - { - m_componentHandlers.remove( keys.next() ); - } - - keyList.clear(); - - m_disposed = true; - } - } - + /*--------------------------------------------------------------- + * ComponentSelector Methods + *-------------------------------------------------------------*/ /** * Return an instance of a component based on a hint. The Composable has already selected the * role, so the only part left it to make sure the Component is handled. @@ -307,6 +231,94 @@ } /** + * Tests for existence of a component. + */ + public boolean hasComponent( final Object hint ) + { + if( !m_initialized ) return false; + if( m_disposed ) return false; + + boolean exists = false; + + try + { + ComponentHandler handler = (ComponentHandler)m_componentHandlers.get( hint ); + exists = (handler != null); + } + catch( Throwable t ) + { + // We can safely ignore all exceptions + } + + return exists; + } + + /** + * Release the Component to the propper ComponentHandler. + */ + public void release( final Component component ) + { + if( null == component ) + { + getLogger().warn( "Attempted to release a null component." ); + return; + } + + final ComponentHandler handler = + (ComponentHandler)m_componentMapping.get( component ); + + if( null == handler ) + { + getLogger().warn( "Attempted to release a " + component.getClass().getName() + + " but its handler could not be located." ); + return; + } + + // ThreadSafe components will always be using a ThreadSafeComponentHandler, + // they will only have a single entry in the m_componentMapping map which + // should not be removed until the ComponentLocator is disposed. All + // other components have an entry for each instance which should be + // removed. + if( !( handler instanceof ThreadSafeComponentHandler ) ) + { + // Remove the component before calling put. This is critical to avoid the + // problem where another thread calls put on the same component before + // remove can be called. + m_componentMapping.remove( component ); + } + + try + { + handler.put( component ); + } + catch( Exception e ) + { + if( getLogger().isDebugEnabled() ) + { + getLogger().debug( "Error trying to release component", e ); + } + } + } + + /*--------------------------------------------------------------- + * Composable Methods + *-------------------------------------------------------------*/ + /** Compose the ComponentSelector so that we know what the parent ComponentLocator is. + */ + public void compose( final ComponentManager componentManager ) + throws ComponentException + { + //HACK: Is this necessary??? + if( null == m_componentManager ) + { + m_componentManager = componentManager; + } + } + + /*--------------------------------------------------------------- + * Configurable Methods + *-------------------------------------------------------------*/ + /** * Default Configuration handler for ComponentSelector. */ public void configure( final Configuration configuration ) @@ -385,6 +397,87 @@ } } + /*--------------------------------------------------------------- + * Initializable Methods + *-------------------------------------------------------------*/ + /** Properly initialize of the Child handlers. + */ + public void initialize() + { + synchronized( this ) + { + m_initialized = true; + + List keys = new ArrayList( m_componentHandlers.keySet() ); + + for( int i = 0; i < keys.size(); i++ ) + { + final Object key = keys.get( i ); + final ComponentHandler handler = + (ComponentHandler)m_componentHandlers.get( key ); + + try + { + handler.initialize(); + } + catch( Exception e ) + { + if( getLogger().isDebugEnabled() ) + { + getLogger().debug( "Caught an exception trying to initialize " + + "of the component handler.", e ); + } + } + + } + } + } + + /*--------------------------------------------------------------- + * ThreadSafe Methods + *-------------------------------------------------------------*/ + // No methods + + /*--------------------------------------------------------------- + * Disposable Methods + *-------------------------------------------------------------*/ + /** + * Properly dispose of all the ComponentHandlers. + */ + public void dispose() + { + synchronized( this ) + { + Iterator keys = m_componentHandlers.keySet().iterator(); + List keyList = new ArrayList(); + + while( keys.hasNext() ) + { + Object key = keys.next(); + ComponentHandler handler = + (ComponentHandler)m_componentHandlers.get( key ); + + handler.dispose(); + + keyList.add( key ); + } + + keys = keyList.iterator(); + + while( keys.hasNext() ) + { + m_componentHandlers.remove( keys.next() ); + } + + keyList.clear(); + + m_disposed = true; + } + } + + /*--------------------------------------------------------------- + * RoleManageable Methods + *-------------------------------------------------------------*/ /** * Configure the RoleManager */ @@ -396,7 +489,9 @@ } } - + /*--------------------------------------------------------------- + * LogKitManageable Methods + *-------------------------------------------------------------*/ /** * Configure the LogKitManager */ @@ -408,61 +503,97 @@ } } + /*--------------------------------------------------------------- + * InstrumentManageable Methods + *-------------------------------------------------------------*/ /** - * Configure the LoggerManager. + * 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 setLoggerManager( final LoggerManager logkit ) + public void setInstrumentManager( final InstrumentManager instrumentManager ) { - if( null == m_logkit ) - { - m_logkit = new LogkitLoggerManager( logkit, null ); - } + m_instrumentManager = instrumentManager; } + /*--------------------------------------------------------------- + * Instrumentable Methods + *-------------------------------------------------------------*/ /** - * Release the Component to the propper ComponentHandler. + * 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. + *

+ * 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 release( final Component component ) + public void setInstrumentableName( String name ) { - if( null == component ) - { - getLogger().warn( "Attempted to release a null component." ); - return; - } + m_instrumentableName = name; + } - final ComponentHandler handler = - (ComponentHandler)m_componentMapping.get( component ); + /** + * Gets the name of the Instrumentable. + * + * @return The name used to identify a Instrumentable. + */ + public String getInstrumentableName() + { + return m_instrumentableName; + } - if( null == handler ) - { - getLogger().warn( "Attempted to release a " + component.getClass().getName() + - " but its handler could not be located." ); - return; - } + /** + * 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 Instrumentable.EMPTY_INSTRUMENT_ARRAY; + } - // ThreadSafe components will always be using a ThreadSafeComponentHandler, - // they will only have a single entry in the m_componentMapping map which - // should not be removed until the ComponentLocator is disposed. All - // other components have an entry for each instance which should be - // removed. - if( !( handler instanceof ThreadSafeComponentHandler ) ) - { - // Remove the component before calling put. This is critical to avoid the - // problem where another thread calls put on the same component before - // remove can be called. - m_componentMapping.remove( component ); - } + /** + * 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() + { + // Get the values. This set is created for this call and thus thread safe. + Collection values = getComponentHandlers().values(); + Instrumentable[] children = new Instrumentable[ values.size() ]; + values.toArray( children ); - try - { - handler.put( component ); - } - catch( Exception e ) + return children; + } + + /*--------------------------------------------------------------- + * Methods + *-------------------------------------------------------------*/ + /** + * Configure the LoggerManager. + */ + public void setLoggerManager( final LoggerManager logkit ) + { + if( null == m_logkit ) { - if( getLogger().isDebugEnabled() ) - { - getLogger().debug( "Error trying to release component", e ); - } + m_logkit = new LogkitLoggerManager( logkit, null ); } } @@ -490,12 +621,17 @@ final LogkitLoggerManager logkitManager ) throws Exception { + String instrumentableName = + configuration.getAttribute( "instrumentable", configuration.getAttribute( "name" ) ); + return ComponentHandler.getComponentHandler( componentClass, configuration, componentManager, context, roleManager, - logkitManager ); + logkitManager, + m_instrumentManager, + instrumentableName ); } /** 1.5 +4 -12 jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/PoolableComponentHandler.java Index: PoolableComponentHandler.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/PoolableComponentHandler.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- PoolableComponentHandler.java 2 Jun 2002 06:03:01 -0000 1.4 +++ PoolableComponentHandler.java 6 Aug 2002 16:28:38 -0000 1.5 @@ -77,7 +77,7 @@ * * * @author Berin Loritsch - * @author Leif Mortenson + * @author Leif Mortenson * @author Ryan Shaw * @version CVS $Revision$ $Date$ * @since 4.0 @@ -140,6 +140,8 @@ m_pool = new ResourceLimitingPool( m_factory, poolMax, poolMaxStrict, poolBlocking, poolTimeout, poolTrimInterval ); + // Initialize the Instrumentable elements. + addChildInstrumentable( m_pool ); } /** @@ -213,15 +215,5 @@ } m_disposed = true; - } - - /** - * Gives subclasses access to the pool. - * - * @return The internal pool - */ - protected ResourceLimitingPool getPool() - { - return m_pool; } } 1.4 +2 -2 jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/ThreadSafeComponentHandler.java Index: ThreadSafeComponentHandler.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/ThreadSafeComponentHandler.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ThreadSafeComponentHandler.java 2 Jun 2002 06:03:01 -0000 1.3 +++ ThreadSafeComponentHandler.java 6 Aug 2002 16:28:38 -0000 1.4 @@ -20,7 +20,7 @@ * * @author Berin Loritsch * @author Ryan Shaw - * @author Leif Mortenson + * @author Leif Mortenson * @version CVS $Revision$ $Date$ * @since 4.0 */ 1.1 jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/AbstractDualLogEnabledInstrumentable.java Index: AbstractDualLogEnabledInstrumentable.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.component; import java.util.ArrayList; import org.apache.excalibur.instrument.Instrument; import org.apache.excalibur.instrument.Instrumentable; /** * Utility class to ease the construction of components that can be instrumented * but must also extend AbstractDualLogEnabled. *

* Subclasses should call addInstrument or * addChildInstrumentable as part of the component's * initialization. * * @author Leif Mortenson */ public abstract class AbstractDualLogEnabledInstrumentable extends AbstractDualLogEnabled implements Instrumentable { /** Name of the instrumentable. */ private String m_instrumentableName; /** Stores the instruments during initialization. */ private ArrayList m_instrumentList; /** Stores the child instrumentables during initialization. */ private ArrayList m_childList; /** Flag which is to used to keep track of when the Instrumentable has been registered. */ private boolean m_registered; /*--------------------------------------------------------------- * Constructors *-------------------------------------------------------------*/ /** * Creates a new AbstractLogEnabledInstrumentable. */ protected AbstractDualLogEnabledInstrumentable() { m_registered = false; m_instrumentList = new ArrayList(); m_childList = new ArrayList(); } /*--------------------------------------------------------------- * Methods *-------------------------------------------------------------*/ /** * Adds an Instrument to the list of Instruments published by the component. * This method may not be called after the Instrumentable has been * registered with the InstrumentManager. * * @param instrument Instrument to publish. */ protected void addInstrument( Instrument instrument ) { if( m_registered ) { throw new IllegalStateException( "Instruments can not be added after the " + "Instrumentable is registered with the InstrumentManager." ); } m_instrumentList.add( instrument ); } /** * Adds a child Instrumentable to the list of child Instrumentables * published by the component. This method may not be called after the * Instrumentable has been registered with the InstrumentManager. *

* Note that Child Instrumentables must be named by the caller using the * setInstrumentableName method. * * @param child Child Instrumentable to publish. */ protected void addChildInstrumentable( Instrumentable child ) { if( m_registered ) { throw new IllegalStateException( "Child Instrumentables can not be added after the " + "Instrumentable is registered with the InstrumentManager." ); } m_childList.add( child ); } /*--------------------------------------------------------------- * Instrumentable Methods *-------------------------------------------------------------*/ /** * Gets the name of the Instrumentable. * * @return The name used to identify a Instrumentable. */ public final String getInstrumentableName() { return m_instrumentableName; } /** * 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. *

* 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 final void setInstrumentableName( String name ) { m_instrumentableName = name; } /** * 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 final Instrumentable[] getChildInstrumentables() { m_registered = true; if( m_childList.size() == 0 ) { return Instrumentable.EMPTY_INSTRUMENTABLE_ARRAY; } else { Instrumentable[] children = new Instrumentable[ m_childList.size() ]; m_childList.toArray( children ); return children; } } /** * 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 final Instrument[] getInstruments() { m_registered = true; if( m_instrumentList.size() == 0 ) { return Instrumentable.EMPTY_INSTRUMENT_ARRAY; } else { Instrument[] instruments = new Instrument[ m_instrumentList.size() ]; m_instrumentList.toArray( instruments ); return instruments; } } } -- To unsubscribe, e-mail: For additional commands, e-mail: