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 2002/07/30 09:05:56 UTC
cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder XMLFacilityCreator.java XMLTypeCreator.java
mcconnell 2002/07/30 00:05:56
Modified: assembly build.xml
assembly/src/etc kernel.xml sevak.xml
assembly/src/java/org/apache/excalibur/merlin Main.java
assembly/src/java/org/apache/excalibur/merlin/assembly
ProfileManager.java ProfileRegistry.java
TypeManager.java TypeRegistry.java
assembly/src/java/org/apache/excalibur/merlin/assembly/resource
LifecycleHelper.java ProfileDesignator.java
ResourceProvider.java
assembly/src/java/org/apache/excalibur/merlin/container/builder
ContainerCreator.java XMLContainerCreator.java
assembly/src/java/org/apache/excalibur/merlin/kernel/builder
XMLKernelCreator.java
assembly/src/java/org/apache/excalibur/merlin/model
Association.java Import.java Profile.java
assembly/src/java/org/apache/excalibur/meta
componentinfo.dtd
assembly/src/java/org/apache/excalibur/meta/info
ExtensionDescriptor.java Facility.java
PhaseDescriptor.java
assembly/src/java/org/apache/excalibur/meta/info/builder
XMLFacilityCreator.java XMLTypeCreator.java
Added: assembly/src/java/org/apache/excalibur/merlin/assembly
Resources.properties
UnresolvedManagerException.java
Log:
Addition of support for pluggable extensions.
Revision Changes Path
1.33 +9 -12 jakarta-avalon-excalibur/assembly/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/build.xml,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- build.xml 26 Jul 2002 15:01:10 -0000 1.32
+++ build.xml 30 Jul 2002 07:05:54 -0000 1.33
@@ -70,7 +70,7 @@
<target name="dist" depends="build"/>
<target name="meta" depends="meta.javadoc"/>
<target name="merlin" depends="merlin.javadoc"/>
- <target name="all" depends="clean,deploy,docs"/>
+ <target name="all" depends="clean,deploy,javadocs,docs"/>
<target name="javadocs" depends="meta.javadoc,merlin.javadoc" />
<target name="javadoc" depends="meta.javadoc,merlin.javadoc" />
@@ -141,6 +141,7 @@
<uptodate property="meta.uptodate" targetfile="${dist.dir}/${meta.jar}">
<srcfiles dir="${src.dir}">
<include name="**/meta/**/*.*"/>
+ <include name="etc/meta.mf"/>
</srcfiles>
</uptodate>
</target>
@@ -180,12 +181,14 @@
</uptodate>
</target>
- <target name="demo.build" depends="demo.context" unless="demo.uptodate" >
+ <target name="demo.build" depends="merlin.build,demo.context" unless="demo.uptodate" >
<echo message="Building Demo"/>
<mkdir dir="${build}/demo"/>
<javac debug="off" destdir="${build}/demo" deprecation="true">
<classpath>
<path refid="project.class.path" />
+ <pathelement path="${dist.dir}/${meta.jar}" />
+ <pathelement path="${dist.dir}/${merlin.jar}" />
</classpath>
<src path="demo/src/java" />
</javac>
@@ -265,7 +268,7 @@
<copy todir="${docs.dir}/api/meta" file="${src.dir}/etc/meta.gif"/>
</target>
- <target name="deploy" depends="build">
+ <target name="deploy" depends="dist">
<mkdir dir="${extensions}"/>
<copy todir="${extensions}" preservelastmodified="true">
<fileset dir="${avalon.tools.path}/lib">
@@ -294,16 +297,10 @@
</java>
</target>
-
<target name="patch">
- <replace
- token="TypeManagerException"
- value="TypeException" dir="src/java">
- <include name="org/apache/excalibur/merlin/**/*.*"/>
- </replace>
- <replace
- token="TypeManagerRuntimeException"
- value="TypeRuntimeException" dir="src/java">
+ <replace dir="${src.dir}/java"
+ token="org.apache.excalibur.merlin.model.TargetProvider"
+ value="org.apache.excalibur.merlin.kernel.model.TargetProvider" >
<include name="org/apache/excalibur/merlin/**/*.*"/>
</replace>
</target>
1.19 +11 -6 jakarta-avalon-excalibur/assembly/src/etc/kernel.xml
Index: kernel.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/kernel.xml,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- kernel.xml 29 Jul 2002 06:14:29 -0000 1.18
+++ kernel.xml 30 Jul 2002 07:05:54 -0000 1.19
@@ -58,7 +58,7 @@
for completness.
-->
- <categories priority="INFO">
+ <categories priority="DEBUG">
<category priority="WARN" name="loader" />
<category priority="WARN" name="loader.assembly" />
<category priority="WARN" name="loader.lifecycle" />
@@ -82,7 +82,7 @@
<component name="complex" class="org.apache.excalibur.playground.ComplexComponent" activation="true">
- <categories priority="INFO">
+ <categories priority="DEBUG">
<category name="init" priority="DEBUG" />
</categories>
@@ -128,10 +128,8 @@
<container name="demo">
- <categories priority="WARN">
+ <categories priority="INFO">
<category priority="WARN" name="loader" />
- <category priority="WARN" name="loader.assembly" />
- <category priority="WARN" name="loader.lifecycle" />
</categories>
<!--
@@ -143,10 +141,17 @@
to the instantiated component is based primarily on this configuration declared here,
and defaults derived from SimpleComponent.xconfig.
-->
- <component name="simple" class="org.apache.excalibur.playground.SimpleComponent" enabled="true" activation="true">
+ <component name="simple"
+ class="org.apache.excalibur.playground.SimpleComponent"
+ enabled="true"
+ activation="true">
+
+ <categories priority="DEBUG"/>
+
<configuration>
<message>This is a custom message.</message>
</configuration>
+
</component>
</container>
1.7 +1 -1 jakarta-avalon-excalibur/assembly/src/etc/sevak.xml
Index: sevak.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/sevak.xml,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- sevak.xml 25 Jul 2002 18:07:15 -0000 1.6
+++ sevak.xml 30 Jul 2002 07:05:54 -0000 1.7
@@ -86,7 +86,7 @@
activation="true">
<context>
- <import key="app.home" name="home"/>
+ <import key="app.home" name="avalon:work"/>
</context>
<!-- you need to provide your own sevak-conf.xml file if you want to override defaults -->
1.10 +2 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/Main.java
Index: Main.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/Main.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Main.java 29 Jul 2002 06:14:29 -0000 1.9
+++ Main.java 30 Jul 2002 07:05:55 -0000 1.10
@@ -81,7 +81,7 @@
* assembly profile.
*
* <pre>
- * <strong><font color="darkred">$ java -jar .\extensions\merlin.jar src\etc\kernel.xml</font></strong>
+ * <strong><font color="darkred">$ java -Djava.ext.dirs=.\extensions -jar .\extensions\merlin.jar src\etc\kernel.xml</font></strong>
*
* <i><font color="darkslategray">The following logging trace shows the kernel initialization and the invocation of a startup request.</font></i>
*
1.2 +143 -13 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileManager.java
Index: ProfileManager.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProfileManager.java 29 Jul 2002 06:14:29 -0000 1.1
+++ ProfileManager.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -40,10 +40,13 @@
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.ResourceDesignator;
import org.apache.excalibur.merlin.model.builder.ProfileBuilder;
+import org.apache.excalibur.meta.info.PhaseDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
+import org.apache.excalibur.meta.info.ExtensionDescriptor;
import org.apache.excalibur.meta.info.Type;
+import org.apache.excalibur.meta.info.Facility;
import org.apache.excalibur.meta.info.builder.TypeBuilder;
import org.apache.excalibur.meta.verifier.ComponentVerifier;
@@ -147,11 +150,17 @@
// constructor
//===================================================================
- public ProfileManager( ClassLoader parent, String name )
+ /**
+ * Creation of a new Profile Manager.
+ * @param parent the parent classloader
+ * @param name the name to assign to this classloader (used with logging)
+ * @param root if TRUE, logging catagories are top level, otherwise logging
+ * catagories are subsidary to the parent
+ */
+ public ProfileManager( ClassLoader parent, String name, boolean root )
{
super( parent );
m_name = name;
-
if( parent instanceof ProfileManager )
{
m_parent = (ProfileManager) parent;
@@ -163,6 +172,14 @@
m_path = DELIMITER + name;
m_map = new DependencyGraph();
}
+ if( !root )
+ {
+ m_path = m_parent.getPath() + DELIMITER + name;
+ }
+ else
+ {
+ m_path = DELIMITER + name;
+ }
}
//=======================================================================
@@ -246,7 +263,7 @@
ResourceDesignator resource = getResource( profile );
if( resource.getState() == ResourceDesignator.NOT_STARTED )
{
- getLogger().info( "STARTING: " + profile );
+ getLogger().info( "starting: " + profile );
resource.getInstance();
}
}
@@ -264,7 +281,7 @@
ResourceDesignator resource = getResource( profile );
if( resource.getState() == ResourceDesignator.STARTED )
{
- getLogger().info( "STOPPING: " + profile );
+ getLogger().info( "stopping: " + profile );
resource.release();
}
}
@@ -315,6 +332,7 @@
final String classname = profile.getType().getInfo().getImplementationKey();
if( isLocal( classname ) )
{
+ getLogger().info("adding: " + profile );
if( m_profiles.get( name ) != null )
throw new IllegalArgumentException(
"Profile named '" + name + "' already registered.");
@@ -323,8 +341,27 @@
ServiceDescriptor[] services = profile.getType().getServices();
for( int i=0; i<services.length; i++ )
{
+ //
+ // register the profile against the service it provides
+ // so we can lookup the profile later based on the supplied
+ // service descriptor
+ //
+
addProfile( services[i].getService(), profile );
}
+
+ if( profile.getType() instanceof Facility )
+ {
+ //
+ // the profile is a facility so we need to
+ // cross reference it against the extension support it
+ // provides
+ //
+
+ Facility facility = (Facility) profile.getType();
+ addProfile( facility.getExtensions(), profile );
+ }
+
getLogger().info("added: " + profile );
}
else
@@ -373,6 +410,39 @@
return local;
}
+ public Profile[] getProfiles( PhaseDescriptor phase )
+ {
+ Profile[] local = getLocalProfiles( phase );
+ ProfileManager parent = getParentManager();
+ if( parent != null )
+ {
+ ArrayList list = new ArrayList();
+ for( int i=0; i<local.length; i++ )
+ {
+ list.add( local[i] );
+ }
+ Profile[] profiles = parent.getProfiles( phase );
+ for( int i=0; i<profiles .length; i++ )
+ {
+ list.add( profiles[i] );
+ }
+ return (Profile[]) list.toArray( new Profile[0] );
+ }
+ return local;
+ }
+
+ /**
+ * Return a single profile matching a supplied phase spec.
+ *
+ * @param phase the phase specification
+ * @return the selected profile
+ */
+ public Profile getProfile( PhaseDescriptor phase )
+ {
+ Profile[] profiles = getProfiles( phase );
+ return getSelector( phase ).select( profiles );
+ }
+
/**
* Return a single profile matching a supplied versioned interface spec
* using a supplied selector.
@@ -432,11 +502,14 @@
}
}
- private ResourceDesignator getLocalResource( Profile profile )
- {
- return (ResourceDesignator) m_resources.get( profile );
- }
-
+ /**
+ * Assemble a set of profiles into a consistent application. This method
+ * attempts to establish associations between all dependencies in order to
+ * resolve an operational application context.
+ *
+ * @param profiles the set of profiles constituting the core components
+ * from which the associations between components will be based
+ */
public void assemble( Profile[] profiles ) throws Exception
{
m_registry.assemble( profiles );
@@ -510,7 +583,7 @@
}
/**
- * Returns the ser of exportable resources.
+ * Returns the set of exportable resources.
*
* @return the resource sequence
*/
@@ -538,6 +611,12 @@
// private
//=============================================================================
+ private ResourceDesignator getLocalResource( Profile profile )
+ {
+ return (ResourceDesignator) m_resources.get( profile );
+ }
+
+
/**
* Returns the set of profiles capable of supporting the supplied service.
* @return the set of candidate component types
@@ -548,6 +627,15 @@
}
/**
+ * Returns the set of profiles capable of supporting the supplied phase.
+ * @return the set of candidate profiles
+ */
+ private Profile[] getLocalProfiles( PhaseDescriptor phase )
+ {
+ return getTable( phase.getReference() ).getProfiles();
+ }
+
+ /**
* Returns the parent profile manager or null if this is the root manager.
* @return the parent
*/
@@ -556,7 +644,6 @@
return m_parent;
}
-
private void addProfile( ReferenceDescriptor reference, Profile profile )
{
ProfileTable table = getTable( reference );
@@ -564,6 +651,23 @@
}
/**
+ * Add a profile and cross-reference this relative to the extensions it
+ * is capable of supporting.
+ *
+ * @param extensions the set of extensions the facility supports
+ * @param profile the profile
+ */
+ private void addProfile( ExtensionDescriptor[] extensions, Profile profile )
+ {
+ for( int i=0; i<extensions.length; i++ )
+ {
+ getLogger().debug("adding profile against extension: " + extensions[i].getReference() );
+ ProfileTable table = getTable( extensions[i].getReference() );
+ table.add( profile );
+ }
+ }
+
+ /**
* Return a table that holds profiles supporting the supplied service reference.
*/
private ProfileTable getTable( ReferenceDescriptor service )
@@ -583,6 +687,32 @@
return table;
}
+ private Selector getSelector( PhaseDescriptor phase )
+ {
+
+ // if the phase declares a selector class then use that,
+ // otherwise, look for a default phase type selector - if none
+ // use the DefaultSelector
+
+ String selectorName = phase.getAttribute("avalon:selector");
+ if( selectorName == null )
+ selectorName = phase.getReference().getClassname() + "Selector";
+ try
+ {
+ Class clazz = loadClass( selectorName );
+ Selector selector = (Selector) clazz.newInstance();
+ if( selector instanceof LogEnabled )
+ {
+ ((LogEnabled)selector).enableLogging( getLogger().getChildLogger("selector") );
+ }
+ return selector;
+ }
+ catch( Throwable e )
+ {
+ return m_selector;
+ }
+ }
+
private Selector getSelector( DependencyDescriptor dependency )
{
@@ -590,7 +720,7 @@
// otherwise, look for a default service type selector - if none
// use the DefaultSelector
- String selectorName = dependency.getAttribute("avalon.service.selector");
+ String selectorName = dependency.getAttribute("avalon:selector");
if( selectorName == null )
selectorName = dependency.getService().getClassname() + "Selector";
try
1.2 +166 -14 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileRegistry.java
Index: ProfileRegistry.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileRegistry.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProfileRegistry.java 29 Jul 2002 06:14:29 -0000 1.1
+++ ProfileRegistry.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -28,7 +28,9 @@
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
+import org.apache.excalibur.meta.info.PhaseDescriptor;
import org.apache.excalibur.meta.info.Type;
+import org.apache.excalibur.meta.info.Facility;
import org.apache.excalibur.meta.verifier.ComponentVerifier;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.ResourceDesignator;
@@ -80,6 +82,11 @@
/**
* For all of the explicity declared profiles, initiate dependency correlation.
+ * The implementation will attempt to assembly each profile in the order
+ * supplied.
+ *
+ * @param profiles the set of profiles to assemble
+ * @exception Exception if an error occurs during assembly
*/
public void assemble( Profile[] profiles ) throws Exception
{
@@ -90,7 +97,8 @@
ArrayList visited = new ArrayList();
assembleProfile( profile, visited, "" );
- final String name = m_classloader.getPath() + ProfileManager.DELIMITER + profile.getName();
+ final String name =
+ m_classloader.getPath() + ProfileManager.DELIMITER + profile.getName();
final ResourceDesignator resource = m_classloader.getResource( profile, true );
getLogger().debug( "created explicit resource for: " + name );
m_map.add( profile );
@@ -108,13 +116,36 @@
return m_classloader.getProfiles( service );
}
+ /**
+ * Returns the set of component types know to the registry that are capable of
+ * supporting the supplied phase.
+ * @return the set of candidate component types
+ */
+ Profile[] getProfiles( PhaseDescriptor phase )
+ {
+ return m_classloader.getProfiles( phase );
+ }
+
+
+ /**
+ * Assemble a single profile.
+ * @param profile the profile to assemble
+ * @param visited the set of profiles already assessed
+ * @param extensions the set of extensions already visited
+ * @param pad used in formatting log messages
+ */
private void assembleProfile(
Profile profile, List visited, String pad ) throws Exception
{
getLogger().debug( pad + "assemble: " + profile );
String pad2 = pad + " ";
+
+ //
+ // for all of the declared depedencies - make sure the
+ // dependency is satisfied
+ //
+
visited.add( profile );
- String warning = null;
DependencyDescriptor[] dependencies = profile.getType().getDependencies();
for( int i=0; i<dependencies.length; i++ )
{
@@ -122,35 +153,156 @@
String role = dependency.getRole();
if( profile.getAssociation( role ) == null )
{
- Profile[] candidates = assembleProfile( profile, dependency, visited, pad2 );
- if( candidates.length == 0 )
+
+ //
+ // there is an unresolve association for one of the depedencies
+ // of the supplied profile - invoking assembleSolutions causes
+ // the resolution of associations between potential suppliers
+ // of the depedency - if assembleSolutions returns true, we
+ // have at least one solution
+ //
+
+ boolean ok = assembleProviders( profile, dependency, visited, pad2 );
+ if( !ok )
{
+ final String message =
+ "No solution for the dependency: "
+ + dependency.getService() + " in profile: " + profile
+ + ", for the role: " + dependency.getRole();
+ getLogger().error( pad + " " + message );
+
profile.setEnabled( false );
- final Exception problem = new Exception( "No available candidates." );
+ final Exception problem = new Exception( message );
throw new UnresolvedProviderException( dependency, problem );
}
+ //
+ // select the preferred provider for the dependency - the depedency
+ // argument contains the selection policy to apply
+ //
+
Profile supplier = m_classloader.getProfile( dependency );
if( supplier == null )
{
+ final String message =
+ "Empty selection for the dependency: "
+ + dependency.getService() + " in profile: " + profile
+ + ", for the role: " + dependency.getRole();
+ getLogger().error( pad + " " + message );
+
profile.setEnabled( false );
final Exception problem = new Exception( "No suitable candidates." );
- throw new UnresolvedProviderException( dependency );
+ throw new UnresolvedProviderException( dependency, problem );
}
+ //
+ // associate the supplier to the profile via an association
+ //
+
+ getLogger().debug( pad + " selection: " + supplier );
ResourceDesignator resource = m_classloader.getResource( supplier, true );
profile.addProvider( role, resource );
+ m_map.add( supplier );
+ }
+ }
+
+ //
+ // for all of the lifecycle phases - make sure we assign an extension
+ // manager
+ //
+
+ PhaseDescriptor[] phases = profile.getType().getPhases();
+ for( int i=0; i<phases.length; i++ )
+ {
+ PhaseDescriptor phase = phases[i];
+ if( profile.getExtension( phase ) == null )
+ {
+ boolean ok = assembleManagers( profile, phase, visited, pad2 );
+ if( !ok )
+ {
+ final String message = "Could not locate an extension for the phase: "
+ + phase.getReference() + ", in profile: " + profile;
+ getLogger().error( pad + " " + message );
+
+ profile.setEnabled( false );
+ final AssemblyException problem = new AssemblyException( message );
+ throw new UnresolvedManagerException( phase, problem );
+ }
+
+ //
+ // select the preferred provider for the phase - the phase
+ // argument contains the selection policy to apply
+ //
+
+ Profile supplier = m_classloader.getProfile( phase );
+ if( supplier == null )
+ {
+ final String message =
+ "Empty selection for a phase extension supporting: "
+ + phase.getReference() + " in profile: " + profile;
+ getLogger().error( pad + " " + message );
+
+ profile.setEnabled( false );
+ final AssemblyException problem = new AssemblyException( message );
+ throw new UnresolvedManagerException( phase, problem );
+ }
+
+ //
+ // associate the supplier to the profile via an association
+ //
+
+ getLogger().debug( pad + " selection: " + supplier );
+ ResourceDesignator resource =
+ m_classloader.getResource( supplier, true );
+ profile.addExtension( phase, supplier, resource );
+ m_map.add( supplier );
+
+ }
+ }
+ }
+
+ private boolean assembleManagers(
+ Profile source, PhaseDescriptor phase, List visited, String pad )
+ throws Exception
+ {
+ boolean ok = false;
+ Profile[] profiles = getProfiles( phase );
+ getLogger().debug(
+ pad
+ + "phase: " + phase.getReference()
+ + ", [" + profiles.length + "]"
+ );
+
+ for( int i=0; i<profiles.length; i++ )
+ {
+ Profile profile = profiles[i];
+ if( !profile.equals( source ) )
+ {
+ try
+ {
+ assembleProfile( profile, visited, pad + " " );
+ ok = true;
+ getLogger().debug( pad + " extension: " + profile );
+ }
+ catch( Throwable e )
+ {
+ // solution is not resolvable
+ getLogger().debug(
+ pad
+ + " ignoring: " + profile + ", cause: " + e.toString()
+ );
+ }
}
}
+ return ok;
}
- private Profile[] assembleProfile(
+ private boolean assembleProviders(
Profile source, DependencyDescriptor dependency, List visited, String pad )
throws Exception
{
+ boolean ok = false;
getLogger().debug( pad + "dependency: " + dependency.getRole() );
- Vector vector = new Vector();
- String pad2 = pad + " ";
Profile[] profiles = getProfiles( dependency.getService() );
for( int i=0; i<profiles.length; i++ )
{
@@ -159,9 +311,9 @@
{
try
{
- assembleProfile( profile, visited, pad2 );
- vector.add( profile );
- getLogger().debug( pad + "candidate: " + profile );
+ assembleProfile( profile, visited, pad + " " );
+ ok = true;
+ getLogger().debug( pad + " provider: " + profile );
}
catch( Throwable e )
{
@@ -169,7 +321,7 @@
}
}
}
- return (Profile[]) vector.toArray( new Profile[0] );
+ return ok;
}
}
1.2 +20 -1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeManager.java
Index: TypeManager.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TypeManager.java 29 Jul 2002 06:14:29 -0000 1.1
+++ TypeManager.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -44,6 +44,7 @@
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.Facility;
import org.apache.excalibur.meta.info.ReferenceDescriptor;
+import org.apache.excalibur.meta.info.PhaseDescriptor;
import org.apache.excalibur.merlin.container.model.IncludeDescriptor;
import org.apache.excalibur.merlin.container.model.ExtensionsDescriptor;
import org.apache.excalibur.merlin.container.model.DirsetDescriptor;
@@ -466,6 +467,15 @@
}
/**
+ * Returns the set of facilities know to the registry.
+ * @return the set of facilities registered with the registry
+ */
+ public Facility[] getFacilities()
+ {
+ return m_types.getFacilities( );
+ }
+
+ /**
* Returns the set of component types know to the registry that are capable of
* supporting the supplied service.
* @return the set of candidate component types
@@ -473,6 +483,15 @@
public Type[] getTypes( ReferenceDescriptor service )
{
return m_types.getTypes( service );
+ }
+
+ /**
+ * Returns the set of facilities know to the registry matching a supplied phase.
+ * @return the set of facilities
+ */
+ public Facility[] getFacilities( PhaseDescriptor phase )
+ {
+ return m_types.getFacilities( phase );
}
/**
1.2 +74 -8 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeRegistry.java
Index: TypeRegistry.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeRegistry.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TypeRegistry.java 29 Jul 2002 06:14:29 -0000 1.1
+++ TypeRegistry.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -9,6 +9,7 @@
import java.util.List;
import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Iterator;
@@ -21,6 +22,9 @@
import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
import org.apache.excalibur.meta.info.Type;
+import org.apache.excalibur.meta.info.Facility;
+import org.apache.excalibur.meta.info.PhaseDescriptor;
+import org.apache.excalibur.meta.info.ExtensionDescriptor;
import org.apache.excalibur.meta.info.builder.TypeBuilder;
import org.apache.excalibur.meta.info.builder.FacilityBuilder;
import org.apache.excalibur.merlin.model.Profile;
@@ -52,6 +56,12 @@
private Hashtable m_types = new Hashtable();
/**
+ * Facility types keyed by classname (facilities are also included
+ * in the m_types table).
+ */
+ private Hashtable m_facilities = new Hashtable();
+
+ /**
* List of TypeTable instances.
*/
private List m_services = new LinkedList();
@@ -132,19 +142,19 @@
* @param classname the component class name
* @return the component type
*/
- public Type addFacility( String path ) throws Exception
+ public Facility addFacility( String path ) throws Exception
{
final String classname = path.replace('/','.');
getLogger().info("facility: " + classname );
- Type type = getType( classname );
- if( type == null )
+ Facility facility = getFacility( classname );
+ if( facility == null )
{
- type = m_facilityBuilder.build( classname, m_classloader );
- verify( type );
- register( type );
+ facility = m_facilityBuilder.build( classname, m_classloader );
+ verify( facility );
+ register( facility );
}
- return type;
+ return facility;
}
private void verify( Type type ) throws Exception
@@ -226,6 +236,41 @@
}
/**
+ * Returns the set of facilities know to the registry.
+ * @return the set of registered facilities
+ */
+ public Facility[] getFacilities()
+ {
+ return (Facility[]) m_facilities.values().toArray( new Facility[0] );
+ }
+
+ /**
+ * Returns the set of facilities matching a supplied phase.
+ * @return the set of matching facilities
+ */
+ public Facility[] getFacilities( PhaseDescriptor phase )
+ {
+ ArrayList list = new ArrayList();
+ Facility[] facilities = getFacilities();
+ for( int i=0; i<facilities.length; i++ )
+ {
+ Facility facility = facilities[i];
+ ExtensionDescriptor[] extensions = facility.getExtensions();
+ for( int j=0; j<extensions.length; j++ )
+ {
+ ExtensionDescriptor extension = extensions[j];
+ if( extension.getReference().matches( phase.getReference() ) )
+ {
+ list.add( facility );
+ break;
+ }
+ }
+ }
+ return (Facility[]) list.toArray( new Facility[ list.size() ] );
+ }
+
+
+ /**
* Returns the set of component types know to the registry that are capable of
* supporting the supplied service.
* @return the set of candidate component types
@@ -242,6 +287,27 @@
public Type getType( String classname )
{
return (Type) m_types.get( classname );
+ }
+
+ /**
+ * Returns a registered facility type.
+ * @return the facility type from the registry or null if the facility is unknown
+ */
+ public Facility getFacility( String classname )
+ {
+ return (Facility) m_facilities.get( classname );
+ }
+
+ /**
+ * Register the facility resulting in the cross-referencing of the facility
+ * with the set of phases is is capable of supporting.
+ */
+ protected void registerFacility( Facility facility )
+ {
+ register( facility );
+ String key = facility.getInfo().getImplementationKey();
+ m_facilities.put( key, facility );
+ getLogger().debug( "Facility: '" + key + "' registered.");
}
/**
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/Resources.properties
Index: Resources.properties
===================================================================
target.nocreate=Error creating LogTarget named "{0}" for file {0}. (Reason: {2}).
unknown-priority=Unknown priority "{0}" for Logger named "{1}".
category-create=Creating a log category named "{0}" that writes to "{1}" target at priority "{2}".
missing.extension=Unable to locate an extension that is required by application.\n Extension Name: {0}\n Specification Vendor: {1}\n Specification Version: {2}\n Implementation Vendor: {3}\n Implementation Vendor-Id: {4}\n Implementation Version: {5}\n Implementation URL: {6}
unsatisfied.extensions=Missing {0} extensions and thus can not build ClassLoader for application.
bad-classpath-entry=There is a bad entry ("{0}") on classpath that made it impossible to load a manifest.
available-extensions=Available extensions: {0}
required-extensions=The list of required extensions for application includes: {0}
optional-packages-added=The list of "Optional Packages" added to the application include: {0}
classpath-entries=The list of classpath entrys for the application include: {0}
1.1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/UnresolvedManagerException.java
Index: UnresolvedManagerException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.assembly;
import org.apache.excalibur.meta.info.PhaseDescriptor;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate that a service provider could not be found.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/30 07:05:55 $
*/
public final class UnresolvedManagerException
extends CascadingException
{
private PhaseDescriptor m_phase;
/**
* Construct a new <code>UnresolvedManagerException</code> instance.
*
* @param phase the unresolved phase
*/
public UnresolvedManagerException( PhaseDescriptor phase )
{
this( phase, null );
}
/**
* Construct a new <code>UnresolvedManagerException</code> instance.
*
* @param phase the unresolved phase
* @param cause the causal exception
*/
public UnresolvedManagerException( PhaseDescriptor phase, Throwable cause )
{
super( getStandardMessage( phase ), cause );
m_phase = phase;
}
/**
* Return the dependency description.
* @return the unresolved dependency.
*/
public PhaseDescriptor getPhase()
{
return m_phase;
}
private static String getStandardMessage( PhaseDescriptor phase )
{
return "Unable to resolve an extensions for the phase '"
+ phase.getReference();
}
}
1.2 +84 -7 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/LifecycleHelper.java
Index: LifecycleHelper.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/LifecycleHelper.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- LifecycleHelper.java 29 Jul 2002 06:14:30 -0000 1.1
+++ LifecycleHelper.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -19,6 +19,7 @@
import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
@@ -28,6 +29,10 @@
import org.apache.avalon.framework.service.Serviceable;
import org.apache.excalibur.merlin.model.Profile;
+import org.apache.excalibur.merlin.model.ResourceDesignator;
+import org.apache.excalibur.meta.info.PhaseDescriptor;
+import org.apache.excalibur.meta.info.ExtensionDescriptor;
+import org.apache.excalibur.meta.info.Facility;
/**
* This is a class to help an Application manage the lifecycle of a component.
@@ -50,11 +55,13 @@
private static final int STAGE_COMPOSE = 3;
private static final int STAGE_CONFIG = 4;
private static final int STAGE_PARAMETER = 5;
- private static final int STAGE_INIT = 6;
- private static final int STAGE_START = 7;
- private static final int STAGE_STOP = 8;
- private static final int STAGE_DISPOSE = 9;
- private static final int STAGE_DESTROY = 10;
+ private static final int STAGE_EXTENSION_PRE = 6;
+ private static final int STAGE_INIT = 7;
+ private static final int STAGE_START = 8;
+ private static final int STAGE_STOP = 9;
+ private static final int STAGE_DISPOSE = 10;
+ private static final int STAGE_EXTENSION_POST = 11;
+ private static final int STAGE_DESTROY = 12;
/**
* Method to run a component through it's startup phase.
@@ -93,10 +100,10 @@
//Contextualize stage
stage = STAGE_CONTEXT;
+ final Context context = provider.createContext( profile );
if( object instanceof Contextualizable )
{
notice( name, stage );
- final Context context = provider.createContext( profile );
ContainerUtil.contextualize( object, context );
}
@@ -137,6 +144,40 @@
ContainerUtil.parameterize( object, parameters );
}
+ //
+ // apply creation phase extensions
+ //
+
+ stage = STAGE_EXTENSION_PRE;
+ PhaseDescriptor[] phases = profile.getType().getPhases();
+ if( phases.length > 0 )
+ notice( name, stage );
+ for( int i=0; i<phases.length; i++ )
+ {
+ PhaseDescriptor phase = phases[i];
+ final Facility facility = profile.getFacility( phase );
+ final ExtensionDescriptor ext = facility.getExtension( phase );
+ if( ext.isApplicable( ExtensionDescriptor.CREATE ) )
+ {
+ ResourceDesignator resource = profile.getExtension( phase );
+ Extension extension = (Extension) resource.getInstance();
+ try
+ {
+ getLogger().info("applying phase " + phase.getReference() + " to " + name );
+ extension.extend( Extension.CREATE, object, context );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Extension " + extension.getClass().getName()
+ + " raised an exception " + e.getClass().getName()
+ + " while processing the creation phase for the component "
+ + name;
+ throw new LifecycleException( error, e );
+ }
+ }
+ }
+
//Initialize stage
stage = STAGE_INIT;
if( object instanceof Initializable )
@@ -167,12 +208,13 @@
/**
* Method to run a component through it's shutdown phase.
- * Errors that occur during shutdown will be logged appropraitely.
+ * Errors that occur during shutdown will be logged appropriately.
*
* @param name the name of the component
* @param object the component to shutdown
*/
public void shutdown( final String name,
+ final Profile profile,
final Object object )
throws LifecycleException
{
@@ -198,6 +240,41 @@
safeFail( name, STAGE_STOP, t );
failure = t;
stage = STAGE_STOP;
+ }
+ }
+
+ //
+ // apply disposal extensions
+ // ### what about context ? ###
+ // ## what about extension exceptions - it should containue
+ // to subsequent extensions - needs testing ##
+ //
+
+ stage = STAGE_EXTENSION_POST;
+ PhaseDescriptor[] phases = profile.getType().getPhases();
+ if( phases.length > 0 )
+ notice( name, stage );
+ for( int i=(phases.length-1); i>-1; i-- )
+ {
+ PhaseDescriptor phase = phases[i];
+ final Facility facility = profile.getFacility( phase );
+ final ExtensionDescriptor ext = facility.getExtension( phase );
+ if( ext.isApplicable( ExtensionDescriptor.DESTROY ) )
+ {
+ try
+ {
+ ResourceDesignator resource = profile.getExtension( phase );
+ Extension extension = (Extension) resource.getInstance();
+ getLogger().info("applying '" + phase.getReference()
+ + "' to '" + name + "'.");
+ extension.extend( Extension.DESTROY, object, new DefaultContext() );
+ }
+ catch( Throwable e )
+ {
+ safeFail( name, STAGE_EXTENSION_POST, e );
+ failure = e;
+ stage = STAGE_EXTENSION_POST;
+ }
}
}
1.2 +2 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ProfileDesignator.java
Index: ProfileDesignator.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ProfileDesignator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProfileDesignator.java 29 Jul 2002 06:14:30 -0000 1.1
+++ ProfileDesignator.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -133,7 +133,7 @@
public void release() throws LifecycleException
{
if( m_service != null )
- m_helper.shutdown( m_path, m_service );
+ m_helper.shutdown( m_path, m_profile, m_service );
setState( STOPPED );
}
1.2 +23 -8 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ResourceProvider.java
Index: ResourceProvider.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ResourceProvider.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ResourceProvider.java 29 Jul 2002 06:14:30 -0000 1.1
+++ ResourceProvider.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -104,6 +104,11 @@
*/
private final Hashtable m_singletons = new Hashtable();
+ /**
+ * A hashtable of profiles keyed by singleton object.
+ */
+ private final Hashtable m_profiles = new Hashtable();
+
private DefaultContext m_dictionary;
//=======================================================================
@@ -122,15 +127,15 @@
m_classloader = loader;
m_logging = logging;
- // ##### WARNING ##########
- // The following is a hack to add the avalon:work context key - this needs to
- // constructed using context creation directives at the level of the kernel
- // defintion
- //#########################
+ // ## WARNING ###################################################################//
+ // The following is a hack to add the avalon:work context key - this needs to //
+ // constructed using context creation directives at the level of the kernel //
+ // defintion (which requires the commons factory interface). //
+ //###############################################################################//
m_dictionary = new DefaultContext( dictionary );
m_dictionary.put( "classloader", loader );
- m_dictionary.put( "home", new File( System.getProperty("user.dir") ) );
+ m_dictionary.put( "avalon:work", new File( System.getProperty("user.dir") ) );
m_dictionary.makeReadOnly();
}
@@ -151,6 +156,10 @@
Object object = getSingletonInstance( profile );
if( object == null )
{
+ //
+ // load the class
+ //
+
Class clazz = null;
String classname = null;
try
@@ -166,6 +175,10 @@
throw new ResourceException( error, e );
}
+ //
+ // create a new instance of the class
+ //
+
try
{
object = clazz.newInstance();
@@ -178,6 +191,7 @@
+ profile;
throw new ResourceException( error, e );
}
+
}
return object;
}
@@ -309,7 +323,7 @@
return parameters;
}
- public Object getSingletonInstance( Profile profile )
+ private Object getSingletonInstance( Profile profile )
{
return m_singletons.get( profile );
}
@@ -317,6 +331,7 @@
private void putSingletonInstance( Profile profile, Object object )
{
m_singletons.put( profile, object );
+ m_profiles.put( object, profile );
}
/**
1.2 +2 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/ContainerCreator.java
Index: ContainerCreator.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/ContainerCreator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ContainerCreator.java 29 Jul 2002 06:14:31 -0000 1.1
+++ ContainerCreator.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -30,7 +30,7 @@
* @return the newly created {@link ContainerDescriptor}
* @throws Exception
*/
- ContainerDescriptor createContainerDescriptor( Parent parent, Configuration config, TypeManager manager, DefaultLoggerManager logging )
+ ContainerDescriptor createContainerDescriptor( Parent parent, Configuration config, TypeManager manager, DefaultLoggerManager logging, boolean root )
throws Exception;
}
1.2 +8 -8 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/XMLContainerCreator.java
Index: XMLContainerCreator.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/XMLContainerCreator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XMLContainerCreator.java 29 Jul 2002 06:14:31 -0000 1.1
+++ XMLContainerCreator.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -59,7 +59,7 @@
* @exception Exception is a error occurs during container descriptor creation
*/
public ContainerDescriptor createContainerDescriptor(
- Parent parent, Configuration config, TypeManager manager, DefaultLoggerManager logging )
+ Parent parent, Configuration config, TypeManager manager, DefaultLoggerManager logging, boolean root )
throws Exception
{
@@ -71,12 +71,12 @@
CategoriesDescriptor categories =
super.createCategoriesDescriptor( name, config.getChild("categories") );
Logger logger;
- if( parent instanceof ContainerDescriptor )
+ if( !root )
{
- final String root =
+ final String base =
parent.getPath().replace('/','.').substring(1) + "." + name;
- logging.addCategories( root, categories );
- logger = logging.getLoggerForCategory( root );
+ logging.addCategories( base, categories );
+ logger = logging.getLoggerForCategory( base );
}
else
{
@@ -90,7 +90,7 @@
logger.info("preparing type manager");
ClasspathDescriptor classpath = createClasspathDescriptor( config.getChild("classpath") );
- final ProfileManager loader = new ProfileManager( manager, name );
+ final ProfileManager loader = new ProfileManager( manager, name, root );
try
{
loader.enableLogging( logger.getChildLogger( "loader" ) );
@@ -139,7 +139,7 @@
for( int i=0; i<configs.length; i++ )
{
final Configuration conf = configs[i];
- container.addContainer( createContainerDescriptor( container, conf, loader, logging ) );
+ container.addContainer( createContainerDescriptor( container, conf, loader, logging, false ) );
}
return container;
1.2 +3 -3 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/builder/XMLKernelCreator.java
Index: XMLKernelCreator.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/builder/XMLKernelCreator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XMLKernelCreator.java 29 Jul 2002 06:14:32 -0000 1.1
+++ XMLKernelCreator.java 30 Jul 2002 07:05:55 -0000 1.2
@@ -76,7 +76,7 @@
logger.info("preparing kernel type manager");
ExtensionsDescriptor extensions = createExtensionsDescriptor( config.getChild("extensions") );
ClasspathDescriptor classpath = createClasspathDescriptor( config.getChild("classpath") );
- final ProfileManager manager = new ProfileManager( loader, name );
+ final ProfileManager manager = new ProfileManager( loader, name, true );
try
{
manager.enableLogging( logger.getChildLogger( "loader" ) );
@@ -103,7 +103,7 @@
logger.info("preparing kernel descriptor");
KernelDescriptor kernel = new KernelDescriptor( name, logger, manager );
ContainerDescriptor container = createContainerDescriptor(
- kernel, config.getChild("container"), manager, logging );
+ kernel, config.getChild("container"), manager, logging, true );
kernel.setContainer( container );
return kernel;
}
1.5 +3 -4 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Association.java
Index: Association.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Association.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Association.java 18 Jul 2002 03:40:11 -0000 1.4
+++ Association.java 30 Jul 2002 07:05:55 -0000 1.5
@@ -29,8 +29,7 @@
private final String m_role;
/**
- * the name of the component metadata instance that represents a component
- * type that is capable of fullfilling the dependency.
+ * A reference to the component that is capable of fullfilling the dependency.
*/
private final ResourceDesignator m_provider;
@@ -60,7 +59,7 @@
}
/**
- * Return the <code>Profile</code> instance that will used to
+ * Return the <code>ResourceDesignator</code> that will used to
* fulfill the dependency.
*
* @return the profile that will fulfill the dependency.
1.4 +2 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Import.java
Index: Import.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Import.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Import.java 23 Jul 2002 15:36:04 -0000 1.3
+++ Import.java 30 Jul 2002 07:05:55 -0000 1.4
@@ -19,7 +19,7 @@
*
* <font color="gray">
* <--
- * Declare the import of the value of avalon.work as a keyed context
+ * Declare the import of the value of "avalon.work" as a keyed context
* value using the key "home".
* --></font>
*
1.12 +47 -1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Profile.java
Index: Profile.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Profile.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Profile.java 29 Jul 2002 06:14:32 -0000 1.11
+++ Profile.java 30 Jul 2002 07:05:55 -0000 1.12
@@ -14,6 +14,8 @@
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.context.Context;
import org.apache.excalibur.meta.info.Type;
+import org.apache.excalibur.meta.info.Facility;
+import org.apache.excalibur.meta.info.PhaseDescriptor;
import org.apache.excalibur.merlin.model.Association;
import org.apache.excalibur.configuration.ConfigurationUtil;
@@ -124,6 +126,16 @@
private final Hashtable m_dependencies = new Hashtable();
/**
+ * The phase extension resource descriptor keyed by phase.
+ */
+ private final Hashtable m_managers = new Hashtable();
+
+ /**
+ * The phase extension profile keyed by phase.
+ */
+ private final Hashtable m_extensions = new Hashtable();
+
+ /**
* The info object for component type.
*/
private final Type m_type;
@@ -326,6 +338,40 @@
m_dependencies.put( role, association );
return association;
}
+
+ /**
+ * Add a lifecycle phase extension.
+ * @param phase the identifier of the phase to assign the manager to
+ * @param resource the reference to the manager
+ */
+ public void addExtension( PhaseDescriptor phase, Profile profile, ResourceDesignator resource )
+ {
+ m_managers.put( phase, resource );
+ m_extensions.put( phase, profile );
+ }
+
+ /**
+ * Return a reference to the lifecycle phase extension assigned to handle
+ * the components custom phase.
+ * @param phase the lifecycle phase specification
+ * @return a reference to the phase extension
+ */
+ public ResourceDesignator getExtension( PhaseDescriptor phase )
+ {
+ return (ResourceDesignator) m_managers.get( phase );
+ }
+
+ /**
+ * Return the facility associated as the phace provider.
+ * @param phase the lifecycle phase specification
+ * @return a reference to the phase extension
+ */
+ public Facility getFacility( PhaseDescriptor phase )
+ {
+ Profile profile = (Profile) m_extensions.get( phase );
+ return (Facility) profile.getType();
+ }
+
/**
* Return the activation policy for the component. If TRUE, activation
1.4 +3 -1 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/componentinfo.dtd
Index: componentinfo.dtd
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/componentinfo.dtd,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- componentinfo.dtd 29 Jul 2002 06:14:33 -0000 1.3
+++ componentinfo.dtd 30 Jul 2002 07:05:56 -0000 1.4
@@ -126,8 +126,10 @@
reference the version lifecycle interface supported
attributes Optional attributes about the extension
-->
+<!ENTITY % stage.attribute "stage (CREATE|ACCESS|RELEASE|DESTROY|ALL|INNER|OUTER) 'ALL'">
<!ELEMENT extension (name,reference,attributes?)>
- <!ATTLIST extension >
+<!ATTLIST extension
+ %stage.attribute; >
<!--
The phase element defines a lifecycle extension phase that this component provides.
1.2 +73 -7 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/ExtensionDescriptor.java
Index: ExtensionDescriptor.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/ExtensionDescriptor.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ExtensionDescriptor.java 29 Jul 2002 06:14:33 -0000 1.1
+++ ExtensionDescriptor.java 30 Jul 2002 07:05:56 -0000 1.2
@@ -15,22 +15,41 @@
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision$ $Date$
*/
-public final class ExtensionDescriptor extends PhaseDescriptor
+public final class ExtensionDescriptor extends Descriptor
{
+ public static final int CREATE = 0;
+ public static final int ACCESS = 1;
+ public static final int RELEASE = 2;
+ public static final int DESTROY = 3;
+ public static final int INNER = 4;
+ public static final int OUTER = 5;
+ public static final int ALL = 6;
+
+ /**
+ * The lifecycle stage.
+ */
+ private final int m_stage;
+
/**
* The name of the lifecycle phase.
*/
private final String m_name;
/**
+ * The interface that represents the client view of the lifecycle phase.
+ */
+ private final ReferenceDescriptor m_reference;
+
+ /**
* Constructor a phase descriptor without attributes.
* @param name the phase name
* @param interface the phase type
*/
public ExtensionDescriptor( final String name,
- final ReferenceDescriptor reference )
+ final int stage,
+ final ReferenceDescriptor reference )
{
- this( name, reference, null );
+ this( name, stage, reference, null );
}
/**
@@ -39,15 +58,22 @@
* @param interface the phase type
*/
public ExtensionDescriptor( final String name,
- final ReferenceDescriptor reference,
- final Properties attributes )
+ final int stage,
+ final ReferenceDescriptor reference,
+ final Properties attributes )
{
- super( reference, attributes );
+ super( attributes );
if( null == name )
throw new NullPointerException( "name" );
+ if( null == reference )
+ throw new NullPointerException( "reference" );
+ if( (ALL < stage) || (stage < CREATE ))
+ throw new IllegalArgumentException( "stage: " + stage );
m_name = name;
+ m_reference = reference;
+ m_stage = stage;
}
/**
@@ -59,5 +85,45 @@
{
return m_name;
}
+
+ /**
+ * Return the version interface reference.
+ *
+ * @return the version interface reference.
+ */
+ public ReferenceDescriptor getReference()
+ {
+ return m_reference;
+ }
+
+ /**
+ * Return the lifecycle stage that this phase is to be applied under.
+ *
+ * @return one of the phase values {@link #CREATE}, {@link #ACCESS}, {@link #RELEASE}, {@link #DESTORY},
+ * {@link #INNER}, {@link #OUTER}, or {@link #ALL}.
+ */
+ public int getStage()
+ {
+ return m_stage;
+ }
+
+ public boolean isApplicable( int stage )
+ {
+
+
+ final int policy = getStage();
+ if( policy == ALL ) return true;
+ if( policy == stage ) return true;
+ if(( stage == CREATE ) || ( stage == DESTROY ))
+ {
+ return ( policy == OUTER );
+ }
+ else if(( stage == ACCESS ) || ( stage == RELEASE ))
+ {
+ return ( policy == INNER );
+ }
+ return false;
+ }
+
}
1.2 +22 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/Facility.java
Index: Facility.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/Facility.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Facility.java 29 Jul 2002 06:14:33 -0000 1.1
+++ Facility.java 30 Jul 2002 07:05:56 -0000 1.2
@@ -63,12 +63,32 @@
/**
* Return the phases supported by this extension.
*
- * @return an array of phase descriptors.
+ * @return an array of extension descriptors.
*/
public ExtensionDescriptor[] getExtensions()
{
return m_extensions;
}
+
+ /**
+ * Return the extension supporting the supplied phase.
+ *
+ * @return a matching extension or null if no matching extension
+ */
+ public ExtensionDescriptor getExtension( PhaseDescriptor phase )
+ {
+ ReferenceDescriptor reference = phase.getReference();
+ ExtensionDescriptor[] extensions = getExtensions();
+ for( int i=0; i<extensions.length; i++ )
+ {
+ ExtensionDescriptor extension = extensions[i];
+ ReferenceDescriptor ref = extension.getReference();
+ if( reference.matches( ref ) )
+ return extension;
+ }
+ return null;
+ }
+
/**
* Return a string representation of the type.
1.3 +4 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/PhaseDescriptor.java
Index: PhaseDescriptor.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/PhaseDescriptor.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PhaseDescriptor.java 29 Jul 2002 06:14:33 -0000 1.2
+++ PhaseDescriptor.java 30 Jul 2002 07:05:56 -0000 1.3
@@ -17,6 +17,7 @@
*/
public class PhaseDescriptor extends Descriptor
{
+
/**
* The interface that represents the client view of the lifecycle phase.
*/
@@ -38,7 +39,7 @@
* @param interface the phase type
*/
public PhaseDescriptor( final ReferenceDescriptor reference,
- final Properties attributes )
+ final Properties attributes )
{
super( attributes );
@@ -57,4 +58,5 @@
{
return m_reference;
}
+
}
1.2 +46 -4 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLFacilityCreator.java
Index: XMLFacilityCreator.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLFacilityCreator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XMLFacilityCreator.java 29 Jul 2002 06:14:34 -0000 1.1
+++ XMLFacilityCreator.java 30 Jul 2002 07:05:56 -0000 1.2
@@ -154,14 +154,56 @@
{
Configuration extension = extensions[i];
final String name = extension.getChild("name").getValue();
- ReferenceDescriptor reference = buildReferenceDescriptor(
- extension.getChild("reference") );
+ final int stage = getStageValue( extension );
+ ReferenceDescriptor reference =
+ buildReferenceDescriptor( extension.getChild("reference") );
final Properties attributes =
super.buildAttributes( extension.getChild( "attributes" ) );
- list.add( new ExtensionDescriptor( name, reference, attributes ) );
+ list.add( new ExtensionDescriptor( name, stage, reference, attributes ) );
}
return (ExtensionDescriptor[]) list.toArray( new ExtensionDescriptor[0] );
}
+
+ private int getStageValue( Configuration phase )
+ {
+ final String stage = phase.getAttribute("stage","CREATE");
+ if( stage.equalsIgnoreCase("CREATE") )
+ {
+ return ExtensionDescriptor.CREATE;
+ }
+ else if( stage.equalsIgnoreCase("DESTORY") )
+ {
+ return ExtensionDescriptor.DESTROY;
+ }
+ else if( stage.equalsIgnoreCase("ACCESS") )
+ {
+ return ExtensionDescriptor.ACCESS;
+ }
+ else if( stage.equalsIgnoreCase("RELEASE") )
+ {
+ return ExtensionDescriptor.RELEASE;
+ }
+ else if( stage.equalsIgnoreCase("INNER") )
+ {
+ return ExtensionDescriptor.INNER;
+ }
+ else if( stage.equalsIgnoreCase("OUTER") )
+ {
+ return ExtensionDescriptor.OUTER;
+ }
+ else if( stage.equalsIgnoreCase("ALL") )
+ {
+ return ExtensionDescriptor.ALL;
+ }
+ else
+ {
+ final String error = "Supplied stage argument '" + stage + " invalid at "
+ + phase.getLocation()
+ + ". Allowable values: CREATE,DESTORY,ACCESS, RELEASE, INNER, OUTER or ALL.";
+
+ throw new IllegalArgumentException( error );
+ }
+ }
}
1.7 +1 -2 jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLTypeCreator.java
Index: XMLTypeCreator.java
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLTypeCreator.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- XMLTypeCreator.java 29 Jul 2002 06:14:34 -0000 1.6
+++ XMLTypeCreator.java 30 Jul 2002 07:05:56 -0000 1.7
@@ -130,7 +130,6 @@
new Integer( phases.length ) );
getLogger().info( message );
}
-
return new Type( descriptor, loggers, context, services, dependencies, phases );
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>