mcconnell 02/03/06 10:38:29
Modified: src/scratchpad/org/apache/avalon/excalibur/service
AbstractManager.java DefaultComponentManager.java
DefaultServiceManager.java DependencyInfo.java
ServiceFactory.java ServiceLoader.java
ServiceRegistry.java TransientProvider.java
UnitInfo.java package.html
Log:
static xinfo based usage configuration in place + updated javadoc.
Revision Changes Path
1.2 +3 -2
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/AbstractManager.java
Index: AbstractManager.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/AbstractManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractManager.java 3 Mar 2002 23:07:49 -0000 1.1
+++ AbstractManager.java 6 Mar 2002 18:38:29 -0000 1.2
@@ -8,6 +8,7 @@
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;
@@ -49,7 +50,7 @@
* The invocing client is totally responsible for service disposal.
* </td>
*/
- private Hashtable m_providers = new Hashtable();
+ private Map m_providers;
/**
* Internal table that maintains a mapping betyween pooled objects and
@@ -58,7 +59,7 @@
*/
private Hashtable m_pooled_table = new Hashtable();
- public AbstractManager( Hashtable providers ) throws Exception
+ public AbstractManager( Map providers )
{
m_providers = providers;
}
1.2 +2 -2
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/DefaultComponentManager.java
Index: DefaultComponentManager.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/DefaultComponentManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultComponentManager.java 3 Mar 2002 23:07:49 -0000 1.1
+++ DefaultComponentManager.java 6 Mar 2002 18:38:29 -0000 1.2
@@ -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.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentException;
@@ -21,7 +21,7 @@
class DefaultComponentManager extends AbstractManager implements
ComponentManager
{
- public DefaultComponentManager( Hashtable providers ) throws Exception
+ public DefaultComponentManager( Map providers )
{
super( providers );
}
1.3 +2 -2
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/DefaultServiceManager.java
Index: DefaultServiceManager.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/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:07:49 -0000 1.2
+++ DefaultServiceManager.java 6 Mar 2002 18:38:29 -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-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/DependencyInfo.java
Index: DependencyInfo.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/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:51:12 -0000 1.1
+++ DependencyInfo.java 6 Mar 2002 18:38:29 -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-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/ServiceFactory.java
Index: ServiceFactory.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/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 09:07:33 -0000 1.5
+++ ServiceFactory.java 6 Mar 2002 18:38:29 -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.6 +46 -54
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/ServiceLoader.java
Index: ServiceLoader.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/ServiceLoader.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ServiceLoader.java 4 Mar 2002 09:07:33 -0000 1.5
+++ ServiceLoader.java 6 Mar 2002 18:38:29 -0000 1.6
@@ -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.4 +39 -82
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/ServiceRegistry.java
Index: ServiceRegistry.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/ServiceRegistry.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ServiceRegistry.java 4 Mar 2002 04:38:22 -0000 1.3
+++ ServiceRegistry.java 6 Mar 2002 18:38:29 -0000 1.4
@@ -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-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/TransientProvider.java
Index: TransientProvider.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/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:51:12 -0000 1.1
+++ TransientProvider.java 6 Mar 2002 18:38:29 -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-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/UnitInfo.java
Index: UnitInfo.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/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:07:49 -0000 1.2
+++ UnitInfo.java 6 Mar 2002 18:38:29 -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-excalibur/src/scratchpad/org/apache/avalon/excalibur/service/package.html
Index: package.html
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/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:35:58 -0000 1.4
+++ package.html 6 Mar 2002 18:38:29 -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>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>