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 2003/07/22 06:11:58 UTC
cvs commit: avalon-sandbox/merlin/merlin-extensions/merlin-jndi/src/java/org/apache/avalon/merlin/jndi ServiceFactory.java
mcconnell 2003/07/21 21:11:58
Modified: merlin maven.xml
merlin/composition/src/java/org/apache/avalon/composition/model/impl
DefaultClassLoaderModel.java
DefaultDependencyModel.java Resources.properties
merlin/composition/src/test/org/apache/avalon/composition/model/test
DependencyTestCase.java
merlin/composition-spi/src/java/org/apache/avalon/composition/data
DependencyDirective.java
merlin/composition-spi/src/java/org/apache/avalon/composition/model
DependencyModel.java
merlin/merlin-extensions/merlin-jndi/src/java/org/apache/avalon/merlin/jndi
ServiceFactory.java
Log:
Fixed a couple of exception throws that wer using 1.4 constructors and updated the composition package to handle service filtering.
Revision Changes Path
1.28 +0 -2 avalon-sandbox/merlin/maven.xml
Index: maven.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/maven.xml,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- maven.xml 14 Jul 2003 22:07:27 -0000 1.27
+++ maven.xml 22 Jul 2003 04:11:56 -0000 1.28
@@ -232,8 +232,6 @@
<j:forEach var="packageGroup" items="${pom.packageGroups}">
<group title="${packageGroup.title}" packages="${packageGroup.packages}"/>
</j:forEach>
- <sourcepath path="${basedir}/../meta-spi/src/java"/>
- <sourcepath path="${basedir}/../meta/src/java"/>
<sourcepath path="${basedir}/../extension-spi/src/java"/>
<sourcepath path="${basedir}/../extension/src/java"/>
<!--
1.13 +3 -3 avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultClassLoaderModel.java
Index: DefaultClassLoaderModel.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultClassLoaderModel.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- DefaultClassLoaderModel.java 17 Jul 2003 21:21:57 -0000 1.12
+++ DefaultClassLoaderModel.java 22 Jul 2003 04:11:57 -0000 1.13
@@ -549,7 +549,7 @@
}
private Manifest[] getManifests( final String[] classPath )
- throws Exception
+ throws ModelException
{
final ArrayList manifests = new ArrayList();
for( int i = 0; i < classPath.length; i++ )
@@ -579,7 +579,7 @@
{
final String message =
REZ.getString( "classloader.bad-classpath-entry.error", element );
- throw new Exception( message, ioe );
+ throw new ModelException( message, ioe );
}
}
}
1.3 +315 -16 avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDependencyModel.java
Index: DefaultDependencyModel.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDependencyModel.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DefaultDependencyModel.java 19 Jul 2003 06:16:42 -0000 1.2
+++ DefaultDependencyModel.java 22 Jul 2003 04:11:57 -0000 1.3
@@ -62,11 +62,13 @@
import org.apache.avalon.composition.model.Model;
import org.apache.avalon.composition.model.ModelException;
import org.apache.avalon.composition.data.DependencyDirective;
+import org.apache.avalon.composition.data.SelectionDirective;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.meta.info.DependencyDescriptor;
+import org.apache.avalon.meta.info.ServiceDescriptor;
/**
* Default implementation of the deplendency model.
@@ -95,6 +97,8 @@
private final String m_name;
+ private final Map m_paths = new Hashtable();
+
//==============================================================
// mutable state
//==============================================================
@@ -125,6 +129,26 @@
m_partition = partition;
m_name = name;
+ //
+ // a dependency directive is either declaring an explicitly
+ // identified provider, or, it is delcaring 0 or more selection
+ // constraints - if its a an absolute source declaration then
+ // add it to the table to paths keyed by depedency key names
+ //
+
+ for( int i=0; i<directives.length; i++ )
+ {
+ DependencyDirective directive = directives[i];
+ if( directive.getSource() != null )
+ {
+ String source = resolvePath( m_partition, directive.getSource() );
+ m_paths.put( directive.getKey(), source );
+
+ final String message =
+ REZ.getString( "dependency.path.debug", source, directive.getKey() );
+ getLogger().debug( message );
+ }
+ }
}
//==============================================================
@@ -132,10 +156,31 @@
//==============================================================
/**
+ * Return an explicit path to a component relative to a supplied
+ * dependency key. If a dependency directive has been declared
+ * and the directive contains a source declaration, the value
+ * returned is the result of parsing the source value relative
+ * to the absolute address of the implementing component.
+ *
+ * @return the explicit path
+ * @exception IllegalArgumentException if the key is unknown
+ */
+ public String getPath( String key ) throws IllegalArgumentException
+ {
+ if( !valideKey( key ) )
+ {
+ final String error =
+ REZ.getString( "dependency.bad-key.error", key, m_partition, m_name );
+ throw new IllegalArgumentException( error );
+ }
+ return (String) m_paths.get( key );
+ }
+
+ /**
* Return the set of dependecies for the model.
*
* @return the the set of descriptors declaring the component
- * depedencies
+ * dependencies
*/
public DependencyDescriptor[] getDependencies()
{
@@ -151,35 +196,251 @@
* @param candidates the set of candidate models
* @return the selected candidate
*/
- public Model select( String key, Model[] candidates )
+ public Model select( String key, Model[] candidates ) throws ModelException
{
DependencyDirective directive = getDirective( key );
if( directive != null )
{
- if( directive != null )
+ if( directive.getSource() != null )
{
- if( directive.getSource() != null )
+ //
+ // its an explicit assignment
+ //
+
+ String path = directive.getSource();
+ String source = resolvePath( m_partition, path );
+ for( int i=0; i<candidates.length; i++ )
{
- String path = directive.getSource();
- String source = resolvePath( m_partition, path );
- for( int i=0; i<candidates.length; i++ )
+ final Model candidate = candidates[i];
+ final String name = candidate.getQualifiedName();
+ if( source.equals( name ) )
{
- final Model candidate = candidates[i];
- final String name = candidate.getQualifiedName();
- if( source.equals( name ) )
- {
- getLogger().debug(
- "selected [" + name + "] for key ["
- + key + "] using [" + path + "].");
- return candidate;
- }
+ getLogger().debug(
+ "selected [" + name + "] for key ["
+ + key + "] using [" + path + "].");
+ return candidate;
}
}
+
+ //
+ // and if we get here it means that the explicit
+ // directive did not lead to a resolvable solution
+ // so we need to get nasty and throw an exception
+ //
+
+ final String error =
+ REZ.getString(
+ "dependency.unresolvable-directive.error",
+ key, m_partition, m_name, path );
+ throw new ModelException( error );
}
}
return null;
}
+ /**
+ * Filter a set of candidate service descriptors and return the
+ * set of acceptable service as a ordered sequence.
+ *
+ * @param key the dependency key
+ * @param candidates the set of candidate services for the dependency
+ * matching the supplied key
+ * @return the accepted candidates in ranked order
+ * @exception IllegalArgumentException if the key is unknown
+ */
+ public ServiceDescriptor[] filter( String key, ServiceDescriptor[] candidates )
+ {
+ if( !valideKey( key ) )
+ {
+ final String error =
+ REZ.getString( "dependency.bad-key.error", key, m_partition, m_name );
+ throw new IllegalArgumentException( error );
+ }
+
+ DependencyDirective directive = getDirective( key );
+ if( directive != null )
+ {
+ if( directive.getSource() == null )
+ {
+ return filter( directive, candidates );
+ }
+ }
+ return candidates;
+ }
+
+ /**
+ * Filter a set of candidate service descriptors and return the
+ * set of acceptable service as a ordered sequence.
+ *
+ * @param key the dependency directive
+ * @param candidates the set of candidate services for the dependency
+ * @return the accepted candidates in ranked order
+ */
+ private ServiceDescriptor[] filter(
+ DependencyDirective directive, ServiceDescriptor[] services )
+ {
+ SelectionDirective[] filters = getFilters( directive );
+ ArrayList list = new ArrayList();
+
+ for( int i=0; i<services.length; i++ )
+ {
+ ServiceDescriptor service = services[i];
+ if( isaCandidate( service, filters ) )
+ {
+ list.add( service );
+ }
+ }
+
+ ServiceDescriptor[] candidates =
+ (ServiceDescriptor[]) list.toArray( new ServiceDescriptor[0] );
+
+ //
+ // TODO: include ranking of candidates
+ //
+
+ return candidates;
+ }
+
+ private boolean isaCandidate(
+ ServiceDescriptor service, SelectionDirective[] filters )
+ {
+ for( int i=0; i<filters.length; i++ )
+ {
+ SelectionDirective filter = filters[i];
+ if( !isaCandidate( service, filter ) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean isaCandidate(
+ ServiceDescriptor service, SelectionDirective filter )
+ {
+ final String feature = filter.getFeature();
+ final String value = filter.getValue();
+ final String criteria = filter.getCriteria();
+
+ if( criteria.equals( SelectionDirective.EQUALS ) )
+ {
+ return value.equals( service.getAttribute( feature ) );
+ }
+ else if( criteria.equals( SelectionDirective.EXISTS ) )
+ {
+ return service.getAttribute( feature ) != null;
+ }
+ else if( criteria.equals( SelectionDirective.INCLUDES ) )
+ {
+ final String v = service.getAttribute( feature );
+ if( v != null )
+ {
+ return v.indexOf( value ) > -1;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ final String error =
+ REZ.getString( "dependency.invalid-criteria.error", criteria, feature );
+ throw new IllegalArgumentException( error );
+ }
+ }
+
+
+ /**
+ * Rank a service relative to the service it provides matching
+ * the dependency key.
+ *
+ * @param directive the dependency directive
+ * @param candidate a candidate model
+ */
+/*
+ private int rank( DependencyDirective directive, ServiceDescriptor service )
+ {
+ int n = 0;
+ SelectionDirective[] selections =
+ directive.getSelectionDirectives();
+ for( int i=0; i<selections.length; i++ )
+ {
+ int ranking = rank( service, selections[i] );
+ if( ranking > -1 )
+ {
+ n = n + ranking;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ return n;
+ }
+
+ private int rank( ServiceDescriptor service, SelectionDirective directive )
+ {
+ String feature = directive.getFeature();
+ String value = directive.getValue();
+ if( directive.getCriteria().equals( SelectionDirective.EQUALS ) )
+ {
+ if( value.equals( service.getAttribute( feature ) )
+ {
+ return 1;
+ }
+ else
+ {
+ if( directive.isRequired() )
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+ else if( directive.getCriteria().equals( SelectionDirective.INCLUDES ) )
+ {
+ final String v = service.getAttribute( feature );
+ if( v != null )
+ {
+ if( v.indexOf( value ) > -1 )
+ {
+ return 1;
+ }
+ }
+ if( directive.isRequired() )
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else if( directive.getCriteria().equals( SelectionDirective.EXISTS ) )
+ {
+ if( service.getAttribute( feature ) != null )
+ {
+ return 1;
+ }
+ else
+ {
+ if( directive.isRequired() )
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+ }
+*/
+
private String resolvePath( String partition, String path )
{
if( path.startsWith( "/" ) )
@@ -232,5 +493,43 @@
if( directive.getKey().equals( key ) ) return directive;
}
return null;
+ }
+
+ /**
+ * Validate that a key is known withing the set of
+ * dependency descriptors.
+ * @param key the key to validate
+ * @return TRUE if the key is known
+ */
+ private boolean valideKey( final String key )
+ {
+ for( int i=0; i<m_descriptors.length; i++ )
+ {
+ if( m_descriptors[i].getKey().equals( key ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the required selection constraints.
+ * @param directive the dependency directive
+ * @return the set of required selection directives
+ */
+ private SelectionDirective[] getFilters( DependencyDirective directive )
+ {
+ ArrayList list = new ArrayList();
+ SelectionDirective[] selections = directive.getSelectionDirectives();
+ for( int i=0; i<selections.length; i++ )
+ {
+ SelectionDirective selection = selections[i];
+ if( selection.isRequired() )
+ {
+ list.add( selection );
+ }
+ }
+ return (SelectionDirective[]) list.toArray( new SelectionDirective[0] );
}
}
1.13 +7 -0 avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/Resources.properties
Index: Resources.properties
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/Resources.properties,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Resources.properties 19 Jul 2003 06:16:42 -0000 1.12
+++ Resources.properties 22 Jul 2003 04:11:57 -0000 1.13
@@ -105,3 +105,10 @@
constructor.directive.load.error=The constructor entry directive declared under the key [{0}] references a class [{1}] that that could not be loaded due to an runtime error.
constructor.invalid-model.error=The component type declares a dependency under the context entry [{0}] on a runtime entry of the type [{1}], however, the corresponding directive declares a constructor that establishes an instance of the class [{2}] which does not implement or extend the class declared by the directive.
+# DefaultDependencyModel
+# ======================
+dependency.unresolvable-directive.error=Unable to resolve a candidate deployment model for the dependency key [{0}] in the deployment model [{1}{2}] relative to the declared source directive [{3}].
+dependency.bad-key.error=The supplied key [{0}] is unknown within the model [{1}{2}].
+dependency.incompatible.error=Cannot process a selection for key [{0}] because an source directive has been declared.
+dependency.invalid-criteria.error=Unknown criteria: [{0}] declared under the selection criteria referencing the feature: [{1}].
+dependency.path.debug=Assigned source [{0}] for the dependency key [{1}].
\ No newline at end of file
1.3 +2 -12 avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/model/test/DependencyTestCase.java
Index: DependencyTestCase.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/model/test/DependencyTestCase.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DependencyTestCase.java 19 Jul 2003 06:16:42 -0000 1.2
+++ DependencyTestCase.java 22 Jul 2003 04:11:57 -0000 1.3
@@ -61,20 +61,10 @@
fail( "null dependency descriptor array" );
}
- Model[] candidates = new Model[]{ a, b };
for( int i=0; i<deps.length; i++ )
{
String key = deps[i].getKey();
- try
- {
- Model selection = dependencyModel.select( key, candidates );
- assertNotNull( "selection for key: " + key, selection );
- }
- catch( Throwable e )
- {
- e.printStackTrace();
- fail( "resolving explicit dependency directive failed for key: " + key );
- }
+ assertNotNull( "selection for key: " + key, dependencyModel.getPath( key ) );
}
- }
+ }
}
1.2 +1 -2 avalon-sandbox/merlin/composition-spi/src/java/org/apache/avalon/composition/data/DependencyDirective.java
Index: DependencyDirective.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition-spi/src/java/org/apache/avalon/composition/data/DependencyDirective.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DependencyDirective.java 17 Jul 2003 21:21:58 -0000 1.1
+++ DependencyDirective.java 22 Jul 2003 04:11:57 -0000 1.2
@@ -129,5 +129,4 @@
{
return m_features;
}
-
}
1.2 +25 -13 avalon-sandbox/merlin/composition-spi/src/java/org/apache/avalon/composition/model/DependencyModel.java
Index: DependencyModel.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition-spi/src/java/org/apache/avalon/composition/model/DependencyModel.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DependencyModel.java 19 Jul 2003 05:25:35 -0000 1.1
+++ DependencyModel.java 22 Jul 2003 04:11:57 -0000 1.2
@@ -51,6 +51,7 @@
package org.apache.avalon.composition.model;
import org.apache.avalon.meta.info.DependencyDescriptor;
+import org.apache.avalon.meta.info.ServiceDescriptor;
/**
* Dependency model defintion.
@@ -60,24 +61,35 @@
*/
public interface DependencyModel
{
-
/**
* Return the set of dependecies for the model.
*
* @return the the set of descriptors declaring the component
- * depedencies
+ * dependencies
*/
DependencyDescriptor[] getDependencies();
- /**
- * Select a model for a set of candidates taking into account the
- * the depedency directives and dependency descriptors associated
- * with the component type that this model is representing.
- *
- * @param key the dependency key
- * @param candidates the set of candidate models
- * @return the selected candidate
- */
- Model select( String key, Model[] candidates );
+ /**
+ * Return an explicit path to a component relative to a supplied
+ * dependency key. If a dependency directive has been declared
+ * and the directive contains a source declaration, the value
+ * returned is the result of parsing the source value relative
+ * to the absolute address of the implementing component.
+ *
+ * @return the explicit path
+ * @exception IllegalArgumentException if the key is unknown
+ */
+ String getPath( String key ) throws IllegalArgumentException;
+
+ /**
+ * Filter a set of candidate service descriptors and return the
+ * set of acceptable service as a andered sequence.
+ *
+ * @param key the dependency key
+ * @param candidates the set of candidate services for the dependency
+ * matching the supplied key
+ * @return the accepted candidates in ranked order
+ */
+ ServiceDescriptor[] filter( String key, ServiceDescriptor[] candidates );
}
1.5 +9 -38 avalon-sandbox/merlin/merlin-extensions/merlin-jndi/src/java/org/apache/avalon/merlin/jndi/ServiceFactory.java
Index: ServiceFactory.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/merlin-extensions/merlin-jndi/src/java/org/apache/avalon/merlin/jndi/ServiceFactory.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ServiceFactory.java 12 Jun 2003 18:56:20 -0000 1.4
+++ ServiceFactory.java 22 Jul 2003 04:11:57 -0000 1.5
@@ -174,58 +174,29 @@
}
}
- private Object loadKernel( ClassLoader loader, Map map )
+ private Object loadKernel( ClassLoader loader, Map map ) throws Exception
{
Thread.currentThread().setContextClassLoader( loader );
Object kernelLoader = null;
- Class clazz;
+
//
// load the kernel loader class from the supplied classloader
+ // and instantiate the loader
//
- try
- {
- clazz = loader.loadClass( MERLIN_KERNEL_LOADER_CLASSNAME );
- }
- catch( Throwable e )
- {
- final String error =
- "Internal error during loader class creation.";
- throw new RuntimeException( error, e );
- }
+ Class clazz = loader.loadClass( MERLIN_KERNEL_LOADER_CLASSNAME );
- //
- // instantiate the loader
- //
-
- try
- {
- Constructor constructor = clazz.getConstructor( new Class[0] );
- kernelLoader = constructor.newInstance( new Object[0] );
- }
- catch( Throwable e )
- {
- final String error =
- "Internal error during loader instantiation.";
- throw new RuntimeException( error, e );
- }
+ Constructor constructor = clazz.getConstructor( new Class[0] );
+ kernelLoader = constructor.newInstance( new Object[0] );
//
// create the kernel instance
//
- try
- {
- Method method = kernelLoader.getClass().getMethod( "build", new Class[]{ Map.class } );
- return method.invoke( kernelLoader, new Object[]{ map } );
- }
- catch( Throwable e )
- {
- final String error =
- "Internal error during kernel resolution.";
- throw new RuntimeException( error, e );
- }
+ Method method =
+ kernelLoader.getClass().getMethod( "build", new Class[]{ Map.class } );
+ return method.invoke( kernelLoader, new Object[]{ map } );
}
private static URL[] getJarFiles( File base )
---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org