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