mcconnell 02/03/06 10:27:54
Modified: enterprise/tools/src/java/org/apache/avalon/excalibur/service
DefaultServiceManager.java DependencyInfo.java
ServiceFactory.java ServiceLoader.java
ServiceRegistry.java TransientProvider.java
UnitInfo.java package.html
enterprise/tools/src/java/org/apache/demo
DirectoryBlock.java DirectoryBlock.xinfo
DirectoryService.java ReferralBlock.java
ReferralBlock.xinfo ReferralService.java
Added: enterprise/tools/src/java/org/apache/avalon/excalibur/mpool
Pool.java
enterprise/tools/src/java/org/apache/avalon/excalibur/service
AbstractManager.java DefaultComponentManager.java
PooledProvider.java
enterprise/tools/src/java/org/apache/demo copyright.xml
util.java
Log:
static xinfo based usage configuration in place + updated javadoc.
Revision Changes Path
1.1
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/mpool/Pool.java
Index: Pool.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.mpool;
/**
* This interface is to define how a Pool is used. We have determined by
* using the previous Pool implementations that the Pool marker interface
* is considered harmful. When generics are introduced in JDK 1.5, this
* interface will be a prime candidate for those improvements.
*
* <p>
* It is important to realize that some objects are cheaper to simply allow
* the garbage collector to take care of them. Therefore, only pool objects
* that are computationally expensive to create. Prime candidates would be
* Components, JDBC Connection objects, Socket connections, etc.
* </p>
* <p>
* The interface is inspired by both the Mutex acquire/release and the
* structure of the ThreadLocal object. In fact, it would be trivial
* to implement a "ThreadLocal" pool.
* </p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/03/06 18:27:53 $
* @since 4.1.2
*/
public interface Pool
{
/**
* Acquire an instance of the pooled object.
*
* @return the pooled Object instance
*/
Object acquire() throws Exception;
/**
* Release the instance of the pooled object.
*
* @param pooledObject The pooled object to release to the pool.
*/
void release( Object pooledObject );
/**
* Create a new instance of the object being pooled.
*
* @return the pooled Object instance
*/
Object newInstance() throws Exception;
}
1.3 +2 -2
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/DefaultServiceManager.java
Index: DefaultServiceManager.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/DefaultServiceManager.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DefaultServiceManager.java 3 Mar 2002 23:08:26 -0000 1.2
+++ DefaultServiceManager.java 6 Mar 2002 18:27:54 -0000 1.3
@@ -8,7 +8,7 @@
package org.apache.avalon.excalibur.service;
import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.Map;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceException;
@@ -22,7 +22,7 @@
/**
* Construct ServiceManager.
*/
- public DefaultServiceManager( Hashtable providers ) throws Exception
+ public DefaultServiceManager( Map providers )
{
super( providers );
}
1.2 +16 -2
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/DependencyInfo.java
Index: DependencyInfo.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/DependencyInfo.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DependencyInfo.java 3 Mar 2002 15:45:58 -0000 1.1
+++ DependencyInfo.java 6 Mar 2002 18:27:54 -0000 1.2
@@ -15,9 +15,11 @@
* components.
*/
-class DependencyInfo extends ServiceInfo
+class DependencyInfo
{
private String m_role;
+ private ServiceInfo m_service;
+ private Configuration m_config;
/**
* Creation of a new <code<DependencyInfo</code> instance.
@@ -25,8 +27,9 @@
*/
public DependencyInfo( final Configuration config ) throws Exception
{
- super( config.getChild("service") );
m_role = config.getChild("role").getValue();
+ m_service = new ServiceInfo( config.getChild("service") );
+ m_config = config.getChild("configuration");
}
/**
@@ -40,4 +43,15 @@
{
return m_role;
}
+
+ public ServiceInfo getService()
+ {
+ return m_service;
+ }
+
+ public Configuration getConfiguration()
+ {
+ return m_config;
+ }
+
}
1.6 +142 -82
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceFactory.java
Index: ServiceFactory.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceFactory.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ServiceFactory.java 4 Mar 2002 04:47:57 -0000 1.5
+++ ServiceFactory.java 6 Mar 2002 18:27:54 -0000 1.6
@@ -8,6 +8,7 @@
package org.apache.avalon.excalibur.service;
import java.io.File;
+import java.util.Map;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
@@ -48,40 +49,53 @@
import org.apache.avalon.excalibur.mpool.Pool;
/**
- *
+ * The <code>ServiceFactory</code> class provides support for the
+ * instantiation of objects based on supplied service meta-info.
*/
-class ServiceFactory extends AbstractLogEnabled implements Disposable
+class ServiceFactory extends AbstractLogEnabled implements Configurable,
Disposable
{
+ private File m_root;
+ private boolean m_verbose;
+ private Configuration m_config;
+
private ServiceRegistry m_registry;
private Hashtable m_table = new Hashtable();
private Hashtable m_pools = new Hashtable();
private Hashtable m_singletons = new Hashtable();
private Hashtable m_transients = new Hashtable();
- private File m_root;
- private boolean m_verbose;
private Logger m_base_logger;
private Hashtable m_services = new Hashtable();
private Hashtable m_lookup = new Hashtable();
- public ServiceFactory( Configuration config, File base, boolean verbose
) throws Exception
+ public ServiceFactory( File base, boolean verbose ) throws Exception
{
- m_registry = new ServiceRegistry( verbose );
- m_table = initalizeBlockConfigurations( config );
m_root = base;
m_verbose = verbose;
}
- public void enableLogging( Logger logger )
+ public void configure( Configuration config ) throws
ConfigurationException
+ {
+ m_config = config;
+ }
+
+ /**
+ * Initialize the factory.
+ */
+ public void initialize() throws Exception
{
- m_base_logger = logger;
- super.enableLogging( logger.getChildLogger( "factory" ) );
- m_registry.enableLogging( logger.getChildLogger("registry") );
+ m_base_logger = getLogger();
+ super.enableLogging( m_base_logger.getChildLogger( "loader"
).getChildLogger( "factory" ) );
+ m_registry = new ServiceRegistry( m_verbose );
+ m_registry.enableLogging( getLogger().getChildLogger("registry") );
+ m_registry.configure( m_config );
+ m_registry.initialize();
}
/**
* Populates the set of available services based on a supplied
- * vector of jar files.
+ * vector of jar files. The implementation delegates registration
+ * actions to the factories registry.
* @param list a list of jar files
*/
public void register( Vector list ) throws PipelineException
@@ -89,63 +103,86 @@
m_registry.register( list );
}
+ /**
+ * Validates that the set of dependecies declared for a given
+ * implementation can be resolved and that all dependencies
+ * can be validated.
+ * @param info the <code>UnitInfo</code> to validate
+ */
public void validate( UnitInfo info ) throws Exception
{
DependencyInfo[] dependencies = info.getDependencies();
for( int i=0; i<dependencies.length; i++ )
{
- ServiceInfo d = dependencies[i];
+ DependencyInfo d = dependencies[i];
if( m_registry.lookup( d ) == null ) throw new Exception(
- "Could not resolve dependent service " +
d.getInterface().getName()
- + " for block " + info.getClassName() );
+ "Could not resolve dependent service " + d.getRole()
+ + " for block " + info.getName() );
}
}
- private ServiceManager createServiceManager( DependencyInfo[]
dependencies ) throws ServiceException
+ /**
+ * Dynamic creation of a <code>ServiceManager</code> based on a set of
+ * supplied dependencies and container configuration.
+ */
+ private ServiceManager createServiceManager( UnitInfo info, Logger base
)
+ throws ServiceException
{
- Hashtable providers = new Hashtable();
- try
- {
- for( int i=0; i<dependencies.length; i++ )
- {
- DependencyInfo info = dependencies[i];
- providers.put( info.getRole(), getProvider( info ));
- }
- return new DefaultServiceManager( providers );
- }
- catch( Throwable e )
- {
- final String error = "Unexpected exception while attempting to
create a ServiceManager.";
- throw new ServiceException( error, e );
- }
+ return new DefaultServiceManager( getProviders( info, base ) );
}
- private ComponentManager createComponentManager( DependencyInfo[]
dependencies ) throws ServiceException
+ /**
+ * Dynamic creation of a <code>ComponentManager</code> based on a set of
+ * supplied dependencies and container configuration.
+ */
+ private ComponentManager createComponentManager( UnitInfo info, Logger
base )
+ throws ServiceException
{
+ return new DefaultComponentManager( getProviders( info, base ) );
+ }
+
+ /**
+ * Returns a table of providers based on the supplied meta-info and
+ * container configuration.
+ * @param info meta-info about the container
+ * @param composition the container composition configuration
+ */
+ private Map getProviders( UnitInfo unit, Logger base ) throws
ServiceException
+ {
+ DependencyInfo[] dependencies = unit.getDependencies();
Hashtable providers = new Hashtable();
+
try
{
for( int i=0; i<dependencies.length; i++ )
{
DependencyInfo info = dependencies[i];
- providers.put( info.getRole(), getProvider( info ));
+ providers.put( info.getRole(), getProvider( info, base ) );
}
- return new DefaultComponentManager( providers );
+ return providers;
}
catch( Throwable e )
{
- final String error = "Unexpected exception while attempting to
create a ComponentManager.";
+ final String error = "Unexpected exception while attempting to
create a ServiceManager.";
throw new ServiceException( error, e );
}
}
- private Object getProvider( DependencyInfo info ) throws Exception
+ /**
+ * Create a provider implementation for a class identified by a
+ * supplied met-info instance and a configuration.
+ * @param info the dependecy declaration
+ * @param profile the configuration profile
+ */
+ private Object getProvider( DependencyInfo info, Logger base ) throws
Exception
{
UnitInfo block_info = m_registry.lookup( info );
+ if( block_info == null ) throw new IllegalStateException(
+ "Registry returned a null block info.");
//
- // Try to establish the type of object by the interface it
implements.
+ // Establish the type of object.
//
Object provider = null;
@@ -170,12 +207,12 @@
if( provider == null )
{
if( m_verbose ) if( getLogger().isDebugEnabled() )
getLogger().debug(
- "Creating singleton provider for :" +
provider_class.getName());
+ "generating singleton provider" );
// create and pipeline the singleton instance and
// add it to the list of singletons
- Object object = pipeline( block_info, info.getRole() );
+ Object object = execute( block_info, info.getRole(), base
);
provider = new SingletonProvider( object, info.getRole() );
m_singletons.put( provider_class, provider );
}
@@ -187,12 +224,12 @@
if( provider == null )
{
if( m_verbose ) if( getLogger().isDebugEnabled() )
getLogger().debug(
- "Creating pooled provider for :" +
provider_class.getName());
+ "generating pooled provider" );
// create and pipeline the singleton instance and
// add it to the list of singletons
- Object object = pipeline( block_info, info.getRole() );
+ Object object = execute( block_info, info.getRole(), base
);
provider = new PooledProvider( (Pool) object,
info.getRole() );
m_pools.put( provider_class, provider );
}
@@ -210,7 +247,7 @@
if( provider == null )
{
if( m_verbose ) if( getLogger().isDebugEnabled() )
getLogger().debug(
- "Creating transient provider for :" +
provider_class.getName());
+ "generating transient provider" );
// create and pipeline the singleton instance and
// add it to the list of singletons
@@ -222,8 +259,39 @@
}
}
+ public Object pipeline( UnitInfo info ) throws Exception
+ {
+ return pipeline( info, info.getName() );
+ }
+
public Object pipeline( UnitInfo info, String role ) throws Exception
{
+ Logger logger = getLogger();
+
+ try
+ {
+ return execute( info, role, m_base_logger );
+ }
+ catch( Exception e )
+ {
+ enableLogging( logger );
+ throw e;
+ }
+ finally
+ {
+ enableLogging( logger );
+ }
+ }
+
+ private Object execute( UnitInfo info, String role, Logger logger )
throws Exception
+ {
+
+ if( m_verbose ) if( getLogger().isDebugEnabled() ) getLogger().debug(
+ "pipelining " + role + " (" + info.getClassName() + ")");
+
+ enableLogging( getLogger().getChildLogger( role ) );
+
+ Configuration config = info.getConfiguration();
//
// create and pipeline the new instance
@@ -240,18 +308,15 @@
throw new PipelineException( error +
info.getBaseClass().getName(), e );
}
- if( m_verbose ) if( getLogger().isDebugEnabled() ) getLogger().debug(
- "pipeline for role: " + role + ", implementation: " +
m_object.getClass().getName() );
-
-
//
// assign a logging channel
//
+ Logger base = logger.getChildLogger( role );
if( m_object instanceof LogEnabled ) try
{
- if( m_verbose ) getLogger().debug( "applying logger to " + role
);
- ((LogEnabled)m_object).enableLogging(
m_base_logger.getChildLogger( role ) );
+ if( m_verbose ) getLogger().debug( "applying logger" );
+ ((LogEnabled)m_object).enableLogging( base );
}
catch( Throwable e )
{
@@ -265,10 +330,8 @@
if( m_object instanceof Configurable ) try
{
- if( m_verbose ) getLogger().debug( role + " configuration" );
- Configuration defaults = info.getDefaultConfiguration();
- Configuration primary = getConfigurationForClass(
info.getClassName() );
- ((Configurable)m_object).configure( new CascadingConfiguration(
primary, defaults ));
+ if( m_verbose ) getLogger().debug( "configuration" );
+ ((Configurable)m_object).configure( config );
}
catch( Throwable e )
{
@@ -277,9 +340,9 @@
}
else if( m_object instanceof Parameterizable ) try
{
- if( m_verbose ) getLogger().debug( role + " parameterization" );
+ if( m_verbose ) getLogger().debug( "parameterization" );
((Parameterizable)m_object).parameterize(
- Parameters.fromConfiguration( getConfigurationForClass(
info.getClassName() ) ) );
+ Parameters.fromConfiguration( config ) );
}
catch( Throwable e )
{
@@ -294,7 +357,7 @@
if( m_object instanceof Contextualizable ) try
{
- if( m_verbose ) getLogger().debug( role + " contextualization" );
+ if( m_verbose ) getLogger().debug( "contextualization" );
Context context = new ServiceContext(
new String[0], m_root, info.getClassName() );
((Contextualizable)m_object).contextualize( context );
@@ -311,9 +374,8 @@
if( m_object instanceof Serviceable ) try
{
- if( m_verbose ) getLogger().debug( role + " service composition"
);
- DependencyInfo[] dependencies = info.getDependencies();
- ServiceManager manager = createServiceManager( dependencies );
+ if( m_verbose ) getLogger().debug( "composition" );
+ ServiceManager manager = createServiceManager( info, base );
((Serviceable)m_object).service( manager );
}
catch( Throwable e )
@@ -323,9 +385,8 @@
}
else if( m_object instanceof Composable ) try
{
- if( m_verbose ) getLogger().debug( role + " composition" );
- DependencyInfo[] dependencies = info.getDependencies();
- ComponentManager manager = createComponentManager( dependencies
);
+ if( m_verbose ) getLogger().debug( "composition" );
+ ComponentManager manager = createComponentManager( info, base );
((Composable)m_object).compose( manager );
}
catch( Throwable e )
@@ -340,7 +401,7 @@
if( m_object instanceof Initializable ) try
{
- if( m_verbose ) getLogger().debug( role + " initilization" );
+ if( m_verbose ) getLogger().debug( "initilization" );
((Initializable)m_object).initialize();
}
catch( Throwable e )
@@ -356,7 +417,7 @@
if( m_object instanceof Startable ) try
{
- if( m_verbose ) getLogger().debug( "starting " + role );
+ if( m_verbose ) getLogger().debug( "starting" );
((Startable)m_object).start();
}
catch( Throwable e )
@@ -369,7 +430,7 @@
}
/**
- * Notification byb the controlling application to dispose of the
+ * Notification by the controlling application to dispose of the
* service factory.
*/
public void dispose()
@@ -454,33 +515,32 @@
/**
* Creates a hashtable of configurations keyed by the block implmentation
- * class name. The configuration file is ssumed to in the following form.
+ * class name. The configuration children are assumed to be in the
following form.
* <pre>
- * <block class="org.apache.demo.MyFirstBlock">
- * <any-child value="red"/>
+ * <font color="blue"><i><--
+ * Modify/suppliment the ReferralBlock default configuration.
+ * --></i></font>
+ *
+ * <block class="org.apache.ReferralBlock">
+ * <profile name="directory">
+ * <policy value="COUNT"/>
+ * </profile>
+ * <any-child some-value="red"/>
* </block>
*
* <k class="org.apache.demo.MySecondBlock"/>
* </pre>
*/
- private Hashtable initalizeBlockConfigurations( Configuration config )
throws ConfigurationException
+ private Hashtable getComposition( Configuration config ) throws
ConfigurationException
{
- Hashtable configs = new Hashtable();
- Configuration[] blocks = config.getChildren("block");
- for( int i=0; i<blocks.length; i++ )
+ Hashtable table = new Hashtable();
+ Configuration[] profiles = config.getChildren("profile");
+ for( int i=0; i<profiles.length; i++ )
{
- final String key = blocks[i].getAttribute("class");
- configs.put( key, blocks[i] );
+ final String key = profiles[i].getAttribute("role");
+ table.put( key, profiles[i] );
}
- return configs;
+ return table;
}
-
- private Configuration getConfigurationForClass( String name )
- {
- Configuration config = (Configuration) m_table.get( name );
- if( config != null ) return config;
- return new DefaultConfiguration( name, null );
- }
-
}
1.5 +46 -54
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceLoader.java
Index: ServiceLoader.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceLoader.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ServiceLoader.java 4 Mar 2002 09:06:26 -0000 1.4
+++ ServiceLoader.java 6 Mar 2002 18:27:54 -0000 1.5
@@ -65,27 +65,21 @@
* <tr>
* <td width="20%" valign="top">Configurable</td>
* <td>
- * The configuration phase supplies static information to the pipeline
processor
- * that may be used to configure target and supporting services. During the
loading
- * of a component, the pipline processor will attempt to locate a block
configuration
- * based on the class name of the block. If there is no configuration
matching the
- * class name an empty configuration will be supplied to the component or a
component
- * the the target component is dependent on (assuming the component in
question
- * implements the Configurable interface).
+ * <p>The configuration phase supplies static information to the pipeline
processor
+ * that may be used to configure the target component. The supplied
configuration
+ * instance will be assigned as the primary configuration on a
<code>CascadingConfiguration</code>
+ * backed by the default configuration declared under the component .xinfo
resource.</p>
*
* <pre>
* <config>
*
- * <block class="org.apache.DirectoryBlock">
- * <-- block specific content -->
- * </block>
- *
- * <block class="org.apache.ActivatorBlock">
- * <-- block specific content -->
- * </block>
+ * <about>This is a sample entry in configuration.</about>
*
* </config>
* </pre>
+ * <p><strong>Note:</strong> The ability to suppliment configurations
associated with component
+ * dependencies is not available at this time. The above configuration is
limited in scope to
+ * the modification of the target component only.</p>
* </td></tr>
* <tr>
* <td width="20%" valign="top">Contextualizable</td>
@@ -97,22 +91,22 @@
* <code>ServiceLoaderContext</code>:
* <p><table border="0" cellpadding="3" cellspacing="0" width="100%">
* <tr>
- * <td width="20%" valign="top"><code>ARGS_KEY</code></td>
+ * <td width="30%" valign="top"><code>ARGS_KEY</code></td>
* <td>
* Contains the command line arguments as a <code>String[]</code>.
* </td></tr>
* <tr>
- * <td width="20%" valign="top"><code>BASE_DIRECTORY_KEY</code></td>
+ * <td valign="top"><code>BASE_DIRECTORY_KEY</code></td>
* <td>
* Contains the application base directory <code>File</code>.
* </td></tr>
* <tr>
- * <td width="20%" valign="top"><code>TARGET_KEY</code></td>
+ * <td valign="top"><code>TARGET_KEY</code></td>
* <td>
* Contains the name of the target class to be instantiated.
* </td></tr>
* <tr>
- * <td width="20%" valign="top"><code>INCLUDES_KEY</code></td>
+ * <td valign="top"><code>INCLUDES_KEY</code></td>
* <td>
* Contains an array of jar files that will be added to the pipeline
classloader.
* Jar files included in the array will be checked for block manifest
entries. If
@@ -120,7 +114,7 @@
* that may be instantiated during the recursive dependecy resolution
process.
* </td></tr>
* <tr>
- * <td width="20%" valign="top"><code>DISPOSAL_POLICY_KEY</code></td>
+ * <td valign="top"><code>DISPOSAL_POLICY_KEY</code></td>
* <td>
* A <code>Boolean</code> value that is applied on completionof the startup
of a
* <code>Startable</code> component. If the value TRUE, the component is
stopped
@@ -130,11 +124,8 @@
* <code>Startable</code> target component are immediately terminated
(providing a
* useful for component testing during development cycles).
* </td></tr>
- * <td width="20%" valign="top"><code>LOGGING_PRIORITY_KEY</code></td>
- * <td>
- * Contains the logging priority to be applied during the pipeline session.
- * </td></tr>
- * <td width="20%" valign="top"><code>VERBOSE_POLICY_KEY</code></td>
+ * <tr>
+ * <td valign="top"><code>VERBOSE_POLICY_KEY</code></td>
* <td>
* If this value is TRUE, debug logging entries from the pipeline processor
will be
* if the overall logging priority permits this. If FALSE (the default), the
logging
@@ -210,9 +201,9 @@
* <p><table border="1" cellpadding="3" cellspacing="0" width="100%">
* <tr bgcolor="#ccccff">
* <td colspan="2"><b>Command Line Parameters and Arguments</b></td>
- * <tr><td
width="20%"><b>Parameter</b></td><td><b>Description</b></td></tr>
+ * <tr><td
width="30%"><b>Parameter</b></td><td><b>Description</b></td></tr>
* <tr>
- * <td width="20%" valign="top"><code>-target
<class-name></code></td>
+ * <td valign="top"><code>-target <class-name></code></td>
* <td>
* <p>The class to instantiate. If the class exposes any Avalon
lifecycle interface
* (such as <code>Configurable</code>, <code>Contextualizable</code>,
<code>Serviceable</code>,
@@ -221,32 +212,32 @@
* </p>
* </td></tr>
* <tr>
- * <td width="20%"
valign="top"><code><supporting-jar-files></code></td>
+ * <td valign="top"><code><supporting-jar-files></code></td>
* <td>
* <p>A list of space seperated jar files that will be added to the
pipeline
* as supporting classes and components. Any jar file included in the
list
* that contains an Avalon <code>Block</code> manifest will be registered
as
* an available service when resolving component dependecies.</p>
* </td></tr>
- * <tr><td width="20%"><code>-verbose <boolean></code></td>
+ * <tr><td valign="top"><code>-verbose <boolean></code></td>
* <td>
* <p>A value of <code>true</code> will force debug level logging of the
actual pipeline
* processor. A value of <code>false</code> will disable pipeline debug
priority logging.
* Visibility of logging infomration is dependent on the level supplied
under the
* <code>priority</code parameter.</p>
* </td></tr>
- * <tr><td width="20%" valign="top"><code>-priority
<priority></code></td>
+ * <tr><td valign="top"><code>-priority <priority></code></td>
* <td>
* <p>Declaration of the logging priority to use during pipeline
execution. Valid values
* include FATAL_ERROR, ERROR, WARN, INFO, and DEBUG. </p>
* </td></tr>
- * <tr><td width="20%" valign="top"><code>-dispose
<boolean></code></td>
+ * <tr><td valign="top"><code>-dispose <boolean></code></td>
* <td>
* If the target component is <code>Startable</code>, and the dispose
argument is <code>FALSE</code> the
* component will be treated as a server and will continue to run
following initialization.
* Otherwise, the component will be disposed of.
* </td></tr>
- * <tr><td width="20%" valign="top"><code>-configuration
<file-path></code></td>
+ * <tr><td valign="top"><code>-configuration <file-path></code></td>
* <td>
* Optional parameter naming a file to be used as the configuration
source.
* </td></tr>
@@ -262,11 +253,15 @@
CLI cli = new CLI( args );
Hierarchy hierarchy = createBootstrapLogger(
cli.getLoggingPriority() );
- Logger logger = new LogKitLogger( hierarchy.getLoggerFor(
"loader" ) );
+ Logger logger = new LogKitLogger( hierarchy.getLoggerFor( "" ) );
File path = cli.getConfigurationPath();
- Configuration config = new DefaultConfiguration("-", null );
- if( path != null ) config = getRuntimeConfiguration( path );
+ Configuration config = null;
+ if( path != null )
+ {
+ config = getRuntimeConfiguration( path );
+ }
+ if( config == null ) config = new
DefaultConfiguration("profile", null );
pipeline = new ServiceLoader();
pipeline.enableLogging( logger );
@@ -276,7 +271,7 @@
}
catch( IllegalParameterException ipe )
{
- System.err.println( "IPE: " + ipe.getMessage() );
+ System.err.println( ipe.getMessage() );
}
catch( PipelineException e )
{
@@ -346,12 +341,19 @@
if( m_target == null ) throw new PipelineException(
"The pipeline task required attribute 'target' has not been not
supplied.");
+ //
+ // setup the factory
+ //
+
try
{
if( m_classloader == null ) m_classloader = createClassloader();
- m_factory = new ServiceFactory( m_config,
+ m_factory = new ServiceFactory(
new File( System.getProperty("user.dir") ), getVerbose() );
m_factory.enableLogging( getLogger() );
+ m_factory.configure( m_config );
+ m_factory.initialize();
+ enableLogging( getLogger().getChildLogger("loader") );
}
catch( Throwable e )
{
@@ -408,7 +410,7 @@
}
catch( Throwable e )
{
- final String error = "Service loader exception encounter while
preparing services.";
+ final String error = "Coould not complete service registration.";
throw new PipelineException( error, e );
}
@@ -417,22 +419,12 @@
// service manager if needed
//
- Class target;
UnitInfo info;
try
{
- target = m_classloader.loadClass( m_target );
- }
- catch( Throwable e )
- {
- final String error = "Could not load target class: " + m_target;
- throw new PipelineException( error , e );
- }
-
- try
- {
- info = ServiceRegistry.createUnitInfo( target );
- if( getVerbose() ) if( getLogger().isDebugEnabled() )
getLogger().debug( "validating target\n" + info );
+ info = new UnitInfo( new UnitInfo( m_target.replace('.','/')),
m_config );
+ if( getVerbose() && getLogger().isDebugEnabled() )
+ getLogger().debug( "validating target");
try
{
m_factory.validate( info );
@@ -455,7 +447,7 @@
try
{
- m_object = m_factory.pipeline( info, "target" );
+ m_object = m_factory.pipeline( info );
}
catch( Throwable e )
{
@@ -487,7 +479,7 @@
if( m_terminated ) return;
m_terminated = true;
if( m_object == null ) return;
- if( getVerbose() ) if( getLogger().isDebugEnabled() )
getLogger().debug(
+ if( getVerbose() && getLogger().isDebugEnabled() )
getLogger().debug(
"terminating " + m_object.getClass().getName() );
if( m_object instanceof Startable )
@@ -535,7 +527,7 @@
m_disposed = true;
- if( getVerbose() ) if( getLogger().isDebugEnabled() )
getLogger().debug( "loader disposal" );
+ if( getVerbose() && getLogger().isDebugEnabled() )
getLogger().debug( "loader disposal" );
if( m_factory instanceof Disposable )
{
try
@@ -601,7 +593,7 @@
* if sucessfull, remove it from the stack - on completion
* the stack should be less than its original size - recursivly
* invoke load until the stack is empty.
- * @param stack a <code>Vecor</code> containing a sequence of jar files
+ * @param stack a <code>Vector</code> containing a sequence of jar files
* to be added to the classloader.
*/
private void load( Vector stack )
1.3 +39 -82
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceRegistry.java
Index: ServiceRegistry.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/ServiceRegistry.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ServiceRegistry.java 4 Mar 2002 04:39:37 -0000 1.2
+++ ServiceRegistry.java 6 Mar 2002 18:27:54 -0000 1.3
@@ -23,30 +23,47 @@
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.CascadingException;
+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;
/**
- * Internal class supporting registration of available services.
+ * Implementation class that provides support for the registration of
+ * meta information about available service implementations.
*/
-class ServiceRegistry extends AbstractLogEnabled
+class ServiceRegistry extends AbstractLogEnabled implements Configurable
{
+ private Configuration m_config;
private Vector m_repository = new Vector();
private UnitInfo[] m_block_info_set;
private Hashtable m_table;
+ private Hashtable m_lookup;
private boolean m_verbose = false;
+ /**
+ * Creation of a new <code>ServiceRegistry</code>
+ * @param verbose if TRUE, enable DEBUG message priority logging
+ */
public ServiceRegistry( boolean verbose )
{
m_verbose = verbose;
}
- public void register( UnitInfo info )
+ public void configure( Configuration config )
{
- m_repository.add( info );
+ m_config = config;
+ }
+
+ /**
+ * Initialize the registry.
+ */
+ public void initialize() throws Exception
+ {
+ if( getLogger() == null ) throw new IllegalStateException("Factory
logging has not been enabled.");
+ if( m_config == null ) throw new IllegalStateException("Factory has
not been configured.");
}
/**
@@ -61,19 +78,15 @@
while( enum.hasMoreElements() )
{
File target = (File) enum.nextElement();
- UnitInfo[] blocks = register( target );
- if( m_verbose ) if( blocks.length > 0 ) if(
getLogger().isDebugEnabled() )
- getLogger().debug(
- "file: " + target + " has " + blocks.length + " block
declarations" );
+ register( target );
}
}
/**
* Register a jar file with the registry.
* @param file the jar file to register
- *
*/
- public UnitInfo[] register( File target ) throws PipelineException
+ public void register( File target ) throws PipelineException
{
UnitInfo[] blocks = getUnitInfo( target );
for( int i=0; i<blocks.length; i++ )
@@ -81,22 +94,33 @@
UnitInfo info = blocks[i];
m_repository.add( info );
}
- return blocks;
}
- public UnitInfo lookup( ServiceInfo info )
+ /**
+ * Lookup the meta info for an implementation based
+ * on a supplied service requirement.
+ * @param info meta info describing the required implemenation info
+ (return null if no implementation info matches the request)
+ * @return UnitInfo meta information about an available implementation
+ */
+ public UnitInfo lookup( DependencyInfo info )
{
Enumeration enum = m_repository.elements();
while( enum.hasMoreElements() )
{
UnitInfo block_info = (UnitInfo) enum.nextElement();
- if( block_info.provides( info ) ) return block_info;
+ if( block_info.provides( info.getService() ) )
+ {
+ Configuration config = info.getConfiguration();
+ return new UnitInfo( block_info, config );
+ }
}
return null;
}
/**
- * Returns an array of block infos provided by the jar file.
+ * Returns an array of block infos provided by a supplied jar file.
+ * @param file a jar file
* @return a <code>UnitInfo[]<code> provided by the jar file
*/
private UnitInfo[] getUnitInfo( File file ) throws PipelineException
@@ -113,25 +137,8 @@
String[] blocks = getBlocks( file );
for( int i=0; i<blocks.length; i++ )
{
- //
- // get the block implementation class and check for
- // dependecies - if dependencies > 0 then ignore it
- // otherwise pipeline the block and add it as a
- // service
- //
-
final String path = blocks[i];
- Configuration config = loadConfiguration( path + ".conf",
true );
- Configuration xinfo = loadConfiguration( path + ".xinfo",
false );
- if( xinfo == null ) throw new IllegalStateException(
- "Could not locate <class>.xinfo resource for: " + path
);
-
- final String classname = path.replace('/','.');
- Class block =
Thread.currentThread().getContextClassLoader().loadClass( classname );
- vector.add( new UnitInfo( block, xinfo, config ));
- //System.out.println("LOADED CONFIG: " + path + ".conf" + ",
" + config.getName() );
- //System.out.println("CHILDREN: " +
config.getChildren().length );
- //System.out.println("PROFILE: " +
config.getChild("profile").getChildren().length );
+ vector.add( new UnitInfo( path ) );
}
}
catch( Throwable e )
@@ -142,31 +149,6 @@
return (UnitInfo[]) vector.toArray( new UnitInfo[0] );
}
- /**
- * Returns a single block info relative to a supplied class.
- * @return a <code>UnitInfo<code> for the class.
- */
- public static UnitInfo createUnitInfo( Class block ) throws
PipelineException
- {
- try
- {
- String path = block.getName().replace('.','/');
- Configuration config = loadConfiguration( path + ".conf", true );
- Configuration xinfo = loadConfiguration( path + ".xinfo", false
);
- if( xinfo == null ) xinfo = new DefaultConfiguration("", null);
-
- //System.out.println("X-LOADED CONFIG: " + path + ".conf" + ", "
+ config.getName() );
- //System.out.println("X-CHILDREN: " +
config.getChildren().length );
- //System.out.println("X-PROFILE: " +
config.getChild("profile").getChildren().length );
-
- return new UnitInfo( block, xinfo, config );
- }
- catch( Throwable e )
- {
- throw new CascadingRuntimeException(
- "Unexpected error while attempting to resolve block info for a
class: " + block.getName(), e );
- }
- }
//===============================================================================
// utilities
@@ -218,31 +200,6 @@
{
return (String[]) vector.toArray( new String[0] );
}
- }
-
- /**
- * Returns a configuration resource form a jar file.
- * @param path the package path to the resource e.g. net/osm/config.xml
- * @param create if TRUE and no configuration found, return an empty
- * configuration, else, return null
- * @exception ConfigurationException if there is a problem
- */
- private static Configuration loadConfiguration( String path, boolean
create )
- throws ConfigurationException
- {
- try
- {
- DefaultConfigurationBuilder builder = new
DefaultConfigurationBuilder( );
- InputStream is =
Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
- if( is != null ) return builder.build( is );
- if( create ) return new DefaultConfiguration("-",null);
- return null;
- }
- catch( Throwable e )
- {
- final String error = "Unexpected exception while attempting to
load a configuration from path: ";
- throw new ConfigurationException( error + path, e );
- }
}
}
1.2 +2 -0
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/TransientProvider.java
Index: TransientProvider.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/TransientProvider.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TransientProvider.java 3 Mar 2002 15:45:58 -0000 1.1
+++ TransientProvider.java 6 Mar 2002 18:27:54 -0000 1.2
@@ -8,6 +8,7 @@
package org.apache.avalon.excalibur.service;
import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.configuration.Configuration;
/**
* A <code>TransientProvider</code> is a provider of transient services. A
@@ -19,6 +20,7 @@
private ServiceFactory m_factory;
private UnitInfo m_info;
private boolean m_disposed;
+ private Configuration m_config;
public TransientProvider( ServiceFactory factory, UnitInfo info, String
role )
{
1.3 +117 -15
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/UnitInfo.java
Index: UnitInfo.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/UnitInfo.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- UnitInfo.java 3 Mar 2002 23:08:26 -0000 1.2
+++ UnitInfo.java 6 Mar 2002 18:27:54 -0000 1.3
@@ -8,10 +8,17 @@
package org.apache.avalon.excalibur.service;
import java.util.Vector;
+import java.io.InputStream;
+import java.io.IOException;
+
import org.apache.avalon.framework.CascadingException;
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.excalibur.mpool.Pool;
+import org.apache.avalon.excalibur.configuration.CascadingConfiguration;
+
/**
* Meta information about a <code>Serviceable</code> component.
*/
@@ -23,13 +30,11 @@
public static final int TRANSIENT_LIFETIME_POLICY = 2;
private Class m_block;
- private Configuration m_xinfo;
private Configuration m_config;
private ServiceInfo[] m_services;
private DependencyInfo[] m_dependencies;
- private boolean m_installed = false;
- private Object m_object;
private int m_policy = SINGLETON_LIFETIME_POLICY;
+ private String m_name;
/**
* Creation of a new UnitInfo based a xinfo configuration
@@ -64,14 +69,18 @@
* </pre>
*
* @param block the implementation class
- * @param the xinfo meta-information in the form of a Configuration
- * @param the default component configuration
+ * @param xinfo the xinfo meta-information in the form of a Configuration
+ * @param runtime the runtime profile
+ * @param profile the default implementation profile
*/
- public UnitInfo( Class block, Configuration xinfo, Configuration config
) throws Exception
+ public UnitInfo( Class block, Configuration xinfo ) throws Exception
{
m_block = block;
- m_xinfo = xinfo;
- m_config = config;
+
+ //
+ // create the list of service provided by block implementation
+ //
+
try
{
Configuration[] services =
xinfo.getChild("services").getChildren("service");
@@ -86,6 +95,11 @@
{
throw new CascadingException( "Could not construct service
information.", e );
}
+
+ //
+ // create the list of computational dependecies
+ //
+
try
{
Configuration[] dependencies =
xinfo.getChild("dependencies").getChildren("dependency");
@@ -101,6 +115,10 @@
throw new CascadingException( "Could not construct dependency
information.", e );
}
+ //
+ // resolve the implementation policy
+ //
+
String policy =
xinfo.getChild("implementation").getAttribute("policy","OTHER");
if( policy.equalsIgnoreCase( "SINGLETON" ) )
{
@@ -121,6 +139,52 @@
m_policy = TRANSIENT_LIFETIME_POLICY;
}
}
+
+ //
+ // get the default configuration
+ //
+
+ m_config = xinfo.getChild("configuration");
+ String base = m_config.getAttribute("extends", null );
+ if( base != null )
+ {
+ Configuration c = loadConfiguration( base );
+ m_config = new CascadingConfiguration( m_config, c );
+ }
+
+ //
+ // get the default name
+ //
+
+ m_name = xinfo.getChild("block").getAttribute("name", getClassName()
);
+
+ }
+
+ /**
+ * Creation of a new <code>UnitInfo</code> based on an existing
+ * info and supplimentary configuration. The implementation will
+ * assigns the supplied configuration as the primary configuration
+ * backed by the info current configuration.
+ * @param info, the primary <code>UnitInfo</code>
+ * @param config, a configuration to assign as the primary
+ * configuration for the created info
+ * @return UnitInfo an equivalent <code>UnitInfo</code> with a
+ * <code>CascadingConfiguration</code> in which the supplied
+ * configuration is primary, backed by the supplied unit configuration
+ */
+ public UnitInfo( UnitInfo info, Configuration config )
+ {
+ m_block = info.getBaseClass();
+ m_config = new CascadingConfiguration( config,
info.getConfiguration() );
+ m_services = info.getServices();
+ m_dependencies = info.getDependencies();
+ m_policy = info.getPolicy();
+ m_name = info.getName();
+ }
+
+ public UnitInfo( String path ) throws Exception
+ {
+ this( loadClass( path ), loadConfiguration( path + ".xinfo" ) );
}
/**
@@ -198,22 +262,32 @@
}
/**
- * Return the default configuration.
- * @return the default configuration
+ * Returns the default configuration.
+ * @return Configuration the default configuration
*/
- public Configuration getDefaultConfiguration()
+ public Configuration getConfiguration()
{
return m_config;
}
/**
+ * Returns the block name.
+ * @return String the block name
+ */
+ public String getName()
+ {
+ return m_name;
+ }
+
+ /**
* Returns a string representation of the descriptor.
* @return stringified representation
*/
public String toString()
{
final StringBuffer buffer = new StringBuffer();
- buffer.append( " block: " + getClassName() );
+ buffer.append( " name: " + getName() );
+ buffer.append( "\n class: " + getClassName() );
ServiceInfo[] services = getServices();
for( int i=0; i<services.length; i++ )
{
@@ -223,12 +297,40 @@
DependencyInfo[] dependencies = getDependencies();
for( int i=0; i<dependencies.length; i++ )
{
- buffer.append( "\n dependecy: "
+ buffer.append( "\n dependency: "
+ "role: " + dependencies[i].getRole()
- + ", service: " + dependencies[i].getInterface().getName()
- + ", version: " + dependencies[i].getVersion() );
+ + ", service: " +
dependencies[i].getService().getInterface().getName()
+ + ", version: " + dependencies[i].getService().getVersion() );
}
return buffer.toString();
+ }
+
+ /**
+ * Returns a configuration resource form a jar file.
+ * @param path the package path to the resource e.g. net/osm/xinfo.xml
+ * @exception ConfigurationException if there is a problem
+ */
+ private static Configuration loadConfiguration( String path )
+ throws ConfigurationException
+ {
+ try
+ {
+ DefaultConfigurationBuilder builder = new
DefaultConfigurationBuilder( );
+ InputStream is =
Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
+ if( is != null ) return builder.build( is );
+ throw new ConfigurationException( "Could not locate
configuration from path: " + path );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected exception while attempting to load .xinfo
configuration from path: ";
+ throw new ConfigurationException( error + path, e );
+ }
+ }
+
+ private static Class loadClass( final String path ) throws Exception
+ {
+ return Thread.currentThread().getContextClassLoader().loadClass(
path.replace('/','.'));
}
}
1.5 +32 -22
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/package.html
Index: package.html
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/package.html,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- package.html 3 Mar 2002 23:34:40 -0000 1.4
+++ package.html 6 Mar 2002 18:27:54 -0000 1.5
@@ -82,10 +82,10 @@
<blockinfo>
<font color="blue"><i><!--
- Block version.
+ Block name and implementation version.
--></i></font>
- <block>
+ <block name="referral">
<version>1.0</version>
</block>
@@ -100,7 +100,7 @@
<font color="blue"><i><!--
A service declaration includes a class name (typically an
interface)
and a service version identifier. Service versions may have up to
- three fiels (e.g. 1.1.3).
+ three fields (e.g. 1.1.3).
--></i></font>
<service name="org.apache.ReferralService" version="1.0" />
@@ -122,44 +122,54 @@
establish and provide the dependencies via the component
Serviceable
implementation. The role name corresponds to the identifying
string
that the component implementation will use to lookup a service from
- a service manager during the serviceable lifecycle phase.
+ a service manager during the serviceable or composable lifecycle
phase.
--></i></font>
<dependency>
+
<role>directory</role>
<service name="org.apache.DirectoryService"
version="1.0"/>
+
+ <font color="blue"><i><!--
+ An optional configuration element may be declared as part of a
+ dependency. The configuration will be applied as the primary
+ configuration backaged by the supporting services default
+ configuration.
+ --></i></font>
+
+ <configuration>
+ <policy value="COUNT"/>
+ </configuration>
+
</dependency>
</dependencies>
<font color="blue"><i><!--
Component implementation policy may be one of the following:
- (a) SINGLETON, service is available for the lifetime of the manager
- (b) TRANSIENT, manager is a factory of transient service instances
- (c) OTHER, (default) The container will check if the class implements
+ (a) <strong>SINGLETON</strong>, service is available for the lifetime
of the manager
+ (b) <strong>TRANSIENT</strong>, manager is a factory of transient
service instances
+ (c) <strong>OTHER</strong>, (default) The container will check if the
class implements
the org.apache.excalibur.mpool.Pool interface. If true,
<code>lookup</code>
and <code>release</code> invocations will be redirected to the pools
<code>acquire</code> and
<code>release</code> methods - otherwise, the class will be registered
under the
- TRANSIENT policy.
+ <strong>TRANSIENT</strong> policy.
--></i></font>
<implementation policy="SINGLETON" />
- </blockinfo>
-</pre>
+ <font color="blue"><i><!--
+ The default configuration for a component is declared under the
<strong>configuration</strong>
+ element. This configuration value may be modified and/or supplimented
by a
+ configuration supplied by a managing container.
+ --></i></font>
+
+ <configuration extends=org/apache/"copyright.xml">
+ <about>Example default configuration for this
component.</about>
+ </configuration>
-<h4>The <classname>.conf File</h4>
-<p>The pipeline processor provides support for the automated retrieval of
default
-configurations for a component. During lifecycle processing, the pipeline
processor
-will attempt to locate a configuration resource with the same path and name
as
-the component implementation class. For example, for the component
<strong><code>org/apache/RefferalBlock.class</code></strong>, the
implementation will look for
-a default configuration under the resource path
<strong><code>org/apache/RefferalBlock.conf</code></strong>.
-During the configuration stage, the pipeline processor will supply the
component with
-a <code>CascadingConfiguration</code> where the primary configuration is
configuration
-derived from the pipeline processor configuration, and a default
configuration corresponding
-to the .conf configuration.
-</p>
-<pre>
+ </blockinfo>
+</pre>
</body>
1.1
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/AbstractManager.java
Index: AbstractManager.java
===================================================================
/*
* File: DefaultServiceManager.java
* License: etc/LICENSE.TXT
* Copyright: Copyright (C) The Apache Software Foundation. All rights
reserved.
* Copyright: OSM SARL 2002, All Rights Reserved.
*/
package org.apache.avalon.excalibur.service;
import java.util.Enumeration;
import java.util.Map;
import java.util.Hashtable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceException;
/**
* Internal helper class the handles the functional requirements of
* both ComponetManager and ServiceManager.
*/
class AbstractManager
{
/**
* Hashtable containing service providers keyed by role name.
* The manager use the providers in this table to aquire services
* in response to <code>lookup</code> invocations. Provider
* types fall into one of the following three catagories:
*
* <table>
* <tr><td><b>Policy</b></td><td><b>Description</b></td><tr>
* <tr><td>SINGLETON_LIFETIME_POLICY</td><td>
* Service of the type singleton are distinguished by the fact
* that they do not inherit from Pool or Transient. The singleton
* provider object is a reference to the singleton service and is
* return directly by the implemetation on invocation of lookup.
* </td>
* <tr><td>POOLED_LIFETIME_POLICY</td><td>
* Pooled services implement the Pool interface. The service
* resolves lookup aquires the pooled service by invoking
* <code>checkout</code> on the pool implementation. Clients
* using pooled services are required to release services using
* the manager <code>release</code> method. The implementation will
* attempt to locate the issuing pool and release the object on
* behalf of the client.
* </td>
* <tr><td>TRANSIENT_LIFETIME_POLICY</td><td>
* A transient provider is factory from which new instances are
* created and pipelined following a invocation of <code>lookup</code>.
* The invocing client is totally responsible for service disposal.
* </td>
*/
private Map m_providers;
/**
* Internal table that maintains a mapping betyween pooled objects and
* the issuing pool. The object is used as the key to lookup the pool
* when handling object release.
*/
private Hashtable m_pooled_table = new Hashtable();
public AbstractManager( Map providers )
{
m_providers = providers;
}
public boolean has( String role )
{
return (m_providers.get( role ) != null );
}
public Object resolve( String role ) throws ServiceException
{
Object provider = m_providers.get( role );
if( provider == null ) throw new ServiceException(
"Could not locate a provider for the role: " + role );
if( provider instanceof TransientProvider )
{
//
// return a transient instance
//
return ((TransientProvider)provider).create( );
}
else if( provider instanceof PooledProvider )
{
//
// return a pooled service after registering the usage
//
Object object = null;
try
{
object = ((PooledProvider)provider).acquire( );
}
catch( Throwable e )
{
final String error = "Pool implementation error.";
throw new ServiceException( error, e );
}
finally
{
// it is invalid for a pool to provide the same object without
// it being released beforehand
if( m_pooled_table.get( object ) != null )
{
final String error =
"Manager has an existing reference to an aquired object
from '"
+ role + "'.";
throw new ServiceException( error );
}
m_pooled_table.put( object, provider );
return object;
}
}
else
{
//
// return a singleton service
//
return ((SingletonProvider)provider).provide( );
}
}
/**
* Release a pooled object.
* @param object a pooled object
*/
public void disgard( Object object )
{
//
// release a pooled service
//
PooledProvider provider = (PooledProvider) m_pooled_table.get( object
);
if( provider != null ) provider.release( object );
}
}
1.1
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/DefaultComponentManager.java
Index: DefaultComponentManager.java
===================================================================
/*
* File: DefaultServiceManager.java
* License: etc/LICENSE.TXT
* Copyright: Copyright (C) The Apache Software Foundation. All rights
reserved.
* Copyright: OSM SARL 2002, All Rights Reserved.
*/
package org.apache.avalon.excalibur.service;
import java.util.Enumeration;
import java.util.Map;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentException;
/**
* Internal helper class the implements the <code>ComponentManager</code>
interface and
* is supplied to dynamically created componets during lifecycle pipeline
processing.
*/
class DefaultComponentManager extends AbstractManager implements
ComponentManager
{
public DefaultComponentManager( Map providers )
{
super( providers );
}
public boolean hasComponent( String role )
{
return super.has( role );
}
public Component lookup( String role ) throws ComponentException
{
Object object = null;
try
{
object = super.resolve( role );
}
catch( Throwable e )
{
final String error = "Provider related error during service
resolution.";
throw new ComponentException( error, e );
}
finally
{
if( object instanceof Component ) return (Component) object;
throw new ComponentException( "Service provider returned a
non-Component." );
}
}
/**
* Release a pooled object.
* @param object a pooled object
*/
public void release( Component component )
{
super.disgard( component );
}
}
1.1
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/avalon/excalibur/service/PooledProvider.java
Index: PooledProvider.java
===================================================================
/*
* File: SingletonProvider.java
* License: etc/LICENSE.TXT
* Copyright: Copyright (C) The Apache Software Foundation. All rights
reserved.
* Copyright: OSM SARL 2002, All Rights Reserved.
*/
package org.apache.avalon.excalibur.service;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.excalibur.mpool.Pool;
/**
* A <code>PooledProvider</code> is a provider of pooled services. Invocations
* of <code>lookup</code> directed towards the manager will be redirected to
* the pooled provider based on the supplied role name. The pooled provider
* handles the invocation of <code>aquired</code> and <code>release</code>
against
* the actual <code>Pool</code> instance.
*/
class PooledProvider extends ServiceProvider
{
private Pool m_pool;
/**
* Creation of a new <code>SingletonProvider</code>.
* @param object the singleton object to provide.
*/
public PooledProvider( Pool pool, String role )
{
super( role );
m_pool = pool;
}
/**
* Acquire an instance of the pooled object.
* @return the pooled Object instance
*/
public Object acquire() throws Exception
{
return m_pool.acquire();
}
/**
* Release the instance of the pooled object.
* @param pooledObject The pooled object to release to the pool.
*/
void release( Object object )
{
m_pool.release( object );
}
/**
* Disposal of the provider and release of related resources.
*/
public void dispose()
{
if(( m_pool != null ) && ( m_pool instanceof Disposable )) try
{
((Disposable)m_pool).dispose();
}
catch( Throwable anything )
{
// ignore it
}
finally
{
m_pool = null;
super.dispose();
}
}
}
1.4 +53 -4
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryBlock.java
Index: DirectoryBlock.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryBlock.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DirectoryBlock.java 4 Mar 2002 13:51:47 -0000 1.3
+++ DirectoryBlock.java 6 Mar 2002 18:27:54 -0000 1.4
@@ -8,6 +8,11 @@
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Executable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.Configuration;
/**
* This is a minimal demonstration service that returns the a list of
@@ -19,21 +24,65 @@
*/
public class DirectoryBlock extends AbstractLogEnabled
-implements Disposable, DirectoryService
+implements Configurable, Initializable, DirectoryService, Disposable
{
+ private File m_base;
+ private Configuration m_config;
+
+ //=======================================================================
+ // Configurable
+ //=======================================================================
+
+ public void configure( final Configuration config )
+ throws ConfigurationException
+ {
+ m_config = config;
+ }
+
+ //=======================================================================
+ // Initializable
+ //=======================================================================
+
+ public void initialize()
+ throws Exception
+ {
+ m_base = new File( System.getProperty("user.dir"));
+ if( getLogger().isDebugEnabled() ) getLogger().debug(
m_config.getChild("about").getValue("-") );
+ util.listConfig( getLogger(), m_config );
+ }
+
+ //=======================================================================
+ // DirectoryService
+ //=======================================================================
+
/**
* Returns the list of files.
* @return File[]
*/
- public File[] getFiles( File file ) throws Exception
+ public void execute( ) throws Exception
{
- if( getLogger().isDebugEnabled() ) getLogger().debug("directory
count");
- return file.listFiles();
+
+ if(
m_config.getChild("policy").getAttribute("value").equalsIgnoreCase("COUNT") )
+ {
+ int n = m_base.listFiles().length;
+ if( getLogger().isInfoEnabled() ) getLogger().info("directory
count: " + n );
+ }
+ else
+ {
+ if( getLogger().isInfoEnabled() ) getLogger().info("listing
directory");
+ File[] files = m_base.listFiles();
+ for( int i=0; i<files.length; i++ )
+ {
+ if( getLogger().isDebugEnabled() ) getLogger().debug(" " +
files[i] );
+ }
+ }
}
public void dispose()
{
+ m_base = null;
+ m_config = null;
if( getLogger().isDebugEnabled() ) getLogger().debug("directory
disposal");
}
1.3 +6 -7
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryBlock.xinfo
Index: DirectoryBlock.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryBlock.xinfo,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DirectoryBlock.xinfo 4 Mar 2002 04:39:37 -0000 1.2
+++ DirectoryBlock.xinfo 6 Mar 2002 18:27:54 -0000 1.3
@@ -11,7 +11,7 @@
<blockinfo>
- <block>
+ <block name="directory">
<version>1.0</version>
</block>
@@ -24,16 +24,15 @@
</services>
<!--
- Default configuration profile name.
- -->
-
- <profile name="directory"/>
-
- <!--
Implementation policy.
-->
<implementation policy="SINGLETON" />
+
+ <configuration extends="org/apache/demo/copyright.xml">
+ <about>Demonstration singleton block.</about>
+ <policy value="LIST"/>
+ </configuration>
</blockinfo>
1.2 +2 -8
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryService.java
Index: DirectoryService.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/DirectoryService.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DirectoryService.java 3 Mar 2002 15:45:59 -0000 1.1
+++ DirectoryService.java 6 Mar 2002 18:27:54 -0000 1.2
@@ -6,7 +6,7 @@
*/
package org.apache.demo;
-import java.io.File;
+import org.apache.avalon.framework.activity.Executable;
/**
* <code>DirectoryService</code>
@@ -14,12 +14,6 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
-public interface DirectoryService
+public interface DirectoryService extends Executable
{
-
- /**
- * Returns the list of files.
- * @return File[]
- */
- public File[] getFiles( File file ) throws Exception;
}
1.3 +60 -10
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralBlock.java
Index: ReferralBlock.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralBlock.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ReferralBlock.java 4 Mar 2002 04:39:37 -0000 1.2
+++ ReferralBlock.java 6 Mar 2002 18:27:54 -0000 1.3
@@ -24,6 +24,7 @@
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Startable;
+import org.apache.avalon.framework.activity.Executable;
/**
@@ -32,10 +33,10 @@
*/
public class ReferralBlock extends AbstractLogEnabled
-implements Configurable, Contextualizable, Serviceable, Initializable,
Disposable, ReferralService
+implements Configurable, Contextualizable, Serviceable, Initializable,
Executable, Disposable
{
- private Configuration m_configuration;
+ private Configuration m_config;
private Context m_context;
private ServiceManager m_manager;
private DirectoryService m_directory;
@@ -57,7 +58,7 @@
public void configure( final Configuration config )
throws ConfigurationException
{
- m_configuration = config;
+ m_config = config;
}
//=================================================================
@@ -95,17 +96,24 @@
if( getLogger() == null ) throw new IllegalStateException(
"Logging channel has not been assigned.");
- if( m_configuration == null ) throw new IllegalStateException(
+ if( m_config == null ) throw new IllegalStateException(
"Configuration has not been declared.");
if( m_manager == null ) throw new IllegalStateException(
"Manager has not been declared.");
//
+ // print out the configuration
+ //
+
+ if( getLogger().isDebugEnabled() ) getLogger().debug(
m_config.getChild("about").getValue("-") );
+ util.listConfig( getLogger(), m_config );
+
+ //
// do something using the directory service
//
- doTest();
+ execute();
}
@@ -113,22 +121,20 @@
// ExampleService
//=======================================================================
- public boolean doTest()
+ public void execute()
{
try
{
if( getLogger().isDebugEnabled() ) getLogger().debug("aquired
directory service");
m_directory = (DirectoryService) m_manager.lookup("directory");
if( getLogger().isDebugEnabled() ) getLogger().debug("executing
service");
- File[] files = m_directory.getFiles( new File(
System.getProperty("user.dir") ));
- getLogger().info( files.length + " file(s)" );
+ m_directory.execute();
if( getLogger().isDebugEnabled() ) getLogger().debug("service
execution ok");
}
catch( Throwable e )
{
throw new CascadingRuntimeException( "zutt", e );
}
- return true;
}
//=======================================================================
@@ -141,8 +147,52 @@
m_disposed = true;
if( getLogger().isDebugEnabled() ) getLogger().debug("referral
disposal");
m_manager.release( m_directory );
- m_configuration = null;
+ m_config = null;
m_context = null;
m_manager = null;
+ }
+
+ //=======================================================================
+ // utilities
+ //=======================================================================
+
+ private void printConfig( Configuration config )
+ {
+ printConfig( " ", config );
+ System.out.println("");
+ }
+
+ private void printConfig( String lead, Configuration config )
+ {
+ System.out.print( lead + "<" + config.getName() );
+ String[] names = config.getAttributeNames();
+ if( names.length > 0 )
+ {
+ for( int i=0; i<names.length; i++ )
+ {
+ System.out.print( " " + names[i] + "=\"" +
config.getAttribute( names[i], "???" ) + "\"" );
+ }
+ }
+ Configuration[] children = config.getChildren();
+ if( children.length > 0 )
+ {
+ System.out.println(">");
+ for( int j=0; j<children.length; j++ )
+ {
+ printConfig( lead + " ", children[j] );
+ }
+ System.out.println( lead + "</" + config.getName() + ">");
+ }
+ else
+ {
+ if( config.getValue( null ) != null )
+ {
+ System.out.println( ">...</" + config.getName() + ">");
+ }
+ else
+ {
+ System.out.println( "/>");
+ }
+ }
}
}
1.2 +9 -2
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralBlock.xinfo
Index: ReferralBlock.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralBlock.xinfo,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ReferralBlock.xinfo 3 Mar 2002 15:45:59 -0000 1.1
+++ ReferralBlock.xinfo 6 Mar 2002 18:27:54 -0000 1.2
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!--
- File: ExampleBlock.xinfo
+ File: ReferralBlock.xinfo
License: etc/LICENSE.TXT
Copyright: Copyright (C) The Apache Software Foundation. All rights
reserved.
Copyright: OSM SARL 2001-2002, All Rights Reserved.
@@ -11,7 +11,7 @@
<blockinfo>
- <block>
+ <block name="referral">
<version>1.0</version>
</block>
@@ -27,8 +27,15 @@
<dependency>
<role>directory</role>
<service name="org.apache.demo.DirectoryService" version="1.0"/>
+ <configuration>
+ <policy value="COUNT"/>
+ </configuration>
</dependency>
</dependencies>
+
+ <configuration extends="org/apache/demo/copyright.xml">
+ <about>Demonstration composite block.</about>
+ </configuration>
</blockinfo>
1.2 +2 -10
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralService.java
Index: ReferralService.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/ReferralService.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ReferralService.java 3 Mar 2002 15:45:59 -0000 1.1
+++ ReferralService.java 6 Mar 2002 18:27:54 -0000 1.2
@@ -6,9 +6,7 @@
*/
package org.apache.demo;
-import org.apache.avalon.framework.component.Component;
-import org.apache.avalon.framework.context.Context;
-import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.activity.Executable;
import org.omg.CORBA_2_3.ORB;
@@ -18,12 +16,6 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
-public interface ReferralService
+public interface ReferralService extends Executable
{
-
- /**
- * Returns TRUE is the demo is working correctly.
- * @return boolean TRUE if the test executes correctly
- */
- public boolean doTest();
}
1.1
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/copyright.xml
Index: copyright.xml
===================================================================
<?xml version="1.0"?>
<!--
File: ReferralBlock.xinfo
License: etc/LICENSE.TXT
Copyright: Copyright (C) The Apache Software Foundation. All rights reserved.
Copyright: OSM SARL 2001-2002, All Rights Reserved.
@author Stephen McConnell
@version 1.0 12/03/2001
-->
<config>
<copyrights>
<copyright>OSM SARL (c) 2002, All Rights Reserved.</copyright>
<copyright>Copyright (C) The Apache Software Foundation. All rights
reserved.</copyright>
</copyrights>
</config>
1.1
jakarta-avalon-apps/enterprise/tools/src/java/org/apache/demo/util.java
Index: util.java
===================================================================
/*
* util.java
*/
package org.apache.demo;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.logger.Logger;
/**
* This is a minimal demonstration server.
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public class util
{
//=======================================================================
// utilities
//=======================================================================
public static void listConfig( Logger log, Configuration config )
{
final StringBuffer buffer = new StringBuffer();
listConfig( buffer, " ", config );
log.debug("configuration listing\n\n" + buffer.toString() );
}
private static void listConfig( StringBuffer buffer, String lead,
Configuration config )
{
buffer.append( lead + "<" + config.getName() );
String[] names = config.getAttributeNames();
if( names.length > 0 )
{
for( int i=0; i<names.length; i++ )
{
buffer.append( " " + names[i] + "=\"" + config.getAttribute(
names[i], "???" ) + "\"" );
}
}
Configuration[] children = config.getChildren();
if( children.length > 0 )
{
buffer.append(">\n");
for( int j=0; j<children.length; j++ )
{
listConfig( buffer, lead + " ", children[j] );
}
buffer.append( lead + "</" + config.getName() + ">\n");
}
else
{
if( config.getValue( null ) != null )
{
buffer.append( ">...</" + config.getName() + ">\n");
}
else
{
buffer.append( "/>\n");
}
}
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>