You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2004/02/22 17:12:58 UTC

cvs commit: avalon/merlin/platform/tutorials/dynamics/src/java/tutorial DefaultGizmo.java DefaultWidget.java HelloFacility.java

mcconnell    2004/02/22 08:12:58

  Modified:    merlin/composition/api/src/java/org/apache/avalon/composition/data
                        ContextDirective.java
               merlin/composition/api/src/java/org/apache/avalon/composition/model
                        ContextModel.java
               merlin/composition/api/src/test/org/apache/avalon/composition/data/test
                        ContextDirectiveTestCase.java
               merlin/composition/impl/src/java/org/apache/avalon/composition/data/builder
                        XMLComponentProfileCreator.java
               merlin/composition/impl/src/java/org/apache/avalon/composition/data/writer
                        XMLComponentProfileWriter.java
               merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl
                        DefaultComponentContext.java
                        DefaultConstructorModel.java DefaultContext.java
                        DefaultContextModel.java DefaultImportModel.java
                        Resources.properties
               merlin/composition/impl/src/test/org/apache/avalon/composition/model/test
                        ContextTestCase.java
               merlin/composition/spi/src/java/org/apache/avalon/composition/provider
                        ComponentContext.java
               merlin/platform/tutorials/dynamics/conf block.xml
               merlin/platform/tutorials/dynamics project.xml
               merlin/platform/tutorials/dynamics/src/java/tutorial
                        DefaultGizmo.java DefaultWidget.java
                        HelloFacility.java
  Added:       merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl
                        OverrideEntryModel.java
  Log:
  A long overdue cleanup of the context modelling strategy.
  
  Revision  Changes    Path
  1.3       +1 -30     avalon/merlin/composition/api/src/java/org/apache/avalon/composition/data/ContextDirective.java
  
  Index: ContextDirective.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/api/src/java/org/apache/avalon/composition/data/ContextDirective.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ContextDirective.java	24 Jan 2004 23:25:24 -0000	1.2
  +++ ContextDirective.java	22 Feb 2004 16:12:58 -0000	1.3
  @@ -57,11 +57,6 @@
       private final String m_classname;
   
       /**
  -     * The optional provider source path.
  -     */
  -    private final String m_source;
  -
  -    /**
        * Creation of a new file target.
        * @param entries the set of entry descriptors
        */
  @@ -77,20 +72,6 @@
        */
       public ContextDirective( final String classname, final EntryDirective[] entries )
       {
  -        this( classname, entries, null );
  -    }
  -
  -    /**
  -     * Creation of a new file target.
  -     * @param classname the context implementation class
  -     * @param entries the set of entry descriptors
  -     * @param source a path to a source component for contextualization
  -     *    phase handling
  -     */
  -    public ContextDirective( 
  -      final String classname, final EntryDirective[] entries, String source )
  -    {
  -        m_source = source;
           m_classname = classname;
           if( entries != null )
           {
  @@ -100,16 +81,6 @@
           {
               m_entries = new EntryDirective[0];
           }
  -    }
  -
  -    /**
  -     * Return the relative path to a source provider component that
  -     * will handle a custom contextualization phase implementation.
  -     * @return the source path
  -     */
  -    public String getSource()
  -    {
  -        return m_source;
       }
   
       /**
  
  
  
  1.4       +24 -2     avalon/merlin/composition/api/src/java/org/apache/avalon/composition/model/ContextModel.java
  
  Index: ContextModel.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/api/src/java/org/apache/avalon/composition/model/ContextModel.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ContextModel.java	24 Jan 2004 23:25:25 -0000	1.3
  +++ ContextModel.java	22 Feb 2004 16:12:58 -0000	1.4
  @@ -48,6 +48,28 @@
       * 
       * @return the context object
       */
  -    public Context getContext();
  +    Context getContext();
  +
  +   /**
  +    * Return the set of entry models associated with this context model.
  +    * 
  +    * @return the entry models
  +    */
  +    EntryModel[] getEntryModels();
  +
  +   /**
  +    * Return an entry model matching the supplied key.
  +    * 
  +    * @return the entry model or null if tyhe key is unknown
  +    */
  +    EntryModel getEntryModel( String key );
  +
  +   /**
  +    * Set the entry model relative to a supplied key.
  +    * 
  +    * @param key the entry key
  +    * @param model the entry model
  +    */
  +    void setEntryModel( String key, EntryModel model );
   
   }
  
  
  
  1.4       +1 -4      avalon/merlin/composition/api/src/test/org/apache/avalon/composition/data/test/ContextDirectiveTestCase.java
  
  Index: ContextDirectiveTestCase.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/api/src/test/org/apache/avalon/composition/data/test/ContextDirectiveTestCase.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ContextDirectiveTestCase.java	24 Jan 2004 23:25:27 -0000	1.3
  +++ ContextDirectiveTestCase.java	22 Feb 2004 16:12:58 -0000	1.4
  @@ -30,8 +30,6 @@
    */
   public class ContextDirectiveTestCase extends TestCase
   {
  -    private String m_source = "../xxx";
  -
       public ContextDirectiveTestCase( String name )
       {
           super( name );
  @@ -71,10 +69,9 @@
       {
           EntryDirective[] entries = new EntryDirective[0];
           ContextDirective cd = 
  -          new ContextDirective( getClass().getName(), entries, m_source );
  +          new ContextDirective( getClass().getName(), entries );
   
           assertEquals( "classname", getClass().getName(), cd.getClassname());
  -        assertEquals( "source", m_source, cd.getSource());
           assertEquals( "entries", entries, cd.getEntryDirectives());
           assertEquals( "length", entries.length, cd.getEntryDirectives().length);
       }
  
  
  
  1.4       +2 -3      avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/data/builder/XMLComponentProfileCreator.java
  
  Index: XMLComponentProfileCreator.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/data/builder/XMLComponentProfileCreator.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XMLComponentProfileCreator.java	24 Jan 2004 23:25:27 -0000	1.3
  +++ XMLComponentProfileCreator.java	22 Feb 2004 16:12:58 -0000	1.4
  @@ -243,9 +243,8 @@
           }
   
           final String classname = config.getAttribute( "class", null );
  -        final String source = config.getAttribute( "source", null );
           EntryDirective[] entries = getEntries( config.getChildren( "entry" ) );
  -        return new ContextDirective( classname, entries, source );
  +        return new ContextDirective( classname, entries );
       }
   
       /**
  
  
  
  1.5       +1 -5      avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/data/writer/XMLComponentProfileWriter.java
  
  Index: XMLComponentProfileWriter.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/data/writer/XMLComponentProfileWriter.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XMLComponentProfileWriter.java	21 Feb 2004 13:27:03 -0000	1.4
  +++ XMLComponentProfileWriter.java	22 Feb 2004 16:12:58 -0000	1.5
  @@ -364,10 +364,6 @@
           {
               writer.write( " class=\"" + context.getClassname() + "\"");
           }
  -        if( context.getSource() != null )
  -        {
  -            writer.write( " source=\"" + context.getSource() + "\"");
  -        }
   
           EntryDirective[] entries = context.getEntryDirectives();
   
  
  
  
  1.7       +1 -103    avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultComponentContext.java
  
  Index: DefaultComponentContext.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultComponentContext.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- DefaultComponentContext.java	10 Feb 2004 16:23:33 -0000	1.6
  +++ DefaultComponentContext.java	22 Feb 2004 16:12:58 -0000	1.7
  @@ -80,12 +80,6 @@
   
       private final ContainmentModel m_model;
   
  -   /**
  -    * Map containing context entry models 
  -    * keyed by entry key.
  -    */
  -    private final Map m_map = new Hashtable();
  -
       //==============================================================
       // constructor
       //==============================================================
  @@ -233,100 +227,4 @@
           return m_classloader;
       }
   
  -   /**
  -    * Add a context entry model to the deployment context.
  -    * @param model the entry model
  -    * @exception IllegalArgumentException if model key is unknown
  -    */
  -    public void register( EntryModel model )
  -    {
  -        final String key = model.getKey();
  -        if( m_map.get( key ) == null )
  -        {
  -            m_map.put( key, model );
  -        }
  -        else
  -        {
  -            final String error = 
  -              REZ.getString( "deployment.registration.override.error", key );
  -            throw new IllegalArgumentException( error );
  -        }
  -    }
  -
  -   /**
  -    * Get a context entry from the deployment context.
  -    * @param alias the entry lookup key
  -    * @return value the corresponding value
  -    * @exception ContextException if the key is unknown
  -    * @exception ModelRuntimeException if the key is unknown
  -    */
  -    public Object resolve( final String alias ) throws ContextException
  -    {
  -        if( alias == null ) throw new NullPointerException( "alias" );
  -
  -        String key = alias;
  -        EntryDescriptor entry = 
  -          getType().getContext().getEntry( alias );
  -
  -        if( entry != null )
  -        {
  -            key = entry.getKey();
  -        }
  -        
  -        if( key.equals( ContainmentModel.KEY ) )
  -        {
  -            return getContainmentModel();
  -        }
  -        else if( key.startsWith( "urn:composition:" ) )
  -        {
  -            return getSystemContext().get( key );
  -        }
  -        else if( key.equals( NAME_KEY ) )
  -        {
  -            return getName();
  -        }
  -        else if( key.equals( PARTITION_KEY ) )
  -        {
  -            return getPartitionName();
  -        }
  -        else if( key.equals( CLASSLOADER_KEY ) )
  -        {
  -            return getClassLoader();
  -        }
  -        else if( key.equals( HOME_KEY ) )
  -        {
  -            return getHomeDirectory();
  -        }
  -        else if( key.equals( TEMP_KEY ) )
  -        {
  -            return getTempDirectory();
  -        }
  -        else
  -        {
  -            Object object = m_map.get( key );
  -            if( null != object )
  -            {
  -                final String classname = object.getClass().getName();
  -                try
  -                {
  -                    return ((EntryModel)object).getValue();
  -                }
  -                catch( Throwable e )
  -                {
  -                    final String error = 
  -                      REZ.getString( 
  -                        "deployment.context.runtime-get", 
  -                        key, classname );
  -                    throw new ModelRuntimeException( error, e );
  -                }
  -            }
  -            else
  -            {
  -                final String error = 
  -                  REZ.getString( 
  -                   "deployment.context.runtime-get", key );
  -                throw new ModelRuntimeException( error );
  -            }
  -        }
  -    }
   }
  
  
  
  1.6       +13 -13    avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultConstructorModel.java
  
  Index: DefaultConstructorModel.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultConstructorModel.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- DefaultConstructorModel.java	10 Feb 2004 16:23:33 -0000	1.5
  +++ DefaultConstructorModel.java	22 Feb 2004 16:12:58 -0000	1.6
  @@ -22,6 +22,7 @@
   
   import org.apache.avalon.composition.data.ConstructorDirective;
   import org.apache.avalon.composition.data.Parameter;
  +import org.apache.avalon.composition.model.EntryModel;
   import org.apache.avalon.composition.model.ModelException;
   import org.apache.avalon.composition.provider.ComponentContext;
   
  @@ -409,24 +410,23 @@
               if ( argument.endsWith( "}" ) )
               {
                   final String key = argument.substring( 2, argument.length() - 1 );
  -                Object value = null;
  -                try
  -                {
  -                    return m_context.resolve( key );
  -                }
  -                catch( ContextException e )
  +                Object value = m_map.get( key );
  +                if ( value != null )
                   {
  -                    value = m_map.get( key );
  -                    if ( value != null )
  +                    if( value instanceof EntryModel )
                       {
  -                        return value;
  +                        return ((EntryModel)value).getValue();
                       }
                       else
                       {
  -                        final String error = 
  -                          "Unresolvable primative context value: '" + key + "'.";
  -                        throw new ModelException( error );
  +                        return value;
                       }
  +                }
  +                else
  +                {
  +                    final String error = 
  +                      "Unresolvable primative context value: '" + key + "'.";
  +                    throw new ModelException( error );
                   }
               }
               else
  
  
  
  1.6       +18 -8     avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultContext.java
  
  Index: DefaultContext.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultContext.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- DefaultContext.java	10 Feb 2004 16:23:33 -0000	1.5
  +++ DefaultContext.java	22 Feb 2004 16:12:58 -0000	1.6
  @@ -17,8 +17,10 @@
   
   package org.apache.avalon.composition.model.impl;
   
  +import java.util.Map;
  +
   import org.apache.avalon.composition.model.ModelRuntimeException;
  -import org.apache.avalon.composition.provider.ComponentContext;
  +import org.apache.avalon.composition.model.EntryModel;
   
   import org.apache.avalon.framework.context.Context;
   import org.apache.avalon.framework.context.ContextException;
  @@ -48,7 +50,7 @@
       // immutable state
       //==============================================================
   
  -    private final ComponentContext m_context;
  +    private final Map m_map;
   
       //==============================================================
       // constructor
  @@ -59,9 +61,9 @@
       *
       * @param context the deployment context
       */
  -    public DefaultContext( ComponentContext context )
  +    public DefaultContext( Map map )
       {
  -        m_context = context;
  +        m_map = map;
       }
       
       //==============================================================
  @@ -73,7 +75,7 @@
       * is unknown a {@link ContextException} containing the key as 
       * as the exception message and a null cause will be thrown.  If 
       * the contrext entry is recognized and a error occurs during 
  -    * value resolvution a {@link ContextException} will be thrown 
  +    * value resolution a {@link ContextException} will be thrown 
       * containing the causal exception.
       * 
       * @param key the context entry key
  @@ -82,11 +84,19 @@
       */
       public Object get( final Object key ) throws ContextException
       {
  +        EntryModel model = (EntryModel) m_map.get( key.toString() );
  +        if( null == model ) 
  +        {
  +            final String error = 
  +              REZ.getString( "context.entry.key.error", key );
  +            throw new ContextException( error );
  +        }
  +
           try
           {
  -            return m_context.resolve( key.toString() );
  +            return model.getValue();
           }
  -        catch( ModelRuntimeException e )
  +        catch( Throwable e )
           {
               final String error = 
                 REZ.getString( "context.entry.model.error", key );
  
  
  
  1.10      +64 -70    avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultContextModel.java
  
  Index: DefaultContextModel.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultContextModel.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- DefaultContextModel.java	10 Feb 2004 16:23:33 -0000	1.9
  +++ DefaultContextModel.java	22 Feb 2004 16:12:58 -0000	1.10
  @@ -25,6 +25,7 @@
   import org.apache.avalon.composition.data.EntryDirective;
   import org.apache.avalon.composition.data.ImportDirective;
   import org.apache.avalon.composition.data.ConstructorDirective;
  +import org.apache.avalon.composition.model.EntryModel;
   import org.apache.avalon.composition.model.ContextModel;
   import org.apache.avalon.composition.model.ComponentModel;
   import org.apache.avalon.composition.model.ContainmentModel;
  @@ -66,6 +67,12 @@
       public static final Class DEFAULT_CONTEXT_CLASS = 
         DefaultContext.class;
   
  +    public static boolean isaStandardKey( String key )
  +    {
  +        return ( key.startsWith( "urn:avalon:" ) 
  +          || key.startsWith( "urn:composition:" ));
  +    }
  +
       //==============================================================
       // immutable state
       //==============================================================
  @@ -94,9 +101,11 @@
       * establishment and uses this to set standard context entries.</p>
       *
       * @param logger the logging channel
  -    * @param descriptor the contextualization stage descriptor
  -    * @param directive the contextualization directive
  -    * @param context the deployment context
  +    * @param descriptor the contextualization stage descriptor that describes
  +    *   the set of context entries that the component type is requesting
  +    * @param directive the contextualization directive that describes a set 
  +    *   of context entry creation strategies
  +    * @param context the component model context argument
       */
       public DefaultContextModel( 
         Logger logger, ContextDescriptor descriptor, 
  @@ -110,7 +119,7 @@
               throw new NullPointerException( "descriptor" );
           }
   
  -        if( null == context ) 
  +        if( null == context )
           {
               throw new NullPointerException( "context" );
           }
  @@ -132,54 +141,13 @@
           for( int i=0; i<entries.length; i++ )
           {
               EntryDescriptor entry = entries[i];
  +            String alias = entry.getAlias();
               final String key = entry.getKey();
  -            if( key.startsWith( "urn:avalon:" ) )
  -            {
  -                try
  -                {
  -                    Object value = m_context.resolve( key );
  -                    m_map.put( key, value );
  -                }
  -                catch( ContextException e )
  -                {
  -                    if( entry.isRequired() )
  -                    {
  -                        final String error = 
  -                          REZ.getString( 
  -                            "context.non-standard-avalon-key.error", key );
  -                         throw new ModelException( error );
  -                    }
  -                }
  -            }
  -            else if( key.equals( ContainmentModel.KEY ) )
  +            if( isaStandardKey( key ) )
               {
  -                //
  -                // TODO: check that the component has permission
  -                // to access the containment model
  -                //
  -
  -                m_map.put( 
  -                  ContainmentModel.KEY, 
  -                  context.getContainmentModel() );
  -            }
  -            else if( key.startsWith( "urn:composition:" ) )
  -            {
  -                try
  -                {
  -                    Object value = 
  -                      m_context.getSystemContext().get( key );
  -                    m_map.put( key, value );
  -                }
  -                catch( ContextException e )
  -                {
  -                    if( entry.isRequired() )
  -                    {
  -                        final String error = 
  -                          REZ.getString( 
  -                            "context.non-standard-avalon-key.error", key );
  -                        throw new ModelException( error );
  -                    }
  -                }
  +                 DefaultImportModel model = 
  +                   new DefaultImportModel( entry, key, m_context );
  +                 m_map.put( alias, model );
               }
               else
               {
  @@ -211,16 +179,16 @@
   
                       if( entryDirective instanceof ImportDirective )
                       {
  +                        //
  +                        // importing under an alias of a container scoped key
  +                        //
  +
                           ImportDirective importDirective = 
                             (ImportDirective) entryDirective;
  +                        String ref = importDirective.getImportKey();
                           DefaultImportModel model = 
  -                          new DefaultImportModel( 
  -                            entry, 
  -                            importDirective, 
  -                            context, 
  -                            m_map );
  -                        m_context.register( model );
  -                        m_map.put( key, model.getValue() );
  +                          new DefaultImportModel( entry, ref, m_context );
  +                        m_map.put( alias, model );
                       }
                       else if( entryDirective instanceof ConstructorDirective )
                       {
  @@ -232,8 +200,7 @@
                               constructor, 
                               context, 
                               m_map );
  -                        m_context.register( model );
  -                        m_map.put( key, model.getValue() );
  +                        m_map.put( alias, model );
                       }
                       else
                       {
  @@ -250,19 +217,46 @@
           }
   
           m_componentContext = 
  -          createComponentContext( m_context, descriptor, directive );
  -
  -        if( getLogger().isDebugEnabled() )
  -        {
  -            getLogger().debug( "context: " + m_map );
  -        }
  +          createComponentContext( m_context, descriptor, directive, m_map );
       }
  +
       
       //==============================================================
       // ContextModel
       //==============================================================
   
      /**
  +    * Return the set of entry models associated with this context model.
  +    * 
  +    * @return the entry models
  +    */
  +    public EntryModel[] getEntryModels()
  +    {
  +        return (EntryModel[]) m_map.values().toArray( new EntryModel[0] );
  +    }
  +
  +   /**
  +    * Return an entry model matching the supplied key.
  +    * 
  +    * @return the entry model or null if tyhe key is unknown
  +    */
  +    public EntryModel getEntryModel( String key )
  +    {
  +        return (EntryModel) m_map.get( key ); 
  +    }
  +
  +   /**
  +    * Set the entry model relative to a supplied key.
  +    * 
  +    * @param key the entry key
  +    * @param model the entry model
  +    */
  +    public void setEntryModel( String key, EntryModel model )
  +    {
  +        return m_map.put( key, model ); 
  +    }
  +
  +   /**
       * Return the class representing the contextualization stage interface.
       * 
       * @return the class representing the contextualization interface
  @@ -357,8 +351,7 @@
       }
   
      /**
  -    * Creates a compoent context using a deployment context that 
  -    * has been pre-populated with constom context entry models.
  +    * Creates a component context instance.
       * 
       * @param context the deployment context
       * @param descriptor the context descriptor
  @@ -369,13 +362,14 @@
       *   construct the context instance
       */
       private Context createComponentContext( 
  -      ComponentContext context, ContextDescriptor descriptor, ContextDirective directive )
  +      ComponentContext context, ContextDescriptor descriptor, 
  +      ContextDirective directive, Map map )
         throws ModelException
       {
           ClassLoader classLoader = context.getClassLoader();
           Class clazz = loadContextClass( directive, classLoader );
           validateCastingConstraint( descriptor, classLoader, clazz );
  -        Context base = new DefaultContext( context );
  +        Context base = new DefaultContext( map );
   
           if( clazz.equals( DefaultContext.class ) ) return base; 
   
  
  
  
  1.6       +77 -59    avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultImportModel.java
  
  Index: DefaultImportModel.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultImportModel.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- DefaultImportModel.java	10 Feb 2004 16:23:33 -0000	1.5
  +++ DefaultImportModel.java	22 Feb 2004 16:12:58 -0000	1.6
  @@ -20,6 +20,7 @@
   import java.util.Map;
   
   import org.apache.avalon.composition.model.ModelException;
  +import org.apache.avalon.composition.model.ContainmentModel;
   import org.apache.avalon.composition.provider.ComponentContext;
   
   import org.apache.avalon.excalibur.i18n.ResourceManager;
  @@ -51,13 +52,11 @@
       // immutable state
       //==============================================================
   
  -    private final ImportDirective m_directive;
  -
       private final EntryDescriptor m_descriptor;
   
  -    private final ComponentContext m_context;
  +    private final String m_key;
   
  -    private final Map m_map;
  +    private final ComponentContext m_context;
   
       //==============================================================
       // mutable state
  @@ -73,31 +72,44 @@
       * Creation of a new context entry import model.
       *
       * @param descriptor the context entry descriptor
  -    * @param directive the context entry directive
  +    * @param key the container scoped key
       * @param context the containment context
       */
       public DefaultImportModel( 
  -      EntryDescriptor descriptor, ImportDirective directive, 
  -      ComponentContext context, Map map )
  +      EntryDescriptor descriptor, String key, 
  +      ComponentContext context ) throws ModelException
       {
           super( descriptor );
  -        if( directive == null )
  +        if( key == null )
           {
  -            throw new NullPointerException( "directive" );
  +            throw new NullPointerException( "key" );
           }
           if( context == null )
           {
               throw new NullPointerException( "context" );
           }
  -        m_descriptor = descriptor;
  -        m_directive = directive;
  +
  +        m_key = key;
           m_context = context;
  -        m_map = map;
  +        m_descriptor = descriptor;
  +
  +        if( !DefaultContextModel.isaStandardKey( key ) )
  +        {
  +            final String error = 
  +              REZ.getString( 
  +                "context.non-standard-key.error", key );
  +            throw new ModelException( error );
  +        }
  +
  +        if( !descriptor.isVolatile() )
  +        {
  +            m_value = getValue();
  +        }
       }
   
  -    //==============================================================
  -    // ContainmentContext
  -    //==============================================================
  +    //--------------------------------------------------------------
  +    // EntryModel
  +    //--------------------------------------------------------------
   
      /**
       * Return the context entry value.
  @@ -106,64 +118,70 @@
       */
       public Object getValue() throws ModelException
       {
  -        if( m_value != null )
  +        if( m_value != null ) return m_value;
  +        return getStandardEntry( m_key );
  +    }
  +
  +
  +    private Object getStandardEntry( String key )
  +    {
  +        if( key.startsWith( "urn:avalon:" ) )
           {
  -            return m_value;
  +            return getStandardAvalonEntry( key );
           }
  -        
  -        String target = m_descriptor.getKey();
  -        String key = m_directive.getImportKey();
  -
  -        Object object = null;
  -        try
  +        else if( key.startsWith( "urn:composition:" ) )
           {
  -            object = m_context.resolve( key );
  +            return getStandardCompositionEntry( key );
           }
  -        catch( ContextException e )
  +        else
           {
  -            object = m_map.get( key );
  -            if( object == null )
  -            {
  -                final String error = 
  -                  REZ.getString( 
  -                    "import.missing-entry.error", key, target );
  -                    throw new ModelException( error );
  -            }
  +            final String error = 
  +              "Unknown key [" + key + "]";
  +            throw new IllegalArgumentException( error );
           }
  +    }
   
  -        //
  -        // validate the value before returning it
  -        // (should move this code up to the context model)
  -        //
  -
  -        String classname = m_descriptor.getClassname();
  -        
  -        Class clazz = null;
  -        try
  +    private Object getStandardAvalonEntry( String key )
  +    {
  +        if( key.equals( ComponentContext.NAME_KEY ) )
           {
  -            clazz = m_context.getClassLoader().loadClass( classname );
  +            return m_context.getName();
           }
  -        catch( Throwable e )
  +        else if( key.equals( ComponentContext.PARTITION_KEY ) )
           {
  -            final String error = 
  -              REZ.getString( 
  -                "import.load.error", target, classname );
  -            throw new ModelException( error, e );
  +            return m_context.getPartitionName();
           }
  -        
  -        if( !( clazz.isAssignableFrom( object.getClass() ) ) )
  +        else if( key.equals( ComponentContext.CLASSLOADER_KEY ) )
           {
  -            final String error = 
  -              REZ.getString( 
  -                "import.type-conflict.error", key, classname, target );
  -            throw new ModelException( error );
  +            return m_context.getClassLoader();
  +        }
  +        else if( key.equals( ComponentContext.HOME_KEY ) )
  +        {
  +            return m_context.getHomeDirectory();
  +        }
  +        else if( key.equals( ComponentContext.TEMP_KEY ) )
  +        {
  +            return m_context.getTempDirectory();
           }
  +        return null;
  +    }
   
  -        if( !m_descriptor.isVolatile() )
  +    private Object getStandardCompositionEntry( String key )
  +    {
  +        if( key.equals( ContainmentModel.KEY ) )
           {
  -            m_value = object;
  +            return m_context.getContainmentModel();
  +        }
  +        else
  +        {
  +            try
  +            {
  +                return m_context.getSystemContext().get( key );
  +            }
  +            catch( ContextException e )
  +            {
  +                return null;
  +            }
           }
  -        
  -        return object;
       }
   }
  
  
  
  1.7       +3 -0      avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/Resources.properties,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Resources.properties	10 Feb 2004 16:23:34 -0000	1.6
  +++ Resources.properties	22 Feb 2004 16:12:58 -0000	1.7
  @@ -102,7 +102,9 @@
   # ==================
   context.strategy.custom=custom strategy: {0}
   context.strategy.avalon=avalon strategy
  +context.non-standard-key.error=The component has requested a context entry that is not know within the family of standard context keys.  The offending key is: {0}.
   context.non-standard-avalon-key.error=The component has requested a Avalon context entry that is not know within the family of standard Avalon context keys.  The offending key is: {0}.
  +context.non-standard-system-key.error=The component has requested a system context entry that is not know within the family of standard context keys.  The offending key is: {0}.
   context.unknown-system-key.error=The component has requested a system context entry that is not know within the family of standard Merlin context keys.  The offending key is: {0}.
   context.missing-directive.error=The component has requested a non-avalon context entry. The container cannot resolve this request because no entry directive can be found the matches the key: {0}.
   context.unsupported-directive.error=The component has requested a context entry under the key [{0}]. The container cannot resolve this request because the entry directive type [{1}] is not supported at this time.
  @@ -116,6 +118,7 @@
   # DefaultContext
   # ==============
   context.entry.model.error=Cannot fulfill request due to an model-related error while attempting to resolve a context entry for the key: {0}.
  +context.entry.key.error=Unknown key: {0}.
   
   # DefaultConstructorModel
   # =======================
  
  
  
  1.1                  avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/OverrideEntryModel.java
  
  Index: OverrideEntryModel.java
  ===================================================================
  /* 
   * Copyright 2004 Apache Software Foundation
   * Licensed  under the  Apache License,  Version 2.0  (the "License");
   * you may not use  this file  except in  compliance with the License.
   * You may obtain a copy of the License at 
   * 
   *   http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed  under the  License is distributed on an "AS IS" BASIS,
   * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
   * implied.
   * 
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.avalon.composition.model.impl;
  
  import org.apache.avalon.meta.info.EntryDescriptor;
  
  /**
   * Utility class that enables assignment of an absolute value to a 
   * context entry.
   *
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2004/02/22 16:12:58 $
   */
  public class OverrideEntryModel extends DefaultEntryModel
  {
      //--------------------------------------------------------------
      // mutable state
      //--------------------------------------------------------------
  
      private Object m_value;
  
      //--------------------------------------------------------------
      // constructor
      //--------------------------------------------------------------
  
     /**
      * Creation of a new overriding context entry.
      *
      * @param descriptor the context entry descriptor
      * @param object the value to return for the entry
      * @param context the containment context
      */
      public OverrideEntryModel( 
        EntryDescriptor descriptor, Object value ) throws ModelException
      {
          super( descriptor );
          if( value == null )
          {
              throw new NullPointerException( "value" );
          }
          m_value = value;
      }
  
      //--------------------------------------------------------------
      // EntryModel
      //--------------------------------------------------------------
  
     /**
      * Return the context entry value.
      * 
      * @return the context entry value
      */
      public Object getValue()
      {
          return m_value;
      }
  }
  
  
  
  1.8       +46 -20    avalon/merlin/composition/impl/src/test/org/apache/avalon/composition/model/test/ContextTestCase.java
  
  Index: ContextTestCase.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/impl/src/test/org/apache/avalon/composition/model/test/ContextTestCase.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ContextTestCase.java	21 Feb 2004 23:54:42 -0000	1.7
  +++ ContextTestCase.java	22 Feb 2004 16:12:58 -0000	1.8
  @@ -32,6 +32,8 @@
      private static final String FACADE_CLASSNAME =
        "org.apache.avalon.composition.model.testa.DefaultFacade";
         
  +   private Context context;
  +
      //-------------------------------------------------------
      // constructor
      //-------------------------------------------------------
  @@ -41,42 +43,47 @@
           super( "context.xml" );
       }
   
  -   //-------------------------------------------------------
  -   // tests
  -   //-------------------------------------------------------
  -
  -   /**
  -    * Validate the composition model.
  -    */
  -    public void testStandardContextModel() throws Exception
  +    public void setUp() throws Exception
       {
  +        super.setUp();
  +
           ComponentModel model = (ComponentModel) m_model.getModel( "test-a" );
  -        if( model == null )
  +        if( null == model )
           {
  -            fail( "null deployment model" );
  +            throw new IllegalStateException( "null deployment model" );
           }
   
           ContextModel contextModel = model.getContextModel();
  -        if( contextModel == null )
  +        if( null == contextModel )
           {
  -            fail( "null context model" );
  +            throw new IllegalStateException( "null context model" );
           }
   
  -        Context context = contextModel.getContext();
  -        if( context == null )
  +        context = contextModel.getContext();
  +        if( null == context )
           {
  -            fail( "null context" );
  +            throw new IllegalStateException( "null context" );
           }
  +    }
   
  +   //-------------------------------------------------------
  +   // tests
  +   //-------------------------------------------------------
  +
  +    public void testClassLoader() throws Exception
  +    {
           try
           {
               ClassLoader loader = (ClassLoader) context.get( "urn:avalon:classloader" );
           }
           catch( ContextException e )
           {
  -            assertTrue( "urn:avalon:classloader", false );
  +            fail( "urn:avalon:classloader" );
           }
  -        
  +    }
  +
  +    public void testHomeDirectory() throws Exception
  +    {   
           try
           {
               File home = (File) context.get( "urn:avalon:home" );
  @@ -85,7 +92,10 @@
           {
               assertTrue( "urn:avalon:home", false );
           }
  +    }
   
  +    public void testTempDirectory() throws Exception
  +    {
           try
           {
               File temp = (File) context.get( "urn:avalon:temp" );
  @@ -94,16 +104,22 @@
           {
               assertTrue( "urn:avalon:temp", false );
           }
  +    }
   
  +    public void testPartition() throws Exception
  +    {
           try
           {
               String partition = (String) context.get( "urn:avalon:partition" );
           }
           catch( ContextException e )
           {
  -            assertTrue( "urn:avalon:partition", false );
  +            fail( "urn:avalon:partition" );
           }
  +    }
   
  +    public void testAlias() throws Exception
  +    {
           //
           // validate context entry lookup using an alias
           //
  @@ -114,8 +130,12 @@
           }
           catch( ContextException e )
           {
  -            assertTrue( "name", false );
  +            fail( "alias based lookup of the component name" );
           }
  +   }
  +
  +    public void testVolatile() throws Exception
  +    {
   
           //
           // validate volatile entries
  @@ -148,7 +168,10 @@
           {
               assertTrue( "now", false );
           }
  +    }
   
  +    public void testImport() throws Exception
  +    {
           //
           // validate an imported context entry
           //
  @@ -159,9 +182,12 @@
           }
           catch( ContextException e )
           {
  -            assertTrue( "path", false );
  +            fail( "path import" );
           }
  +    }
   
  +    public void testContextCasting() throws Exception
  +    {
           //
           // validate context safe-casting
           // (e.g. ((MyContext)m_context).myMethod() type of thing)
  
  
  
  1.2       +3 -3      avalon/merlin/composition/spi/src/java/org/apache/avalon/composition/provider/ComponentContext.java
  
  Index: ComponentContext.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/composition/spi/src/java/org/apache/avalon/composition/provider/ComponentContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ComponentContext.java	10 Feb 2004 16:23:35 -0000	1.1
  +++ ComponentContext.java	22 Feb 2004 16:12:58 -0000	1.2
  @@ -123,7 +123,7 @@
       * Add a context entry model to the deployment context.
       * @param model the entry model
       */
  -    public void register( EntryModel model );
  +    //public void register( EntryModel model );
   
      /**
       * Get a context entry from the deployment context.
  @@ -131,6 +131,6 @@
       * @return value the corresponding value
       * @exception ContextException if a key corresponding to the supplied alias is unknown
       */
  -    Object resolve( String alias ) throws ContextException;
  +    //Object resolve( String alias ) throws ContextException;
   
   }
  
  
  
  1.2       +9 -1      avalon/merlin/platform/tutorials/dynamics/conf/block.xml
  
  Index: block.xml
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/platform/tutorials/dynamics/conf/block.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- block.xml	21 Feb 2004 23:54:43 -0000	1.1
  +++ block.xml	22 Feb 2004 16:12:58 -0000	1.2
  @@ -1,6 +1,14 @@
   
   <container name="tutorial">
   
  -   <component name="hello" class="tutorial.HelloFacility" activation="startup"/>
  +     <classloader>
  +       <classpath>
  +         <repository>
  +           <resource id="avalon-framework:avalon-framework-impl" version="4.1.5"/>
  +         </repository>
  +       </classpath>
  +     </classloader>
  +
  +   <component name="facility" class="tutorial.HelloFacility" activation="startup"/>
   
   </container>
  
  
  
  1.2       +5 -0      avalon/merlin/platform/tutorials/dynamics/project.xml
  
  Index: project.xml
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/platform/tutorials/dynamics/project.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- project.xml	21 Feb 2004 23:54:43 -0000	1.1
  +++ project.xml	22 Feb 2004 16:12:58 -0000	1.2
  @@ -19,6 +19,11 @@
         <version>4.1.5</version>
       </dependency>
       <dependency>
  +      <groupId>avalon-framework</groupId>
  +      <artifactId>avalon-framework-impl</artifactId>
  +      <version>4.1.5</version>
  +    </dependency>
  +    <dependency>
         <groupId>avalon-composition</groupId>
         <artifactId>avalon-composition-api</artifactId>
         <version>2.0-SNAPSHOT</version>
  
  
  
  1.2       +18 -1     avalon/merlin/platform/tutorials/dynamics/src/java/tutorial/DefaultGizmo.java
  
  Index: DefaultGizmo.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/platform/tutorials/dynamics/src/java/tutorial/DefaultGizmo.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultGizmo.java	21 Feb 2004 23:54:43 -0000	1.1
  +++ DefaultGizmo.java	22 Feb 2004 16:12:58 -0000	1.2
  @@ -1,6 +1,9 @@
   package tutorial;
   
   import org.apache.avalon.framework.logger.Logger;
  +import org.apache.avalon.framework.configuration.Configurable;
  +import org.apache.avalon.framework.configuration.Configuration;
  +import org.apache.avalon.framework.configuration.ConfigurationException;
   
   /**
    * A component that implements the Gizmo service.
  @@ -8,7 +11,7 @@
    * @avalon.component name="gizmo" lifestyle="singleton"
    * @avalon.service type="tutorial.Gizmo"
    */
  -public class DefaultGizmo implements Gizmo
  +public class DefaultGizmo implements Gizmo, Configurable
   {
      //---------------------------------------------------------
      // immutable state
  @@ -32,4 +35,18 @@
          m_logger = logger;
          m_logger.info( "I've been created" );
      }
  +
  +   //---------------------------------------------------------
  +   // configurable
  +   //---------------------------------------------------------
  +
  +   /**
  +    * Configuration of the gizmo by the container.
  +    * @param config the supplied configuration
  +    */
  +    public void configure( Configuration config ) throws ConfigurationException
  +    {
  +        final String message = config.getChild( "message" ).getValue( "" );
  +        m_logger.info( "I've been configured with the message: [" + message + "]" );
  +    }
   }
  
  
  
  1.2       +45 -3     avalon/merlin/platform/tutorials/dynamics/src/java/tutorial/DefaultWidget.java
  
  Index: DefaultWidget.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/platform/tutorials/dynamics/src/java/tutorial/DefaultWidget.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultWidget.java	21 Feb 2004 23:54:43 -0000	1.1
  +++ DefaultWidget.java	22 Feb 2004 16:12:58 -0000	1.2
  @@ -1,14 +1,18 @@
   package tutorial;
   
   import org.apache.avalon.framework.logger.Logger;
  +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.activity.Disposable;
   
   /**
  - * A component that implements the Gizmo service.
  + * A component that implements the Widget service.
    *
    * @avalon.component name="widget" lifestyle="singleton"
    * @avalon.service type="tutorial.Widget"
    */
  -public class DefaultWidget implements Widget
  +public class DefaultWidget implements Widget, Configurable, Disposable
   {
      //---------------------------------------------------------
      // immutable state
  @@ -30,7 +34,45 @@
      public DefaultWidget( Logger logger )
      {
          m_logger = logger;
  -       m_logger.info( "I've been created" );
  +       m_logger.info( "hello" );
  +   }
  +
  +   //---------------------------------------------------------
  +   // Configurable
  +   //---------------------------------------------------------
  +
  +   /**
  +    * Configuration of the gizmo by the container.
  +    * @param config the supplied configuration
  +    */
  +    public void configure( Configuration config ) throws ConfigurationException
  +    {
  +        final String message = config.getChild( "message" ).getValue( null );
  +        if( null != message )
  +        {
  +            m_logger.info( message );
  +        }
  +    }
  +
  +   //---------------------------------------------------------
  +   // Disposable
  +   //---------------------------------------------------------
  +
  +  /**
  +   * End-of-life processing initiated by the container.
  +   */
  +   public void dispose()
  +   {
  +        m_logger.info( "time to die" );
  +   }
  +
  +   //---------------------------------------------------------
  +   // Object
  +   //---------------------------------------------------------
  +
  +   public String toString()
  +   {
  +       return "[widget:" + System.identityHashCode( this ) + "]";
      }
   }
   
  
  
  
  1.2       +52 -2     avalon/merlin/platform/tutorials/dynamics/src/java/tutorial/HelloFacility.java
  
  Index: HelloFacility.java
  ===================================================================
  RCS file: /home/cvs/avalon/merlin/platform/tutorials/dynamics/src/java/tutorial/HelloFacility.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- HelloFacility.java	21 Feb 2004 23:54:43 -0000	1.1
  +++ HelloFacility.java	22 Feb 2004 16:12:58 -0000	1.2
  @@ -2,12 +2,14 @@
   
   import org.apache.avalon.composition.model.ContainmentModel;
   import org.apache.avalon.composition.model.DeploymentModel;
  +import org.apache.avalon.composition.model.ComponentModel;
   
   import org.apache.avalon.framework.logger.Logger;
   import org.apache.avalon.framework.context.Context;
   import org.apache.avalon.framework.context.ContextException;
   import org.apache.avalon.framework.context.Contextualizable;
   import org.apache.avalon.framework.activity.Executable;
  +import org.apache.avalon.framework.configuration.DefaultConfiguration;
   
   import org.apache.avalon.meta.info.ReferenceDescriptor;
   
  @@ -75,8 +77,24 @@
      // Executable
      //---------------------------------------------------------
   
  +  /**
  +   * Request for execution trigger by the container.  The implementation
  +   * uses the containment model supplied during the contextualization phase
  +   * to dynamically respove a reference to a deployment model capable of 
  +   * supporting the Widget service interface.  The implementation uses this
  +   * model to instantiate the instance.  Subsequent steps in the example 
  +   * show the decommissining of the widget model, the modification of the 
  +   * model state (buy updating the models configuration) and the 
  +   * recommissioning of the model.  Finally a new widget instance is 
  +   * resolved and we can see (via logging messages) that the widget behaviour
  +   * has been modified as a result of the modification to the configuration.
  +   * 
  +   * @exception Exception is a runtime error occurs
  +   */
      public void execute() throws Exception
      {
  +       getLogger().info( "looking for a widget" );
  +
          //
          // create a reference to the widget service
          //
  @@ -87,16 +105,48 @@
          // get hold of a model representing a widget deployment scenario
          //
   
  -       DeploymentModel model = m_model.getModel( reference );
  -       getLogger().info( "got the widget model: " + model );
  +       ComponentModel model = (ComponentModel) m_model.getModel( reference );
  +       getLogger().info( "got a widget model: " + model );
   
          //
          // commission the model and resolve a component instance
          //
   
  +       getLogger().info( "commissioning the widget model" );
          model.commission();
          Widget widget = (Widget) model.resolve();
  +       getLogger().info( "got a widget instance: " + widget );
  +
  +       getLogger().info( "releasing the widget" );
  +       model.release( widget );
  +
  +       getLogger().info( "time for a change" );
  +       getLogger().info( "decommissioning the widget model" );
  +       model.decommission();
  +
  +       //
  +       // create an alternative configuration and apply it to the 
  +       // widget model
  +       //
  +
  +       getLogger().info( "building alternative configuration" );
  +       DefaultConfiguration message = new DefaultConfiguration( "message" );
  +       message.setValue( "bonjour!" );
  +       DefaultConfiguration config = new DefaultConfiguration( "config" );
  +       config.addChild( message );
  +       model.setConfiguration( config );
  +
  +       //
  +       // redeploy the model and create a new instance
  +       //
  +
  +       getLogger().info( "recommissioning the widget model" );
  +       model.commission();
  +       widget = (Widget) model.resolve();
          getLogger().info( "got the widget instance: " + widget );
  +       model.release( widget );
  +       model.decommission();
  +
      }
   
      //---------------------------------------------------------
  
  
  

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