mcconnell 2002/07/23 08:10:40 Modified: assembly/src/java/org/apache/excalibur/merlin/container LifecycleHelper.java ResourceProvider.java assembly/src/java/org/apache/excalibur/merlin/kernel DefaultKernel.java assembly/src/java/org/apache/excalibur/merlin/model ContextDirective.java Import.java Parameter.java assembly/src/java/org/apache/excalibur/merlin/model/builder XMLProfileCreator.java Log: addition of support for configuration by reference and context refernces in parameters Revision Changes Path 1.5 +1 -1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/LifecycleHelper.java Index: LifecycleHelper.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/LifecycleHelper.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- LifecycleHelper.java 20 Jul 2002 00:54:07 -0000 1.4 +++ LifecycleHelper.java 23 Jul 2002 15:10:40 -0000 1.5 @@ -106,7 +106,7 @@ { notice( name, stage ); final ServiceManager manager = - provider.createServiceManager( profile); + provider.createServiceManager( profile ); ContainerUtil.service( object, manager ); } else if( object instanceof Composable ) 1.8 +12 -37 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/ResourceProvider.java Index: ResourceProvider.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/ResourceProvider.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ResourceProvider.java 20 Jul 2002 00:54:07 -0000 1.7 +++ ResourceProvider.java 23 Jul 2002 15:10:40 -0000 1.8 @@ -113,7 +113,7 @@ private DefaultContainer m_locator; - private Context m_dictionary; + private DefaultContext m_dictionary; //======================================================================= // constructor @@ -125,7 +125,9 @@ m_classloader = loader; m_logging = manager; m_locator = locator; - m_dictionary = dictionary; + m_dictionary = new DefaultContext( dictionary ); + m_dictionary.put( "classloader", loader ); + m_dictionary.makeReadOnly(); } //======================================================================= @@ -217,17 +219,17 @@ parent.put( key, object ); getLogger().debug( "adding context entry: " + key - + ", with name: " + name + + ", from: " + name + ", and object: " + object ); } catch( Throwable e ) { final String error = - "Could not resolve a value for the import directive in profile '" - + profile.getName() - + "' with the name '" + name - + "' for the key '" + key - + "'."; + "Could not resolve a value for the import directive in profile '" + + profile.getName() + + "' with the name '" + name + + "' for the key '" + key + + "'."; throw new ContainerException( error ); } } @@ -247,24 +249,6 @@ { final Map services = getServices( profile ); final DefaultComponentManager componentManager = new DefaultComponentManager( services ); -/* - final Iterator keys = services.keySet().iterator(); - while( keys.hasNext() ) - { - final String key = (String)keys.next(); - final Object service = services.get( key ); - if( !Component.class.isInstance( service ) ) - { - final String message = - REZ.getString( "resource.service-not-a-component.error", - key, - service.getClass().getName() ); - throw new Exception( message ); - } - componentManager.put( key, (Component)service ); - } - componentManager.makeReadOnly(); -*/ return componentManager; } @@ -280,16 +264,6 @@ { final Map services = getServices( profile ); final DefaultServiceManager serviceManager = new DefaultServiceManager( services ); -/* - final Iterator keys = services.keySet().iterator(); - while( keys.hasNext() ) - { - final String key = (String)keys.next(); - final Object service = services.get( key ); - serviceManager.put( key, service ); - } - serviceManager.makeReadOnly(); -*/ return serviceManager; } @@ -348,6 +322,7 @@ */ private Map getServices( Profile profile ) throws Exception { + getLogger().debug("preparing services for profile: " + profile ); final Type type = profile.getType(); final DependencyDescriptor[] dependencies = type.getDependencies(); final HashMap services = new HashMap(); 1.20 +3 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java Index: DefaultKernel.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- DefaultKernel.java 20 Jul 2002 05:03:01 -0000 1.19 +++ DefaultKernel.java 23 Jul 2002 15:10:40 -0000 1.20 @@ -125,7 +125,8 @@ /** * Invoked by the bootstrap process to supply to kernel defintion. * @param context the context object containing the inital parameters - * @exception ContextException if the supplied does not contain a DESCRIPTOR_KEY value + * @exception ContextException if the supplied does not contain a CLASSLOADER_KEY, + * LOG_MANAGER_KEY, or ROOT_CONTAINER_DESCRIPTOR_KEY value. */ public void contextualize( Context context ) throws ContextException { 1.3 +3 -3 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/ContextDirective.java Index: ContextDirective.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/ContextDirective.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ContextDirective.java 19 Jul 2002 14:08:07 -0000 1.2 +++ ContextDirective.java 23 Jul 2002 15:10:40 -0000 1.3 @@ -25,7 +25,7 @@ * statement corresponds to a request for a context value from the container.</p> * <pre> * <context class="<font color="darkred">MyContextCLass</font>"> - * <import key="<font color="darkred">avalon.work</font>" as="<font color="darkred">base</font>"/> + * <import name="<font color="darkred">avalon.work</font>" key="<font color="darkred">base</font>"/> * <entry key="<font color="darkred">location</font>" value="<font color="darkred">Paris</font>"/> * </context> * </pre> @@ -151,7 +151,7 @@ final String key = entry.getKey(); try { - final Object value = entry.getValue( loader ); + final Object value = entry.getValue( loader, parent ); map.put( key, value ); } catch( Throwable e ) 1.2 +2 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Import.java Index: Import.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Import.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Import.java 19 Jul 2002 14:08:07 -0000 1.1 +++ Import.java 23 Jul 2002 15:10:40 -0000 1.2 @@ -24,7 +24,7 @@ * --></font> * * <font color="gray"><context></font> - * <import key="<font color="darkred">home</font>" resource="<font color="darkred">avalon.home</font>">; + * <import key="<font color="darkred">home</font>" name="<font color="darkred">avalon.home</font>">; * <font color="gray"></context></font> * </pre> * 1.4 +148 -14 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Parameter.java Index: Parameter.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Parameter.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- Parameter.java 19 Jul 2002 14:08:07 -0000 1.3 +++ Parameter.java 23 Jul 2002 15:10:40 -0000 1.4 @@ -8,7 +8,7 @@ package org.apache.excalibur.merlin.model; import java.lang.reflect.Constructor; - +import org.apache.avalon.framework.context.Context; /** * A <code>Parameter</code> represents a single constructor typed argument value. A parameter @@ -47,9 +47,9 @@ private final String m_classname; /** - * The derived value. + * The supplied argument. */ - private Object m_value; + private String m_argument; /** * The sub-parameters from which the value for this parameter may be derived. @@ -57,6 +57,11 @@ private final Parameter[] m_parameters; /** + * The derived value. + */ + private Object m_value; + + /** * Creation of a new parameter using the default <code>java.lang.String</code> * type and a supplied value. * @@ -66,7 +71,7 @@ { m_parameters = new Parameter[0]; m_classname = "java.lang.String"; - m_value = value; + m_argument = value; } /** @@ -81,8 +86,9 @@ if( null == value ) throw new NullPointerException("value"); - m_parameters = new Parameter[]{ new Parameter( value ) }; + m_parameters = new Parameter[0]; m_classname = classname; + m_argument = value; } /** @@ -175,10 +181,89 @@ * Return the derived parameter value. * @return the value */ - public Object getValue( ClassLoader loader ) throws ModelException + public Object getValue( ClassLoader loader, Context context ) throws ModelException { + // + // if the parameter value has already been established - return it now + // + if( m_value != null ) - return m_value; + { + return m_value; + } + + // + // if the parameter contains a text argument then check if its a reference + // to a context entry (in the form"${<key>}" ), otherwise its a simple constructor + // case with a single string paremeter + // + + if( m_argument != null ) + { + if( m_argument.startsWith("${") ) + { + if( m_argument.endsWith("}") ) + { + final String key = m_argument.substring( 2, m_argument.length() -1 ); + try + { + m_value = context.get( key ); + return m_value; + } + catch( Throwable e ) + { + final String error = "Missing context value: '" + key + "'."; + throw new IllegalArgumentException( error ); + } + } + else + { + final String error = "Illegal formal for context refernence: '" + m_argument + "'."; + throw new IllegalArgumentException( error ); + } + } + else + { + // + // the argument is a single string parameter + // + + try + { + final Class[] params = new Class[]{ String.class }; + Constructor constructor = getParameterClass( loader ).getConstructor( params ); + final Object[] values = new Object[]{ m_argument }; + m_value = constructor.newInstance( values ); + return m_value; + } + catch( InstantiationException e ) + { + final String error = "Unable to instantiate instance of class: " + m_classname + + " with the single argument: '" + m_argument + "'"; + throw new ModelException( error, e ); + } + catch( IllegalAccessException e ) + { + final String error = + "Cannot access single string parameter constructor for the class: '" + + m_classname + "'."; + throw new ModelException( error, e ); + } + catch( Throwable e ) + { + final String error = + "Unexpected exception while creating a single string parameter value for the class: '" + + m_classname + "'."; + throw new ModelException( error, e ); + } + + } + } + + // + // getting here means we are dealing with 0..n types parameter constructor where the + // parameters are defined by the nested parameter definitions + // if( m_parameters.length == 0 ) { @@ -224,7 +309,7 @@ try { - values[i] = m_parameters[i].getValue( loader ); + values[i] = m_parameters[i].getValue( loader, context ); } catch( Throwable e ) { @@ -235,19 +320,22 @@ } } - Constructor constructor; + Constructor constructor = null; try { constructor = getParameterClass( loader ).getConstructor( params ); } catch( NoSuchMethodException e ) { + final String stack = new String( this.toString() ); + System.out.println( stack ); + System.out.println( getClassesAsString( params ) ); final String error = - "Supplied parameters in " + m_classname - + " do not match an available constructor."; - throw new ModelException( error, e ); + "Supplied parameters for " + m_classname + + " does not match an available constructor. Cause: " + e.toString() + + "\n" + stack; + throw new ModelException( error ); } - try { @@ -275,6 +363,52 @@ + "for the class: '" + m_classname + "'."; throw new ModelException( error, e ); } + } + } + + private String getClassesAsString( Class[] classes ) + { + StringBuffer buffer = new StringBuffer(); + for( int i=0; i<classes.length; i++ ) + { + buffer.append( classes[i].getName() ); + if( (i+1)<classes.length ) + buffer.append(","); + } + return buffer.toString(); + } + + public String toString() + { + StringBuffer buffer = new StringBuffer(); + asString( buffer, " " ); + return buffer.toString(); + } + + protected void asString( StringBuffer buffer, String lead ) + { + buffer.append( + lead + "[\n" + + lead + " type: " + this.getClass().getName() + "\n" + + lead + " class: " + m_classname + "\n" + + lead + " arg: " + m_argument + "\n" + + lead + " value: " + m_value + "\n" + + lead + " params: " + m_parameters.length ); + + if( m_parameters.length > 0 ) + { + buffer.append("\n"); + String str = lead + " "; + getParamsAsString( buffer, str ); + } + buffer.append("\n" + lead + "]\n"); + } + + private void getParamsAsString( StringBuffer buffer, String lead ) + { + for( int i=0; i<m_parameters.length; i++ ) + { + m_parameters[i].asString( buffer, lead + " " ); } } } 1.9 +49 -7 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/XMLProfileCreator.java Index: XMLProfileCreator.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/XMLProfileCreator.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- XMLProfileCreator.java 20 Jul 2002 00:54:07 -0000 1.8 +++ XMLProfileCreator.java 23 Jul 2002 15:10:40 -0000 1.9 @@ -121,19 +121,61 @@ final Configuration loggersConfig = profile.getChild("loggers"); final CategoryDescriptor loggers = createCategoryDescriptor( loggersConfig, name ); final ContextDirective context = createContextDirective( profile.getChild("context") ); + final Configuration config = createConfiguration( loader, type, profile.getChild("configuration") ); + return new Profile( name, params, config, context, loggers, type, enabled, activation, mode ); + } + + public Configuration createConfiguration( ClassLoader loader, Type type, Configuration config ) + throws Exception + { final Configuration defaults = type.getDefaultConfiguration( loader ); - final Configuration base = profile.getChild("configuration"); - Configuration config; + Configuration base = null; + if( config.getAttribute("src", null ) != null ) + { + String src = config.getAttribute("src" ); + if( src.startsWith("resource://") ) + { + final String url = src.substring( 11 ); + final InputStream stream = + loader.getResourceAsStream( url ); + if( null == stream ) + { + final String error = + "Requested configuration source does not exist: " + src; + throw new ConfigurationException( error ); + } + final InputSource source = new InputSource( stream ); + base = ConfigurationBuilder.build( source ); + } + else + { + try + { + base = ConfigurationBuilder.build( src ); + } + catch( Throwable e ) + { + final String error = + "Unexpected exception while attempting to resolve configuration fro src : " + src; + throw new ConfigurationException( error ); + } + } + } + else + { + base = config; + } + if( null == defaults ) { - config = base; + return base; } else { - config = new CascadingConfiguration( base, defaults ); + return new CascadingConfiguration( base, defaults ); } - return new Profile( name, params, config, context, loggers, type, enabled, activation, mode ); } + public ContextDirective createContextDirective( Configuration config ) throws ConfigurationException { @@ -201,7 +243,7 @@ public Parameter createParameter( Configuration config ) throws ConfigurationException { - String classname = config.getAttribute( "classname", "java.lang.String" ); + String classname = config.getAttribute( "class", "java.lang.String" ); String value = config.getValue( null ); if( value != null ) {
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>