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/25 00:14:55 UTC
cvs commit: avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/data/test DeploymentProfileTestCase.java
mcconnell 2003/07/24 15:14:55
Modified: merlin/composition/src/java/org/apache/avalon/composition/data/builder
XMLDeploymentProfileCreator.java
merlin/composition/src/java/org/apache/avalon/composition/data/writer
XMLDeploymentProfileWriter.java
merlin/composition/src/java/org/apache/avalon/composition/model/impl
DefaultDeploymentModel.java
merlin/composition/src/test/org/apache/avalon/composition/data/test
DeploymentProfileTestCase.java
Added: merlin/composition/src/java/org/apache/avalon/composition/model/impl
DefaultStageModel.java
Log:
Implementation of a stage model that provides suppport for the explicit declaration of a stage provider (via component address) or via extension selection constrain filtering.
Revision Changes Path
1.2 +48 -5 avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/data/builder/XMLDeploymentProfileCreator.java
Index: XMLDeploymentProfileCreator.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/data/builder/XMLDeploymentProfileCreator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XMLDeploymentProfileCreator.java 17 Jul 2003 21:21:56 -0000 1.1
+++ XMLDeploymentProfileCreator.java 24 Jul 2003 22:14:55 -0000 1.2
@@ -111,14 +111,16 @@
getContextDirective( config.getChild( "context", false ) );
final DependencyDirective[] dependencies =
getDependencyDirectives( config.getChild( "dependencies" ) );
+ final StageDirective[] stages =
+ getStageDirectives( config.getChild( "stages" ) );
final Parameters params =
getParameters( config.getChild( "parameters", false ) );
final Configuration configuration =
config.getChild( "configuration", false );
return new DeploymentProfile(
- name, activation, classname, categories, context, dependencies, params,
- configuration, Mode.EXPLICIT );
+ name, activation, classname, categories, context, dependencies,
+ stages, params, configuration, Mode.EXPLICIT );
}
protected DependencyDirective[] getDependencyDirectives( Configuration config )
@@ -160,6 +162,45 @@
}
}
+ protected StageDirective[] getStageDirectives( Configuration config )
+ throws ConfigurationException
+ {
+ if( config != null )
+ {
+ ArrayList list = new ArrayList();
+ Configuration[] deps = config.getChildren( "stage" );
+ for( int i=0; i<deps.length; i++ )
+ {
+ list.add( getStageDirective( deps[i] ) );
+ }
+ return (StageDirective[]) list.toArray( new StageDirective[0] );
+ }
+ return new StageDirective[0];
+ }
+
+ protected StageDirective getStageDirective( Configuration config )
+ throws ConfigurationException
+ {
+ final String key = config.getAttribute( "key" );
+ final String source = config.getAttribute( "source", null );
+ if( source != null )
+ {
+ return new StageDirective( key, source );
+ }
+ else
+ {
+ Configuration[] children = config.getChildren( "select" );
+ ArrayList list = new ArrayList();
+ for( int i=0; i<children.length; i++ )
+ {
+ list.add( getSelectionDirective( children[i] ) );
+ }
+ SelectionDirective[] features =
+ (SelectionDirective[]) list.toArray( new SelectionDirective[0] );
+ return new StageDirective( key, features );
+ }
+ }
+
protected SelectionDirective getSelectionDirective( Configuration config )
throws ConfigurationException
{
@@ -170,14 +211,16 @@
return new SelectionDirective( feature, value, match, optional );
}
- protected CategoriesDirective getCategoriesDirective( Configuration config, String name )
+ protected CategoriesDirective getCategoriesDirective(
+ Configuration config, String name )
throws ConfigurationException
{
if( config != null )
{
String priority = config.getAttribute( "priority", null );
String target = target = config.getAttribute( "target", null );
- CategoryDirective[] categories = getCategoryDirectives( config.getChildren( "category" ) );
+ CategoryDirective[] categories =
+ getCategoryDirectives( config.getChildren( "category" ) );
return new CategoriesDirective( name, priority, target, categories );
}
return null;
1.2 +54 -2 avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/data/writer/XMLDeploymentProfileWriter.java
Index: XMLDeploymentProfileWriter.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/data/writer/XMLDeploymentProfileWriter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XMLDeploymentProfileWriter.java 17 Jul 2003 21:21:57 -0000 1.1
+++ XMLDeploymentProfileWriter.java 24 Jul 2003 22:14:55 -0000 1.2
@@ -68,6 +68,7 @@
import org.apache.avalon.composition.data.ImportDirective;
import org.apache.avalon.composition.data.EntryDirective;
import org.apache.avalon.composition.data.ConstructorDirective;
+import org.apache.avalon.composition.data.StageDirective;
import org.apache.avalon.composition.data.Parameter;
import org.apache.excalibur.configuration.ConfigurationUtil;
@@ -132,6 +133,7 @@
writeCategories( writer, profile.getCategories(), pad );
writeContext( writer, profile.getContext(), pad );
writeDependencies( writer, profile.getDependencyDirectives(), pad );
+ writeStages( writer, profile.getStageDirectives(), pad );
writeConfiguration( writer, profile.getConfiguration(), pad );
writeParameters( writer, profile.getParameters(), pad );
}
@@ -187,7 +189,57 @@
}
/**
- * Write out xml representation of a dependency selection directive.
+ * Write out xml representation of the dependency directives.
+ *
+ * @param writer the writer
+ * @param dependencies the dependency directives
+ * @throws IOException if unable to write xml
+ */
+ private void writeStages(
+ final Writer writer, final StageDirective[] stages, String pad )
+ throws IOException
+ {
+ if( stages.length == 0 ) return;
+ writer.write( "\n" + pad + "<stages>" );
+ final String padding = pad + INDENT;
+ for( int i=0; i<stages.length; i++ )
+ {
+ writeStage( writer, stages[i], padding );
+ }
+ writer.write( "\n" + pad + "</stages>" );
+ }
+
+ /**
+ * Write out xml representation of a stage directive.
+ *
+ * @param writer the writer
+ * @param stage the stage directive
+ * @throws IOException if unable to write xml
+ */
+ private void writeStage(
+ final Writer writer, final StageDirective stage, String pad )
+ throws IOException
+ {
+ writer.write( "\n" + pad + "<stage key=\"" + stage.getKey() + "\"" );
+ if( stage.getSource() != null )
+ {
+ writer.write( " source=\"" + stage.getSource() + "\"/>" );
+ }
+ else
+ {
+ writer.write( ">" );
+ SelectionDirective[] features = stage.getSelectionDirectives();
+ final String padding = pad + INDENT;
+ for( int i=0; i<features.length; i++ )
+ {
+ writeSelectionDirective( writer, features[i], padding );
+ }
+ writer.write( "\n" + pad + "</stage>" );
+ }
+ }
+
+ /**
+ * Write out xml representation of a selection directive.
*
* @param writer the writer
* @param feature the dependency selection directive
1.17 +39 -3 avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDeploymentModel.java
Index: DefaultDeploymentModel.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDeploymentModel.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- DefaultDeploymentModel.java 24 Jul 2003 13:14:54 -0000 1.16
+++ DefaultDeploymentModel.java 24 Jul 2003 22:14:55 -0000 1.17
@@ -64,7 +64,9 @@
import org.apache.avalon.composition.model.ClassLoaderModel;
import org.apache.avalon.composition.model.ModelException;
import org.apache.avalon.composition.model.SystemContext;
+import org.apache.avalon.composition.model.StageModel;
import org.apache.avalon.composition.data.DependencyDirective;
+import org.apache.avalon.composition.data.StageDirective;
import org.apache.avalon.composition.repository.Repository;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
@@ -120,6 +122,8 @@
private final DependencyModel[] m_dependencies;
+ private final StageModel[] m_stages;
+
//==============================================================
// mutable state
//==============================================================
@@ -230,6 +234,29 @@
descriptor,
directive );
}
+
+ //
+ // create the stage models for subsequent assembly
+ // management
+ //
+
+ StageDescriptor[] stages =
+ m_context.getType().getStages();
+ m_stages = new DefaultStageModel[ stages.length ];
+
+ for( int i=0; i<stages.length; i++ )
+ {
+ StageDescriptor descriptor = stages[i];
+ StageDirective directive =
+ context.getProfile().getStageDirective( descriptor.getKey() );
+ m_stages[i] =
+ new DefaultStageModel(
+ context.getLogger().getChildLogger( "stages" ),
+ context.getPartitionName(),
+ context.getProfile().getName(),
+ descriptor,
+ directive );
+ }
}
//==============================================================
@@ -517,15 +544,24 @@
}
/**
- * Return the dependency model for this component type.
+ * Return the dependency models for this component type.
*
- * @return the dependency model
+ * @return the dependency models
*/
public DependencyModel[] getDependencyModels()
{
return m_dependencies;
}
+ /**
+ * Return the stage models for this component type.
+ *
+ * @return the stage models
+ */
+ public StageModel[] getStageModels()
+ {
+ return m_stages;
+ }
//==============================================================
// implementation
1.1 avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultStageModel.java
Index: DefaultStageModel.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
"Apache Software Foundation" must not be used to endorse or promote
products derived from this software without prior written
permission. For written permission, please contact apache@apache.org.
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation. For more information on the
Apache Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.avalon.composition.model.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Hashtable;
import java.util.Map;
import org.apache.avalon.composition.model.DeploymentContext;
import org.apache.avalon.composition.model.StageModel;
import org.apache.avalon.composition.model.Model;
import org.apache.avalon.composition.model.ModelException;
import org.apache.avalon.composition.data.StageDirective;
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.StageDescriptor;
import org.apache.avalon.meta.info.ExtensionDescriptor;
/**
* Default implementation of the stage model.
*
* @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2003/07/24 22:14:55 $
*/
public class DefaultStageModel extends AbstractLogEnabled implements StageModel
{
//==============================================================
// static
//==============================================================
private static final Resources REZ =
ResourceManager.getPackageResources( DefaultDependencyModel.class );
//==============================================================
// immutable state
//==============================================================
private final StageDescriptor m_descriptor;
private final StageDirective m_directive;
private final String m_partition;
private final String m_name;
private final String m_source;
//==============================================================
// constructor
//==============================================================
/**
* Creation of a new stage model.
*
* @param logger the logging channel
* @param descriptors the dependency descriptors
* @param directives the dependency directives (possibly null)
*/
public DefaultStageModel(
final Logger logger, final String partition, final String name,
final StageDescriptor descriptor, StageDirective directive )
throws ModelException
{
if( logger == null ) throw new NullPointerException( "logger" );
if( descriptor == null ) throw new NullPointerException( "descriptor" );
enableLogging( logger );
m_descriptor = descriptor;
m_directive = directive;
m_partition = partition;
m_name = name;
//
// a stage directive is either declaring with an explicitly
// identified provider, or, it is delcaring 0 or more selection
// constraints - if its an absolute source declaration then
// resolve it now
//
if( directive != null )
{
if( directive.getSource() != null )
{
m_source = resolvePath( partition, directive.getSource() );
final String message =
REZ.getString( "dependency.path.debug", m_source, directive.getKey() );
getLogger().debug( message );
}
else
{
m_source = null;
}
}
else
{
m_source = null;
}
}
//==============================================================
// StageModel
//==============================================================
/**
* Return the stage descriptor.
*
* @return the descriptor
*/
public StageDescriptor getStage()
{
return m_descriptor;
}
/**
* Return an explicit path to a supplier component.
* If a stage 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 dependent component.
*
* @return the explicit path
*/
public String getPath()
{
return m_source;
}
/**
* Filter a set of candidate extension descriptors and return the
* set of acceptable extensions as a ordered sequence.
*
* @param candidates the set of candidate stage providers
* @return the accepted candidates in ranked order
*/
public ExtensionDescriptor[] filter( ExtensionDescriptor[] candidates )
{
if( m_directive != null )
{
if( m_directive.getSource() == null )
{
return filter( m_directive, candidates );
}
}
return candidates;
}
/**
* Filter a set of candidate service descriptors and return the
* set of acceptable stage providers 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 ExtensionDescriptor[] filter(
StageDirective directive, ExtensionDescriptor[] providers )
{
SelectionDirective[] filters = getFilters( directive );
ArrayList list = new ArrayList();
for( int i=0; i<providers.length; i++ )
{
ExtensionDescriptor provider = providers[i];
if( isaCandidate( provider, filters ) )
{
list.add( provider );
}
}
ExtensionDescriptor[] candidates =
(ExtensionDescriptor[]) list.toArray( new ExtensionDescriptor[0] );
//
// TODO: include ranking of candidates
//
return candidates;
}
private boolean isaCandidate(
ExtensionDescriptor provider, SelectionDirective[] filters )
{
for( int i=0; i<filters.length; i++ )
{
SelectionDirective filter = filters[i];
if( !isaCandidate( provider, filter ) )
{
return false;
}
}
return true;
}
private boolean isaCandidate(
ExtensionDescriptor provider, 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( provider.getAttribute( feature ) );
}
else if( criteria.equals( SelectionDirective.EXISTS ) )
{
return provider.getAttribute( feature ) != null;
}
else if( criteria.equals( SelectionDirective.INCLUDES ) )
{
final String v = provider.getAttribute( feature );
if( v != null )
{
return v.indexOf( value ) > -1;
}
else
{
return false;
}
}
else
{
final String error =
REZ.getString( "stage.invalid-criteria.error", criteria, feature );
throw new IllegalArgumentException( error );
}
}
private String resolvePath( String partition, String path )
{
if( path.startsWith( "/" ) )
{
return path;
}
else if( path.startsWith( "../" ) )
{
final String parent = getParentPath( partition );
return resolvePath( parent, path.substring( 3 ) );
}
else if( path.startsWith( "./" ) )
{
return resolvePath( partition, path.substring( 2 ) );
}
else
{
return partition + path;
}
}
private String getParentPath( String partition )
{
int n = partition.lastIndexOf( "/" );
if( n > 0 )
{
int index = partition.substring( 0, n-1 ).lastIndexOf( "/" );
if( index == 0 )
{
return "/";
}
else
{
return partition.substring( 0, index );
}
}
else
{
final String error =
"Illegal attempt to reference a containment context above the root context.";
throw new IllegalArgumentException( error );
}
}
/**
* Return the required selection constraints.
* @param directive the dependency directive
* @return the set of required selection directives
*/
private SelectionDirective[] getFilters( StageDirective 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.2 +4 -1 avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/data/test/DeploymentProfileTestCase.java
Index: DeploymentProfileTestCase.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/data/test/DeploymentProfileTestCase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DeploymentProfileTestCase.java 17 Jul 2003 21:21:58 -0000 1.1
+++ DeploymentProfileTestCase.java 24 Jul 2003 22:14:55 -0000 1.2
@@ -78,6 +78,7 @@
private Configuration m_configuration;
private ContextDirective m_context;
private DependencyDirective[] m_dependencies;
+ private StageDirective[] m_stages;
private String m_name;
private String m_classname;
@@ -94,6 +95,7 @@
new ContextDirective( getClass().getName(), new ImportDirective[0] );
m_configuration = new DefaultConfiguration("test");
m_dependencies = new DependencyDirective[0];
+ m_stages = new StageDirective[0];
m_parameters = Parameters.fromProperties(System.getProperties());
m_activation = true;
m_mode = Mode.IMPLICIT;
@@ -104,7 +106,8 @@
{
DeploymentProfile profile = new DeploymentProfile(
m_name, m_activation, m_classname, m_categories,
- m_context, m_dependencies, m_parameters, m_configuration, m_mode );
+ m_context, m_dependencies, m_stages, m_parameters,
+ m_configuration, m_mode );
assertEquals( "name", m_name, profile.getName() );
assertEquals( "classname", m_classname, profile.getClassname() );
---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org