mcconnell 2002/07/28 23:14:34
Modified: assembly kernel.bat
assembly/demo/src/etc demo.mf
assembly/demo/src/java/org/apache/excalibur/playground
BasicComponent.xinfo ComplexComponent.xinfo
InvalidComponent.xinfo SimpleComponent.java
SimpleComponent.xinfo TerminalComponent.xinfo
assembly/lib excalibur-i18n-1.0.jar
assembly/src/etc kernel.xml merlin.html meta.mf project.mf
assembly/src/java/org/apache/excalibur/merlin
DefaultController.java DefaultController.xinfo
Main.java
assembly/src/java/org/apache/excalibur/merlin/container
Container.java DefaultContainer.java
DefaultContainer.xinfo package.html
assembly/src/java/org/apache/excalibur/merlin/kernel
DefaultKernel.java DefaultKernel.xinfo
assembly/src/java/org/apache/excalibur/merlin/model
Category.java Profile.java ResourceDesignator.java
package.html
assembly/src/java/org/apache/excalibur/merlin/model/builder
ProfileBuilder.java ProfileCreator.java
XMLProfileCreator.java
assembly/src/java/org/apache/excalibur/merlin/model/verifier
AssemblyVerifier.java MetaDataVerifier.java
assembly/src/java/org/apache/excalibur/meta
componentinfo.dtd
assembly/src/java/org/apache/excalibur/meta/info
DependencyDescriptor.java PhaseDescriptor.java
ServiceDescriptor.java Type.java
assembly/src/java/org/apache/excalibur/meta/info/builder
Resources.properties XMLTypeCreator.java
package.html
assembly/src/java/org/apache/excalibur/meta/info/doc-files
Type.gif
assembly/src/xdocs assembly.xml
Added: assembly/demo/src/java/org/apache/excalibur/playground
DefaultExploitationManager.java
DefaultExploitationManager.xinfo Exploitable.java
ExploitationManager.java
assembly/src/java/org/apache/excalibur/merlin/assembly
AssemblyException.java
AssemblyRuntimeException.java
DefaultLoggerManager.java DefaultSelector.java
DependencyGraph.java ProfileManager.java
ProfileRegistry.java ProfileTable.java
Selector.java TypeException.java TypeManager.java
TypeRegistry.java TypeRuntimeException.java
TypeTable.java UnresolvedProviderException.java
package.html
assembly/src/java/org/apache/excalibur/merlin/assembly/doc-files
DependencyGraph.gif
assembly/src/java/org/apache/excalibur/merlin/assembly/resource
AbstractLifecycleExtensionManager.java~
DefaultComponentManager.java DefaultManager.java
DefaultServiceManager.java ExtensionManager.java~
LifecycleException.java
LifecycleExtensionManager.java~
LifecycleHelper.java PhaseManager.java
ProfileDesignator.java ResourceException.java
ResourceProvider.java package.html
assembly/src/java/org/apache/excalibur/merlin/container/builder
ContainerCreator.java Resources.properties
XMLContainerCreator.java package.html
assembly/src/java/org/apache/excalibur/merlin/container/model
ClasspathDescriptor.java ContainerDescriptor.java
DirsetDescriptor.java ExtensionsDescriptor.java
FilesetDescriptor.java IncludeDescriptor.java
Parent.java package.html
assembly/src/java/org/apache/excalibur/merlin/kernel/builder
KernelCreator.java Resources.properties
XMLKernelCreator.java package.html
assembly/src/java/org/apache/excalibur/merlin/kernel/model
FileTargetProvider.java KernelDescriptor.java
LoggingDescriptor.java TargetDescriptor.java
TargetProvider.java package.html
assembly/src/java/org/apache/excalibur/meta/info
ExtensionDescriptor.java Facility.java
ReferenceDescriptor.java
assembly/src/java/org/apache/excalibur/meta/info/builder
FacilityBuilder.java FacilityCreator.java
SerializedFacilityCreator.java
XMLFacilityCreator.java
assembly/src/java/org/apache/excalibur/meta/info/builder/doc-files
FacilityBuilder.gif
Removed: assembly/src/java/org/apache/excalibur/merlin/container
AssemblyException.java
AssemblyRuntimeException.java
DefaultComponentManager.java DefaultManager.java
DefaultSelector.java DefaultServiceManager.java
DependencyGraph.java LifecycleException.java
LifecycleHelper.java ProfileDesignator.java
ProfileRegistry.java ProfileTable.java
ResourceProvider.java Selector.java
UnresolvedProviderException.java
assembly/src/java/org/apache/excalibur/merlin/container/doc-files
DependencyGraph.gif
assembly/src/java/org/apache/excalibur/merlin/extension
PhaseManager.java package.html
assembly/src/java/org/apache/excalibur/merlin/model
ClasspathDescriptor.java ContainerDescriptor.java
DirsetDescriptor.java ExtensionsDescriptor.java
FileTargetProvider.java FilesetDescriptor.java
IncludeDescriptor.java KernelDescriptor.java
LoggingDescriptor.java Parent.java
TargetDescriptor.java TargetProvider.java
assembly/src/java/org/apache/excalibur/merlin/model/builder
ContainerCreator.java DefaultLoggerManager.java
KernelCreator.java ProfileManager.java
TypeException.java TypeManager.java
TypeRegistry.java TypeRuntimeException.java
TypeTable.java XMLContainerCreator.java
XMLKernelCreator.java
assembly/src/java/org/apache/excalibur/meta/info
Extension.java ServiceDesignator.java
assembly/src/java/org/apache/excalibur/meta/info/builder
ExtensionBuilder.java ExtensionCreator.java
SerializedExtensionCreator.java
XMLExtensionCreator.java
assembly/src/java/org/apache/excalibur/meta/info/builder/doc-files
ExtensionBuilder.gif
Log:
general restructuring (better seperation of kernal, container and component
abstractions)
Revision Changes Path
1.5 +1 -1 jakarta-avalon-excalibur/assembly/kernel.bat
Index: kernel.bat
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/kernel.bat,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- kernel.bat 13 Jul 2002 00:09:44 -0000 1.4
+++ kernel.bat 29 Jul 2002 06:14:28 -0000 1.5
@@ -1 +1 @@
-java -jar .\extensions\merlin.jar src\etc\kernel.xml
+java -Djava.ext.dirs=.\extensions -jar .\extensions\merlin.jar
src\etc\kernel.xml
1.5 +6 -4 jakarta-avalon-excalibur/assembly/demo/src/etc/demo.mf
Index: demo.mf
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/demo/src/etc/demo.mf,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- demo.mf 4 Jul 2002 19:46:07 -0000 1.4
+++ demo.mf 29 Jul 2002 06:14:28 -0000 1.5
@@ -1,9 +1,8 @@
Manifest-Version: 1.0
Created-By: OSM SARL
-Extension-List: framework
-framework-Extension-Name: avalon-framework
-framework-Specification-Version: 1.0
-framework-Implementation-Version: 4.1.2
+Extension-List: meta
+meta-Extension-Name: avalon-meta
+meta-Specification-Version: 1.0
Name: org/apache/excalibur/playground/SimpleComponent.class
Avalon-Block: true
@@ -19,3 +18,6 @@
Name: org/apache/excalibur/playground/InvalidComponent.class
Avalon-Block: true
+
+Name: org/apache/excalibur/playground/DefaultExploitationManager.class
+Avalon-Facility: true
1.7 +1 -1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/BasicComponent.xinfo
Index: BasicComponent.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/BasicComponent.xinfo,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- BasicComponent.xinfo 18 Jul 2002 17:34:32 -0000 1.6
+++ BasicComponent.xinfo 29 Jul 2002 06:14:28 -0000 1.7
@@ -16,7 +16,7 @@
<services>
<service>
- <service-ref type="org.apache.excalibur.playground.BasicService"/>
+ <reference type="org.apache.excalibur.playground.BasicService"/>
</service>
</services>
1.7 +2 -2
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/ComplexComponent.xinfo
Index: ComplexComponent.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/ComplexComponent.xinfo,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ComplexComponent.xinfo 12 Jul 2002 15:11:57 -0000 1.6
+++ ComplexComponent.xinfo 29 Jul 2002 06:14:28 -0000 1.7
@@ -16,11 +16,11 @@
<dependencies>
<dependency>
<role>basic</role>
- <service-ref type="org.apache.excalibur.playground.BasicService"/>
+ <reference type="org.apache.excalibur.playground.BasicService"/>
</dependency>
<dependency>
<role>simple</role>
- <service-ref type="org.apache.excalibur.playground.SimpleService"/>
+ <reference type="org.apache.excalibur.playground.SimpleService"/>
</dependency>
</dependencies>
1.6 +1 -1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/InvalidComponent.xinfo
Index: InvalidComponent.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/InvalidComponent.xinfo,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- InvalidComponent.xinfo 7 Jul 2002 23:06:39 -0000 1.5
+++ InvalidComponent.xinfo 29 Jul 2002 06:14:28 -0000 1.6
@@ -12,7 +12,7 @@
<dependencies>
<dependency>
<role>silly</role>
- <service-ref
type="org.apache.excalibur.playground.InvalidService"/>
+ <reference type="org.apache.excalibur.playground.InvalidService"/>
</dependency>
</dependencies>
1.7 +21 -10
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.java
Index: SimpleComponent.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- SimpleComponent.java 20 Jul 2002 01:35:50 -0000 1.6
+++ SimpleComponent.java 29 Jul 2002 06:14:28 -0000 1.7
@@ -19,7 +19,7 @@
*/
public class SimpleComponent extends AbstractLogEnabled
-implements Configurable, Serviceable, Initializable, Startable, SimpleService
+implements Configurable, Serviceable, Initializable, Startable,
SimpleService, Exploitable
{
private String m_message;
@@ -28,15 +28,6 @@
private boolean CONTINUE = false;
//=======================================================================
- // PrimaryService
- //=======================================================================
-
- public void doObjective()
- {
- getLogger().info( m_message );
- }
-
- //=======================================================================
// Configurable
//=======================================================================
@@ -57,6 +48,15 @@
}
//=======================================================================
+ // Exploitable
+ //=======================================================================
+
+ public void exploit()
+ {
+ getLogger().debug( "I've been exploited!" );
+ }
+
+ //=======================================================================
// Initializable
//=======================================================================
@@ -111,4 +111,15 @@
{
}
}
+
+ //=======================================================================
+ // PrimaryService
+ //=======================================================================
+
+ public void doObjective()
+ {
+ getLogger().info( m_message );
+ }
+
+
}
1.5 +21 -3
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.xinfo
Index: SimpleComponent.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.xinfo,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SimpleComponent.xinfo 7 Jul 2002 23:06:39 -0000 1.4
+++ SimpleComponent.xinfo 29 Jul 2002 06:14:28 -0000 1.5
@@ -11,16 +11,34 @@
<services>
<service>
- <service-ref type="org.apache.excalibur.playground.SimpleService"/>
+ <reference type="org.apache.excalibur.playground.SimpleService"/>
</service>
</services>
<dependencies>
+
+ <!--
+ Declaration of the services that this component type is
+ dependent on.
+ -->
<dependency>
- <role>basic</role>
- <service-ref type="org.apache.excalibur.playground.BasicService"/>
+ <role>basic</role>
+ <reference type="org.apache.excalibur.playground.BasicService"/>
</dependency>
+
</dependencies>
+
+ <!--
+ Declaration of the extended lifecycle phases that this component type will
require.
+ Each phase element contains a reference to a lifecycle phase interface
that
+ the container has to manage.
+ -->
+ <phases>
+ <phase>
+ <reference type="org.apache.excalibur.playground.Exploitable"
version="1.0"/>
+ <attributes/>
+ </phase>
+ </phases>
</component-info>
1.5 +1 -1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/TerminalComponent.xinfo
Index: TerminalComponent.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/TerminalComponent.xinfo,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- TerminalComponent.xinfo 7 Jul 2002 23:06:39 -0000 1.4
+++ TerminalComponent.xinfo 29 Jul 2002 06:14:28 -0000 1.5
@@ -11,7 +11,7 @@
<services>
<service>
- <service-ref type="org.apache.excalibur.playground.BasicService"/>
+ <reference type="org.apache.excalibur.playground.BasicService"/>
</service>
</services>
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/DefaultExploitationManager.java
Index: DefaultExploitationManager.java
===================================================================
package org.apache.excalibur.playground;
import org.apache.avalon.framework.context.Context;
import org.apache.excalibur.merlin.assembly.resource.PhaseManager;
/**
* Definition of an extension type.
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public class DefaultExploitationManager implements PhaseManager
{
/**
* Create, called when the given component is being
* instantiated.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void create( Object component, Context context )
throws Exception
{
if( component instanceof Exploitable )
{
((Exploitable)component).exploit();
}
}
/**
* Destroy, called when the given component is being
* decomissioned.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void destroy( Object component, Context context )
throws Exception {}
/**
* Access, called when the given component is being
* accessed (ie. via lookup() or select()).
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void access( Object component, Context context )
throws Exception {}
/**
* Release, called when the given component is being
* released (ie. by a CM or CS).
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void release( Object component, Context context )
throws Exception {}
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/DefaultExploitationManager.xinfo
Index: DefaultExploitationManager.xinfo
===================================================================
<?xml version="1.0"?>
<!--
Definition of the extension type phase support.
-->
<component-info>
<component>
<name>exploitation</name>
</component>
<!--
Declaration of the lifecycle support phases that this manager provides.
-->
<extensions>
<!--
Each extension has a name, a versioned interface reference, and optional
attributes.
-->
<extension>
<name>exploit</name>
<reference type="org.apache.excalibur.playground.Exploitable"
version="1.0"/>
<attributes>
<attribute key="status" value="experimental"/>
</attributes>
</extension>
</extensions>
</component-info>
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/Exploitable.java
Index: Exploitable.java
===================================================================
package org.apache.excalibur.playground;
/**
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public interface Exploitable
{
public void exploit();
}
1.1
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/ExploitationManager.java
Index: ExploitationManager.java
===================================================================
package org.apache.excalibur.playground;
import org.apache.excalibur.merlin.assembly.resource.PhaseManager;
/**
* Definition of an extension type.
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public interface ExploitationManager extends PhaseManager
{
}
1.4 +73 -69
jakarta-avalon-excalibur/assembly/lib/excalibur-i18n-1.0.jar
<<Binary file>>
1.18 +13 -13 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.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- kernel.xml 25 Jul 2002 18:07:15 -0000 1.17
+++ kernel.xml 29 Jul 2002 06:14:29 -0000 1.18
@@ -21,7 +21,7 @@
the corresponds to the name of the logging file.
-->
- <logging priority="DEBUG" target="default">
+ <logging priority="INFO" target="default">
<target name="kernel">
<file location="kernel.log" />
</target>
@@ -29,10 +29,10 @@
<categories priority="INFO">
<category priority="WARN" name="logging" />
+ <category priority="WARN" name="loader" />
+ <category priority="WARN" name="loader.assembly" />
+ <category priority="WARN" name="loader.lifecycle" />
<category priority="INFO" name="export" />
- <category priority="WARN" name="installer" />
- <category priority="WARN" name="installer.types" />
- <category priority="WARN" name="installer.types.builder" />
</categories>
<!--
@@ -60,14 +60,8 @@
<categories priority="INFO">
<category priority="WARN" name="loader" />
- <category priority="WARN" name="loader.types" />
- <category priority="WARN" name="loader.types.builder" />
- <category priority="WARN" name="assembly" />
- <category priority="WARN" name="assembly.selector" />
- <category priority="WARN" name="provider" />
- <category priority="WARN" name="lifecycle" />
- <category priority="INFO" name="sub" />
- <category priority="INFO" name="sub.demo" />
+ <category priority="WARN" name="loader.assembly" />
+ <category priority="WARN" name="loader.lifecycle" />
</categories>
<!--
@@ -134,6 +128,12 @@
<container name="demo">
+ <categories priority="WARN">
+ <category priority="WARN" name="loader" />
+ <category priority="WARN" name="loader.assembly" />
+ <category priority="WARN" name="loader.lifecycle" />
+ </categories>
+
<!--
Including the next entry demonstrates the resolution of a
dependency via a profile
resolved from a parent container. SimpleComponent needs
BasicService with is available
@@ -143,7 +143,7 @@
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">
+ <component name="simple"
class="org.apache.excalibur.playground.SimpleComponent" enabled="true"
activation="true">
<configuration>
<message>This is a custom message.</message>
</configuration>
1.8 +1 -1 jakarta-avalon-excalibur/assembly/src/etc/merlin.html
Index: merlin.html
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/merlin.html,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- merlin.html 17 Jul 2002 13:48:37 -0000 1.7
+++ merlin.html 29 Jul 2002 06:14:29 -0000 1.8
@@ -16,7 +16,7 @@
<h3>Kernel Model</h3>
<p>Merlin seperates the notion of a kernel from a container. A kernal
manages resources (Objects) whereas a container manages services (Objects that
serve as service providers and consumers). The Merlin implementation provides
a default kernal that manages a container hierachy. The kernel provides the
framework for overall management including startup, shutting down, extensions
management, and other system wide facilities. The Melin implementation
provides a utility class [EMAIL PROTECTED] org.apache.excalibur.merlin.Main}
that handles establish of a kernel based on a single command line argument.</p>
-<p>A merlin kernel is created using a kernel model ([EMAIL PROTECTED]
org.apache.excalibur.merlin.model.KernelDescriptor}). The model may be defined
programatically or through an XML file. A kernel XML file contains the
defintion of kernal execution parameters and a root container.</P>
+<p>A merlin kernel is created using a kernel model ([EMAIL PROTECTED]
org.apache.excalibur.merlin.kernel.model.KernelDescriptor}). The model may be
defined programatically or through an XML file. A kernel XML file contains the
defintion of kernal execution parameters and a root container.</P>
<p><i>Minimilist kernel defintion.</i></p>
<pre>
<kernel>
1.2 +8 -2 jakarta-avalon-excalibur/assembly/src/etc/meta.mf
Index: meta.mf
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/meta.mf,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- meta.mf 7 Jul 2002 05:17:13 -0000 1.1
+++ meta.mf 29 Jul 2002 06:14:29 -0000 1.2
@@ -1,8 +1,14 @@
Manifest-Version: 1.0
Created-By: OSM SARL
-Extension-Name: AvalonMetaModel
+Extension-Name: avalon-meta
Specification-Vendor: Apache Software Foundation
Specification-Version: 1.0
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 0.1
-Class-Path: avalon-framework.jar logkit.jar excalibur-i18n-1.0.jar
+Extension-List: framework i18n
+framework-Extension-Name: avalon-framework
+framework-Specification-Version: 1.0
+framework-Implementation-Version: 4.1.2
+i18n-Extension-Name: excalibur-i18n
+i18n-Specification-Version: 1.0
+Class-Path: logkit.jar
1.11 +17 -4 jakarta-avalon-excalibur/assembly/src/etc/project.mf
Index: project.mf
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/project.mf,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- project.mf 17 Jul 2002 13:48:37 -0000 1.10
+++ project.mf 29 Jul 2002 06:14:29 -0000 1.11
@@ -1,13 +1,26 @@
Manifest-Version: 1.0
Created-By: OSM SARL
-Extension-Name: Assembler
+Extension-Name: org/apache/avalon/merlin
Specification-Vendor: Apache Software Foundation
Specification-Version: 1.0
Implementation-Vendor: Apache Software Foundation
Implementation-Version: 0.1
-Class-Path: avalon-framework.jar logkit.jar excalibur-logger-1.0.jar
excalibur-i18n-1.0.jar
- excalibur-configuration-1.0.jar excalibur-extension-1.0a.jar
- avalon-meta.jar xerces-2.0.1.jar xml-apis.jar xalan-2.3.1.jar
+Extension-List: framework meta configuration i18n logger extension
+framework-Extension-Name: avalon-framework
+framework-Specification-Version: 1.0
+framework-Implementation-Version: 4.1.2
+meta-Extension-Name: avalon-meta
+meta-Specification-Version: 1.0
+meta-Implementation-Version: 0.1
+configuration-Extension-Name: excalibur-configuration
+configuration-Specification-Version: 1.0
+i18n-Extension-Name: excalibur-i18n
+i18n-Specification-Version: 1.0
+logger-Extension-Name: excalibur-logger
+logger-Specification-Version: 1.0
+extension-Extension-Name: excalibur-extension
+extension-Specification-Version: 1.0
+Class-Path: logkit.jar xerces-2.0.1.jar xml-apis.jar xalan-2.3.1.jar
Main-Class: org.apache.excalibur.merlin.Main
Name: org/apache/excalibur/merlin/container/DefaultContainer.class
1.8 +8 -9
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/DefaultController.java
Index: DefaultController.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/DefaultController.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DefaultController.java 26 Jul 2002 06:17:04 -0000 1.7
+++ DefaultController.java 29 Jul 2002 06:14:29 -0000 1.8
@@ -24,17 +24,16 @@
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.logger.Logger;
+import org.apache.excalibur.merlin.assembly.ProfileManager;
+import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
import org.apache.excalibur.merlin.kernel.DefaultKernel;
-//import org.apache.excalibur.merlin.kernel.DefaultLoggerManager;
-import org.apache.excalibur.merlin.model.builder.DefaultTypeManager;
import org.apache.excalibur.merlin.kernel.KernelException;
+import org.apache.excalibur.merlin.kernel.model.KernelDescriptor;
+import org.apache.excalibur.merlin.kernel.builder.XMLKernelCreator;
import org.apache.excalibur.merlin.model.ResourceDesignator;
-import org.apache.excalibur.merlin.model.builder.XMLKernelCreator;
-import org.apache.excalibur.merlin.model.KernelDescriptor;
-import org.apache.excalibur.merlin.model.ClasspathDescriptor;
-import org.apache.excalibur.merlin.model.ExtensionsDescriptor;
-import org.apache.excalibur.merlin.model.LoggingDescriptor;
-import org.apache.excalibur.merlin.model.ContainerDescriptor;
+import org.apache.excalibur.merlin.container.model.ClasspathDescriptor;
+import org.apache.excalibur.merlin.container.model.ExtensionsDescriptor;
+import org.apache.excalibur.merlin.kernel.model.LoggingDescriptor;
/**
1.2 +1 -1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/DefaultController.xinfo
Index: DefaultController.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/DefaultController.xinfo,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultController.xinfo 13 Jul 2002 00:09:44 -0000 1.1
+++ DefaultController.xinfo 29 Jul 2002 06:14:29 -0000 1.2
@@ -23,7 +23,7 @@
<services>
<service>
- <service-ref type="org.apache.excalibur.merlin.Controller"
version="1.0"/>
+ <reference type="org.apache.excalibur.merlin.Controller"
version="1.0"/>
</service>
</services>
1.9 +9 -18
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.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Main.java 25 Jul 2002 18:07:15 -0000 1.8
+++ Main.java 29 Jul 2002 06:14:29 -0000 1.9
@@ -52,28 +52,19 @@
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.ExceptionUtil;
-import org.apache.avalon.excalibur.extension.PackageRepository;
-import org.apache.avalon.excalibur.extension.Extension;
-import org.apache.avalon.excalibur.extension.OptionalPackage;
-import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
-import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
-import org.apache.excalibur.meta.info.ServiceDesignator;
-import org.apache.excalibur.merlin.model.builder.XMLKernelCreator;
-import org.apache.excalibur.merlin.model.KernelDescriptor;
-import org.apache.excalibur.merlin.model.ClasspathDescriptor;
-import org.apache.excalibur.merlin.model.ExtensionsDescriptor;
-import org.apache.excalibur.merlin.model.LoggingDescriptor;
-import org.apache.excalibur.merlin.model.ContainerDescriptor;
+import org.apache.excalibur.meta.info.ReferenceDescriptor;
+import org.apache.excalibur.merlin.assembly.ProfileManager;
+import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
+import org.apache.excalibur.merlin.kernel.builder.XMLKernelCreator;
+import org.apache.excalibur.merlin.kernel.model.KernelDescriptor;
+import org.apache.excalibur.merlin.container.model.ClasspathDescriptor;
+import org.apache.excalibur.merlin.container.model.ExtensionsDescriptor;
+import org.apache.excalibur.merlin.kernel.model.LoggingDescriptor;
import org.apache.excalibur.merlin.kernel.DefaultKernel;
-//import org.apache.excalibur.merlin.kernel.DefaultLoggerManager;
-import org.apache.excalibur.merlin.model.builder.DefaultTypeManager;
import org.apache.excalibur.merlin.kernel.KernelException;
-import org.apache.log.Hierarchy;
-import org.apache.log.Priority;
-import org.apache.log.output.io.StreamTarget;
/**
* <p>Utility class supporting the establishment of a new
<code>Controller</code>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/AssemblyException.java
Index: AssemblyException.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 java.util.Enumeration;
import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate that there was an error during assembly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public final class AssemblyException
extends CascadingException
{
private static final Hashtable EMPTY_TABLE = new Hashtable();
private Dictionary m_errors;
/**
* Construct a new <code>AssemblyException</code> instance.
*
* @param message The detail message for this exception.
*/
public AssemblyException( final String message )
{
this( null, message, null );
}
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
*/
public AssemblyException( final Dictionary errors, final String message )
{
this( errors, message, null );
}
/**
* Construct a new <code>AssemblyException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public AssemblyException( final String message, final Throwable throwable
)
{
this( null, message, throwable );
}
/**
* Construct a new <code>AssemblyException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public AssemblyException( final Dictionary errors, final String message,
final Throwable throwable )
{
super( message, throwable );
if( errors != null )
{
m_errors = errors;
}
else
{
m_errors = EMPTY_TABLE;
}
}
/**
* Return the table of supplimentary messages.
* @return the messages table
*/
public Dictionary getDictionary()
{
return m_errors;
}
/**
* Returns a stringified representation of the exception.
* @return the exception as a string.
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( super.toString() );
buffer.append( " Errors: " + m_errors.size() );
Enumeration keys = m_errors.keys();
while( keys.hasMoreElements() )
{
Object key = keys.nextElement();
buffer.append( "\n source: " + key.toString() + " cause: " +
m_errors.get( key ) );
}
return buffer.toString();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/AssemblyRuntimeException.java
Index: AssemblyRuntimeException.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 java.util.Enumeration;
import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.avalon.framework.CascadingRuntimeException;
/**
* Exception to indicate that there was a runtime error during assembly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public final class AssemblyRuntimeException
extends CascadingRuntimeException
{
private static final Hashtable EMPTY_TABLE = new Hashtable();
private Dictionary m_errors;
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param message The detail message for this exception.
*/
public AssemblyRuntimeException( final String message )
{
this( null, message, null );
}
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
*/
public AssemblyRuntimeException( final Dictionary errors, final String
message )
{
this( errors, message, null );
}
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public AssemblyRuntimeException( final String message, final Throwable
throwable )
{
this( null, message, throwable );
}
/**
* Construct a new <code>AssemblyRuntimeException</code> instance.
*
* @param errors a list of warning messages related to the exception.
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public AssemblyRuntimeException( final Dictionary errors, final String
message,
final Throwable throwable )
{
super( message, throwable );
if( errors != null )
{
m_errors = errors;
}
else
{
m_errors = EMPTY_TABLE;
}
}
/**
* Return the table of supplimentary messages.
* @return the messages table
*/
public Dictionary getDictionary()
{
return m_errors;
}
/**
* Returns a stringified representation of the exception.
* @return the exception as a string.
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( super.toString() );
buffer.append( " Errors: " + m_errors.size() );
Enumeration keys = m_errors.keys();
while( keys.hasMoreElements() )
{
Object key = keys.nextElement();
buffer.append( "\n source: " + key.toString() + " cause: " +
m_errors.get( key ) );
}
return buffer.toString();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/DefaultLoggerManager.java
Index: DefaultLoggerManager.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 java.io.File;
import java.io.IOException;
import java.util.HashMap;
import org.apache.log.Hierarchy;
import org.apache.log.LogTarget;
import org.apache.log.Logger;
import org.apache.log.Priority;
import org.apache.log.output.io.FileTarget;
import org.apache.log.output.io.StreamTarget;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.excalibur.logger.LoggerManager;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.AvalonFormatter;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.excalibur.merlin.container.model.Parent;
import org.apache.excalibur.merlin.kernel.model.TargetDescriptor;
import org.apache.excalibur.merlin.kernel.model.LoggingDescriptor;
import org.apache.excalibur.merlin.kernel.model.TargetProvider;
import org.apache.excalibur.merlin.kernel.model.FileTargetProvider;
import org.apache.excalibur.merlin.model.Category;
import org.apache.excalibur.merlin.model.CategoriesDescriptor;
/**
* A <code>LoggerManager</code> that supports management of a logging
hierarchy.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Eung-ju Park</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
*/
public class DefaultLoggerManager
implements LoggerManager
{
public static final String DEFAULT_PRIORITY = "INFO";
public static final String DEFAULT_TARGET = "default";
public static final String HOME_KEY = "app.home";
private static final Resources REZ =
ResourceManager.getPackageResources( DefaultLoggerManager.class );
private static final String DEFAULT_FORMAT =
"[%7.7{priority}] (%{category}): %{message}\\n%{throwable}";
/**
* Base directory of file targets.
*/
private File m_baseDirectory;
/**
* log hierarchy.
*/
private Hierarchy m_logHierarchy;
/**
* default logger
*/
private org.apache.avalon.framework.logger.Logger m_logger;
/**
* default logger target
*/
private StreamTarget m_stream;
private final HashMap m_targets = new HashMap();
private DefaultLoggerManager m_parent;
private String m_category;
//===============================================================
// constructor
//===============================================================
/**
* Creation of a new LoggerManager.
* @param descriptor the logging system description
* @exception Exception is an error occurs
*/
public DefaultLoggerManager( final LoggingDescriptor descriptor ) throws
Exception
{
//
// setup the hierarchy, default logging target, and default priority
//
m_stream = new StreamTarget( System.out, new AvalonFormatter(
DEFAULT_FORMAT ) );
m_baseDirectory = new File( System.getProperty("user.dir") );
m_logHierarchy = new Hierarchy();
getHierarchy().setDefaultLogTarget( m_stream );
m_targets.put( DEFAULT_TARGET, m_stream );
if( descriptor.getPriority() != null )
{
getLogger().debug("supplied system priority: " +
descriptor.getPriority() );
getHierarchy().setDefaultPriority(
Priority.getPriorityForName( descriptor.getPriority( ) )
);
}
else
{
getLogger().debug("internal system priority: " + DEFAULT_PRIORITY
);
getHierarchy().setDefaultPriority(
Priority.getPriorityForName( DEFAULT_PRIORITY )
);
}
//
// build targets based on the information contained in the descriptor
//
TargetDescriptor[] targets = descriptor.getTargetDescriptors();
for( int i=0; i<targets.length; i++ )
{
addTarget( targets[i] );
}
//
// set the default target
//
String name = descriptor.getTarget();
if( name != null )
{
LogTarget target = (LogTarget) m_targets.get( name );
if( target != null )
{
getHierarchy().setDefaultLogTarget( target );
}
else
{
throw new TypeException(
"Supplied default logging target: '" + name + "' does not
exist." );
}
}
}
/**
* Add a set of category entries using the system wide defaults.
* @param path the category header
* @param descriptor a set of category descriptors to be added under the
path
*/
public void addCategories( CategoriesDescriptor descriptor )
{
addCategories( "", descriptor );
}
/**
* Add a set of category entries using the system wide defaults.
* @param path the category header
* @param descriptor a set of category descriptors to be added under the
path
*/
public void addCategories( Parent parent, CategoriesDescriptor descriptor
)
{
String path = null;
final String name = descriptor.getName();
if( parent != null )
{
path = parent.getPath().replace('/','.').substring(1) + "." +
name;
}
else
{
path = name;
}
addCategories( path, descriptor );
}
/**
* Add a set of category entries using the system wide defaults.
* @param path the category header
* @param descriptor a set of category descriptors to be added under the
path
*/
public void addCategories( String path, CategoriesDescriptor descriptor )
{
addSingleCategory( path, descriptor.getPriority(),
descriptor.getTarget( ) );
Category[] categories = descriptor.getCategories();
for( int i=0; i<categories.length; i++ )
{
Category category = categories[i];
final String priority = category.getPriority();
final String target = category.getTarget();
if( path.equals("") )
{
addSingleCategory( category.getName(), priority, target );
}
else
{
addSingleCategory( path + "." + category.getName(), priority,
target );
}
}
}
private Logger addSingleCategory( String path, String priority, String
target )
{
final Logger logger = getHierarchy().getLoggerFor( path );
if( priority != null )
{
final Priority priorityValue = Priority.getPriorityForName(
priority );
if( !priorityValue.getName().equals( priority ) )
{
final String message = REZ.getString( "unknown-priority",
priority, path );
throw new IllegalArgumentException( message );
}
logger.setPriority( priorityValue );
}
if( target != null )
{
final LogTarget logTarget = (LogTarget) m_targets.get( target );
if( logTarget != null )
logger.setLogTargets( new LogTarget[]{ logTarget } );
}
else
{
logger.setLogTargets( new LogTarget[]{ (LogTarget) m_targets.get(
DEFAULT_TARGET ) } );
}
if( getLogger().isDebugEnabled() )
{
final String message =
REZ.getString( "category-create", path, target,
logger.getPriority() );
getLogger().info( message );
}
return logger;
}
private void addTarget( TargetDescriptor target ) throws Exception
{
File base = new File( System.getProperty("user.dir") );
final String name = target.getName();
TargetProvider provider = target.getProvider();
if( provider instanceof FileTargetProvider )
{
FileTargetProvider fileProvider = (FileTargetProvider) provider;
String filename = fileProvider.getLocation();
final AvalonFormatter formatter = new AvalonFormatter(
DEFAULT_FORMAT );
try
{
File file = new File( base, filename );
FileTarget logTarget = new FileTarget(
file.getAbsoluteFile(), false, formatter );
m_targets.put( name, logTarget );
}
catch( final IOException ioe )
{
final String message =
REZ.getString( "target.nocreate", name, filename,
ioe.getMessage() );
throw new TypeException( message, ioe );
}
}
else
{
final String error =
"Unrecognized logging provider: " +
provider.getClass().getName();
throw new IllegalArgumentException( error );
}
}
/**
* Configure Logging categories.
*
* @param categories configuration data for categories
* @param targets a hashmap containing the already existing taregt
* @throws ConfigurationException if an error occurs
*/
public org.apache.avalon.framework.logger.Logger getLoggerForCategory(
final String name, String target, String priority )
throws Exception
{
return new LogKitLogger( addSingleCategory( name, target, priority )
);
}
/**
* Configure Logging categories.
*
* @param categories configuration data for categories
* @param targets a hashmap containing the already existing taregt
* @throws ConfigurationException if an error occurs
*/
public org.apache.avalon.framework.logger.Logger getLoggerForCategory(
final Category category )
throws Exception
{
return new LogKitLogger(
addSingleCategory(
category.getName(),
category.getPriority(),
category.getTarget()
)
);
}
//===============================================================
// LoggerManager
//===============================================================
/**
* Return the Logger for the specified category.
*/
public org.apache.avalon.framework.logger.Logger getLoggerForCategory(
final String category )
{
if( category == null )
{
return new LogKitLogger( getHierarchy().getLoggerFor( "" ) );
}
else
{
return new LogKitLogger( getHierarchy().getLoggerFor( category )
);
}
}
/**
* Return the default Logger. This is the same
* as getting the Logger for the "" category.
*/
public org.apache.avalon.framework.logger.Logger getDefaultLogger( )
{
if( m_logger == null )
m_logger = getLoggerForCategory("");
return m_logger;
}
/**
* Return the default Logger. This is the same
* as getting the Logger for the "" category.
*/
public org.apache.avalon.framework.logger.Logger getLogger( )
{
if( m_logger == null )
m_logger = getLoggerForCategory("kernel.logging");
return m_logger;
}
private Hierarchy getHierarchy()
{
if( m_parent != null )
{
return m_parent.getHierarchy();
}
return m_logHierarchy;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/DefaultSelector.java
Index: DefaultSelector.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.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.merlin.model.Profile;
/**
* Default selector class.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
class DefaultSelector extends AbstractLogEnabled
implements Selector
{
/**
* Returns the preferred profile form an available selection of candidate
provider profiles.
* @param profiles the set of profiles of potential service providers
* @return the preferred provider or null if no satisfactory provider can
be established
* from the supplied profiles.
*/
public Profile select( Profile[] profiles )
{
Profile profile = select( profiles, Profile.EXPLICIT );
if( profile == null ) profile = select( profiles, Profile.PACKAGED );
if( profile == null ) profile = select( profiles, Profile.IMPLICIT );
return profile;
}
/**
* Returns the preferred profile form an available selection of candidate
provider profiles.
* @param facilities the set of profiles of potential service providers
available in the
* container hierachy
* @param profiles the set of profiles of potential service providers
contained with the
* local container
* @return the preferred provider or null if no satisfactory provider can
be established
* from the supplied profiles.
*/
public Profile select( Profile[] facilities, Profile[] profiles )
{
//
// apply default selection policy
//
Profile profile = select( profiles, Profile.EXPLICIT );
if( profile == null )
{
profile = select( facilities );
}
else
{
getLogger().debug("local selection: " + profile );
}
if( profile == null )
{
profile = select( profiles );
}
else
{
getLogger().debug("facility selection: " + profile );
}
return profile;
}
private Profile select( Profile[] profiles, int mode )
{
for( int i=0; i<profiles.length; i++ )
{
if( profiles[i].getMode() == mode )
return profiles[i];
}
return null;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/DependencyGraph.java
Index: DependencyGraph.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 java.util.ArrayList;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.Association;
import org.apache.excalibur.meta.info.DependencyDescriptor;
/**
* <p>Utility class to help aquire a ordered graph of
* consumers and providers for specific components.</p>
* <p><b>UML</b></p>
* <p><image src="doc-files/DependencyGraph.gif" border="0"/></p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public class DependencyGraph
{
/**
* Parent Map. Components in parent
* Map are potential Providers for services
* if no profile in current assembly satisfies dependency.
*/
private final DependencyGraph m_parent;
/**
* The set of components declared by the container as available.,
* Used when searching for providers/consumers.
*/
private final ArrayList m_components = new ArrayList();
/**
* The child [EMAIL PROTECTED] DependencyGraph} objects.
* Possible consumers of services in this assembly.
*/
private final ArrayList m_children = new ArrayList();
public DependencyGraph()
{
this( null );
}
public DependencyGraph( final DependencyGraph parent )
{
m_parent = parent;
}
/**
* Add child dependency graph.
*
* @param child the child map
*/
public void addChild( final DependencyGraph child )
{
m_children.add( child );
}
/**
* Remove child dependency graph.
*
* @param child the child map
*/
public void removeChild( final DependencyGraph child )
{
m_children.remove( child );
}
/**
* Add a profile to current dependency graph.
*
* @param profile the profile
*/
public void add( final Profile profile )
{
if( !m_components.contains( profile ) )
m_components.add( profile );
}
/**
* Get the serilized graph of [EMAIL PROTECTED] Profile} objects
* required when starting up all the components. This makes sure
* that all providers occur before their coresponding
* consumers in graph.
*
* @return the ordered list of components
*/
public Profile[] getStartupGraph()
{
return walkGraph( true );
}
/**
* Get the serilized graph of [EMAIL PROTECTED] Profile} objects
* required when shutting down all the components. This makes
* sure that all consumers occur before their coresponding
* providers in graph.
*
* @return the ordered list of components
*/
public Profile[] getShutdownGraph()
{
return walkGraph( false );
}
/**
* Get the serilized graph of [EMAIL PROTECTED] Profile} objects
* that use services of specified profile.
*
* @param profile the profile
* @return the ordered list of consumers
*/
public Profile[] getConsumerGraph( final Profile profile )
{
return referencedProfiles( profile, getComponentGraph( profile, false
));
}
/**
* Get the serilized graph of [EMAIL PROTECTED] Profile} objects
* that provide specified profile with services.
*
* @param profile the profile
* @return the ordered list of providers
*/
public Profile[] getProviderGraph( final Profile profile )
{
return referencedProfiles( profile, getComponentGraph( profile, true
));
}
/**
* Return a profile array that does not include the provided profile.
*/
private Profile[] referencedProfiles( final Profile profile, Profile[]
profiles )
{
ArrayList list = new ArrayList();
for( int i=0; i<profiles.length; i++ )
{
if( !profiles[i].equals( profile ) )
list.add( profiles[i] );
}
return (Profile[]) list.toArray( new Profile[0] );
}
/**
* Get the graph of a single profile.
*
* @param profile the profile
* @param providers true if traversing providers, false if consumers
* @return the list of components in graph
*/
private Profile[] getComponentGraph( final Profile profile, final boolean
providers )
{
final ArrayList result = new ArrayList();
visitcomponent( profile,
providers,
new ArrayList(),
result );
final Profile[] returnValue = new Profile[ result.size() ];
return (Profile[])result.toArray( returnValue );
}
/**
* Method to generate an ordering of nodes to traverse.
* It is expected that the specified components have passed
* verification tests and are well formed.
*
* @param providers true if forward dependencys traced, false if
dependencies reversed
* @return the ordered node names
*/
private Profile[] walkGraph( final boolean providers )
{
final ArrayList result = new ArrayList();
final ArrayList done = new ArrayList();
final int size = m_components.size();
for( int i = 0; i < size; i++ )
{
final Profile profile =
(Profile)m_components.get( i );
visitcomponent( profile,
providers,
done,
result );
}
final Profile[] returnValue = new Profile[ result.size() ];
return (Profile[])result.toArray( returnValue );
}
/**
* Visit a profile when traversing dependencies.
*
* @param profile the profile
* @param providers true if walking tree looking for providers, else false
* @param done those nodes already traversed
* @param order the order in which nodes have already been
* traversed
*/
private void visitcomponent( final Profile profile,
final boolean providers,
final ArrayList done,
final ArrayList order )
{
//If already visited this profile then bug out early
if( done.contains( profile ) )
{
return;
}
done.add( profile );
if( providers )
{
visitProviders( profile, done, order );
}
else
{
visitConsumers( profile, done, order );
}
order.add( profile );
}
/**
* Traverse graph of components that provide services to
* the specified profile.
*
* @param profile the Profile
*/
private void visitProviders( final Profile profile,
final ArrayList done,
final ArrayList order )
{
final DependencyDescriptor[] descriptors =
profile.getType().getDependencies();
for( int i = 0; i < descriptors.length; i++ )
{
final Association assignment =
profile.getAssociation( descriptors[ i ].getRole() );
// added != null clause to catch cases where an optional
// dependency exists and the dependecy has not been bound
// to a provider
if( assignment != null )
{
final Profile provider =
assignment.getProvider().getProfile();
visitcomponent( provider, true, done, order );
}
else
{
if( descriptors[i].isRequired() )
throw new IllegalStateException(
"unresolved dependency for role: " +
descriptors[i].getRole()
+ " in profile: " + profile );
}
}
}
/**
* Traverse all Consumers of profile. ie Anyone that uses
* service provided by profile.
*
* @param profile the Profile
*/
private void visitConsumers( final Profile profile,
final ArrayList done,
final ArrayList order )
{
final String name = profile.getName();
final int size = m_components.size();
for( int i = 0; i < size; i++ )
{
final Profile other =
(Profile)m_components.get( i );
final Association[] providers = other.getAssociations();
for( int j = 0; j < providers.length; j++ )
{
if( providers[ j ].getProvider().equals( profile ) )
{
visitcomponent( other, false, done, order );
}
}
}
final int childCount = m_children.size();
for( int i = 0; i < childCount; i++ )
{
final DependencyGraph map = (DependencyGraph)m_children.get( i );
map.visitConsumers( profile, done, order );
}
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileManager.java
Index: ProfileManager.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 java.io.File;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Hashtable;
import java.util.ArrayList;
import java.util.Vector;
import java.util.Iterator;
import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.excalibur.merlin.assembly.resource.LifecycleHelper;
import org.apache.excalibur.merlin.assembly.resource.ResourceProvider;
import org.apache.excalibur.merlin.assembly.resource.ProfileDesignator;
import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
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.ServiceDescriptor;
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.builder.TypeBuilder;
import org.apache.excalibur.meta.verifier.ComponentVerifier;
/**
* Classloader for an assembly of components.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public class ProfileManager extends TypeManager implements Startable
{
//===================================================================
// static
//===================================================================
private static final Resources REZ =
ResourceManager.getPackageResources( ProfileManager.class );
public static final String DELIMITER = "/";
/**
* Context key used to locate the logging manager.
*/
public static final String LOGGING_MANAGER_KEY = "logging";
//===================================================================
// state
//===================================================================
/**
* The default selector.
*/
private LifecycleHelper m_helper = new LifecycleHelper();
/**
* The default selector.
*/
private DefaultSelector m_selector = new DefaultSelector();
/**
* Profiles keyed by name.
*/
private Hashtable m_profiles = new Hashtable();
/**
* List of ServiceTable instances.
*/
private List m_services = new LinkedList();
/**
* Utility class used to create type meta info for components not
explicity declared
* in the meta data model.
*/
private ProfileBuilder m_builder = new ProfileBuilder();
/**
* The logging manager - one instance in a root manager.
* @see #getLoggingManager()
*/
private DefaultLoggerManager m_logging;
/**
* Utility class that manages supply of context, config, services, etc.
during
* startup of a profile.
*/
private ResourceProvider m_provider;
/**
* The manager name from which the manager path is resolved.
*/
private String m_name;
/**
* The manager's path.
*/
private String m_path;
/**
* The parent manager.
*/
private ProfileManager m_parent;
/**
* Mapping of established resource designators keyed by profile.
*/
private Hashtable m_resources = new Hashtable();
/**
* The dependency map.
*/
private DependencyGraph m_map;
/**
* Utility class to handle assembly.
*/
private ProfileRegistry m_registry;
//===================================================================
// constructor
//===================================================================
public ProfileManager( ClassLoader parent, String name )
{
super( parent );
m_name = name;
if( parent instanceof ProfileManager )
{
m_parent = (ProfileManager) parent;
m_path = m_parent.getPath() + DELIMITER + name;
m_map = new DependencyGraph( m_parent.getDependencyMap() );
}
else
{
m_path = DELIMITER + name;
m_map = new DependencyGraph();
}
}
//=======================================================================
// Contextualizable
//=======================================================================
/**
* Declaration of the logging manager.
* @param context the context object containing the inital parameters
*/
public void contextualize( Context context ) throws ContextException
{
super.contextualize( context );
if( getLoggingManager() == null )
m_logging = (DefaultLoggerManager) context.get(
LOGGING_MANAGER_KEY );
}
//=======================================================================
// Initializable
//=======================================================================
public void initialize() throws Exception
{
super.initialize();
getLogger().info("profile manager");
m_selector.enableLogging( getLogger().getChildLogger("selector") );
m_helper.enableLogging( getLogger().getChildLogger("lifecycle") );
//
// setup the resource provider
//
DefaultContext context = new DefaultContext();
context.put("avalon:work", new File( System.getProperty("user.dir") )
);
m_provider = new ResourceProvider( this, context, getLoggingManager()
);
m_provider.enableLogging( getLogger().getChildLogger("provider") );
//
// setup the assembly sub-system
//
m_registry = new ProfileRegistry( this, m_map );
m_registry.enableLogging( getLogger().getChildLogger( "assembly") );
//
// build the profiles
//
getLogger().debug("packaged and implicit profile registration");
Type[] types = getTypes();
getLogger().info("type count: " + types.length );
for( int i=0; i<types.length; i++ )
{
Profile[] profiles = m_builder.build( this, types[i] );
for( int j=0; j<profiles.length; j++ )
{
addProfile( profiles[j] );
}
}
getLogger().info("profile count: " + m_profiles.size() );
}
//======================================================================
// Startable
//======================================================================
/**
* Method invoked by the container's container to signal the activation of
* all components.
*
* @exception Exception if a start related error occurs
*/
public void start() throws Exception
{
Profile[] profiles = m_map.getStartupGraph();
for( int i=0; i<profiles.length; i++ )
{
Profile profile = profiles[i];
if( profile.getActivationPolicy() )
{
ResourceDesignator resource = getResource( profile );
if( resource.getState() == ResourceDesignator.NOT_STARTED )
{
getLogger().info( "STARTING: " + profile );
resource.getInstance();
}
}
}
}
public void stop()
{
Profile[] profiles = m_map.getShutdownGraph();
for( int i=0; i<profiles.length; i++ )
{
Profile profile = profiles[i];
try
{
ResourceDesignator resource = getResource( profile );
if( resource.getState() == ResourceDesignator.STARTED )
{
getLogger().info( "STOPPING: " + profile );
resource.release();
}
}
catch ( Throwable e )
{
final String warning =
"Could not shutdown a service derived from profile: '"
+ profile.getName() + "'.";
getLogger().warn( warning, e );
}
}
}
//===================================================================
// ProfileManager
//===================================================================
/**
* Returns the path name of this manager.
* @return the manager's path
*/
public String getPath()
{
return m_path;
}
DefaultLoggerManager getLoggingManager()
{
ProfileManager parent = getParentManager();
if( parent != null )
{
return parent.getLoggingManager();
}
else
{
return m_logging;
}
}
/**
* Add a type profile to the manager.
*
* @param profile the profile to add to the manager.
*/
public void addProfile( Profile profile )
{
final String name = profile.getName();
final String classname =
profile.getType().getInfo().getImplementationKey();
if( isLocal( classname ) )
{
if( m_profiles.get( name ) != null )
throw new IllegalArgumentException(
"Profile named '" + name + "' already registered.");
m_profiles.put( profile.getName(), profile );
ServiceDescriptor[] services = profile.getType().getServices();
for( int i=0; i<services.length; i++ )
{
addProfile( services[i].getService(), profile );
}
getLogger().info("added: " + profile );
}
else
{
ProfileManager parent = getParentManager();
if( parent != null )
{
parent.addProfile( profile );
}
else
{
final String error = "Unknown type reference in profile: " +
profile;
throw new TypeRuntimeException( error );
}
}
}
public boolean isLocal( Profile profile )
{
return m_profiles.containsKey( profile.getName() );
}
/**
* Return the set of profiles matching a version interface.
* @param reference a consumer component dependency declaration
* @return the set of available potential supplier profiles
*/
public Profile[] getProfiles( ReferenceDescriptor reference )
{
Profile[] local = getLocalProfiles( reference );
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( reference );
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 versioned interface spec
* using a supplied selector.
*
* @param reference a consumer component dependency declaration
* @return the selected profile
*/
public Profile getProfile( DependencyDescriptor dependency )
{
Selector selector = getSelector( dependency );
return getProfile( dependency.getService(), selector );
}
/**
* Return a single profile matching a supplied versioned interface spec
* using a supplied selector.
*
* @param reference a consumer component dependency declaration
* @return the selected profile
*/
public Profile getProfile( ReferenceDescriptor reference, Selector
selector )
{
Profile[] profiles = getProfiles( reference );
return selector.select( profiles );
}
public ResourceDesignator getResource( Profile profile ) throws
TypeException
{
return getResource( profile, false );
}
public ResourceDesignator getResource( Profile profile, boolean create )
throws TypeException
{
if( isLocal( profile ) )
{
ResourceDesignator resource = getLocalResource( profile );
if(( resource == null ) && create )
{
final String name = getPath() + DELIMITER + profile.getName();
resource = new ProfileDesignator( name, profile, m_helper,
m_provider );
m_resources.put( profile, resource );
}
return resource;
}
else
{
ProfileManager parent = getParentManager();
if( parent != null )
{
return parent.getResource( profile, create );
}
else
{
final String error = "Unknown profile: " + profile;
throw new TypeException( error );
}
}
}
private ResourceDesignator getLocalResource( Profile profile )
{
return (ResourceDesignator) m_resources.get( profile );
}
public void assemble( Profile[] profiles ) throws Exception
{
m_registry.assemble( profiles );
}
/**
* Returns an order sequence of resource designators that have a startup
activation
* policy.
*
* @return the resource sequence
*/
public ResourceDesignator[] getStartupGraph()
{
ArrayList list = new ArrayList();
Profile[] startup = m_map.getStartupGraph();
for( int i=0; i<startup.length; i++ )
{
Profile profile = startup[i];
getLogger().info( "PROFILE: " + profile + ", " + isLocal( profile
) );
if( isLocal( profile ) )
{
if( profile.getActivationPolicy() )
{
ResourceDesignator resource = getLocalResource( profile );
if( resource != null )
{
list.add( resource );
}
else
{
final String warning = "Missing resource for profile:
" + profile;
getLogger().warn( warning );
}
}
}
}
return (ResourceDesignator[]) list.toArray( new ResourceDesignator[
list.size() ] );
}
/**
* Returns an order sequence of resource designators for shutdown.
*
* @return the resource sequence
*/
public ResourceDesignator[] getShutdownGraph()
{
ArrayList list = new ArrayList();
Profile[] shutdown = m_map.getShutdownGraph();
for( int i=0; i<shutdown.length; i++ )
{
Profile profile = shutdown[i];
if( isLocal( profile ) )
{
ResourceDesignator resource = getLocalResource( profile );
if( resource != null )
{
list.add( resource );
}
}
}
return (ResourceDesignator[]) list.toArray( new ResourceDesignator[0]
);
}
/**
* Returns a child dependency graph.
* @return a new dependency graph
*/
protected DependencyGraph getDependencyMap()
{
return new DependencyGraph( m_map );
}
/**
* Returns the ser of exportable resources.
*
* @return the resource sequence
*/
public ResourceDesignator[] getExport()
{
ArrayList list = new ArrayList();
Profile[] startup = m_map.getStartupGraph();
for( int i=0; i<startup.length; i++ )
{
Profile profile = startup[i];
try
{
list.add( getResource( profile ) );
}
catch( Throwable e )
{
final String warning = "Missing resource for profile: " +
profile;
getLogger().warn( warning );
}
}
return (ResourceDesignator[]) list.toArray( new ResourceDesignator[
list.size() ] );
}
//=============================================================================
// private
//=============================================================================
/**
* Returns the set of profiles capable of supporting the supplied service.
* @return the set of candidate component types
*/
private Profile[] getLocalProfiles( ReferenceDescriptor service )
{
return getTable( service ).getProfiles();
}
/**
* Returns the parent profile manager or null if this is the root manager.
* @return the parent
*/
private ProfileManager getParentManager()
{
return m_parent;
}
private void addProfile( ReferenceDescriptor reference, Profile profile )
{
ProfileTable table = getTable( reference );
table.add( profile );
}
/**
* Return a table that holds profiles supporting the supplied service
reference.
*/
private ProfileTable getTable( ReferenceDescriptor service )
{
ProfileTable table = null;
Iterator iterator = m_services.iterator();
while( iterator.hasNext() )
{
table = (ProfileTable) iterator.next();
if( table.matches( service ) )
return table;
}
// otherwise create a new table
table = new ProfileTable( service );
m_services.add( table );
return table;
}
private Selector getSelector( DependencyDescriptor dependency )
{
// if the dependency declares a selector class then use that,
// otherwise, look for a default service type selector - if none
// use the DefaultSelector
String selectorName =
dependency.getAttribute("avalon.service.selector");
if( selectorName == null )
selectorName = dependency.getService().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;
}
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileRegistry.java
Index: ProfileRegistry.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 java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Hashtable;
import java.util.ArrayList;
import java.util.Vector;
import java.util.Iterator;
import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.excalibur.meta.info.builder.TypeBuilder;
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.Type;
import org.apache.excalibur.meta.verifier.ComponentVerifier;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.ResourceDesignator;
import org.apache.excalibur.merlin.model.builder.ProfileBuilder;
/**
* Internal table that holds available component type keyed relative
* to the service it provides and provides the functional support
* for profile assembly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
final class ProfileRegistry extends AbstractLogEnabled
{
//=======================================================================
// state
//=======================================================================
/**
* Classloader used to load a service profile selector.
*/
private ProfileManager m_classloader;
/**
* The dependency map that is populated during the assembly process.
*/
private DependencyGraph m_map;
//=======================================================================
// constructor
//=======================================================================
/**
* Creation of a new service registry.
* @param loader the registry class loader
* @param map the dependency map
*/
public ProfileRegistry( ProfileManager loader, DependencyGraph map )
{
m_classloader = loader;
m_map = map;
}
//=======================================================================
// ProfileRegistry
//=======================================================================
/**
* For all of the explicity declared profiles, initiate dependency
correlation.
*/
public void assemble( Profile[] profiles ) throws Exception
{
for( int i=0; i<profiles.length; i++ )
{
Profile profile = profiles[i];
getLogger().debug("assembly target: " + profile );
ArrayList visited = new ArrayList();
assembleProfile( profile, visited, "" );
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 );
}
}
/**
* 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
*/
Profile[] getProfiles( ReferenceDescriptor service )
{
return m_classloader.getProfiles( service );
}
private void assembleProfile(
Profile profile, List visited, String pad ) throws Exception
{
getLogger().debug( pad + "assemble: " + profile );
String pad2 = pad + " ";
visited.add( profile );
String warning = null;
DependencyDescriptor[] dependencies =
profile.getType().getDependencies();
for( int i=0; i<dependencies.length; i++ )
{
DependencyDescriptor dependency = dependencies[i];
String role = dependency.getRole();
if( profile.getAssociation( role ) == null )
{
Profile[] candidates = assembleProfile( profile, dependency,
visited, pad2 );
if( candidates.length == 0 )
{
profile.setEnabled( false );
final Exception problem = new Exception( "No available
candidates." );
throw new UnresolvedProviderException( dependency,
problem );
}
Profile supplier = m_classloader.getProfile( dependency );
if( supplier == null )
{
profile.setEnabled( false );
final Exception problem = new Exception( "No suitable
candidates." );
throw new UnresolvedProviderException( dependency );
}
ResourceDesignator resource = m_classloader.getResource(
supplier, true );
profile.addProvider( role, resource );
}
}
}
private Profile[] assembleProfile(
Profile source, DependencyDescriptor dependency, List visited, String
pad )
throws Exception
{
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++ )
{
Profile profile = profiles[i];
if( !profile.equals( source ) )
{
try
{
assembleProfile( profile, visited, pad2 );
vector.add( profile );
getLogger().debug( pad + "candidate: " + profile );
}
catch( Throwable e )
{
// solution is not resolvable
}
}
}
return (Profile[]) vector.toArray( new Profile[0] );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileTable.java
Index: ProfileTable.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 java.util.List;
import java.util.LinkedList;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.merlin.model.Profile;
/**
* Internal table that holds references to the available component types
* that represent candidate providers for a single service type.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
final class ProfileTable
{
//=======================================================================
// state
//=======================================================================
/**
* Component type lists keyed by service designator.
*/
private List m_providers = new LinkedList();
/**
* Identification of the service type that this table is supporting.
*/
private ReferenceDescriptor m_designator;
public ProfileTable( ReferenceDescriptor designator )
{
m_designator = designator;
}
//=======================================================================
// ServiceTable
//=======================================================================
/**
* Add a service provider to the set of provider managed by this table.
*
* @param classname the component class name
* @return the component type
*/
public void add( Profile profile )
{
m_providers.add( profile );
}
/**
* Returns the set of providers currently registered in the table.
* @return the set of component types capable of acting as a provider for
the
* service managed by the table
*/
public Profile[] getProfiles()
{
return (Profile[]) m_providers.toArray( new Profile[0] );
}
/**
* Return the service type for the table.
* @return the service designator
*/
public ReferenceDescriptor getService()
{
return m_designator;
}
/**
* Return the number of entries in the table.
* @return the number of providers
*/
public int getSize()
{
return m_providers.size();
}
/**
* Returns true if the table service designator matches the supplied
designator.
* @param service a service type designator
* @return TRUE if the supplied service type matches the the service type
for
* this table.
*/
public boolean matches( ReferenceDescriptor service )
{
return m_designator.matches( service );
}
public String toString()
{
return "ProfileTable:"
+ System.identityHashCode( this )
+ ", "
+ m_designator;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/Selector.java
Index: Selector.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.merlin.model.Profile;
/**
* Interface implemented by a service selection implementation mechanism.
Classes
* implementing the selector interface may be activated during the selection
of
* candidate service providers in an autom assembly process. A selector my be
* declared via inclusion a implemetation class nameed
<code><service-type>Selector</code>.
* Alternatively, a component author may declare a selection class explicitly
via a
* service dependecy attribute with the attribute name of
<code>avalon.service.selector</code>.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public interface Selector
{
/**
* Returns the preferred profile form an available selection of candidate
provider profiles.
* @param profiles the set of profiles of potential service providers
* @return the preferred provider or null if no satisfactory provider can
be established
* from the supplied profiles.
*/
Profile select( Profile[] profiles );
/**
* Returns the preferred profile form an available selection of candidate
provider profiles.
* @param facilities the set of profiles of potential service providers
available in the
* container hierachy
* @param profiles the set of profiles of potential service providers
contained with the
* local container
* @return the preferred provider or null if no satisfactory provider can
be established
* from the supplied profiles.
*/
Profile select( Profile[] facilities, Profile[] profiles );
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeException.java
Index: TypeException.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.avalon.framework.CascadingException;
/**
* Exception to indicate that there was a model related error.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public final class TypeException
extends CascadingException
{
/**
* Construct a new <code>TypeException</code> instance.
*
* @param message The detail message for this exception.
*/
public TypeException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>TypeException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public TypeException( final String message, final Throwable throwable )
{
super( message, throwable );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeManager.java
Index: TypeManager.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 java.io.File;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.List;
import java.util.LinkedList;
import java.net.URLClassLoader;
import java.net.URL;
import java.net.JarURLConnection;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.excalibur.extension.Extension;
import org.apache.avalon.excalibur.extension.PackageManager;
import org.apache.avalon.excalibur.extension.PackageRepository;
import org.apache.avalon.excalibur.extension.OptionalPackage;
import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
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.merlin.container.model.IncludeDescriptor;
import org.apache.excalibur.merlin.container.model.ExtensionsDescriptor;
import org.apache.excalibur.merlin.container.model.DirsetDescriptor;
import org.apache.excalibur.merlin.container.model.ClasspathDescriptor;
import org.apache.excalibur.merlin.container.model.FilesetDescriptor;
import org.apache.excalibur.merlin.container.model.IncludeDescriptor;
import org.apache.excalibur.merlin.container.model.ExtensionsDescriptor;
import org.apache.excalibur.merlin.container.model.DirsetDescriptor;
/**
* Abstract type manager.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public abstract class TypeManager extends URLClassLoader
implements LogEnabled, Contextualizable, Initializable
{
//===================================================================
// static
//===================================================================
private static final Resources REZ =
ResourceManager.getPackageResources( TypeManager.class );
/**
* Optional context key referencing an instance of [EMAIL PROTECTED]
ExtensionsDescriptor}
* that defines the set of extension directories to use.
*/
public static final String EXTENSIONS_DESCRIPTOR_KEY = "extensions";
/**
* Optional classpath key referencing an instance of [EMAIL PROTECTED]
ClasspathDescriptor}
* that defines the set of jar files to install.
*/
public static final String CLASSPATH_DESCRIPTOR_KEY = "classpath";
//===================================================================
// state
//===================================================================
/**
* Logging channel.
*/
private Logger m_logger;
/**
* Description of the extension directories.
*/
private ExtensionsDescriptor m_extensions;
/**
* Utility class to manage extension jar files.
*/
private PackageManager m_manager;
/**
* The classpath descriptor.
*/
private ClasspathDescriptor m_classpath;
/**
* The registry of installed component types.
*/
private TypeRegistry m_types;
//===================================================================
// constructor
//===================================================================
/**
* Creation of a new type manager.
*/
public TypeManager( )
{
super( new URL[ 0 ], Thread.currentThread().getContextClassLoader() );
}
/**
* Creation of a new type manager using the supplied parent class loader.
* @param parent the parent class loader
*/
public TypeManager( ClassLoader parent )
{
super( new URL[ 0 ], parent );
}
//=======================================================================
// LogEnabled
//=======================================================================
public void enableLogging( Logger logger )
{
m_logger = logger;
}
protected Logger getLogger()
{
return m_logger;
}
//=======================================================================
// Contextualizable
//=======================================================================
/**
* Declaration of the extensions and classpath descriptors.
* @param context the context object containing the inital parameters
* @exception ContextException if the supplied does not contain a
DESCRIPTOR_KEY value
*/
public void contextualize( Context context ) throws ContextException
{
getLogger().debug( "contextualize" );
try
{
m_extensions = (ExtensionsDescriptor) context.get(
EXTENSIONS_DESCRIPTOR_KEY );
}
catch( ContextException e )
{
// ignore - optional context element
}
try
{
m_classpath = (ClasspathDescriptor) context.get(
CLASSPATH_DESCRIPTOR_KEY );
}
catch( ContextException e )
{
// ignore - optional context element
}
}
//=======================================================================
// Initializable
//=======================================================================
public void initialize() throws Exception
{
//
// initialize the type registries and install the classpath
//
getLogger().debug("initialize");
m_types = new TypeRegistry( this, getLogger().getChildLogger( "types"
) );
//
// setup the extension directories
//
if( m_extensions != null )
{
getLogger().debug( "initializing extensions libraries" );
ArrayList list = new ArrayList();
File dir = new File( System.getProperty("user.dir") );
DirsetDescriptor[] dirs = m_extensions.getDirsetDescriptors();
for( int i=0; i<dirs.length; i++ )
{
DirsetDescriptor descriptor = dirs[i];
File base = new File( dir, descriptor.getBaseDirectory() );
IncludeDescriptor[] includes =
descriptor.getIncludeDescriptors();
for( int j=0; j<includes.length; j++ )
{
File include = new File( base, includes[j].getFile() );
if( include.isDirectory() )
{
list.add( include );
}
else
{
throw new IllegalArgumentException(
"Include dir does not refer to a directory: " +
include );
}
}
}
File[] files = (File[]) list.toArray( new File[0] );
PackageRepository repository = new DefaultPackageRepository(
files );
m_manager = new PackageManager( repository );
}
//
// install the classpath
//
if( m_classpath != null )
{
getLogger().debug("installing classpath");
addClasspath( m_classpath );
}
}
/**
* Add a URL to the classpath.
* @param url the URL to add to the classpath
*/
protected void addURL( URL url )
{
super.addURL( url );
scan( url );
}
/**
* Register any components declared in the manifest.
* @param url pointing to the jar file
*/
private void scan( URL url )
{
try
{
final URL resource = new URL( "jar:" + url.toString() + "!/" );
final JarURLConnection jar =
(JarURLConnection)resource.openConnection();
final Map map = jar.getManifest().getEntries();
final Iterator iterator = map.keySet().iterator();
while( iterator.hasNext() )
{
final String name = (String)iterator.next();
final Attributes attributes = (Attributes)map.get( name );
final Iterator it = attributes.keySet().iterator();
while( it.hasNext() )
{
final Object entry = it.next();
if( entry.toString().equals( "Avalon-Block" ) )
{
if( attributes.get( entry ).equals( "true" ) )
{
final String path = name.substring( 0,
name.indexOf( ".class" ) );
try
{
m_types.addType( path );
}
catch( Throwable e )
{
final String warning = "Bypassing type: " +
path ;
getLogger().warn( warning, e );
}
}
}
else if( entry.toString().equals( "Avalon-Facility" ) )
{
if( attributes.get( entry ).equals( "true" ) )
{
final String path = name.substring( 0,
name.indexOf( ".class" ) );
try
{
m_types.addFacility( path );
}
catch( Throwable e )
{
final String warning = "Bypassing extension:
" + path ;
getLogger().warn( warning, e );
}
}
}
}
}
}
catch( IOException e )
{
final String error = "IO exception while attempt to read block
manifest.";
throw new TypeRuntimeException( error, e );
}
catch( Throwable e )
{
final String error = "Unexpected exception while inspecting
manifest on file: ";
throw new TypeRuntimeException( error + url, e );
}
}
//===================================================================
// TypeManager
//===================================================================
/**
* Add classes to the manager declared within a classpath structure.
* @param classpath the classpath descriptor
* @exception Exception if an exception occurs during class loading
*/
void addClasspath( ClasspathDescriptor classpath ) throws Exception
{
getLogger().debug( "adding classpath" );
List list = new ArrayList();
Vector stack = new Vector();
File dir = new File( System.getProperty("user.dir") );
FilesetDescriptor[] dirs = classpath.getFilesetDescriptors();
for( int i=0; i<dirs.length; i++ )
{
FilesetDescriptor descriptor = dirs[i];
File base = new File( dir, descriptor.getBaseDirectory() );
IncludeDescriptor[] includes = descriptor.getIncludeDescriptors();
for( int j=0; j<includes.length; j++ )
{
File include = new File( base, includes[j].getFile() );
list.add( include.toURL() );
stack.add( include );
}
}
URL[] urls = (URL[]) list.toArray( new URL[0] );
String[] path = urlsToStrings( urls );
final File[] extensions = getOptionalPackagesFor( path );
for( int i = 0; i < extensions.length; i++ )
{
URL url = extensions[ i ].toURL();
getLogger().info("extension: " + url );
super.addURL( url );
}
load( stack );
for( int i = 0; i < urls.length; i++ )
{
getLogger().info("adding: " + urls[i] );
scan( urls[i] );
}
getLogger().debug( "classpath addition complete" );
}
/**
* Load the supplied jar files recursively.
* For each entry in the stack, try to load it and
* if sucessfull, remove it from the stack - on completion
* of each pass over the stack the stack should be less
* than its original size - recursivly invoke load until
* the stack is empty.
*
* @param stack a <code>Vector</code> containing a sequence of jar files
* to be added to the classloader.
*/
private void load( Vector stack )
{
int size = stack.size();
getLogger().debug( "Stack size: " + stack.size() );
Hashtable errors = new Hashtable();
Enumeration enum = stack.elements();
while( enum.hasMoreElements() )
{
File file = (File)enum.nextElement();
getLogger().debug( "Loading resource: " + file );
try
{
super.addURL( file.toURL() );
stack.remove( file );
}
catch( Throwable error )
{
getLogger().warn(
"Encountered error while loading resource: " + file,
error );
errors.put( file, error );
}
}
if( stack.size() == 0 )
{
return;
}
if( stack.size() < size )
{
load( stack );
}
else
{
Enumeration keys = errors.keys();
getLogger().error( "Load error count = " + errors.size() );
while( keys.hasMoreElements() )
{
File key = (File)keys.nextElement();
getLogger().error(
"Error while loading file."
+ "\n\tfile: " + key.toString(), (Throwable)errors.get(
key ) );
}
throw new RuntimeException( "Unable to load file stack - see
trace for details." );
}
}
private String[] urlsToStrings( URL[] urls )
{
Vector vector = new Vector();
for( int i=0; i<urls.length; i++ )
{
vector.add( urls[i].toString() );
}
return (String[]) vector.toArray( new String[ vector.size() ] );
}
/**
* Resolve a [EMAIL PROTECTED] Type} from a classname.
*
* @param classname the component type
* @return the type
*/
public Type loadType( String classname ) throws Exception
{
getLogger().debug("LOOKUP: " + classname );
Type type = m_types.loadType( classname );
if( type != null )
{
return type;
}
else
{
ClassLoader parent = getParent();
if( parent instanceof TypeManager )
{
return ((TypeManager)parent).loadType( classname );
}
else
{
throw new TypeException("Type not found, classname: " +
classname );
}
}
}
/**
* Returns the set of component types know to the registry.
* @return the set of component types registered with the registry
*/
public Type[] getTypes()
{
return m_types.getTypes( );
}
/**
* 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
*/
public Type[] getTypes( ReferenceDescriptor service )
{
return m_types.getTypes( service );
}
/**
* Returns a registered component type.
* @return the component type from the registry or null if the type is
unknown
*/
public Type getType( String classname )
{
return m_types.getType( classname );
}
boolean isLocal( String classname )
{
return m_types.isLocal( classname );
}
//================================================================================
// Jar extension support
//================================================================================
/**
* Retrieve the files for the optional packages required by
* the jars in ClassPath.
*
* @param classPath the Classpath array
* @return the files that need to be added to ClassLoader
*/
protected File[] getOptionalPackagesFor( final String[] classPath )
throws Exception
{
if( m_manager == null )
{
ClassLoader parent = getParent();
if( parent != null )
{
if( parent instanceof TypeManager )
{
return ((TypeManager)parent).getOptionalPackagesFor(
classPath );
}
}
return new File[0];
}
final Manifest[] manifests = getManifests( classPath );
final Extension[] available = Extension.getAvailable( manifests );
final Extension[] required = Extension.getRequired( manifests );
final ArrayList dependencies = new ArrayList();
final ArrayList unsatisfied = new ArrayList();
m_manager.scanDependencies( required,
available,
dependencies,
unsatisfied );
if( 0 != unsatisfied.size() )
{
final int size = unsatisfied.size();
for( int i = 0; i < size; i++ )
{
final Extension extension = (Extension)unsatisfied.get( i );
final Object[] params = new Object[]
{
extension.getExtensionName(),
extension.getSpecificationVendor(),
extension.getSpecificationVersion(),
extension.getImplementationVendor(),
extension.getImplementationVendorID(),
extension.getImplementationVersion(),
extension.getImplementationURL()
};
final String message = REZ.format( "missing.extension",
params );
getLogger().warn( message );
}
final String message =
REZ.getString( "unsatisfied.extensions", new Integer( size )
);
throw new Exception( message );
}
final OptionalPackage[] packages =
(OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ]
);
return OptionalPackage.toFiles( packages );
}
private Manifest[] getManifests( final String[] classPath )
throws Exception
{
final ArrayList manifests = new ArrayList();
for( int i = 0; i < classPath.length; i++ )
{
final String element = classPath[ i ];
if( element.endsWith( ".jar" ) )
{
try
{
final URL url = new URL( "jar:" + element + "!/" );
final JarURLConnection connection =
(JarURLConnection)url.openConnection();
final Manifest manifest = connection.getManifest();
manifests.add( manifest );
}
catch( final IOException ioe )
{
final String message = REZ.getString(
"bad-classpath-entry", element );
throw new Exception( message );
}
}
}
return (Manifest[])manifests.toArray( new Manifest[ 0 ] );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeRegistry.java
Index: TypeRegistry.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 java.util.List;
import java.util.LinkedList;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Iterator;
import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.configuration.Configuration;
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.Type;
import org.apache.excalibur.meta.info.builder.TypeBuilder;
import org.apache.excalibur.meta.info.builder.FacilityBuilder;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.meta.verifier.ComponentVerifier;
import org.apache.excalibur.configuration.ConfigurationUtil;
/**
* Internal table that holds available component type keyed relative
* to the service it provides.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
class TypeRegistry extends AbstractLogEnabled
{
//=======================================================================
// state
//=======================================================================
private TypeBuilder m_typeBuilder = new TypeBuilder();
private FacilityBuilder m_facilityBuilder = new FacilityBuilder();
private ClassLoader m_classloader;
/**
* Component types keyed by classname.
*/
private Hashtable m_types = new Hashtable();
/**
* List of TypeTable instances.
*/
private List m_services = new LinkedList();
//=======================================================================
// constructor
//=======================================================================
/**
* Creation of a new service registry.
* @param registry the registry that will be supplied to new component
defintions
* @param loader the registry class loader
* @param profiles the configuration fragment containing explicit
component profiles
*/
public TypeRegistry( ClassLoader loader, Logger logger )
{
m_classloader = loader;
super.enableLogging( logger );
m_typeBuilder.enableLogging( logger.getChildLogger("component") );
m_facilityBuilder.enableLogging( logger.getChildLogger("facility") );
getLogger().info("type registry established");
}
//=======================================================================
// implemetation (TypeManager handler)
//=======================================================================
/**
* Test is a type is know.
*/
public boolean isLocal( String classname )
{
Type type = getType( classname );
if( type != null )
return true;
return false;
}
/**
* Resolve a [EMAIL PROTECTED] Type} from a classname.
*
* @param classname the component type
* @return the component type or null if unknown
*/
public Type loadType( String classname ) throws Exception
{
return getType( classname );
}
/**
* Register a potential supplier component type. The implementation will
* create a component type instance for the entry if not already known and
* return the existing or new instance to the invoking client.
*
* @param classname the component class name
* @return the component type
*/
public Type addType( String path ) throws Exception
{
final String classname = path.replace('/','.');
getLogger().info("type: " + classname );
Type type = getType( classname );
if( type == null )
{
type = m_typeBuilder.build( classname, m_classloader );
verify( type );
register( type );
}
return type;
}
/**
* Register a potential supplier component type. The implementation will
* create a component type instance for the entry if not already known and
* return the existing or new instance to the invoking client.
*
* @param classname the component class name
* @return the component type
*/
public Type addFacility( String path ) throws Exception
{
final String classname = path.replace('/','.');
getLogger().info("facility: " + classname );
Type type = getType( classname );
if( type == null )
{
type = m_facilityBuilder.build( classname, m_classloader );
verify( type );
register( type );
}
return type;
}
private void verify( Type type ) throws Exception
{
String name = type.getInfo().getName();
Class clazz = getComponentClass( type );
Class[] classes = getServiceClasses( type );
ComponentVerifier verifier = new ComponentVerifier();
verifier.enableLogging( getLogger().getChildLogger( "verifier" ));
verifier.verifyComponent( name, clazz, classes );
}
//=======================================================================
// TypeRegistry (private and protected)
//=======================================================================
protected Class[] getServiceClasses( Type type )
{
Vector vector = new Vector();
ServiceDescriptor[] services = type.getServices();
for( int i=0; i<services.length; i++ )
{
vector.add( getServiceClass( services[i] ) );
}
return (Class[]) vector.toArray( new Class[0] );
}
/**
* Returns the component type implementation class.
* @param type the component type descriptor
* @return the class implementing the component type
*/
protected Class getComponentClass( Type type ) throws TypeException
{
if( null == type )
throw new NullPointerException("Illegal null component type
argument.");
final String classname = type.getInfo().getImplementationKey();
try
{
return m_classloader.loadClass( classname );
}
catch( Throwable e )
{
final String error = "Could not load implementation class for
component type: "
+ classname;
throw new TypeException( error, e );
}
}
/**
* Returns the service type implementation class.
* @param service the service type descriptor
* @return the class implementing the service type
*/
protected Class getServiceClass( ServiceDescriptor service ) throws
TypeRuntimeException
{
final String classname = service.getService().getClassname();
try
{
return m_classloader.loadClass( classname );
}
catch( Throwable e )
{
final String error = "Could not load implementation class for
service type: "
+ classname;
throw new TypeRuntimeException( error, e );
}
}
/**
* Returns the set of component types know to the registry.
* @return the set of component types registered with the registry
*/
public Type[] getTypes()
{
return (Type[]) m_types.values().toArray( new Type[0] );
}
/**
* 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
*/
public Type[] getTypes( ReferenceDescriptor service )
{
return getTable( service ).getTypes();
}
/**
* Returns a registered component type.
* @return the component type from the registry or null if the type is
unknown
*/
public Type getType( String classname )
{
return (Type) m_types.get( classname );
}
/**
* Register the type resulting in the cross-referencing of the type with
the set of
* service tables that the type is is capable of supporting.
*/
protected void register( Type type )
{
String key = type.getInfo().getImplementationKey();
m_types.put( key, type );
getLogger().debug( "Type: '" + key + "' registered.");
ServiceDescriptor[] services = type.getServices();
for( int i=0; i<services.length; i++ )
{
register( services[i].getService(), type );
}
}
/**
* Register a type under a service cross-reference.
*/
private void register( ReferenceDescriptor service, Type type )
{
TypeTable table = getTable( service );
table.add( type );
}
/**
* Return a table holding table capable of supply the supplied service.
*/
private TypeTable getTable( ReferenceDescriptor service )
{
TypeTable table = null;
Iterator iterator = m_services.iterator();
while( iterator.hasNext() )
{
table = (TypeTable) iterator.next();
if( table.matches( service ) )
return table;
}
// otherwise create a new table
table = new TypeTable( service, getLogger().getChildLogger("table")
);
m_services.add( table );
return table;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeRuntimeException.java
Index: TypeRuntimeException.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.avalon.framework.CascadingRuntimeException;
/**
* Exception to indicate that there was a model related runtime error.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public final class TypeRuntimeException
extends CascadingRuntimeException
{
/**
* Construct a new <code>TypeRuntimeException</code> instance.
*
* @param message The detail message for this exception.
*/
public TypeRuntimeException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>TypeRuntimeException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public TypeRuntimeException( final String message, final Throwable
throwable )
{
super( message, throwable );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeTable.java
Index: TypeTable.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 java.util.List;
import java.util.LinkedList;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.info.Type;
/**
* Internal table that holds references to the available component types
* that represent candidate providers for a single service type.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
final class TypeTable extends AbstractLogEnabled
{
//=======================================================================
// state
//=======================================================================
/**
* Component type lists keyed by service designator.
*/
private List m_providers = new LinkedList();
/**
* Identification of the service type that this table is supporting.
*/
private ReferenceDescriptor m_designator;
public TypeTable( ReferenceDescriptor designator, Logger logger )
{
m_designator = designator;
super.enableLogging( logger );
}
//=======================================================================
// ServiceTable
//=======================================================================
/**
* Add a service provider to the set of provider managed by this table.
*
* @param classname the component class name
* @return the component type
*/
public void add( Type type )
{
m_providers.add( type );
}
/**
* Returns the set of providers currently registered in the table.
* @return the set of component types capable of acting as a provider for
the
* service managed by the table
*/
public Type[] getTypes()
{
return (Type[]) m_providers.toArray( new Type[0] );
}
/**
* Return the service type for the table.
* @return the service designator
*/
public ReferenceDescriptor getService()
{
return m_designator;
}
/**
* Return the number of entries in the table.
* @return the number of providers
*/
public int getSize()
{
return m_providers.size();
}
/**
* Returns true if the table service designator matches the supplied
designator.
* @param service a service type designator
* @return TRUE if the supplied service type matches the the service type
for
* this table.
*/
public boolean matches( ReferenceDescriptor service )
{
return m_designator.matches( service );
}
public String toString()
{
return "TypeTable:"
+ System.identityHashCode( this )
+ ", "
+ m_designator;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/UnresolvedProviderException.java
Index: UnresolvedProviderException.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.DependencyDescriptor;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate that a service provider could not be found.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:29 $
*/
public final class UnresolvedProviderException
extends CascadingException
{
private DependencyDescriptor m_dependency;
/**
* Construct a new <code>UnresolvedProviderException</code> instance.
*
* @param dependency the unresolved dependency
*/
public UnresolvedProviderException( DependencyDescriptor dependency )
{
this( dependency, null );
}
/**
* Construct a new <code>UnresolvedProviderException</code> instance.
*
* @param dependency the unresolved dependency
* @param cause the causal exception
*/
public UnresolvedProviderException( DependencyDescriptor dependency,
Throwable cause )
{
super( getStandardMessage( dependency ), cause );
m_dependency = dependency;
}
/**
* Return the dependency description.
* @return the unresolved dependency.
*/
public DependencyDescriptor getDependency()
{
return m_dependency;
}
private static String getStandardMessage( DependencyDescriptor dependency
)
{
return "Unable to resolve a provider for the dependency '"
+ dependency.getService() + "' for the role: " +
dependency.getRole();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/package.html
Index: package.html
===================================================================
<body>
<p>
The <code>assembly</code> package contains the main type, profile, and
assembly manegment.
</p>
</body>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/doc-files/DependencyGraph.gif
<<Binary file>>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/AbstractLifecycleExtensionManager.java~
Index: AbstractLifecycleExtensionManager.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.extension;
import java.lang.reflect.Method;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
/**
* <code>AbstractLifecycleExtensionManager</code> class.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Marcus Crafter</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/07/29 06:14:30 $
*/
public abstract class AbstractLifecycleExtensionManager extends
AbstractLogEnabled
{
// Lifecycle method constants, these are passed to executeExtensions()
protected final Method ACCESS;
protected final Method RELEASE;
protected final Method CREATION;
protected final Method DESTRUCTION;
/**
* Constructor, creates a lifecycle manager, and caches all lifecycle
* <code>Method</code> objects for later use.
*/
public AbstractLifecycleExtensionManager()
{
final Class[] params = { Object.class, Context.class };
final Class clazz = LifecycleExtension.class;
try
{
ACCESS = clazz.getDeclaredMethod( "access", params );
RELEASE = clazz.getDeclaredMethod( "release", params );
CREATION = clazz.getDeclaredMethod( "create", params );
DESTRUCTION = clazz.getDeclaredMethod( "destroy", params );
}
catch ( NoSuchMethodException e )
{
throw new IllegalStateException(
"Bad environment, cannot reference LifecycleExtension class:
" +
e.getMessage()
);
}
}
/**
* <code>executeExtensions</code> method, executes a given array of
lifecycle interfaces
* on a given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @param type a <code>Method</code> instance, referencing which phase the
* extensions array adheres to
* @exception Exception if an error occurs
*/
protected void executeExtensions(
Object[] extensions, Object component, Context context, Method type
)
throws Exception
{
final Object[] params = { component, context };
for ( int i = 0; i < extensions.length; ++i )
{
if ( getLogger().isDebugEnabled() )
{
getLogger().debug(
"Executing extension " + extensions[i] +
" on component " + component +
" (" + type.getName() + " phase)"
);
}
type.invoke( ( LifecycleExtension ) extensions[i], params );
}
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/DefaultComponentManager.java
Index: DefaultComponentManager.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.
*
* Original contribution by OSM SARL, http://www.osm.net
*/
package org.apache.excalibur.merlin.assembly.resource;
import java.util.Map;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
/**
* Internal helper class the implements the <code>ComponentLocator</code>
interface and
* is supplied to dynamically created componets during lifecycle pipeline
processing.
* @author Stephen McConnell <[EMAIL PROTECTED]>
*/
class DefaultComponentManager
extends DefaultManager
implements ComponentManager
{
public DefaultComponentManager( Map providers )
{
super( providers );
}
public boolean hasComponent( String role )
{
return super.has( role );
}
public Component lookup( String role ) throws ComponentException
{
Object object = null;
try
{
object = super.resolve( role );
if( object instanceof Component )
{
return (Component)object;
}
throw new ComponentException( role, "Service provider returned a
non-Component." );
}
catch( ResourceException e )
{
final String error = "Provider related error during service
resolution.";
throw new ComponentException( role, error, e );
}
}
/**
* Release a pooled object.
*
* @param component a pooled object
*/
public void release( Component component )
{
super.disgard( component );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/DefaultManager.java
Index: DefaultManager.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.
*
* Original contribution by OSM SARL, http://www.osm.net
*/
package org.apache.excalibur.merlin.assembly.resource;
import java.util.Map;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.excalibur.merlin.model.ResourceDesignator;
/**
* Internal helper class the handles the functional requirements of
* both ComponetManager and ComponentLocator.
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
class DefaultManager
{
/**
* A map of resources keyed by lookup role.
*/
private Map m_providers;
/**
* Creation of a new manager.
* @param providers the resource map
*/
public DefaultManager( Map providers )
{
m_providers = providers;
}
/**
* Return TRUE is the manager has a resoruce for the role.
* @param role the role name to look for in the resource map
* @return TRUE is a resource exists for the role
*/
public boolean has( String role )
{
return ( m_providers.get( role ) != null );
}
/**
* Returns the service object.
* @return the service instance
*/
public Object resolve( String role ) throws ResourceException
{
ResourceDesignator resource = (ResourceDesignator) m_providers.get(
role );
if( resource == null )
{
throw new ResourceException(
"Could not locate a provider for the role: " + role );
}
else
{
try
{
return resource.getInstance();
}
catch( Throwable e )
{
final String error = "Unexpected exception while resolving
the service from "
+ resource.getPath() + " for the role: " + role;
throw new ResourceException( error, e );
}
}
}
/**
* Release a pooled object.
* @param object a pooled object
*/
public void disgard( Object object )
{
//
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/DefaultServiceManager.java
Index: DefaultServiceManager.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.
*
* Original contribution by OSM SARL, http://www.osm.net
*/
package org.apache.excalibur.merlin.assembly.resource;
import java.util.Map;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
/**
* Internal helper class the implements the <code>ServiceManager</code>
interface and
* is supplied to dynamically created componets during lifecyle pipeline
processing.
* @author Stephen McConnell <[EMAIL PROTECTED]>
*/
class DefaultServiceManager
extends DefaultManager
implements ServiceManager
{
/**
* Construct a new ServiceManager.
*/
public DefaultServiceManager( Map providers )
{
super( providers );
}
/**
* Returns true if a provider exists for the supplied role.
* @param role the service identifier
* @return boolean TRUE if the service is available else FALSE
*/
public boolean hasService( String role )
{
return super.has( role );
}
/**
* Retrieve Object by role from ComponentLocator.
* @param role the role
* @return the Object
* @throws ServiceException if an error occurs
*/
public Object lookup( String role ) throws ServiceException
{
try
{
return super.resolve( role );
}
catch( ResourceException e )
{
final String error = "Service resolution failure for role: " +
role;
throw new ServiceException( error, e );
}
}
/**
* Release a pooled object.
* @param object a pooled object
*/
public void release( Object object )
{
super.disgard( object );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ExtensionManager.java~
Index: ExtensionManager.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.extension;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.context.Context;
/**
* <code>ExtensionManager</code> interface. This interface shall be
implemented by
* classes providing support for lifecycle extension.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Marcus Crafter</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/07/29 06:14:30 $
*/
public interface ExtensionManager
{
/**
* The <code>executeAccess</code> method, executes all access level
* extensions on the given component.
*
* @param component a component instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
void executeAccess( Object component, Context context )
throws Exception;
/**
* The <code>executeRelease</code> method, executes all release level
* extensions on the given component.
*
* @param component a component instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
void executeRelease( Object component, Context context )
throws Exception;
/**
* The <code>executeCreation</code> method, executes all creation level
* extensions on the given component.
*
* @param component a component instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
void executeCreation( Object component, Context context )
throws Exception;
/**
* The <code>executeDestruction</code> method, executes all destruction
* level extensions on the given component.
*
* @param component a component instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
void executeDestruction( Object component, Context context )
throws Exception;
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/LifecycleException.java
Index: LifecycleException.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.resource;
import org.apache.avalon.framework.CascadingException;
import org.apache.excalibur.meta.verifier.VerifyException;
/**
* Exception to indicate error processing a component through its lifecycle.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:30 $
*/
public final class LifecycleException
extends CascadingException
{
/**
* Construct a new <code>VerifyException</code> instance.
*
* @param message The detail message for this exception.
*/
public LifecycleException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>VerifyException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public LifecycleException( final String message, final Throwable
throwable )
{
super( message, throwable );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/LifecycleExtensionManager.java~
Index: LifecycleExtensionManager.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.extension;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.context.Context;
/**
* <code>LifecycleExtensionManager</code> class. This class manages a list
* of extensions objects that are executed on components during the various
* stages of their lifecycles.
*
* <p>
* It provides methods for adding extension objects to the system,
* and a method for executing them on a particular component object. The
* current context is also passed in to the extension objects to facilitate
* the communication of any global values.
* </p>
*
* <p>
* Extensions are stored internally in a list. This guarentees that the
* order in which they are executed matches the order in which they are
* inserted.
* </p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Marcus Crafter</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/07/29 06:14:30 $
*/
public class LifecycleExtensionManager
extends AbstractLifecycleExtensionManager
{
// extensions objects
private final CachedArrayList m_extensions = new CachedArrayList();
/**
* <code>executeAccessExtensions</code> method, executes all access level
* extensions on the given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void executeAccessExtensions( Object component, Context context )
throws Exception
{
executeExtensions( m_extensions.toArray(), component, context, ACCESS
);
}
/**
* <code>executeReleaseExtensions</code> method, executes all release
level
* extensions on the given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void executeReleaseExtensions( Object component, Context context )
throws Exception
{
executeExtensions( m_extensions.toArray(), component, context,
RELEASE );
}
/**
* <code>executeCreationExtensions</code> method, executes all creation
level
* extensions on the given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void executeCreationExtensions( Object component, Context context )
throws Exception
{
executeExtensions( m_extensions.toArray(), component, context,
CREATION );
}
/**
* <code>executeDestructionExtensions</code> method, executes all
destruction
* level extensions on the given component.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
public void executeDestructionExtensions( Object component, Context
context )
throws Exception
{
executeExtensions( m_extensions.toArray(), component, context,
DESTRUCTION );
}
// The following methods define operations that modify the internal list
// of extensions. I've refrained from returning the List directly, via a
// getExtensions() method for the following reasons:
//
// 1. Returning List breaks encapsulation, implicitly exposing all of
List's
// current and future operations to the client
// 2. List operates with type Object, not LifecycleExtension which means
we need
// more error handling code if we make it possible for the user to add
instances
// of any type to the extension lists.
// 3. Wrapping add/remove methods allow us to add optimizations to
improve performance
// (eg. to convert the List to an array upon each add/remove, and not
upon each
// execute operation)
// 4. The book 'Refactoring' says we shouldn't do it :-)
//
// I'm open to suggestions though if there's any better ideas ?
/**
* Adds an extension to the manager
*
* @param extension a <code>LifecycleExtension</code> instance
*/
public void addExtension( LifecycleExtension extension )
{
m_extensions.add( extension );
}
/**
* Inserts an extension at a given index in the manager
*
* @param position an <code>int</code> index value
* @param extension a <code>LifecycleExtension</code> instance
*/
public void insertExtension( int position, LifecycleExtension extension )
{
m_extensions.insert( position, extension );
}
/**
* Removes a particular extension from the manager
*
* @param position an <code>int</code> index value
* @return a <code>LifecycleExtension</code> instance
*/
public LifecycleExtension removeExtension( int position )
{
return (LifecycleExtension) m_extensions.remove( position );
}
/**
* Obtain an iterator.
*
* @return an <code>Iterator</code> instance
*/
public Iterator extensionsIterator()
{
return m_extensions.iterator();
}
/**
* Find out the total number of extensions registered with this manager
*
* @return an <code>int</code> value
*/
public int extensionsCount()
{
return m_extensions.size();
}
/**
* Obtain the particular extension at the given index
*
* @param index an <code>int</code> index value
* @return a <code>LifecycleExtension</code> instance
*/
public LifecycleExtension getExtension( int index )
{
return (LifecycleExtension) m_extensions.get( index );
}
/**
* Check whether the given extension is already registered
* with this manager
*
* @param extension a <code>LifecycleExtension</code> instance
* @return index of given extension, -1 if non-existing.
*/
public int indexOfExtension( LifecycleExtension extension )
{
return m_extensions.indexOf( extension );
}
/**
* Clears all extensions registered with this manager
*/
public void clearExtensions()
{
m_extensions.clear();
}
/**
* <code>CachedArrayList</code> class.
*
* <p>
* This class wraps a synchronized ArrayList to provide an optimized
* <code>toArray()</code> method that returns an internally cached array,
rather
* than a new array generated per <code>toArray()</code> invocation.
* </p>
*
* <p>
* Use of the class by the Manager results in <code>toArray()</code>
being invoked
* far more often than any other method. Caching the value
<code>toArray</code>
* normally returns is intended to be a performance optimization.
* </p>
*
* <p>
* The cached array value is updated upon each write operation to the
List.
* </p>
*
* <p>
* REVISIT(MC): investigate using FastArrayList from collections ?
* </p>
*/
private final class CachedArrayList
{
// Empty array constant
private final Object[] EMPTY_ARRAY = new Object[0];
// Actual list for storing elements
private final List m_proxy = Collections.synchronizedList( new
ArrayList() );
// Proxy cache, saves unnecessary conversions from List to Array
private Object[] m_cache = EMPTY_ARRAY;
/**
* Add an object to the list
*
* @param object an <code>Object</code> value
*/
public void add( final Object object )
{
m_proxy.add( object );
m_cache = m_proxy.toArray();
}
/**
* Insert an object into a particular position in the list
*
* @param position an <code>int</code> value
* @param object an <code>Object</code> value
*/
public void insert( final int position, final Object object )
{
m_proxy.add( position, object );
m_cache = m_proxy.toArray();
}
/**
* Remove an object from the list
*
* @param position an <code>int</code> value
* @return a <code>Object</code> value
*/
public Object remove( final int position )
{
final Object object = m_proxy.remove( position );
m_cache = m_proxy.toArray();
return object;
}
/**
* Obtain an iterator
*
* @return an <code>Iterator</code> value
*/
public Iterator iterator()
{
return m_proxy.iterator();
}
/**
* Obtain the size of the list
*
* @return an <code>int</code> value
*/
public int size()
{
return m_proxy.size();
}
/**
* Access an object that is in the list
*
* @param index an <code>int</code> value
* @return a <code>Object</code> value
*/
public Object get( final int index )
{
return m_proxy.get( index );
}
/**
* Find out the index of an object in the list
*
* @param object an <code>Object</code> value
* @return an <code>int</code> value
*/
public int indexOf( final Object object )
{
return m_proxy.indexOf( object );
}
/**
* Clear the list
*/
public void clear()
{
m_proxy.clear();
m_cache = EMPTY_ARRAY;
}
/**
* Obtain the list as an array. Subsequents calls to this method
* will return the same array object, until a write operation is
* performed on the list.
*
* @return an <code>Object[]</code> value
*/
public Object[] toArray()
{
return m_cache;
}
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/LifecycleHelper.java
Index: LifecycleHelper.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.resource;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
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.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.parameters.Parameterizable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.excalibur.merlin.model.Profile;
/**
* This is a class to help an Application manage the lifecycle of a component.
* The implementation provides support for the processing of a component
through
* each lifecycle stage, and manage errors in a consistent way.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
*/
public class LifecycleHelper
extends AbstractLogEnabled
{
private static final Resources REZ =
ResourceManager.getPackageResources( LifecycleHelper.class );
//Constants to designate stages
private static final int STAGE_CREATE = 0;
private static final int STAGE_LOGGER = 1;
private static final int STAGE_CONTEXT = 2;
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;
/**
* Method to run a component through it's startup phase.
* Errors that occur during startup will be logged appropriately and
* cause exceptions with useful messages to be raised.
*
* @param name the name of the component
* @param profile representing the instance criteria
* @param provider the resource provider
* @throws LifecycleException if an error occurs when the component passes
* through a specific lifecycle stage
*/
public Object startup( final String name,
final Profile profile,
final ResourceProvider provider )
throws LifecycleException
{
getLogger().info("startup initiated for '" + name + "'." );
int stage = 0;
try
{
//Creation stage
stage = STAGE_CREATE;
notice( name, stage );
final Object object = provider.createObject( profile );
//LogEnabled stage
stage = STAGE_LOGGER;
if( object instanceof LogEnabled )
{
notice( name, stage );
final Logger logger = provider.createLogger( profile );
ContainerUtil.enableLogging( object, logger );
}
//Contextualize stage
stage = STAGE_CONTEXT;
if( object instanceof Contextualizable )
{
notice( name, stage );
final Context context = provider.createContext( profile );
ContainerUtil.contextualize( object, context );
}
//Composition stage
stage = STAGE_COMPOSE;
if( object instanceof Serviceable )
{
notice( name, stage );
final ServiceManager manager =
provider.createServiceManager( profile );
ContainerUtil.service( object, manager );
}
else if( object instanceof Composable )
{
notice( name, stage );
final ComponentManager componentManager =
provider.createComponentManager( profile );
ContainerUtil.compose( object, componentManager );
}
//Configuring stage
stage = STAGE_CONFIG;
if( object instanceof Configurable )
{
notice( name, stage );
final Configuration configuration =
provider.createConfiguration( profile );
ContainerUtil.configure( object, configuration );
}
//Parameterizing stage
stage = STAGE_PARAMETER;
if( object instanceof Parameterizable )
{
notice( name, stage );
final Parameters parameters =
provider.createParameters( profile );
ContainerUtil.parameterize( object, parameters );
}
//Initialize stage
stage = STAGE_INIT;
if( object instanceof Initializable )
{
notice( name, stage );
ContainerUtil.initialize( object );
}
//Start stage
stage = STAGE_START;
if( object instanceof Startable )
{
notice( name, stage );
ContainerUtil.start( object );
}
return object;
}
catch( final Throwable t )
{
fail( name, stage, t );
//fail() throws an exception so next
//line will never be executed
return null;
}
}
/**
* Method to run a component through it's shutdown phase.
* Errors that occur during shutdown will be logged appropraitely.
*
* @param name the name of the component
* @param object the component to shutdown
*/
public void shutdown( final String name,
final Object object )
throws LifecycleException
{
getLogger().info("shutdown initiated for '" + name + "'." );
//Stage at which failure occured
int stage = 0;
//Failure exception
Throwable failure = null;
//Stoppable stage
if( object instanceof Startable )
{
notice( name, STAGE_STOP );
try
{
ContainerUtil.stop( object );
}
catch( final Throwable t )
{
safeFail( name, STAGE_STOP, t );
failure = t;
stage = STAGE_STOP;
}
}
//Disposable stage
if( object instanceof Disposable )
{
notice( name, STAGE_DISPOSE );
try
{
ContainerUtil.dispose( object );
}
catch( final Throwable t )
{
safeFail( name, STAGE_DISPOSE, t );
failure = t;
stage = STAGE_DISPOSE;
}
}
notice( name, STAGE_DESTROY );
if( null != failure )
{
fail( name, stage, failure );
}
}
/**
* Utility method to report that a lifecycle stage is about to be
processed.
*
* @param name the name of component that is the subject of the notice
* @param stage the lifecycle processing stage
*/
private void notice( final String name, final int stage )
{
if( getLogger().isDebugEnabled() )
{
final String message =
REZ.getString( "lifecycle.stage.notice",
name,
new Integer( stage ) );
getLogger().debug( message );
}
}
/**
* Utility method to report that there was an error processing
* specified lifecycle stage.
*
* @param name the name of component that caused failure
* @param stage the lefecycle stage
* @param t the exception thrown
*/
private void safeFail( final String name,
final int stage,
final Throwable t )
{
//final String reason = t.getMessage();
final String reason = t.toString();
final String message =
REZ.getString( "lifecycle.fail.error",
name,
new Integer( stage ),
reason );
getLogger().error( message );
}
/**
* Utility method to report that there was an error processing
* specified lifecycle stage. It will also re-throw an exception
* with a better error message.
*
* @param name the name of block that caused failure
* @param stage the stage
* @param t the exception thrown
* @throws LifecycleException containing error
*/
private void fail( final String name,
final int stage,
final Throwable t )
throws LifecycleException
{
//final String reason = t.getMessage();
final String reason = t.toString();
final String message =
REZ.getString( "lifecycle.fail.error",
name,
new Integer( stage ), reason );
getLogger().error( message );
throw new LifecycleException( message, t );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/PhaseManager.java
Index: PhaseManager.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.resource;
import org.apache.avalon.framework.context.Context;
/**
* <code>PhaseExtension</code> interface. This interface defines the methods
that
* a container can invoke on a phase handler.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Marcus Crafter</a>
* @version CVS $Revision: 1.1 $ $Date: 2002/07/29 06:14:30 $
*/
public interface PhaseManager
{
/**
* Create, called when the given component is being
* instantiated.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
void create( Object component, Context context )
throws Exception;
/**
* Destroy, called when the given component is being
* decomissioned.
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
void destroy( Object component, Context context )
throws Exception;
/**
* Access, called when the given component is being
* accessed (ie. via lookup() or select()).
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
void access( Object component, Context context )
throws Exception;
/**
* Release, called when the given component is being
* released (ie. by a CM or CS).
*
* @param component a <code>Component</code> instance
* @param context a <code>Context</code> instance
* @exception Exception if an error occurs
*/
void release( Object component, Context context )
throws Exception;
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ProfileDesignator.java
Index: ProfileDesignator.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.resource;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.merlin.assembly.resource.LifecycleHelper;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.ResourceDesignator;
import org.apache.excalibur.meta.info.ServiceDescriptor;
/**
* Opaque type that maps a path to a profile.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:30 $
*/
public class ProfileDesignator implements ResourceDesignator
{
public static final String HEADER = "service:";
/**
* The path of the profile designator.
*/
private final String m_path;
/**
* The profile that disignator refers to.
*/
private final Profile m_profile;
/**
* A singleton reference to the instantiated service.
*/
private Object m_service;
/**
* The lifecycle helper.
*/
private final LifecycleHelper m_helper;
/**
* The resource provider.
*/
private final ResourceProvider m_provider;
/**
* The current state
*/
private int m_state = NOT_STARTED;
/**
* Create a profile designator instance.
*
* @param path the path of the profile designator
* @param profile the profile
* @param helper the lifecycle helper
* @param provider the resource provider
*/
public ProfileDesignator( final String path,
final Profile profile,
final LifecycleHelper helper,
final ResourceProvider provider )
{
if( null == path )
{
throw new NullPointerException( "path" );
}
if( null == profile )
{
throw new NullPointerException( "profile" );
}
if( null == helper )
{
throw new NullPointerException( "helper" );
}
if( null == provider )
{
throw new NullPointerException( "provider" );
}
m_path = path;
m_profile = profile;
m_helper = helper;
m_provider = provider;
}
/**
* Returns the path of the resource.
*
* @return the simbolic path of the resource
*/
public String getPath()
{
return HEADER + m_path;
}
/**
* Returns the service descriptor.
*
* @return the service descriptor
*/
public ServiceDescriptor[] getServices()
{
return m_profile.getType().getServices();
}
/**
* Get the resource instance.
*
* @return the service instance.
* @exception LifecycleException if an error occurs while establishing
the object
*/
public Object getInstance() throws LifecycleException
{
if( m_service == null )
m_service = m_helper.startup( m_path, m_profile, m_provider );
setState( STARTED );
return m_service;
}
/**
* Release the service instance.
*
* @exception LifecycleException if an error occurs while releasing the
object
*/
public void release() throws LifecycleException
{
if( m_service != null )
m_helper.shutdown( m_path, m_service );
setState( STOPPED );
}
/**
* Returns the active state of the resoruce.
* @return one of the values NOT_STARTED, STARTED, or STOPPED
*/
public int getState()
{
return m_state;
}
private synchronized void setState( int state )
{
m_state = state;
}
/**
* Return the profile.
*
* @return the profile
*/
public Profile getProfile()
{
return m_profile;
}
public String toString()
{
return "ProfileResource: " + getPath();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ResourceException.java
Index: ResourceException.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.resource;
import java.util.Enumeration;
import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.avalon.framework.CascadingException;
/**
* Exception to indicate that there was an error relating to resource
management.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:30 $
*/
public final class ResourceException
extends CascadingException
{
/**
* Construct a new <code>ResourceException</code> instance.
*
* @param message The detail message for this exception.
*/
public ResourceException( final String message )
{
this( message, null );
}
/**
* Construct a new <code>ResourceException</code> instance.
*
* @param message The detail message for this exception.
* @param throwable the root cause of the exception
*/
public ResourceException( final String message, final Throwable throwable
)
{
super( message, throwable );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ResourceProvider.java
Index: ResourceProvider.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.resource;
import java.io.InputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.JarURLConnection;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.List;
import java.util.LinkedList;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.Iterator;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.security.Policy;
import java.io.FileInputStream;
import java.util.HashMap;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.AvalonFormatter;
import org.apache.avalon.framework.logger.LogKitLogger;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.excalibur.configuration.ConfigurationUtil;
import org.apache.excalibur.meta.verifier.VerifyException;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.merlin.assembly.ProfileManager;
import org.apache.excalibur.merlin.assembly.DefaultLoggerManager;
import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.Association;
import org.apache.excalibur.merlin.model.ResourceDesignator;
import org.apache.excalibur.merlin.model.Import;
/**
* Internal class that handles the establishment of component instances based
on a supplied
* type profile.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:30 $
*/
public class ResourceProvider extends AbstractLogEnabled
{
//=======================================================================
// state
//=======================================================================
private final static Resources REZ =
ResourceManager.getPackageResources( ResourceProvider.class );
//=======================================================================
// state
//=======================================================================
/**
* The log manager.
*/
private DefaultLoggerManager m_logging;
/**
* The classloader to use when servicing object creation requests.
*/
private ProfileManager m_classloader;
/**
* A hashtable of service implemenentation object references keyed by
profile.
*/
private final Hashtable m_singletons = new Hashtable();
private DefaultContext m_dictionary;
//=======================================================================
// constructor
//=======================================================================
/**
* Creation of a new resource provider.
*
* @param logger the parent logger to use when creating loggers for
services.
* @param loader the class loader
* @param dictionary the parent dictionary
*/
public ResourceProvider( ProfileManager loader, Context dictionary,
DefaultLoggerManager logging )
{
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
//#########################
m_dictionary = new DefaultContext( dictionary );
m_dictionary.put( "classloader", loader );
m_dictionary.put( "home", new File( System.getProperty("user.dir") )
);
m_dictionary.makeReadOnly();
}
//=======================================================================
// ResourceProvider
//=======================================================================
/**
* Create an object specified by profile.
*
* @param profile the profile
* @return the new object
* @throws Exception if unable to resolve resource
*/
public Object createObject( Profile profile )
throws Exception
{
Object object = getSingletonInstance( profile );
if( object == null )
{
Class clazz = null;
String classname = null;
try
{
classname =
profile.getType().getInfo().getImplementationKey();
clazz = m_classloader.loadClass( classname );
}
catch( Throwable e )
{
final String error =
"Unexpected exception while attempting to load class '"
+ classname + "' for the profile: " + profile;
throw new ResourceException( error, e );
}
try
{
object = clazz.newInstance();
putSingletonInstance( profile, object );
}
catch( Throwable e )
{
final String error =
"Unexpected exception while attempting to instantiate an
instance from profile: "
+ profile;
throw new ResourceException( error, e );
}
}
return object;
}
/**
* Create a new Logger for component.
*
* @param profile the profile
* @return a new Logger for service
* @throws Exception if unable to create the logger
*/
public Logger createLogger( Profile profile )
throws Exception
{
final String path = m_classloader.getPath();
final String root = path.replace('/','.').substring(1) + "." +
profile.getName();
m_logging.addCategories( root, profile.getCategories() );
return m_logging.getLoggerForCategory( root );
}
/**
* Create a new Context for component.
*
* @param profile the profile
* @return a new Context for service
* @throws Exception if unable to create context
*/
public Context createContext( Profile profile )
throws Exception
{
DefaultContext parent = new DefaultContext();
Import[] imports = profile.getContext().getImports();
for( int i=0; i<imports.length; i++ )
{
Import directive = imports[i];
final String name = directive.getImportName();
final String key = directive.getKey();
Object object = null;
try
{
object = m_dictionary.get( name );
parent.put( key, object );
getLogger().debug(
"adding context entry: " + key
+ ", from: " + name
+ ", and object: " + object );
}
catch( Throwable e )
{
final String error =
"Could not resolve a value for the import directive in
profile '"
+ profile.getName()
+ "' with the name '" + name
+ "' for the key '" + key
+ "'.";
throw new ResourceException( error );
}
}
return profile.getContext().getContext( m_classloader, parent );
}
/**
* Create a new ComponentManager for component.
*
* @param profile the profile
* @return a new ComponentManager for component
* @throws Exception if unable to create the component manager
*/
public ComponentManager createComponentManager( Profile profile )
throws Exception
{
final Map services = getServices( profile );
final DefaultComponentManager componentManager = new
DefaultComponentManager( services );
return componentManager;
}
/**
* Create a new ServiceManager for component.
*
* @param entry the entry
* @return a new ServiceManager for component
* @throws Exception if unable to create resource
*/
public ServiceManager createServiceManager( Profile profile )
throws Exception
{
final Map services = getServices( profile );
final DefaultServiceManager serviceManager = new
DefaultServiceManager( services );
return serviceManager;
}
/**
* Create a new Configuration object for component.
*
* @param entry the entry
* @return a new Configuration object for component
* @throws Exception if unable to create resource
*/
public Configuration createConfiguration( Profile profile )
throws Exception
{
Configuration config = profile.getConfiguration();
if( config == null )
config = new DefaultConfiguration("configuration", null );
return config;
}
/**
* Create a new Parameters object for component.
*
* @param entry the entry
* @return a new Parameters object for component
* @throws Exception if unable to create resource
*/
public Parameters createParameters( Profile profile )
throws Exception
{
final Parameters parameters = profile.getParameters();
if( null == parameters )
{
final String message =
REZ.getString( "resource.missing-parameters.error",
profile.getName() );
throw new Exception( message );
}
parameters.makeReadOnly();
return parameters;
}
public Object getSingletonInstance( Profile profile )
{
return m_singletons.get( profile );
}
private void putSingletonInstance( Profile profile, Object object )
{
m_singletons.put( profile, object );
}
/**
* Prepare a map of the dependent services keyed by role name.
* @param profile the profile referencing a type declaring dependecies
* @return a map of the services
*/
private Map getServices( Profile profile ) throws Exception
{
getLogger().debug("preparing services for profile: " + profile );
final Type type = profile.getType();
final DependencyDescriptor[] dependencies = type.getDependencies();
final HashMap services = new HashMap();
for( int i = 0; i < dependencies.length; i++ )
{
DependencyDescriptor dependency = dependencies[i];
final String role = dependency.getRole();
try
{
final Association association = profile.getAssociation( role
);
Object resource = association.getProvider();
services.put( role, resource );
}
catch( Throwable e )
{
final String error =
"Unexpected exception while attempting to locate a service
to fulfill a dependency for "
+ "the role: " + role + " in profile: " + profile.getName()
+ ".";
throw new ResourceException( error, e );
}
}
return services;
}
/**
* Check whether the specified value is compatible with specified type.
*
* @param value the value
* @param type the desired type
* @return true if value is compatible with type, false otherwise
*/
/*
private boolean objectImplementsType( final Object value, final String
type ) throws Exception
{
// ######### need to handle this sort of checking inside a service
manager
if( value == null )
return false;
try
{
final Class clazz = value.getClass();
final ClassLoader classLoader = clazz.getClassLoader();
final Class typeClass = classLoader.loadClass( type );
if( typeClass.isAssignableFrom( clazz ) )
{
return true;
}
}
catch( final ClassNotFoundException cnfe )
{
}
return false;
}
*/
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/package.html
Index: package.html
===================================================================
<body>
Interfaces and classes supporting component lifecycle management.
</body>
1.6 +2 -54
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/Container.java
Index: Container.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/Container.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Container.java 19 Jul 2002 14:08:06 -0000 1.5
+++ Container.java 29 Jul 2002 06:14:30 -0000 1.6
@@ -10,7 +10,7 @@
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.ResourceDesignator;
-import org.apache.excalibur.meta.info.ServiceDesignator;
+import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.merlin.Verifiable;
import org.apache.excalibur.merlin.Controller;
@@ -31,30 +31,6 @@
*/
public interface Container extends Controller, Verifiable
{
- /**
- * Assembly function that return an establish candidate resource from a
parent or local
- * container matching a supplied profile.
- *
- * @param profile a supplier profile
- * @return the corresponding candidate resource or null if no matching
resource
- */
- ResourceDesignator getCandidateResource( Profile profile );
-
- /**
- * Assembly function that returns the set of potential profiles
- * matching a dependency that may be applied as candidates to an assembly
- * process.
- *
- * @param dependency a consumer component dependency declaration
- * @return the set of available potential supplier profiles
- */
- Profile[] getProviders( ServiceDesignator service );
-
- /**
- * Returns the path name of this container.
- * @return the container's path
- */
- String getPath();
/**
* Post-assembly function that returns the set of resources
@@ -63,33 +39,5 @@
* @return the set of available resources
*/
ResourceDesignator[] getResources();
-
- /**
- * Post-assembly function that return the set of resources available in
the
- * container that matches the supplied service type.
- *
- * @param service the service type
- * @return the set of available resources matching the service type
- */
- ResourceDesignator[] getResources( ServiceDesignator service );
-
- /**
- * <p>Post-assembly function that returns a resource by name. The path
- * argument shall be in the form:</p>
- *
- * <pre>
- * <path> == <resource-type> + ":" +
<container-path> + "/" + <profile-name>
- * <container-path> == <parent-path> + "/" +
<container-name>
- * <parent-path> == <root> | <container-path>
- * </pre>
- * <p><b>Example</b><p>
- * <pre>
- * service:/facilities/security/vault
- * </pre>
- *
- * @param path the resource identifier
- * @return the named resource or null if the resource does not exist
- */
- ResourceDesignator getResource( String path );
}
1.17 +40 -375
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.java
Index: DefaultContainer.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- DefaultContainer.java 26 Jul 2002 06:17:04 -0000 1.16
+++ DefaultContainer.java 29 Jul 2002 06:14:30 -0000 1.17
@@ -62,25 +62,18 @@
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
-import org.apache.excalibur.meta.info.ServiceDesignator;
+import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.verifier.VerifyException;
+import org.apache.excalibur.merlin.assembly.TypeManager;
+import org.apache.excalibur.merlin.assembly.ProfileManager;
+import org.apache.excalibur.merlin.assembly.DefaultLoggerManager;
+import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
import org.apache.excalibur.merlin.model.Profile;
-import org.apache.excalibur.merlin.model.Profile;
-import org.apache.excalibur.merlin.model.ContainerDescriptor;
+import org.apache.excalibur.merlin.model.ResourceDesignator;
import org.apache.excalibur.merlin.model.verifier.AssemblyVerifier;
import org.apache.excalibur.merlin.model.verifier.MetaDataVerifier;
-import org.apache.excalibur.merlin.model.builder.ProfileBuilder;
-import org.apache.excalibur.merlin.model.builder.TypeManager;
-import org.apache.excalibur.merlin.model.ResourceDesignator;
-import org.apache.excalibur.merlin.model.builder.DefaultTypeManager;
-import org.apache.excalibur.merlin.model.builder.DefaultLoggerManager;
import org.apache.excalibur.merlin.Verifiable;
import org.apache.excalibur.merlin.Controller;
-import org.apache.log.Hierarchy;
-import org.apache.log.Priority;
-import org.apache.log.output.io.StreamTarget;
-
-import org.apache.excalibur.merlin.container.UnresolvedProviderException;
/**
* Default container implementation that manages a registry of componet
providers and
@@ -132,26 +125,9 @@
private List m_containers = new LinkedList();
/**
- * Parent container.
- */
- private Container m_parent;
-
- /**
* The classloader resolved from the meta model.
*/
- private TypeManager m_classloader;
-
- /**
- * Dependecy graph shared across all containers within the container
hierachy.
- */
- private DependencyGraph m_map;
-
- /**
- * Utility class providing support for establishments of objects that get
- * supplied to components (cofiguration, context, etc.). Interacts
between
- * the meta model, container implementation, resources and service
managers.
- */
- private ResourceProvider m_provider;
+ private ProfileManager m_classloader;
/**
* The meta data model of this container.
@@ -159,37 +135,10 @@
private ContainerDescriptor m_descriptor;
/**
- * The lifecycle helper to use to process startup and shutdown of
services.
- */
- private LifecycleHelper m_helper = new LifecycleHelper();
-
- /**
- * Internal class that maintains information about profile types managed
- * by this container.
- */
- private ProfileRegistry m_profiles;
-
- /**
- * Table of resources that have been created - keyed by the associated
profile.
- */
- private Hashtable m_mapping = new Hashtable();
-
- /**
- * Utility class used to create type meta info for compoents not
explicity declared
- * in the meta data model.
- */
- private ProfileBuilder m_builder = new ProfileBuilder();
-
- /**
* Flag showing initialization status.
*/
private boolean m_initialized = false;
- /**
- * The context object against which resoruce requests will be evaluated.
- */
- private Context m_dictionary;
-
//=======================================================================
// Contextualizable
//=======================================================================
@@ -199,32 +148,13 @@
* <ul>
* <li>[EMAIL PROTECTED] #CONTAINER_DESCRIPTOR_KEY} the container meta
model as
* a [EMAIL PROTECTED] ContainerDescriptor} (REQUIRED}</li>
- * <li>[EMAIL PROTECTED] #DICTIONARY_KEY} the kernel context import
dictionary as
- * a [EMAIL PROTECTED] Context} object from which import
directives may be resolved
- * (REQUIRED)</li>
- * <li>[EMAIL PROTECTED] #CONTAINER_KEY} the parent [EMAIL PROTECTED]
Container} (OPTIONAL) - if null,
- * this is a root container </li>
- * <li>[EMAIL PROTECTED] #MAP_KEY} the shared dependecy map [EMAIL
PROTECTED] DependencyGraph} (OPTIONAL)
- * - if null, this is a root container</li>
* </ul>
* @param context the service context value
*/
public void contextualize( Context context ) throws ContextException
{
m_descriptor = (ContainerDescriptor) context.get(
CONTAINER_DESCRIPTOR_KEY );
- m_dictionary = (Context) context.get( DICTIONARY_KEY );
- m_classloader = m_descriptor.getTypeManager();
-
- try
- {
- m_parent = (Container) context.get( CONTAINER_KEY );
- m_map = (DependencyGraph) context.get( MAP_KEY );
- }
- catch( ContextException e )
- {
- // root container
- m_map = new DependencyGraph();
- }
+ m_classloader = m_descriptor.getProfileManager();
}
//=======================================================================
@@ -242,27 +172,7 @@
public void initialize() throws Exception
{
getLogger().debug("initialization");
- getLogger().debug( "container creation using clasloader: " +
m_classloader );
-
- m_helper.enableLogging( getLogger().getChildLogger("lifecycle") );
- m_provider = new ResourceProvider( m_classloader, this, m_dictionary
);
- m_provider.enableLogging( getLogger().getChildLogger("provider") );
-
- //
- // initiate profile creation
- //
-
- m_profiles = new ProfileRegistry(
- m_descriptor,
- m_classloader,
- getPath(),
- m_parent,
- m_map,
- m_helper,
- m_provider,
- m_mapping );
-
- m_profiles.enableLogging( getLogger().getChildLogger( "assembly") );
+ getLogger().debug( "container creation using classloader: " +
m_classloader );
//
// explicit component profile registration
@@ -272,35 +182,20 @@
Profile[] children = m_descriptor.getComponents( Profile.EXPLICIT,
true );
for( int i=0; i<children.length; i++ )
{
- m_profiles.register( children[i] );
- }
-
- //
- // add packaged and implict profile registration
- //
-
- getLogger().debug("packaged and implicit profile registration");
- Type[] types = m_classloader.getTypes();
- for( int i=0; i<types.length; i++ )
- {
- Profile[] profiles = m_builder.build( m_descriptor, types[i] );
- for( int j=0; j<profiles.length; j++ )
- {
- Profile profile = profiles[j];
- m_descriptor.addComponent( (Profile) profile );
- m_profiles.register( profile );
- }
+ Profile profile = children[i];
+ m_classloader.addProfile( profile );
}
try
{
getLogger().debug("profile assembly");
- m_profiles.assemble();
+ //m_profiles.assemble( children );
+ m_classloader.assemble( children );
}
catch( Throwable e )
{
final String error = "Assembly failure.";
- throw new AssemblyException( error, e );
+ throw new ContainerException( error, e );
}
//
@@ -309,7 +204,6 @@
// with the creation of the subsidiary containers.
//
- validateResourceMapping( m_mapping );
getLogger().debug("subsidiary container creation");
ContainerDescriptor[] containers = m_descriptor.getContainers();
for( int i=0; i<containers.length; i++ )
@@ -359,37 +253,7 @@
public void start() throws Exception
{
getLogger().debug("start");
- Profile[] startup = m_map.getStartupGraph();
- for( int i=0; i<startup.length; i++ )
- {
- Profile profile = startup[i];
- if( this.contains( profile ) )
- {
- final String name = profile.getName();
- try
- {
- ResourceDesignator resource =
- (ResourceDesignator) m_mapping.get( profile );
- if( resource.getProfile().getActivationPolicy() )
- {
- if( getLogger().isDebugEnabled() )
- getLogger().debug("starting: " +
resource.getPath() );
- Object object = resource.getInstance();
- if( getLogger().isInfoEnabled() )
- getLogger().info("started: " + resource.getPath()
);
- }
- }
- catch( LifecycleException le )
- {
- final String warning =
- "Could not startup a service derived from profile: " +
profile;
- getLogger().warn( warning, le );
-
- // need to retract all profiles dependent on this profile
- }
- }
- }
- getLogger().debug("started");
+ m_classloader.start();
}
/**
@@ -401,28 +265,7 @@
public void stop()
{
getLogger().debug("stop");
- Profile[] shutdown = m_map.getShutdownGraph();
- for( int i=0; i<shutdown.length; i++ )
- {
- Profile profile = shutdown[i];
- if( this.contains( profile ) )
- {
- final String name = profile.getName();
- ResourceDesignator resource =
- (ResourceDesignator) m_mapping.get( profile );
- try
- {
- resource.release();
- }
- catch( Exception le )
- {
- final String warning =
- "Could not shutdown a service derived from profile:
'" + name + "'.";
- getLogger().warn( warning, le );
- }
- }
- }
- getLogger().debug("stopped");
+ m_classloader.stop();
}
//======================================================================
@@ -480,118 +323,6 @@
//=======================================================================
/**
- * Return an establish candidate resource from a parent or local
- * container matching a supplied profile.
- *
- * @param profile a supplier profile
- * @return the corresponding candidate resource or null if no matching
resource
- */
- public ResourceDesignator getCandidateResource( Profile profile )
- {
- ResourceDesignator resource = (ResourceDesignator) m_mapping.get(
profile );
- if(( resource == null) && (m_parent != null ))
- resource = m_parent.getCandidateResource( profile );
- return resource;
- }
-
- /**
- * Return the set of available potential profiles matching a dependency
that
- * may be applied as candidates to an assembly.
- * @param dependency a consumer component dependency declaration
- * @return the set of available potential supplier profiles
- */
- public Profile[] getProviders( ServiceDesignator designator )
- {
- Profile[] local = getLocalProviders( designator );
- if( m_parent != null )
- {
- Profile[] facilities = m_parent.getProviders( designator );
- ArrayList list = new ArrayList();
- for( int i=0; i<local.length; i++ )
- {
- list.add( local[i] );
- }
- for( int i=0; i<facilities.length; i++ )
- {
- list.add( facilities[i] );
- }
- return (Profile[]) list.toArray( new Profile[0] );
- }
- return local;
- }
-
- /**
- * Return the set of explicit, packed and implict providers capable of
handling the
- * supplied service.
- * @param designator the service designator
- * @return the set of candidate profiles
- */
- private Profile[] getLocalProviders( ServiceDesignator designator )
- {
- ArrayList list = new ArrayList();
- Profile[] local = m_descriptor.getComponents( true );
- for( int i=0; i<local.length; i++ )
- {
- Profile profile = local[i];
- ServiceDescriptor[] services = profile.getType().getServices();
- for( int j=0; j<services.length; j++ )
- {
- if( services[j].getService().matches( designator ) )
- {
- list.add( profile );
- break;
- }
- }
- }
- return (Profile[]) list.toArray( new Profile[0] );
- }
-
- /**
- * Returns the path name of this container.
- * @return the container's path
- */
- public String getPath()
- {
- if( m_parent == null ) return ContainerDescriptor.DELIMITER +
m_descriptor.getName();
- return m_parent.getPath() + ContainerDescriptor.DELIMITER +
m_descriptor.getName();
- }
-
- /**
- * Returns a resource by name.
- *
- * @param path the resource identifier
- * @return the named resource or null if the resource does not exist
- */
- public ResourceDesignator getResource( String path )
- {
- if( !m_initialized )
- throw new IllegalStateException("not-initialized");
-
- //
- // if we have a parent container then let the parent handle the
request
- // otherwise, we are the root container, in which case get the
aggregated
- // set of resources from the container hierachy and select the
resoruce
- // by matching the name
- //
-
- if( m_parent != null )
- {
- return m_parent.getResource( path );
- }
- else
- {
- ResourceDesignator[] resources = getResources();
- for( int i=0; i<resources.length; i++ )
- {
- final ResourceDesignator resource = resources[i];
- if( resource.getPath().equals( path ) )
- return resource;
- }
- return null;
- }
- }
-
- /**
* Return the set of resources exported by this container.
*
* @return the set of exported resources
@@ -602,84 +333,24 @@
throw new IllegalStateException("not-initialized");
ArrayList list = new ArrayList();
- getResources( list );
- return (ResourceDesignator[]) list.toArray( new
ResourceDesignator[0] );
- }
-
- protected void getResources( List list )
- {
- list.addAll( m_mapping.values() );
- Iterator iterator = m_containers.iterator();
- while( iterator.hasNext() )
- {
- ((DefaultContainer)iterator.next()).getResources( list );
- }
- }
-
- /**
- * Return the set of resources available in this container and all
subsidary containers
- * that match the supplied service type
- *
- * @param service the service type
- * @return the set of available resources matching the service type
- */
- public ResourceDesignator[] getResources( ServiceDesignator service )
- {
- if( !m_initialized )
- throw new IllegalStateException("not-initialized");
-
- ArrayList list = new ArrayList();
- getResources( list, service );
- return (ResourceDesignator[]) list.toArray( new
ResourceDesignator[0] );
- }
-
- protected void getResources( List list, ServiceDesignator service )
- {
- ResourceDesignator[] resources =
- (ResourceDesignator[]) m_mapping.values().toArray( new
ResourceDesignator[0] );
-
- for( int i=0; i<resources.length; i++ )
+ ResourceDesignator[] local = m_classloader.getExport();
+ for( int i=0; i<local.length; i++ )
{
- ResourceDesignator resource = resources[i];
- ServiceDescriptor[] services = resource.getServices();
- for( int j=0; j<services.length; j++ )
- {
- if( services[j].getService().matches( service ) )
- {
- list.add( resource );
- break;
- }
- }
+ list.add( local[i] );
}
Iterator iterator = m_containers.iterator();
while( iterator.hasNext() )
{
- ((DefaultContainer)iterator.next()).getResources( list, service
);
- }
- }
-
- /**
- * Internal validation. Probably no longer needed.
- * @param map the dependency map
- */
- private void validateResourceMapping( Map map )
- {
- Profile[] profiles = m_map.getStartupGraph();
- for( int i=0; i<profiles.length; i++ )
- {
- Profile profile = profiles[i];
- if( this.contains( profile ) )
- {
- ResourceDesignator resource = (ResourceDesignator) map.get(
profile );
- if( resource == null )
- {
- String name = getPath() + "/" + profile.getName();
- resource = new ProfileDesignator( name, profile,
m_helper, m_provider );
- m_mapping.put( profile, resource );
- getLogger().info("added suppliment: " + name );
- }
+ Container container = (Container)iterator.next();
+ ResourceDesignator[] resources = container.getResources();
+ for( int j=0; j<resources.length; j++ )
+ {
+ ResourceDesignator resource = resources[j];
+ if( !list.contains( resource ) )
+ list.add( resources[j] );
}
}
+ return (ResourceDesignator[]) list.toArray( new
ResourceDesignator[0] );
}
//=======================================================================
@@ -699,17 +370,6 @@
//=======================================================================
/**
- * Test if the container is managing a supplied profile.
- * @param profile the profile
- * @return TRUE if the profile is managed by the container.
- */
- private boolean contains( Profile profile )
- {
- return m_profiles.isLocalProfile( profile );
- }
-
-
- /**
* Internal verification of the container.
*
* @exception ValidationException if a validation failure occurs
@@ -718,6 +378,9 @@
{
getLogger().debug("verify");
+ /*
+ ### Need to move this to the profile manager ####
+
Profile[] profiles = m_map.getStartupGraph();
MetaDataVerifier mdv = new MetaDataVerifier();
for( int i=0; i<profiles.length; i++ )
@@ -737,8 +400,10 @@
getLogger().debug("commencing assembly verification");
verifier.verifyAssembly( profiles );
listProfiles( profiles );
+ */
}
+/*
private void listProfiles( Profile[] profiles )
{
getLogger().debug("listing profiles");
@@ -769,20 +434,20 @@
}
}
}
+*/
+ /**
+ * Internal utility to create a subsidiary container.
+ *
+ * @param descriptor the subsidiary container descriptor
+ * @exception Exception is an error occurs
+ */
private DefaultContainer createContainer( ContainerDescriptor descriptor
) throws Exception
{
-
String name = descriptor.getName();
getLogger().info("creating child container: " + name );
- DependencyGraph map = new DependencyGraph( m_map );
- m_map.addChild( map );
-
DefaultContext context = new DefaultContext();
- context.put( CONTAINER_KEY, this );
- context.put( MAP_KEY, map );
context.put( CONTAINER_DESCRIPTOR_KEY, descriptor );
- context.put( DICTIONARY_KEY, m_dictionary );
context.makeReadOnly();
DefaultContainer container = new DefaultContainer();
1.5 +6 -6
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.xinfo
Index: DefaultContainer.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.xinfo,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DefaultContainer.xinfo 25 Jul 2002 18:07:15 -0000 1.4
+++ DefaultContainer.xinfo 29 Jul 2002 06:14:30 -0000 1.5
@@ -18,16 +18,16 @@
</component>
<context>
- <entry key="classloader"
type="org.apache.excalibur.merlin.model.builder.DefaultTypeManager"
optional="false"/>
- <entry key="logging"
type="org.apache.excalibur.merlin.kernel.DefaultLoggerManager"
optional="false"/>
- <entry key="descriptor"
type="org.apache.excalibur.merlin.model.ContainerDescriptor" optional="false"/>
- <entry key="map"
type="org.apache.excalibur.merlin.kernel.DependencyGraph" optional="false"/>
- <entry key="container" type="org.apache.excalibur.merlin.Container"
optional="true"/>
+ <entry key="classloader"
type="org.apache.excalibur.merlin.assembly.ProfileManager" optional="false"/>
+ <entry key="logging"
type="org.apache.excalibur.merlin.assembly.DefaultLoggerManager"
optional="false"/>
+ <entry key="descriptor"
type="org.apache.excalibur.merlin.container.model.ContainerDescriptor"
optional="false"/>
+ <entry key="map"
type="org.apache.excalibur.merlin.assembly.DependencyGraph" optional="false"/>
+ <entry key="container"
type="org.apache.excalibur.merlin.container.Container" optional="true"/>
</context>
<services>
<service>
- <service-ref type="org.apache.excalibur.merlin.container.Container"
version="1.0"/>
+ <reference type="org.apache.excalibur.merlin.container.Container"
version="1.0"/>
</service>
</services>
1.4 +1 -1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/package.html
Index: package.html
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/package.html,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- package.html 12 Jul 2002 19:09:26 -0000 1.3
+++ package.html 29 Jul 2002 06:14:30 -0000 1.4
@@ -1,7 +1,7 @@
<body>
<p>
-A geneneric component type management service supporting automated component
assembly, service deployment and service decommissioning . The service acts as
a repository for component types and profiles. The repository enables
resolution of component types based on a classloader, extension directory set
defintion (managemed by the host kernel), a supplied classpath, and component
deployment directives. Components are established based on the publication of
components across a set jar file manifest together with explicit component
profile directives included within the registry configuration. Given a manifest
declaration of a component implementation class, a component type definition
will be resolvable providing the registry can resolve all type constraints
(specifically the validation of the dependecies of candidate supplier
components).
+A component type management service supporting automated component assembly,
service deployment and service decommissioning. The service acts as a
repository for component types and profiles. The repository enables resolution
of component types based on a classloader, extension directory set defintion
(managemed by the host kernel), a supplied classpath, and component deployment
directives. Components are established based on the publication of components
across a set jar file manifest together with explicit component profile
directives included within the registry configuration. Given a manifest
declaration of a component implementation class, a component type definition
will be resolvable providing the registry can resolve all type constraints
(specifically the validation of the dependecies of candidate supplier
components).
</p>
<h3>Funtional Summary</h3>
<ul>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/ContainerCreator.java
Index: ContainerCreator.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.container.builder;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.logger.Logger;
import org.apache.excalibur.merlin.assembly.TypeManager;
import org.apache.excalibur.merlin.assembly.DefaultLoggerManager;
import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
import org.apache.excalibur.merlin.container.model.Parent;
/**
* Simple interface used to create [EMAIL PROTECTED] ContainerDescriptor}
* from a Configuration sorce.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public interface ContainerCreator
{
/**
* Create a [EMAIL PROTECTED] org.apache.excalibur.merlin.model.Profile}
from configuration
*
* @param config the confiugration source
* @return the newly created [EMAIL PROTECTED] ContainerDescriptor}
* @throws Exception
*/
ContainerDescriptor createContainerDescriptor( Parent parent,
Configuration config, TypeManager manager, DefaultLoggerManager logging )
throws Exception;
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/Resources.properties
Index: Resources.properties
===================================================================
builder.redundent-role.notice=Warning: Type for class {0} redundently
specifies role name "{1}" in dependency when it is identical to the name of
service. It is recomended that the <role/> section be elided.
builder.creating-info.notice=Creating a Type for class "{0}".
builder.created-info.notice=Constructed Type object for class {0}.
ComponentInfo contains {1} services, {2} dependencies, {3} context entrys and
{4} loggers.
builder.bad-toplevel-element.error=Error the component implemented by "{0}"
has an invalid element at top level of component info descriptor. Expected:
"component-info". Actual: "{1}"
builder.missing-info.error=Unable to locate resource from which to load info
for component implemented by class "{0}".
builder.missing-xml-creator.error=Unable to create XMLTypeCreator, usually
due to not having XML classes on Classpath. Thus unable to lookup XML
descriptor for component type "{0}".
builder.creating-profile.notice=Creating Profiles for class "{0}".
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/container/builder/XMLContainerCreator.java
Index: XMLContainerCreator.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.container.builder;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.configuration.ContextFactory;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.CategoriesDescriptor;
import org.apache.excalibur.merlin.model.Category;
import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
import org.apache.excalibur.merlin.container.model.IncludeDescriptor;
import org.apache.excalibur.merlin.container.model.FilesetDescriptor;
import org.apache.excalibur.merlin.container.model.ClasspathDescriptor;
import org.apache.excalibur.merlin.container.model.Parent;
import org.apache.excalibur.merlin.model.ModelException;
import org.apache.excalibur.merlin.model.builder.XMLProfileCreator;
import org.apache.excalibur.merlin.assembly.TypeManager;
import org.apache.excalibur.merlin.assembly.ProfileManager;
import org.apache.excalibur.merlin.assembly.DefaultLoggerManager;
import org.apache.excalibur.meta.info.Type;
/**
* Handles internalization of an XML based description of a [EMAIL PROTECTED]
ContainerDescriptor}
* from a Configuration object. The format for Configuration object
* is specified in the <a href="package-summary.html#external">package
summary</a>.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public class XMLContainerCreator extends XMLProfileCreator
implements ContainerCreator
{
private static final Resources REZ =
ResourceManager.getPackageResources( XMLContainerCreator.class );
/**
* Create a new container descriptor.
* @param config the container configuration
* @param manager the parent type manager
* @param logger the parent logger
* @exception Exception is a error occurs during container descriptor
creation
*/
public ContainerDescriptor createContainerDescriptor(
Parent parent, Configuration config, TypeManager manager,
DefaultLoggerManager logging )
throws Exception
{
//
// create the logging categories for this container
//
final String name = config.getAttribute("name");
CategoriesDescriptor categories =
super.createCategoriesDescriptor( name,
config.getChild("categories") );
Logger logger;
if( parent instanceof ContainerDescriptor )
{
final String root =
parent.getPath().replace('/','.').substring(1) + "." + name;
logging.addCategories( root, categories );
logger = logging.getLoggerForCategory( root );
}
else
{
logging.addCategories( name, categories );
logger = logging.getLoggerForCategory( name );
}
//
// create a new classloader for this container
//
logger.info("preparing type manager");
ClasspathDescriptor classpath = createClasspathDescriptor(
config.getChild("classpath") );
final ProfileManager loader = new ProfileManager( manager, name );
try
{
loader.enableLogging( logger.getChildLogger( "loader" ) );
DefaultContext context = new DefaultContext();
context.put(
TypeManager.CLASSPATH_DESCRIPTOR_KEY,
classpath );
context.makeReadOnly();
loader.contextualize( context );
loader.initialize();
}
catch( Throwable e )
{
final String error = "Classloader establishment failure.";
throw new ModelException( error, e );
}
//
// create an empty container
//
logger.info("container descriptor creation");
ContainerDescriptor container = new ContainerDescriptor(
parent, name, logger, loader );
//
// add all of the profiles declared within the container using the
container's
// type manager
//
logger.info("component creation");
Configuration[] children = config.getChildren("component");
for( int i=0; i<children.length; i++ )
{
Configuration child = children[i];
Type type = loader.loadType( child.getAttribute("class") );
Profile profile = createProfile( loader, type, child );
container.addComponent( profile );
}
//
// add all of the nested containers
//
final Configuration[] configs = config.getChildren("container");
for( int i=0; i<configs.length; i++ )
{
final Configuration conf = configs[i];
container.addContainer( createContainerDescriptor( container,
conf, loader, logging ) );
}
return container;
}
public ClasspathDescriptor createClasspathDescriptor( Configuration
config )
throws ConfigurationException
{
ArrayList list = new ArrayList();
Configuration[] configs = config.getChildren("fileset");
for( int i=0; i<configs.length; i++ )
{
Configuration c = configs[i];
list.add( createFilesetDescriptor( c ) );
}
FilesetDescriptor[] filesets = (FilesetDescriptor[]) list.toArray(
new FilesetDescriptor[0] );
return new ClasspathDescriptor( filesets );
}
public FilesetDescriptor createFilesetDescriptor( Configuration config )
throws ConfigurationException
{
String base = config.getAttribute("dir");
ArrayList list = new ArrayList();
Configuration[] includeConfigs = config.getChildren("include");
for( int i=0; i<includeConfigs.length; i++ )
{
Configuration includeConfig = includeConfigs[i];
list.add( createIncludeDescriptor( includeConfig ) );
}
IncludeDescriptor[] includes = (IncludeDescriptor[]) list.toArray(
new IncludeDescriptor[0] );
return new FilesetDescriptor( base, includes );
}
public IncludeDescriptor createIncludeDescriptor( Configuration config )
throws ConfigurationException
{
String filename = config.getAttribute("name");
return new IncludeDescriptor( filename );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/package.html
Index: package.html
===================================================================
<body>
Utilities supporting the creation of a container from an XML description.
</body>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/model/ClasspathDescriptor.java
Index: ClasspathDescriptor.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.container.model;
import java.io.Serializable;
/**
* <p>A classpath descriptor that describes a scoped set of jar files.
Classpath
* descriptors are contained with [EMAIL PROTECTED]
org.apache.excalibur.merlin.kernel.model.KernelDescriptor} and
* [EMAIL PROTECTED]
org.apache.excalibur.merlin.container.model.ContainerDescriptor} declarations.
* A classpath contains 0-n [EMAIL PROTECTED] FilesetDescriptor}
instances.</p>
*
* <p><b>XML</b></p>
* <p>The XML form for a classpath description is shown below. The classpath
element contains
* no attributes. The element may contain multiple fileset elements that
collectively define
* the scope of the classpath.
* </p>
* <pre>
* <classpath>
*
* <font color="gray"><i><!--
* Declaration of multiple filesets.
* --></i></font>
*
* <fileset dir=<font color="darkred">"dist"</font>>
* <include name="<font color="darkred">demo.jar</font>"/>
* <include name="<font
color="darkred">new-application-1.0.jar</font>"/>
* </fileset>
*
* <fileset dir="<font color="darkred">lib</font>">
* <include name="<font
color="darkred">avalon-framework.jar</font>"/>
* </fileset>
*
* </classpath>
* </pre>
*
* @see FilesetDescriptor
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public class ClasspathDescriptor implements Serializable
{
/**
* The collection of filesets.
*/
private final FilesetDescriptor[] m_filesets;
/**
* Create a ClasspathDescriptor instance.
*
* @param filesets the set of filesets to include in the classpath
*/
public ClasspathDescriptor( final FilesetDescriptor[] filesets )
{
m_filesets = filesets;
}
/**
* Return the filesets held within the classpath descriptor.
*
* @return the filesets
*/
public FilesetDescriptor[] getFilesetDescriptors()
{
return m_filesets;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/model/ContainerDescriptor.java
Index: ContainerDescriptor.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.container.model;
import java.util.ArrayList;
import org.apache.avalon.framework.logger.Logger;
import org.apache.excalibur.merlin.assembly.ProfileManager;
import org.apache.excalibur.merlin.model.Profile;
/**
* <p>A container descriptor is a description of the crieria supporting the
* construction of a container. It may may include multiple
* component profile declarations, and multiple nested container
declarations.</p>
*
* <p><b>XML</b><p>
* A single container element is required within a kernel defintion.
Multiple
* container declarations may appear within an enclosing container.
* <pre>
* <font color="gray"><i><!--
* Definition of a container. The name attribute declares bother the
container
* name and the base logging category that will be supplied to the
container
* by its parent. Logging category defintions declared within the
container
* declaration are relative to the container name.
* --></i></font>
*
* <container name="<font color="darkred">root</font>">
*
* <font color="gray"><i><!--
* Classpath declaration. Classes accessible to a component are
constrained
* to the classes available in the jar files declared within the
immediate
* classpath, together with and resources declared in any parent
container.
* --></i></font>
*
* <classpath>
* <fileset dir="<font color="darkred">dist</font>">
* <include name="<font color="darkred">demo.jar</font>"/>
* <include name="<font
color="darkred">new-application-1.0.jar</font>"/>
* </fileset>
* </classpath>
*
* <font color="gray"><i><!--
* Logging categories declaration. Logging categories are relative to
the name of the
* enaclosing container. Logging priorities and targets will default to
the parent
* containtains values if undefined.
* --></i></font>
*
* <categories priority="<font color="darkred">INFO</font>">
* <category name="<font color="darkred">profiles</font>" />
* <category name="<font color="darkred">lifecycle</font>" />
* <category name="<font color="darkred">verifier</font>" />
* </categories>
*
* <font color="gray"><i><!--
* Multiple component profile declarations. If a component declares
dependecies,
* the container will attempt to resolve the dependency locally relative
to any
* other declared components, otherwise, the container will attempt to
resolve
* the dependecy using services established (explicitly or implicitly)
in the
* parent containers before attempting a local implicit solution.
* --></i></font>
*
* <component name="<font color="darkred">my-component</font>"
* class="<font
color="darkred">org.apache.excalibur.playground.SimpleComponent</font>" />
*
* <font color="gray"><i><!--
* Multiple subsidiary container declarations.
* --></i></font>
*
* <container name="<font color="darkred">child</font>">
* <component name="<font color="darkred">demo-component</font>"
class="<font
color="darkred">org.apache.excalibur.playground.BasicComponent</font>" />
* <container>
*
* </container>
* </pre>
*
* @see Profile
* @see ClasspathDescriptor
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public class ContainerDescriptor extends Parent
{
/**
* The component described within the scope of the container.
*/
private final ArrayList m_components = new ArrayList();
/**
* The component described within the scope of the container.
*/
private final ArrayList m_containers = new ArrayList();
/**
* Create a ContainerDescriptor instance.
* @param parent the parent container
* @param name the container name
* @param logger the logging channel the the container
* @param manager the containers type manager
* @param components the set of components to be included in the container
* @param containers the set of subsidiary containers to include in the
container
*/
public ContainerDescriptor(
final Parent parent,
final String name,
final Logger logger,
final ProfileManager manager )
{
super( parent, manager, name, logger );
}
/**
* Returns the path name of this container descriptor.
* @return the container's path
*/
public String getPath()
{
if( getParent() instanceof ContainerDescriptor )
{
return getParent().getPath() + DELIMITER + getName();
}
else
{
return DELIMITER + getName();
}
}
/**
* Add a component profile to this container.
*
* @param component the component profile to add to the container
*/
public void addComponent( Profile component )
{
if( !m_components.contains( component ) )
{
m_components.add( component );
}
}
/**
* Return the set of component descriptors contained within this
container.
*
* @return the target descriptors
*/
public Profile[] getComponents()
{
return (Profile[]) m_components.toArray( new Profile[0] );
}
/**
* Return the set of enabled or disable components based on the supplied
criteria.
*
* @param enabled TRUE to select enabled components, FALSE returns
disabled components
* @return the descriptors matching the supplied enabled status
*/
public Profile[] getComponents( boolean enabled )
{
ArrayList list = new ArrayList();
Profile[] components = getComponents();
for( int i=0; i<components.length; i++ )
{
Profile component = components[i];
if( component.isEnabled() == enabled )
list.add( component );
}
return (Profile[] ) list.toArray( new Profile[0] );
}
/**
* Return the set of component descriptors contained within this
container matching
* the supplied mode.
*
* @param mode one of enumerated value [EMAIL PROTECTED]
Profile#IMPLICIT}, [EMAIL PROTECTED] Profile#PACKAGED},
* or [EMAIL PROTECTED] Profile#EXPLICIT}
* @param enabled TRUE to select enabled components, FALSE returs
disabled compoents
* @return the descriptors matching the supplied creation mode
*/
public Profile[] getComponents( int mode, boolean enabled )
{
ArrayList list = new ArrayList();
Profile[] components = getComponents( enabled );
return selectComponentsByMode( components, mode );
}
/**
* Return the set of component descriptors contained within this
container matching
* the supplied mode.
*
* @param mode one of enumerated value [EMAIL PROTECTED]
Profile#IMPLICIT}, [EMAIL PROTECTED] Profile#PACKAGED},
* or [EMAIL PROTECTED] Profile#EXPLICIT},
* @return the descriptors matching the supplied creation mode
*/
public Profile[] getComponents( int mode )
{
return selectComponentsByMode( getComponents(), mode );
}
/**
* Add a container descriptor to this container.
*
* @param container the container to add
*/
public void addContainer( ContainerDescriptor container )
{
if( !m_containers.contains( container ) )
{
m_containers.add( container );
}
}
/**
* Return the set of subsidiary containers contained within this
container.
*
* @return the target descriptors
*/
public ContainerDescriptor[] getContainers()
{
return (ContainerDescriptor[]) m_containers.toArray( new
ContainerDescriptor[0] );
}
/**
* Returns a sub-set of the supplied containers matching the supplied
creation mode.
* @param components the compoennts to select from
* @param mode the creation mode to retrict the returned selection to
* @param the subset of the supplied components with a creation mode
matching
* the supplied mode value
*/
private Profile[] selectComponentsByMode( Profile[] components, int mode )
{
ArrayList list = new ArrayList();
for( int i=0; i<components.length; i++ )
{
Profile component = components[i];
if( component.getMode() == mode )
list.add( component );
}
return (Profile[] ) list.toArray( new Profile[0] );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/model/DirsetDescriptor.java
Index: DirsetDescriptor.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.container.model;
import java.io.Serializable;
/**
* <p>A description of a directory set. A directory set is a declaration of a
* a set of directories scoped relative to a parent directory.</p>
*
* <p><b>XML</b></p>
* <pre>
* <dirset dir="<font color="darkred">../system</font>">
* <include name="<font color="darkred">extensions</font>"/>
* <include name="<font color="darkred">lib</font>"/>
* </dirset>
* </pre>
*
* @see IncludeDescriptor
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public class DirsetDescriptor implements Serializable
{
/**
* The base directory
*/
private final String m_base;
/**
* The set of include directives.
*/
private final IncludeDescriptor[] m_includes;
/**
* Create a DirsetDescriptor instance using a base directory and a set of
* include statements that should reference directories relative to the
base.
*
* @param base the base directory from which include directory name will
be resolved
* @param includes the set of include directives
*/
public DirsetDescriptor( final String base, final IncludeDescriptor[]
includes )
{
m_base = base;
m_includes = includes;
}
/**
* Return the base directory.
*
* @return the directory
*/
public String getBaseDirectory()
{
return m_base;
}
/**
* Return the set of include deirectives.
*
* @return the include directives
*/
public IncludeDescriptor[] getIncludeDescriptors()
{
return m_includes;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/model/ExtensionsDescriptor.java
Index: ExtensionsDescriptor.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.container.model;
import java.io.Serializable;
/**
* <p>An extensions descriptor that declares a set of directories to be used
* referenced as the installed extension directories. An extensions
descriptor
* may contain multiple [EMAIL PROTECTED] DirsetDescriptor} instances.</p>
*
* <p><b>XML</b></p>
* <pre>
* <extensions>
* <dirset dir="<font color="darkred">.</font>">
* <include name="<font color="darkred">extensions</font>"/>
* <include name="<font color="darkred">lib</font>"/>
* </dirset>
* </extensions>
* </pre>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public class ExtensionsDescriptor implements Serializable
{
/**
* The base directory
*/
private final DirsetDescriptor[] m_dirs;
/**
* Create a ExtensionsDescriptor instance.
*
* @param dirs the set of dirsets to include in the classpath
*/
public ExtensionsDescriptor( final DirsetDescriptor[] dirs )
{
m_dirs = dirs;
}
/**
* Return the dirsets held within the extensions descriptor.
*
* @return the set of directory set instances
*/
public DirsetDescriptor[] getDirsetDescriptors()
{
return m_dirs;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/model/FilesetDescriptor.java
Index: FilesetDescriptor.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.container.model;
import java.io.Serializable;
/**
* <p>A fileset descriptor is a scoped defintion of a set of files. A fileset
* a structurally defined as a base directory and a set of relative filenames
* represented as include directives.</p>
*
* <p><b>XML</b></p>
* <pre>
* <fileset dir="<font color="darkred">lib</font>">
* <include name="<font
color="darkred">avalon-framework.jar</font>"/>
* <include name="<font color="darkred">logkit.jar</font>"/>
* </dirset>
* </pre>
*
* @see IncludeDescriptor
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public class FilesetDescriptor implements Serializable
{
/**
* The base directory from which include directives will be resolved.
*/
private final String m_base;
/**
* The set of include directives.
*/
private final IncludeDescriptor[] m_includes;
/**
* Create a FilesetDescriptor instance.
*
* @param includes the set of includes to include in the fileset
*/
public FilesetDescriptor( final String base, final IncludeDescriptor[]
includes )
{
m_base = base;
m_includes = includes;
}
/**
* Return the base directory.
*
* @return the directory
*/
public String getBaseDirectory()
{
return m_base;
}
/**
* Return the filesets held within the classpath descriptor.
*
* @return the filesets
*/
public IncludeDescriptor[] getIncludeDescriptors()
{
return m_includes;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/model/IncludeDescriptor.java
Index: IncludeDescriptor.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.container.model;
import java.io.Serializable;
/**
* <p>An file include directive.</p>
* <p><b>XML</b></p>
* <p>An include element is normally contained within a scoping structure
such as a
* fileset or directory set. The include element contains the single
attribute name
* which is used to refer to the file or directory (depending on the
containing
* context.</p>
* <pre>
* <font color="gray"><fileset dir="lib"></font>
* <include name="<font color="darkred">avalon-framework.jar</font>"
/>
* <font color="gray"></fileset></font>
* </pre>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public class IncludeDescriptor implements Serializable
{
/**
* The base directory
*/
private final String m_file;
/**
* Create a FilesetDescriptor instance.
*
* @param file the filename
*/
public IncludeDescriptor( final String file )
{
m_file = file;
}
/**
* Return the included filename.
*
* @return the file
*/
public String getFile()
{
return m_file;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/model/Parent.java
Index: Parent.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.container.model;
import java.io.Serializable;
import org.apache.avalon.framework.logger.Logger;
import org.apache.excalibur.merlin.assembly.DefaultLoggerManager;
import org.apache.excalibur.merlin.assembly.ProfileManager;
import org.apache.excalibur.merlin.kernel.model.KernelDescriptor;
/**
* Abstract class for types that can act as logical parents in the mera-date
hierachy.
*
* @see KernelDescriptor
* @see ContainerDescriptor
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:31 $
*/
public abstract class Parent
implements Serializable
{
/**
* The container classpath descriptor.
*/
private final ProfileManager m_manager;
/**
* Container path delimiter.
*/
public static final String DELIMITER = "/";
/**
* The kernel name
*/
private final String m_name;
/**
* The logging channel.
*/
private Logger m_logger;
/**
* The parent of this parent.
*/
private Parent m_parent;
/**
* Abstract constructor that handles name and logging category
assignment. The logging
* category supplied under this constructor will be used as the parent to
subsidary
* objects (enabling the creation of logging category chains.
*
* @param name the name of the instance
* @param categories the logging categories descriptor
*/
public Parent(
final Parent parent, ProfileManager manager, final String name, final
Logger logger )
{
if( name == null )
throw new NullPointerException("name");
if( logger == null )
throw new NullPointerException("logger");
if( manager == null )
throw new NullPointerException("manager");
m_manager = manager;
m_name = name;
m_logger = logger;
m_parent = parent;
}
/**
* Return the type manager assigned to the abstract container.
*
* @return the [EMAIL PROTECTED] ProfileManager} for the container.
*/
public ProfileManager getProfileManager()
{
return m_manager;
}
/**
* Return the instance name.
*
* @return the name of the container
*/
public String getName()
{
return m_name;
}
/**
* Returns the path name of this container descriptor.
* @return the container's path
*/
public String getPath()
{
if( getParent() == null )
{
return DELIMITER + getName();
}
else
{
return getParent().getPath() + DELIMITER + getName();
}
}
/**
* Set the parent container.
*
* @param the container containing this container.
* @exception IllegalStateException if the parent is already set
*/
public void setParent( Parent parent ) throws IllegalStateException
{
if( m_parent != null )
throw new IllegalStateException("parent");
m_parent = parent;
}
/**
* Return the parent container.
*
* @return the container containing this container.
*/
public Parent getParent()
{
return m_parent;
}
/**
* Return the default logger.
*
* @return the [EMAIL PROTECTED] Logger}.
*/
public Logger getLogger()
{
return m_logger;
}
/**
* Add a set of categories to the logging system as direct sub-categrories
* of the category representing this container.
*
* @param categories [EMAIL PROTECTED] CategoriesDescriptor} set
*/
//public void addCategories( CategoriesDescriptor categories )
//{
// m_logging.addCategories( this, categories );
//}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/model/package.html
Index: package.html
===================================================================
<body>
<p>
The <code>model</code> package contains the formal meta data model describing
a container including stuctures for the representation of extension
directories, classpath descriptors and subsidiary containers.
</p>
</body>
1.23 +13 -22
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java
Index: DefaultKernel.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- DefaultKernel.java 26 Jul 2002 06:17:04 -0000 1.22
+++ DefaultKernel.java 29 Jul 2002 06:14:32 -0000 1.23
@@ -62,15 +62,16 @@
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
-import org.apache.excalibur.meta.info.ServiceDesignator;
+import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.info.EntryDescriptor;
-import org.apache.excalibur.merlin.model.KernelDescriptor;
-import org.apache.excalibur.merlin.model.DirsetDescriptor;
+import org.apache.excalibur.merlin.kernel.model.KernelDescriptor;
+import org.apache.excalibur.merlin.container.model.DirsetDescriptor;
import org.apache.excalibur.merlin.model.Profile;
-import org.apache.excalibur.merlin.model.ContainerDescriptor;
-import org.apache.excalibur.merlin.model.builder.TypeManager;
+import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
import org.apache.excalibur.merlin.model.ResourceDesignator;
-import org.apache.excalibur.merlin.model.builder.XMLKernelCreator;
+import org.apache.excalibur.merlin.assembly.TypeManager;
+import org.apache.excalibur.merlin.assembly.ProfileManager;
+import org.apache.excalibur.merlin.kernel.builder.XMLKernelCreator;
import org.apache.excalibur.merlin.container.DefaultContainer;
/**
@@ -116,7 +117,7 @@
<font color="gray">//
// Following initialization the assembly of components has been
completed and
// resource descriptiors have been assigned. Service exported by
the kernel may
- // may be access via [EMAIL PROTECTED] ResourceDescriptor}
references exposed by the
+ // may be access via [EMAIL PROTECTED] ResourceDesignator}
references exposed by the
// {link #getResources()} method. The following method start all
resources
// declared as activatable on startup.
//</font>
@@ -139,7 +140,9 @@
// static
//=======================================================================
- public static final String WORKING_DIRECTORY_KEY = "avalon:work";
+ /**
+ * Context key used by the kernel to access the kernel meta-data
descriptor.
+ */
public static final String KERNEL_DESCRIPTOR_KEY = "descriptor";
//=======================================================================
@@ -185,28 +188,16 @@
public void initialize() throws Exception
{
- getLogger().debug(
- "creating root container descriptor using classloader: "
- + m_descriptor.getTypeManager() );
+ getLogger().debug( "creating root container descriptor" );
ContainerDescriptor descriptor = m_descriptor.getContainer();
//
- // dictionary creation
- //
-
- getLogger().debug("container dictionary" );
- DefaultContext dictionary = new DefaultContext();
- dictionary.put( WORKING_DIRECTORY_KEY, new File(
System.getProperty("user.dir") ) );
- dictionary.makeReadOnly();
-
- //
// root container context creation
//
getLogger().debug( "root container context creation" );
DefaultContext context = new DefaultContext();
context.put( DefaultContainer.CONTAINER_DESCRIPTOR_KEY, descriptor );
- context.put( DefaultContainer.DICTIONARY_KEY, dictionary );
context.makeReadOnly();
//
1.7 +4 -4
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.xinfo
Index: DefaultKernel.xinfo
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.xinfo,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DefaultKernel.xinfo 25 Jul 2002 18:07:15 -0000 1.6
+++ DefaultKernel.xinfo 29 Jul 2002 06:14:32 -0000 1.7
@@ -18,14 +18,14 @@
</component>
<context>
- <entry key="classloader"
type="org.apache.excalibur.merlin.model.builder.DefaultTypeManager"
optional="false"/>
- <entry key="logging"
type="org.apache.excalibur.merlin.kernel.DefaultLoggerManager"
optional="false"/>
- <entry key="descriptor"
type="org.apache.excalibur.merlin.model.KernelDescriptor" optional="false"/>
+ <entry key="classloader"
type="org.apache.excalibur.merlin.assembly.ProfileManager" optional="false"/>
+ <entry key="logging"
type="org.apache.excalibur.merlin.assembly.DefaultLoggerManager"
optional="false"/>
+ <entry key="descriptor"
type="org.apache.excalibur.merlin.kernel.model.KernelDescriptor"
optional="false"/>
</context>
<services>
<service>
- <service-ref type="org.apache.excalibur.merlin.kernel.Kernel"
version="1.0"/>
+ <reference type="org.apache.excalibur.merlin.kernel.Kernel"
version="1.0"/>
</service>
</services>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/builder/KernelCreator.java
Index: KernelCreator.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.kernel.builder;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.excalibur.merlin.kernel.model.KernelDescriptor;
/**
* Simple interface used to create [EMAIL PROTECTED] KernelDescriptor}
* from a Configuration sorce.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:32 $
*/
public interface KernelCreator
{
/**
* Create a [EMAIL PROTECTED] KernelDescriptor} from configuration
*
* @param config the configration source
* @return the newly created [EMAIL PROTECTED] KernelDescriptor}
* @throws Exception
*/
KernelDescriptor createKernelDescriptor( Configuration config,
ClassLoader loader )
throws Exception;
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/builder/Resources.properties
Index: Resources.properties
===================================================================
builder.redundent-role.notice=Warning: Type for class {0} redundently
specifies role name "{1}" in dependency when it is identical to the name of
service. It is recomended that the <role/> section be elided.
builder.creating-info.notice=Creating a Type for class "{0}".
builder.created-info.notice=Constructed Type object for class {0}.
ComponentInfo contains {1} services, {2} dependencies, {3} context entrys and
{4} loggers.
builder.bad-toplevel-element.error=Error the component implemented by "{0}"
has an invalid element at top level of component info descriptor. Expected:
"component-info". Actual: "{1}"
builder.missing-info.error=Unable to locate resource from which to load info
for component implemented by class "{0}".
builder.missing-xml-creator.error=Unable to create XMLTypeCreator, usually
due to not having XML classes on Classpath. Thus unable to lookup XML
descriptor for component type "{0}".
builder.creating-profile.notice=Creating Profiles for class "{0}".
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/kernel/builder/XMLKernelCreator.java
Index: XMLKernelCreator.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.kernel.builder;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.merlin.assembly.TypeManager;
import org.apache.excalibur.merlin.assembly.ProfileManager;
import org.apache.excalibur.merlin.assembly.DefaultLoggerManager;
import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
import org.apache.excalibur.merlin.container.builder.XMLContainerCreator;
import org.apache.excalibur.merlin.kernel.model.KernelDescriptor;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.Category;
import org.apache.excalibur.merlin.model.CategoriesDescriptor;
import org.apache.excalibur.merlin.container.model.IncludeDescriptor ;
import org.apache.excalibur.merlin.container.model.FilesetDescriptor;
import org.apache.excalibur.merlin.container.model.ClasspathDescriptor;
import org.apache.excalibur.merlin.container.model.DirsetDescriptor;
import org.apache.excalibur.merlin.container.model.ExtensionsDescriptor;
import org.apache.excalibur.merlin.kernel.model.TargetDescriptor;
import org.apache.excalibur.merlin.kernel.model.FileTargetProvider;
import org.apache.excalibur.merlin.kernel.model.TargetProvider;
import org.apache.excalibur.merlin.kernel.model.LoggingDescriptor;
import org.apache.excalibur.merlin.model.ModelException;
/**
* Handles internalization of an XML based description of a [EMAIL PROTECTED]
KernelDescriptor}
* from a Configuration object. The format for Configuration object
* is specified in the <a href="package-summary.html#external">package
summary</a>.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:32 $
*/
public final class XMLKernelCreator extends XMLContainerCreator
implements KernelCreator
{
private static final Resources REZ =
ResourceManager.getPackageResources( XMLKernelCreator.class );
/**
* Create a [EMAIL PROTECTED] KernelDescriptor} from configuration
*
* @param config the configration source
* @param loader the parent classloader
* @return the newly created [EMAIL PROTECTED] ContainerDescriptor}
* @throws Exception
*/
public KernelDescriptor createKernelDescriptor( Configuration config,
ClassLoader loader )
throws Exception
{
final String name = config.getName();
LoggingDescriptor loggingDescriptor = createLoggingDescriptor(
config.getChild("logging"), name );
DefaultLoggerManager logging = new DefaultLoggerManager(
loggingDescriptor );
CategoriesDescriptor categories = super.createCategoriesDescriptor(
name, config.getChild("categories") );
logging.addCategories( name, categories );
Logger logger = logging.getLoggerForCategory( name );
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 );
try
{
manager.enableLogging( logger.getChildLogger( "loader" ) );
DefaultContext context = new DefaultContext();
context.put(
TypeManager.EXTENSIONS_DESCRIPTOR_KEY,
extensions );
context.put(
TypeManager.CLASSPATH_DESCRIPTOR_KEY,
classpath );
context.put(
ProfileManager.LOGGING_MANAGER_KEY,
logging );
context.makeReadOnly();
manager.contextualize( context );
manager.initialize();
}
catch( Throwable e )
{
final String error = "Classloader establishment failure.";
throw new ModelException( error, e );
}
logger.info("preparing kernel descriptor");
KernelDescriptor kernel = new KernelDescriptor( name, logger, manager
);
ContainerDescriptor container = createContainerDescriptor(
kernel, config.getChild("container"), manager, logging );
kernel.setContainer( container );
return kernel;
}
public LoggingDescriptor createLoggingDescriptor( Configuration config,
String name )
throws ConfigurationException
{
final String target = config.getAttribute(
"target", Category.DEFAULT_LOGGING_TARGET );
final String priority = config.getAttribute( "priority", null );
ArrayList list = new ArrayList();
Configuration[] configs = config.getChildren("target");
for( int i=0; i<configs.length; i++ )
{
Configuration c = configs[i];
list.add( createTargetDescriptor( c ) );
}
TargetDescriptor[] targets = (TargetDescriptor[]) list.toArray( new
TargetDescriptor[0] );
return new LoggingDescriptor( name, priority, target, targets );
}
public TargetDescriptor createTargetDescriptor( Configuration config )
throws ConfigurationException
{
final String name = config.getAttribute("name");
if( config.getChildren().length == 0 )
throw new ConfigurationException(
"missing target provider elememt in '" + config.getName() + "'.");
final Configuration c = config.getChildren()[0];
TargetProvider provider = null;
if( c.getName().equals("file") )
{
provider = createFileTargetProvider( c );
}
else
{
throw new ConfigurationException(
"Unrecognized provider: " + c.getName() + " in " +
config.getName() );
}
return new TargetDescriptor( name, provider );
}
public FileTargetProvider createFileTargetProvider( Configuration config )
throws ConfigurationException
{
String file = config.getAttribute("location");
return new FileTargetProvider( file );
}
public ExtensionsDescriptor createExtensionsDescriptor( Configuration
config )
throws ConfigurationException
{
ArrayList list = new ArrayList();
Configuration[] configs = config.getChildren("dirset");
for( int i=0; i<configs.length; i++ )
{
Configuration c = configs[i];
list.add( createDirsetDescriptor( c ) );
}
DirsetDescriptor[] dirs = (DirsetDescriptor[]) list.toArray( new
DirsetDescriptor[0] );
return new ExtensionsDescriptor( dirs );
}
public DirsetDescriptor createDirsetDescriptor( Configuration config )
throws ConfigurationException
{
String base = config.getAttribute("dir");
ArrayList list = new ArrayList();
Configuration[] includeConfigs = config.getChildren("include");
for( int i=0; i<includeConfigs.length; i++ )
{
Configuration includeConfig = includeConfigs[i];
list.add( createIncludeDescriptor( includeConfig ) );
}
IncludeDescriptor[] includes = (IncludeDescriptor[]) list.toArray(
new IncludeDescriptor[0] );
return new DirsetDescriptor( base, includes );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/builder/package.html
Index: package.html
===================================================================
<body>
Utilities supporting the creation of a kernel from an XML description.
</body>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/model/FileTargetProvider.java
Index: FileTargetProvider.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.kernel.model;
/**
* File target provider descriptor declares the criteria for the creation of
* an file based logging target provider.
*
* <p><b>XML</b></p>
* <p>A file target element may be contained within a target element to
declare
* the target as a file based logging sink.</p>
* <pre>
* <font color="gray"><target name="kernel"></font>
* <file location="<font color="darkred">kernel.log</font>" />
* <font color="gray"></target></font>
* </pre>
*
* @see TargetDescriptor
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:32 $
*/
public class FileTargetProvider extends TargetProvider
{
private final String m_location;
/**
* Creation of a new file target.
* @param location the filename of the logging destination
*/
public FileTargetProvider( final String location )
{
m_location = location;
}
/**
* Return the filename of the logging target.
* @return the filename
*/
public String getLocation()
{
return m_location;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/model/KernelDescriptor.java
Index: KernelDescriptor.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.kernel.model;
import org.apache.avalon.framework.logger.Logger;
import org.apache.excalibur.merlin.assembly.ProfileManager;
import org.apache.excalibur.merlin.container.model.ContainerDescriptor;
import org.apache.excalibur.merlin.container.model.ClasspathDescriptor;
import org.apache.excalibur.merlin.container.model.ExtensionsDescriptor;
import org.apache.excalibur.merlin.container.model.Parent;
import org.apache.excalibur.merlin.kernel.model.LoggingDescriptor;
/**
* Kernel creation directive that includes a root container, an extensions
directive,
* common application level classpath directive and logigng category
descriptors.
*
* <p><b>XML</b></p>
* A kernel element may contain a logging defintion, extensions element, and
classpath
* element. A kernel element must contain a single root container
element.</p>
* <pre>
* <font color="gray"><i><!--
* Definition of a kernel.
* --></i></font>
*
* <kernel>
*
* <font color="gray"><i><!--
* Logging targets and defaults.
* --></i></font>
*
* <logging priority="<font color="darkred">INFO</font>"
target="<font color="darkred">kernel</font>">
* <target name="<font color="darkred">kernel</font>">
* <file location="<font color="darkred">kernel.log</font>" />
* </target>
* </logging>
*
* <font color="gray"><i><!--
* Declaration of loggin categories within the scope of the kernel.
* --></i></font>
*
* <categories priority="<font color="darkred">WARN</font>">
* <category name="<font color="darkred">logging</font>"/>
* <category name="<font color="darkred">loader</font>"/>
* <category name="<font color="darkred">installer</font>"/>
* </categories>
*
* <font color="gray"><i><!--
* Declaration of the extensions directories.
* --></i></font>
*
* <extensions>
* <dirset dir="<font color="darkred">.</font>">
* <include name="<font color="darkred">extensions</font>"/>
* <include name="<font color="darkred">lib</font>"/>
* </dirset>
* </extensions>
*
* <font color="gray"><i><!--
* Common application classpath declaration.
* --></i></font>
*
* <classpath>
* <fileset dir="<font color="darkred">dist</font>">
* <include name="<font
color="darkred">new-application-1.0.jar</font>"/>
* </fileset>
* </classpath>
*
* <font color="gray"><i><!--
* Single root container declaration.
* --></i></font>
*
* <container name="<font color="darkred">child</font>">
* <classpath>
* <fileset dir="<font color="darkred">dist</font>">
* <include name="<font color="darkred">demo.jar</font>"/>
* </fileset>
* </classpath>
* <component name="<font color="darkred">demo-component</font>"
class="<font
color="darkred">org.apache.excalibur.playground.BasicComponent</font>">
* <categories priority="<font color="darkred">WARN</font>">
* <category name="<font color="darkred">cache</font>"/>
* <category name="<font color="darkred">store</font>"/>
* </categories>
* <context>
* <entry name="<font color="darkred">location</font>"
value="<font color="darkred">Paris</font>"/>
* </context>
* </component>
* <container>
* <font color="gray"><i><!-- Etc., etc. --></i></font>
* </container>
* </container>
*
* </kernel>
* </pre>
*
* @see ClasspathDescriptor
* @see ExtensionsDescriptor
* @see LoggingDescriptor
* @see ContainerDescriptor
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:32 $
*/
public class KernelDescriptor extends Parent
{
/**
* The root container.
*/
private ContainerDescriptor m_container;
/**
* Create a KernelDescriptor instance.
*
* @param name the kernel name
* @param logging the logging manager
* @param manager the type manager
* @param container the root container
*/
public KernelDescriptor( final String name,
final Logger logger,
final ProfileManager manager )
{
super( null, manager, name, logger );
}
/**
* Return the root container.
*
* @return the root [EMAIL PROTECTED] ContainerDescriptor}.
*/
public ContainerDescriptor getContainer()
{
return m_container;
}
/**
* Set the root container.
*
* @param container [EMAIL PROTECTED] ContainerDescriptor}.
*/
public void setContainer( ContainerDescriptor container )
{
m_container = container;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/model/LoggingDescriptor.java
Index: LoggingDescriptor.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.kernel.model;
import java.io.Serializable;
import org.apache.excalibur.merlin.model.Category;
/**
* Description of a top level logging environment.
*
* <p><b>XML</b></p>
* <p>A logging element declares the top level defaults for priority and
target name, a set of
* targets to which logging events shall be directed.
* The logging element declares the application wide default logging
priority.
* A target element enables defintion of a logging file to which log entries
will
* be directed. The target name attribute is the name referenced by category
elements
* defined within the loggers element. The priority attribute may container
one of the values
* <code>DEBUG</code>, <code>INFO</code>, <code>WARN</code> or
<code>ERROR</code>.
* The target must contain a single file element with the attribute
<code>location</code>
* the corresponds to the name of the logging file.</p>
*
* <pre>
* <font color="gray"><i><!--
* Definition of a logging system.
* --></i></font>
*
* <logging name="" priority="<font color="darkred">INFO</font>"
target="<font color="darkred">kernel</font>">
* <target name="<font color="darkred">kernel</font>">
* <file location="<font color="darkred">kernel.log</font>" />
* </target>
* </logging>
* </pre>
*
* @see TargetDescriptor
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:32 $
*/
public final class LoggingDescriptor extends Category implements Serializable
{
/**
* The dependencies keyed by role name.
*/
private final TargetDescriptor[] m_targets;
/**
* Create a LoggingDescriptor instance.
*
* @param root the root logger category name
* @param priority the default logging priority
* @param target the default logging target
* @param targets the set of logging targets
*/
public LoggingDescriptor( final String root,
final String priority,
final String target,
final TargetDescriptor[] targets )
{
super( root, priority, target );
m_targets = targets;
}
/**
* Return the set of logging target descriptors.
*
* @return the target descriptors
*/
public TargetDescriptor[] getTargetDescriptors()
{
return m_targets;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/model/TargetDescriptor.java
Index: TargetDescriptor.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.kernel.model;
import java.io.Serializable;
/**
* A logging target descriptor.
*
* <p><b>XML</b></p>
* A logging target declares target name and a mechanism.</p>
*
* <pre>
* <target name="<font color="darkred">kernel</font>">
* <file location="<font color="darkred">kernel.log</font>" />
* </target>
* </pre>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:32 $
*/
public final class TargetDescriptor implements Serializable
{
/**
* The target name.
*/
private final String m_name;
/**
* The target provider descriptor.
*/
private final TargetProvider m_provider;
/**
* Create a LoggingDescriptor instance.
*
* @param name the target name
* @param provider the target provider description
*/
public TargetDescriptor( final String name,
final TargetProvider provider )
{
m_name = name;
m_provider = provider;
}
/**
* Return the target name.
*
* @return the target name.
*/
public String getName()
{
return m_name;
}
/**
* Return the target provider descriptor
*
* @return the provider descriptor
*/
public TargetProvider getProvider()
{
return m_provider;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/model/TargetProvider.java
Index: TargetProvider.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.kernel.model;
import java.io.Serializable;
/**
* Abstract logging target provider type. This is an emty abstract class
from
* all logging providers must inherit.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:32 $
*/
public abstract class TargetProvider implements Serializable
{
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/model/package.html
Index: package.html
===================================================================
<body>
<p>
The <code>model</code> package contains the formal meta data model extensions
supporting the declaration of a kernel, its logging infrasturcture, and root
container.
</p>
</body>
1.3 +1 -2
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Category.java
Index: Category.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Category.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Category.java 26 Jul 2002 06:17:04 -0000 1.2
+++ Category.java 29 Jul 2002 06:14:32 -0000 1.3
@@ -66,7 +66,6 @@
* @param priority the category priority - DEBUG, INFO, WARN, or ERROR
* @param target the name of a logging category target
*
- * @see TargetDescriptor
*/
public Category(
final String name, final String priority, final String target )
1.11 +10 -10
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.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Profile.java 26 Jul 2002 06:17:04 -0000 1.10
+++ Profile.java 29 Jul 2002 06:14:32 -0000 1.11
@@ -114,9 +114,9 @@
private final String m_name;
/**
- * The profile assigned logger.
+ * The assigned logging categories.
*/
- private final Logger m_logger;
+ private final CategoriesDescriptor m_categories;
/**
* The dependencies keyed by role name.
@@ -176,7 +176,7 @@
final Parameters parameters,
final Configuration configuration,
final ContextDirective context,
- final Logger logger,
+ final CategoriesDescriptor categories,
final Type type,
final boolean enabled,
final boolean activation,
@@ -193,12 +193,12 @@
if( null == type )
throw new NullPointerException( "type" );
- if( null == logger )
- throw new NullPointerException( "logger" );
+ if( null == categories )
+ throw new NullPointerException( "categories" );
m_parameters = parameters;
m_configuration = configuration;
- m_logger = logger;
+ m_categories = categories;
m_type = type;
m_context = context;
m_enabled = enabled;
@@ -238,13 +238,13 @@
}
/**
- * Return the logger for the profile.
+ * Return the logging categories for the profile.
*
* @return the logger
*/
- public Logger getLogger()
+ public CategoriesDescriptor getCategories()
{
- return m_logger;
+ return m_categories;
}
/**
1.2 +12 -1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/ResourceDesignator.java
Index: ResourceDesignator.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/ResourceDesignator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ResourceDesignator.java 18 Jul 2002 03:38:12 -0000 1.1
+++ ResourceDesignator.java 29 Jul 2002 06:14:32 -0000 1.2
@@ -18,6 +18,11 @@
public interface ResourceDesignator
{
+ static final int NOT_STARTED = 0;
+ static final int STARTED = 1;
+ static final int STOPPED = 2;
+
+
/**
* Returns the designated resource path.
*
@@ -52,5 +57,11 @@
* @return the profile
*/
Profile getProfile();
+
+ /**
+ * Returns the active state of the resoruce.
+ * @return one of the values NOT_STARTED, STARTED, or STOPPED
+ */
+ int getState();
}
1.3 +1 -1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/package.html
Index: package.html
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/package.html,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- package.html 12 Jul 2002 19:09:27 -0000 1.2
+++ package.html 29 Jul 2002 06:14:32 -0000 1.3
@@ -1,7 +1,7 @@
<body>
<p>
-The <code>model</code> package contains the formal meta data model for the
Merlin kernel, container and profile abstractions. These classes define the
criteria for creation of new containers, component and factory profiles,
classloaders, extensions, and the kernel itself.
+The <code>model</code> package contains the formal profile meta data model.
These classes define the criteria used to populate a Profile, including context
management, confuration management, logging category management and extension
and lifecycle phase management.
</p>
<h3>Object Model (UML)</h3>
1.4 +7 -9
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/ProfileBuilder.java
Index: ProfileBuilder.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/ProfileBuilder.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ProfileBuilder.java 25 Jul 2002 18:07:16 -0000 1.3
+++ ProfileBuilder.java 29 Jul 2002 06:14:33 -0000 1.4
@@ -18,8 +18,6 @@
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.builder.TypeBuilder;
import org.apache.excalibur.merlin.model.Profile;
-import org.apache.excalibur.merlin.model.ContainerDescriptor;
-import org.xml.sax.InputSource;
/**
* A ProfileBuilder is responsible for building [EMAIL PROTECTED] Profile}
@@ -38,21 +36,21 @@
/**
* Build Profile from the XML descriptor format.
*
- * @param classname The classname of Component
- * @param classLoader the ClassLoader to load info from
- * @return the created Type
+ * @param loader the ClassLoader to load info from
+ * @param type the Type on which the profile is based
+ * @return the created Profile
* @throws Exception if an error occurs
*/
- public Profile[] build( ContainerDescriptor container, Type type )
+ public Profile[] build( ClassLoader loader, Type type )
throws Exception
{
final String xprofile =
type.getInfo().getImplementationKey().replace( '.', '/' ) +
".xprofile";
final InputStream inputStream =
- container.getTypeManager().getResourceAsStream( xprofile );
+ loader.getResourceAsStream( xprofile );
final ProfileCreator creator = getXMLProfileCreator( xprofile );
- return creator.createProfiles( container, type, inputStream );
+ return creator.createProfiles( loader, type, inputStream );
}
1.4 +3 -4
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/ProfileCreator.java
Index: ProfileCreator.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/ProfileCreator.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ProfileCreator.java 25 Jul 2002 18:07:16 -0000 1.3
+++ ProfileCreator.java 29 Jul 2002 06:14:33 -0000 1.4
@@ -11,7 +11,6 @@
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.merlin.model.Profile;
-import org.apache.excalibur.merlin.model.ContainerDescriptor;
/**
* Simple interface used to create [EMAIL PROTECTED] Profile}
@@ -30,7 +29,7 @@
* @return the newly created [EMAIL PROTECTED] Type}
* @throws Exception
*/
- Profile[] createProfiles( ContainerDescriptor container, Type type,
InputStream inputStream )
+ Profile[] createProfiles( ClassLoader loader, Type type, InputStream
inputStream )
throws Exception;
/**
@@ -40,7 +39,7 @@
* @return the profile
* @exception Exception if an error occurs during profile creation
*/
- Profile createProfile( ContainerDescriptor container, Type type,
Configuration config )
+ Profile createProfile( ClassLoader loader, Type type, Configuration
config )
throws Exception;
}
1.11 +27 -21
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/XMLProfileCreator.java
Index: XMLProfileCreator.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/XMLProfileCreator.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- XMLProfileCreator.java 25 Jul 2002 18:07:16 -0000 1.10
+++ XMLProfileCreator.java 29 Jul 2002 06:14:33 -0000 1.11
@@ -24,7 +24,6 @@
import org.apache.excalibur.meta.info.builder.XMLTypeCreator;
import org.apache.excalibur.meta.ConfigurationBuilder;
import org.apache.excalibur.merlin.model.Profile;
-import org.apache.excalibur.merlin.model.ContainerDescriptor;
import org.apache.excalibur.merlin.model.Category;
import org.apache.excalibur.merlin.model.CategoriesDescriptor;
import org.apache.excalibur.merlin.model.ContextDirective;
@@ -60,18 +59,18 @@
* @throws ConfigurationException if an error occurs
*/
public Profile[] createProfiles(
- ContainerDescriptor container, Type type, InputStream inputStream )
+ ClassLoader loader, Type type, InputStream inputStream )
throws Exception
{
if( inputStream != null )
{
final InputSource input = new InputSource( inputStream );
final Configuration configuration = ConfigurationBuilder.build(
input );
- return createPackagedProfiles( container, type, configuration );
+ return createPackagedProfiles( loader, type, configuration );
}
else
{
- Profile profile = createImplicitProfile( container, type );
+ Profile profile = createImplicitProfile( loader, type );
return new Profile[]{ profile };
}
}
@@ -84,10 +83,10 @@
* @exception Exception if an error occurs during profile creation
*/
public Profile createProfile(
- ContainerDescriptor container, Type type, Configuration config )
+ ClassLoader loader, Type type, Configuration config )
throws Exception
{
- return buildProfile( container, type, config, Profile.EXPLICIT );
+ return buildProfile( loader, type, config, Profile.EXPLICIT );
}
/**
@@ -100,25 +99,25 @@
* @throws ConfigurationException if an error occurs
*/
private Profile[] createPackagedProfiles(
- ContainerDescriptor container, Type type, final Configuration info )
+ ClassLoader loader, Type type, final Configuration info )
throws Exception
{
Vector vector = new Vector();
Configuration[] profiles = info.getChildren("component");
if( profiles.length == 0 )
{
- Profile profile = createImplicitProfile( container, type );
+ Profile profile = createImplicitProfile( loader, type );
return new Profile[]{ profile };
}
for( int i=0; i<profiles.length; i++ )
{
- vector.add( buildProfile( container, type, profiles[i],
Profile.PACKAGED ) );
+ vector.add( buildProfile( loader, type, profiles[i],
Profile.PACKAGED ) );
}
return (Profile[]) vector.toArray( new Profile[0] );
}
private Profile buildProfile(
- ContainerDescriptor container, Type type, Configuration profile, int
mode )
+ ClassLoader loader, Type type, Configuration profile, int mode )
throws Exception
{
@@ -128,9 +127,10 @@
Logger logger;
final String name = profile.getAttribute("name");
- CategoriesDescriptor categories = createCategoriesDescriptor( name,
profile.getChild("categories") );
- container.addCategories( categories );
- logger = container.getLogger().getChildLogger( name );
+ CategoriesDescriptor categories =
+ createCategoriesDescriptor( name, profile.getChild("categories") );
+ //container.addCategories( categories );
+ //logger = container.getLogger().getChildLogger( name );
//
// build the profile directives
@@ -140,14 +140,14 @@
final boolean activation = profile.getAttributeAsBoolean(
"activation", false );
final Parameters params = Parameters.fromConfiguration(
profile.getChild("parameters") );
final ContextDirective context = createContextDirective(
profile.getChild("context") );
- final Configuration config = createConfiguration(
- container.getTypeManager(), type,
profile.getChild("configuration") );
+ final Configuration config =
+ createConfiguration( loader, type,
profile.getChild("configuration") );
//
// create the profile instance
//
- return new Profile( name, params, config, context, logger, type,
enabled, activation, mode );
+ return new Profile( name, params, config, context, categories, type,
enabled, activation, mode );
}
public Configuration createConfiguration( ClassLoader loader, Type type,
Configuration config )
@@ -308,17 +308,23 @@
}
private Profile createImplicitProfile(
- ContainerDescriptor container, Type type ) throws Exception
+ ClassLoader loader, Type type ) throws Exception
{
- Logger logger = container.getLogger().getChildLogger(
type.getInfo().getName() );
ContextDirective context = new ContextDirective(
ContextDirective.DEFAULT_CONTEXT_CLASS, new Import[0], new
Entry[0] );
- final Configuration defaults = type.getDefaultConfiguration(
container.getTypeManager() );
+ final Configuration defaults = type.getDefaultConfiguration( loader
);
+ final CategoriesDescriptor categories =
createDefaultCategoriesDescriptor( type );
return new Profile(
- type.getInfo().getName(), null, defaults, context, logger, type,
true, false,
+ type.getInfo().getName(), null, defaults, context, categories,
type, true, false,
Profile.IMPLICIT
);
+ }
+
+ private CategoriesDescriptor createDefaultCategoriesDescriptor( Type
type )
+ {
+ final String name = type.getInfo().getName();
+ return new CategoriesDescriptor( name, null, null, new Category[0] );
}
1.4 +5 -5
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/verifier/AssemblyVerifier.java
Index: AssemblyVerifier.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/verifier/AssemblyVerifier.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AssemblyVerifier.java 18 Jul 2002 03:40:11 -0000 1.3
+++ AssemblyVerifier.java 29 Jul 2002 06:14:33 -0000 1.4
@@ -16,7 +16,7 @@
import org.apache.excalibur.meta.verifier.VerifyException;
import org.apache.excalibur.meta.info.DependencyDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
-import org.apache.excalibur.meta.info.ServiceDesignator;
+import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.Association;
@@ -251,7 +251,7 @@
{
final String providerName = roles[ i
].getProvider().getProfile().getName();
final String roleName = roles[ i ].getRole();
- final ServiceDesignator service =
+ final ReferenceDescriptor service =
info.getDependency( roleName ).getService();
//Get the other component that is providing service
@@ -450,12 +450,12 @@
* @return true if candidate services contains a service that matches
* specified service, false otherwise
*/
- protected boolean hasMatchingService( final ServiceDesignator service,
+ protected boolean hasMatchingService( final ReferenceDescriptor service,
final ServiceDescriptor[]
candidates )
{
for( int i = 0; i < candidates.length; i++ )
{
- final ServiceDesignator other = candidates[ i ].getService();
+ final ReferenceDescriptor other = candidates[ i ].getService();
if( service.matches( other ) )
{
return true;
1.3 +3 -3
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/verifier/MetaDataVerifier.java
Index: MetaDataVerifier.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/verifier/MetaDataVerifier.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- MetaDataVerifier.java 12 Jul 2002 19:09:28 -0000 1.2
+++ MetaDataVerifier.java 29 Jul 2002 06:14:33 -0000 1.3
@@ -18,7 +18,7 @@
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.ContextDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
-import org.apache.excalibur.meta.info.ServiceDesignator;
+import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.verifier.VerifyException;
import org.apache.excalibur.meta.verifier.ComponentVerifier;
@@ -198,7 +198,7 @@
final Class[] classes = new Class[ services.length ];
for( int i = 0; i < services.length; i++ )
{
- final ServiceDesignator service = services[ i ].getService();
+ final ReferenceDescriptor service = services[ i ].getService();
final String classname = service.getClassname();
try
{
1.3 +53 -14
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.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- componentinfo.dtd 26 Jul 2002 16:29:10 -0000 1.2
+++ componentinfo.dtd 29 Jul 2002 06:14:33 -0000 1.3
@@ -21,6 +21,15 @@
-->
<!--
+Updated to allow
+1. declaration of lifecycle phase dependecies and addition of phase
dependecies to
+ the main type
+2. usage of the reference element in preference to service-ref (where
reference is an
+ equivalent structure to service-ref than can be used in phase
dependecies, service
+ provision declaration, and service dependecies.
+-->
+
+<!--
The component-info is the document root, it defines:
component the specifc details about this component
@@ -31,7 +40,7 @@
dependencies the lifecycle phases that this component manages
-->
-<!ELEMENT component-info (component, loggers?, context?, services?,
dependencies?, phases?)>
+<!ELEMENT component-info (component, loggers?, context?, services?,
dependencies?, phases?, extensions?)>
<!--
!ATTLIST component-info id ID #IMPLIED
xmlns CDATA #FIXED
"http://jakarta.apache.org/avalon/componentinfo_1_0.dtd"
@@ -78,7 +87,8 @@
service-ref the reference to service.
attributes Optional attributes about service
-->
-<!ELEMENT service (service-ref,attributes?) >
+<!ENTITY % ref "(service-ref|reference)">
+<!ELEMENT service (%ref;,attributes?) >
<!--
The service element defines a reference to a service that the component
@@ -96,34 +106,63 @@
version CDATA #IMPLIED >
<!--
-The service dependency describes a service that the component
-requires. It defines:
+The reference element defines a reference to a versioned interface.
+It defines:
-role the role of the service. This is the value that is used to
lookup the
- service in the ComponentManager. If not provided it defaults to
the
- value specified in the name attribute of service element
-service-ref the service that is required
+type the class of the interface. This must be equal to the class
name of the
+ interface.
+version the version of the interface in (in the format #.#.#, #.# or #
where
+ # is a integer
-->
-<!ELEMENT dependency (role?,service-ref,attributes?) >
- <!ATTLIST dependency optional CDATA #IMPLIED >
- <!ELEMENT role (#PCDATA) >
+<!ELEMENT reference EMPTY >
+ <!ATTLIST reference
+ type CDATA #REQUIRED
+ version CDATA #IMPLIED >
+
+<!--
+The extension element defines a lifecycle extension phase supplied by a type:
+
+name the extension name.
+reference the version lifecycle interface supported
+attributes Optional attributes about the extension
+-->
+<!ELEMENT extension (name,reference,attributes?)>
+ <!ATTLIST extension >
<!--
The phase element defines a lifecycle extension phase that this component
provides.
It contains:
name the phase name.
-interface the client interface phase class element
+interface the client interface phase dependency
attributes Optional attributes about phase
-->
-<!ELEMENT phase (name,attributes?)>
- <!ATTLIST phase type CDATA #REQUIRED >
+<!ELEMENT phase (reference,attributes?)>
<!--
The phases element contains a list of phases that this component provides.
It contains phase elements.
-->
<!ELEMENT phases (phase*)>
+
+<!--
+The extensions element contains a list of phases that this component
requires.
+It contains phase elements.
+-->
+<!ELEMENT extensions (extension*)>
+
+<!--
+The service dependency describes a service that the component
+requires. It defines:
+
+role the role of the service. This is the value that is used to
lookup the
+ service in the ComponentManager. If not provided it defaults to
the
+ value specified in the name attribute of service element
+service-ref the service that is required
+-->
+<!ELEMENT dependency (role?,%ref;,attributes?) >
+ <!ATTLIST dependency optional CDATA #IMPLIED >
+ <!ELEMENT role (#PCDATA) >
<!--
1.2 +6 -6
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/DependencyDescriptor.java
Index: DependencyDescriptor.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/DependencyDescriptor.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DependencyDescriptor.java 5 Jul 2002 10:39:00 -0000 1.1
+++ DependencyDescriptor.java 29 Jul 2002 06:14:33 -0000 1.2
@@ -45,7 +45,7 @@
/**
* The service class/interface that the dependency must provide.
*/
- private final ServiceDesignator m_service;
+ private final ReferenceDescriptor m_service;
/**
* True if dependency is optional, false otherwise.
@@ -56,7 +56,7 @@
* Constructor a dependency sans Attributes.
*/
public DependencyDescriptor( final String role,
- final ServiceDesignator service )
+ final ReferenceDescriptor service )
{
this( role, service, false, null );
}
@@ -65,7 +65,7 @@
* Constructor that has all parts sans parent.
*/
public DependencyDescriptor( final String role,
- final ServiceDesignator service,
+ final ReferenceDescriptor service,
final boolean optional,
final Properties attributes )
{
@@ -100,10 +100,10 @@
* Return the service class/interface descriptor that describes the
* dependency must fulfilled by a provider.
*
- * @return a reference to service descriptor that describes the
fulfillment
+ * @return a reference to service reference that describes the
fulfillment
* obligations that must be met by a service provider.
*/
- public ServiceDesignator getService()
+ public ReferenceDescriptor getService()
{
return m_service;
}
1.2 +12 -33
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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- PhaseDescriptor.java 26 Jul 2002 16:29:10 -0000 1.1
+++ PhaseDescriptor.java 29 Jul 2002 06:14:33 -0000 1.2
@@ -15,27 +15,21 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision$ $Date$
*/
-public final class PhaseDescriptor extends Descriptor
+public class PhaseDescriptor extends Descriptor
{
/**
- * The name of the lifecycle phase.
- */
- private final String m_name;
-
- /**
* The interface that represents the client view of the lifecycle phase.
*/
- private final String m_type;
+ private final ReferenceDescriptor m_reference;
/**
* Constructor a phase descriptor without attributes.
* @param name the phase name
* @param interface the phase type
*/
- public PhaseDescriptor( final String name,
- final String type )
+ public PhaseDescriptor( final ReferenceDescriptor reference )
{
- this( name, type, null );
+ this( reference, null );
}
/**
@@ -43,39 +37,24 @@
* @param name the phase name
* @param interface the phase type
*/
- public PhaseDescriptor( final String name,
- final String type,
+ public PhaseDescriptor( final ReferenceDescriptor reference,
final Properties attributes )
{
super( attributes );
- if( null == name )
- throw new NullPointerException( "name" );
- if( null == type )
- throw new NullPointerException( "type" );
-
- m_name = name;
- m_type = type;
- }
+ if( null == reference )
+ throw new NullPointerException( "reference" );
- /**
- * Return the name of the lifecycle phase.
- *
- * @return the name the lifecycle phase.
- */
- public String getName()
- {
- return m_name;
+ m_reference = reference;
}
/**
- * Return the classname of the interface for the lifecycle phase.
+ * Return the version interface reference.
*
- * @return the classname of the interface implemented by client
components
- * that the extension supports.
+ * @return the version interface reference.
*/
- public String getClassname()
+ public ReferenceDescriptor getReference()
{
- return m_type;
+ return m_reference;
}
}
1.3 +8 -8
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/ServiceDescriptor.java
Index: ServiceDescriptor.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/ServiceDescriptor.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ServiceDescriptor.java 8 Jul 2002 01:14:02 -0000 1.2
+++ ServiceDescriptor.java 29 Jul 2002 06:14:33 -0000 1.3
@@ -39,14 +39,14 @@
/**
* The service reference that descriptor is describing.
*/
- private final ServiceDesignator m_designator;
+ private final ReferenceDescriptor m_designator;
/**
- * Construct a service descriptor for specified ServiceDesignator.
+ * Construct a service descriptor for specified ReferenceDescriptor
*
- * @param designator the ServiceDesignator
+ * @param service reference
*/
- public ServiceDescriptor( final ServiceDesignator designator )
+ public ServiceDescriptor( final ReferenceDescriptor designator )
{
this( designator, null );
}
@@ -54,10 +54,10 @@
/**
* Construct a service with specified name, version and attributes.
*
- * @param designator the ServiceDesignator
+ * @param designator the ReferenceDescriptor
* @param attributes the attributes of service
*/
- public ServiceDescriptor( final ServiceDesignator designator,
+ public ServiceDescriptor( final ReferenceDescriptor designator,
final Properties attributes )
{
super( attributes );
@@ -75,7 +75,7 @@
*
* @return the service that service descriptor refers to.
*/
- public ServiceDesignator getService()
+ public ReferenceDescriptor getService()
{
return m_designator;
}
1.7 +43 -4
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/Type.java
Index: Type.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/Type.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Type.java 20 Jul 2002 00:54:07 -0000 1.6
+++ Type.java 29 Jul 2002 06:14:33 -0000 1.7
@@ -11,14 +11,14 @@
import org.xml.sax.InputSource;
import java.io.InputStream;
+import org.apache.avalon.framework.configuration.Configuration;
import org.apache.excalibur.meta.ConfigurationBuilder;
import org.apache.excalibur.meta.info.ComponentDescriptor;
import org.apache.excalibur.meta.info.ContextDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
import org.apache.excalibur.meta.info.LoggerDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
-import org.apache.excalibur.meta.info.ServiceDesignator;
-import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.excalibur.meta.info.PhaseDescriptor;
/**
* This class contains the meta information about a particular
@@ -31,8 +31,12 @@
* <li>the services that this component type is capable of providing</li>
* <li>the services that this component type requires to operate (and the
* names via which services are accessed)</li>
+ * <li>extended lifecycle phases that this component uses</li>
* </ul>
*
+ * <p><b>UML</b></p>
+ * <p><image src="doc-files/Type.gif" border="0"/></p>
+ *
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision$ $Date$
@@ -44,6 +48,7 @@
private final ServiceDescriptor[] m_services;
private final DependencyDescriptor[] m_dependencies;
private final LoggerDescriptor[] m_loggers;
+ private final PhaseDescriptor[] m_phases;
private transient Configuration m_configuration;
private transient boolean m_loaded = false;
@@ -55,7 +60,8 @@
final LoggerDescriptor[] loggers,
final ContextDescriptor context,
final ServiceDescriptor[] services,
- final DependencyDescriptor[] dependencies )
+ final DependencyDescriptor[] dependencies,
+ final PhaseDescriptor[] phases )
{
if( null == descriptor )
{
@@ -77,11 +83,16 @@
{
throw new NullPointerException( "dependencies" );
}
+ if( null == phases )
+ {
+ throw new NullPointerException( "phases" );
+ }
m_descriptor = descriptor;
m_loggers = loggers;
m_context = context;
m_services = services;
m_dependencies = dependencies;
+ m_phases = phases;
}
/**
@@ -105,6 +116,24 @@
}
/**
+ * Return TRUE if the set of Logger descriptors includes the supplied
name.
+ *
+ * @param name the logging subcategory name
+ * @return TRUE if the logging subcategory is declared.
+ */
+ public boolean isaLogger( String name )
+ {
+ LoggerDescriptor[] loggers = getLoggers();
+ for( int i=0; i<loggers.length; i++ )
+ {
+ LoggerDescriptor logger = loggers[i];
+ if( logger.getName().equals( name ) )
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Return the ContextDescriptor for component, may be null.
* If null then this component does not implement Contextualizable.
*
@@ -179,6 +208,16 @@
m_loaded = true;
}
return m_configuration;
+ }
+
+ /**
+ * Return the lifecycle phases extensions required by this extension.
+ *
+ * @return an array of phase descriptors.
+ */
+ public PhaseDescriptor[] getPhases()
+ {
+ return m_phases;
}
/**
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/ExtensionDescriptor.java
Index: ExtensionDescriptor.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.meta.info;
import java.util.Properties;
/**
* A descriptor that describes a name and inteface of a lifecycle phase.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:33 $
*/
public final class ExtensionDescriptor extends PhaseDescriptor
{
/**
* The name of the lifecycle phase.
*/
private final String m_name;
/**
* Constructor a phase descriptor without attributes.
* @param name the phase name
* @param interface the phase type
*/
public ExtensionDescriptor( final String name,
final ReferenceDescriptor reference )
{
this( name, reference, null );
}
/**
* Constructor a phase descriptor with attributes.
* @param name the phase name
* @param interface the phase type
*/
public ExtensionDescriptor( final String name,
final ReferenceDescriptor reference,
final Properties attributes )
{
super( reference, attributes );
if( null == name )
throw new NullPointerException( "name" );
m_name = name;
}
/**
* Return the name of the lifecycle phase.
*
* @return the name the lifecycle phase.
*/
public String getName()
{
return m_name;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/Facility.java
Index: Facility.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.meta.info;
import java.io.Serializable;
import org.xml.sax.InputSource;
import java.io.InputStream;
import org.apache.excalibur.meta.ConfigurationBuilder;
import org.apache.excalibur.meta.info.ComponentDescriptor;
import org.apache.excalibur.meta.info.ContextDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
import org.apache.excalibur.meta.info.LoggerDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.avalon.framework.configuration.Configuration;
/**
* This class contains the meta information about a particular
* container facility. A facility is a component that can act as extension
* provider towards a container. Facilities may provide multiple lifecyle
* extensions, or may may simply provide functional services usable by a
* container in relation to the contains support of the components it is
* managing.
*
* <p><b>UML</b></p>
* <p><image src="doc-files/Facility.gif" border="0"/></p>
*
* @see Type
* @see ExtensionDescriptor
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:33 $
*/
public class Facility extends Type
{
private final ExtensionDescriptor[] m_extensions;
/**
* Basic constructor that takes as parameters all parts.
*/
public Facility( final ComponentDescriptor descriptor,
final LoggerDescriptor[] loggers,
final ContextDescriptor context,
final ServiceDescriptor[] services,
final DependencyDescriptor[] dependencies,
final PhaseDescriptor[] phases,
final ExtensionDescriptor[] extensions )
{
super( descriptor, loggers, context, services, dependencies, phases );
if( null == extensions )
{
throw new NullPointerException( "extensions" );
}
m_extensions = extensions;
}
/**
* Return the phases supported by this extension.
*
* @return an array of phase descriptors.
*/
public ExtensionDescriptor[] getExtensions()
{
return m_extensions;
}
/**
* Return a string representation of the type.
* @return the stringified type
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
ExtensionDescriptor[] extensions = getExtensions();
for( int i=0; i<extensions.length; i++ )
{
buffer.append( extensions[i].getName() );
if( i<(extensions.length -1) )
buffer.append( ", " );
}
return "Extension name: " + getInfo().getName() + " extensions: " +
buffer.toString();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/ReferenceDescriptor.java
Index: ReferenceDescriptor.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.meta.info;
import java.io.Serializable;
import org.apache.avalon.framework.Version;
/**
* This reference defines the type of interface required
* by a component. The type corresponds to the class name of the
* interface implemented by component. Associated with each
* classname is a version object so that different versions of same
* interface can be represented.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:33 $
*/
public final class ReferenceDescriptor
implements Serializable
{
/**
* The name of service class.
*/
private final String m_classname;
/**
* The version of service class.
*/
private final Version m_version;
/**
* Construct a service with specified name, version and attributes.
*
* @param classname the name of the service
* @param version the version of service
*/
public ReferenceDescriptor( final String classname,
final Version version )
{
if( null == classname )
{
throw new NullPointerException( "classname" );
}
if( null == version )
{
throw new NullPointerException( "version" );
}
m_classname = classname;
m_version = version;
}
/**
* Return classname of interface this reference refers to.
*
* @return the classname of the Service
*/
public String getClassname()
{
return m_classname;
}
/**
* Return the version of interface.
*
* @return the version of interface
*/
public Version getVersion()
{
return m_version;
}
/**
* Determine if specified service will match this service.
* To match a service has to have same name and must comply with version.
*
* @param other the other ServiceInfo
* @return true if matches, false otherwise
*/
public boolean matches( final ReferenceDescriptor other )
{
return
other.getClassname().equals( getClassname() ) &&
other.getVersion().complies( getVersion() );
}
/**
* Convert to a string of format name/version
*
* @return string describing service
*/
public String toString()
{
return getClassname() + "/" + getVersion();
}
}
1.3 +4 -4
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/Resources.properties
Index: Resources.properties
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/Resources.properties,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Resources.properties 26 Jul 2002 16:29:11 -0000 1.2
+++ Resources.properties 29 Jul 2002 06:14:34 -0000 1.3
@@ -1,10 +1,10 @@
builder.redundent-role.notice=Warning: Type for class {0} redundently
specifies role name "{1}" in dependency when it is identical to the name of
service. It is recomended that the <role/> section be elided.
-builder.creating-info.notice=Creating a Type for class "{0}".
-builder.created-info.notice=Constructed Type object for class {0}.
ComponentInfo contains {1} services, {2} dependencies, {3} context entrys and
{4} loggers.
+builder.creating-info.notice=Creating a Type from class "{0}".
+builder.created-info.notice=Constructed Type from class {0} with {1}
services, {2} dependencies, {3} context entries, {4} loggers, and {5} extended
phases depedencies.
builder.bad-toplevel-element.error=Error the component implemented by "{0}"
has an invalid element at top level of component info descriptor. Expected:
"component-info". Actual: "{1}"
builder.missing-info.error=Unable to locate resource from which to load info
for component implemented by class "{0}".
builder.missing-xml-creator.error=Unable to create XMLTypeCreator, usually
due to not having XML classes on Classpath. Thus unable to lookup XML
descriptor for component type "{0}".
-builder.creating-extension.notice=Creating a Extension for class "{0}".
-builder.created-extension.notice=Constructed Extension object for class {0}
with {1} services, {2} dependencies, {3} context entries, and {4} phases.
+builder.creating-facility.notice=Creating a Facility from class "{0}".
+builder.created-facility.notice=Constructed Facility from class {0} with {1}
services, {2} dependencies, {3} context entries, {4} loggers, {5} extended
phases dependecies, and {6} phase extensions.
1.6 +64 -32
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.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- XMLTypeCreator.java 26 Jul 2002 16:29:11 -0000 1.5
+++ XMLTypeCreator.java 29 Jul 2002 06:14:34 -0000 1.6
@@ -24,7 +24,8 @@
import org.apache.excalibur.meta.info.EntryDescriptor;
import org.apache.excalibur.meta.info.LoggerDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
-import org.apache.excalibur.meta.info.ServiceDesignator;
+import org.apache.excalibur.meta.info.ReferenceDescriptor;
+import org.apache.excalibur.meta.info.PhaseDescriptor;
import org.apache.excalibur.meta.ConfigurationBuilder;
import org.xml.sax.InputSource;
@@ -98,6 +99,10 @@
Configuration configuration = null;
+ configuration = info.getChild( "component" );
+ final ComponentDescriptor descriptor =
+ buildComponentDescriptor( classname, configuration );
+
configuration = info.getChild( "loggers" );
final LoggerDescriptor[] loggers = buildLoggers( configuration );
@@ -110,11 +115,10 @@
configuration = info.getChild( "dependencies" );
final DependencyDescriptor[] dependencies = buildDependencies(
classname, configuration );
- configuration = info.getChild( "component" );
- final ComponentDescriptor descriptor =
- buildComponentDescriptor( classname, configuration );
+ configuration = info.getChild( "phases" );
+ final PhaseDescriptor[] phases = buildPhases( configuration );
- if( getLogger().isDebugEnabled() )
+ if( getLogger().isInfoEnabled() )
{
final String message =
REZ.getString( "builder.created-info.notice",
@@ -122,11 +126,51 @@
new Integer( services.length ),
new Integer( dependencies.length ),
new Integer( context.getEntrys().length ),
- new Integer( loggers.length ) );
- getLogger().debug( message );
+ new Integer( loggers.length ),
+ new Integer( phases.length ) );
+ getLogger().info( message );
}
- return new Type( descriptor, loggers, context, services,
dependencies );
+ return new Type( descriptor, loggers, context, services,
dependencies, phases );
+ }
+
+ /**
+ * Utility function to create a set of phase descriptor from a
configuration.
+ * @param config a configuration containing 0..n phase elements
+ * @return an array of phase descriptors
+ * @exception Exception if a build error occurs
+ */
+ protected PhaseDescriptor[] buildPhases( Configuration config ) throws
Exception
+ {
+ ArrayList list = new ArrayList();
+ Configuration[] phases = config.getChildren("phase");
+ for( int i=0; i<phases.length; i++ )
+ {
+ Configuration phase = phases[i];
+ ReferenceDescriptor reference =
+ buildReferenceDescriptor( phase.getChild("reference") );
+ final Properties attributes =
+ buildAttributes( phase.getChild( "attributes" ) );
+ list.add( new PhaseDescriptor( reference, attributes ) );
+ }
+ return (PhaseDescriptor[]) list.toArray( new PhaseDescriptor[0] );
+ }
+
+ /**
+ * A utility method to build a [EMAIL PROTECTED] ReferenceDescriptor}
+ * object from specified configuraiton data.
+ *
+ * @param service the service Configuration
+ * @return the created ReferenceDescriptor
+ * @throws ConfigurationException if an error occurs
+ */
+ protected ReferenceDescriptor buildReferenceDescriptor( final
Configuration service )
+ throws ConfigurationException
+ {
+ final String type = service.getAttribute( "type" );
+ final String versionString = service.getAttribute( "version", "1.0"
);
+ final Version version = buildVersion( versionString );
+ return new ReferenceDescriptor( type, version );
}
/**
@@ -207,14 +251,18 @@
final Configuration
dependency )
throws ConfigurationException
{
- final ServiceDesignator service =
- buildServiceDesignator( dependency.getChild( "service-ref" ) );
+ //
+ // try both merlin and containerkit variants for this attribute
+ //
+
+ Configuration serviceRef = dependency.getChild( "service-ref", false
);
+ if( serviceRef == null ) serviceRef = dependency.getChild(
"reference" );
+ final ReferenceDescriptor service =
+ buildReferenceDescriptor( serviceRef );
final boolean optional =
dependency.getAttributeAsBoolean( "optional", false );
-
final Properties attributes =
buildAttributes( dependency.getChild( "attributes" ) );
-
String role = dependency.getChild( "role" ).getValue( null );
//default to name of service if role unspecified
@@ -327,23 +375,6 @@
}
/**
- * A utility method to build a [EMAIL PROTECTED] ServiceDesignator}
- * object from specified configuraiton data.
- *
- * @param service the service Configuration
- * @return the created ServiceDesignator
- * @throws ConfigurationException if an error occurs
- */
- private ServiceDesignator buildServiceDesignator( final Configuration
service )
- throws ConfigurationException
- {
- final String name = service.getAttribute( "type" );
- final String versionString = service.getAttribute( "version", "1.0"
);
- final Version version = buildVersion( versionString );
- return new ServiceDesignator( name, version );
- }
-
- /**
* A utility method to build a <code>ServiceDescriptor</code>
* object from specified configuraiton data.
*
@@ -354,8 +385,9 @@
private ServiceDescriptor buildService( final Configuration service )
throws ConfigurationException
{
- final Configuration serviceRef = service.getChild( "service-ref" );
- final ServiceDesignator designator = buildServiceDesignator(
serviceRef );
+ Configuration serviceRef = service.getChild( "service-ref", false );
+ if( serviceRef == null ) serviceRef = service.getChild( "reference"
);
+ final ReferenceDescriptor designator = buildReferenceDescriptor(
serviceRef );
final Properties attributes =
buildAttributes( service.getChild( "attributes" ) );
return new ServiceDescriptor( designator, attributes );
1.4 +2 -2
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/package.html
Index: package.html
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/package.html,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- package.html 13 Jul 2002 00:09:45 -0000 1.3
+++ package.html 29 Jul 2002 06:14:34 -0000 1.4
@@ -100,7 +100,7 @@
<service>
- <service-ref type="<font color="darkred">SimpleService</font>"
version="<font color="darkred">3.2</font>">
+ <reference type="<font color="darkred">SimpleService</font>"
version="<font color="darkred">3.2</font>">
<attributes>
@@ -149,7 +149,7 @@
and the version value where version defaults to 1.0
--></i></font>
- <service-ref type="<font
color="darkred">org.apache.cocoon.api.Transformer</font>" version="<font
color="darkred">1.1</font>"/>
+ <reference type="<font
color="darkred">org.apache.cocoon.api.Transformer</font>" version="<font
color="darkred">1.1</font>"/>
<font color="gray"><i><!-- the set of attributes associated with
the dependecy --></i></font>
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/FacilityBuilder.java
Index: FacilityBuilder.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.meta.info.builder;
import java.io.InputStream;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.excalibur.meta.info.Facility;
/**
* A FacilityBuilder is responsible for building [EMAIL PROTECTED] Facility}
* objects from Configuration objects. The format for Configuration object
* is specified in the <a href="package-summary.html#external">package
summary</a>.
*
* <p><b>UML</b></p>
* <p><image src="doc-files/FacilityBuilder.gif" border="0"/></p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:34 $
*/
public final class FacilityBuilder
extends AbstractLogEnabled
{
private static final Resources REZ =
ResourceManager.getPackageResources( FacilityBuilder.class );
private final FacilityCreator m_xmlFacilityCreator =
createXMLFacilityCreator();
private final FacilityCreator m_serialFacilityCreator = new
SerializedFacilityCreator();
/**
* Setup logging for all subcomponents
*/
public void enableLogging( final Logger logger )
{
super.enableLogging( logger );
setupLogger( m_serialFacilityCreator );
if( null != m_xmlFacilityCreator )
{
setupLogger( m_xmlFacilityCreator );
}
}
/**
* Create a [EMAIL PROTECTED] Facility} object for specified Class.
*
* @param clazz The class of Component
* @return the created Facility
* @throws ConfigurationException if an error occurs
*/
public Facility build( final Class clazz )
throws Exception
{
return build( clazz.getName(), clazz.getClassLoader() );
}
/**
* Create a [EMAIL PROTECTED] Facility} object for specified
* classname, in specified ClassLoader.
*
* @param classname The classname of Component
* @param classLoader the ClassLoader to load info from
* @return the created Facility
* @throws ConfigurationException if an error occurs
*/
public Facility build( final String classname,
final ClassLoader classLoader )
throws Exception
{
final Facility info = buildFromSerDescriptor( classname, classLoader
);
if( null != info )
{
return info;
}
else
{
return buildFromXMLDescriptor( classname, classLoader );
}
}
/**
* Build Facility from the XML descriptor format.
*
* @param classname The classname of Component
* @param classLoader the ClassLoader to load info from
* @return the created Facility
* @throws Exception if an error occurs
*/
private Facility buildFromSerDescriptor( final String classname,
final ClassLoader
classLoader )
throws Exception
{
final String xinfo =
classname.replace( '.', '/' ) + ".sinfo";
final InputStream inputStream =
classLoader.getResourceAsStream( xinfo );
if( null == inputStream )
{
return null;
}
return m_serialFacilityCreator.createFacility( classname, inputStream
);
}
/**
* Build Facility from the XML descriptor format.
*
* @param classname The classname of Component
* @param classLoader the ClassLoader to load info from
* @return the created Facility
* @throws Exception if an error occurs
*/
private Facility buildFromXMLDescriptor( final String classname,
final ClassLoader
classLoader )
throws Exception
{
//
// get the input stream for the .xinfo resource
//
final String xinfo =
classname.replace( '.', '/' ) + ".xinfo";
final InputStream inputStream =
classLoader.getResourceAsStream( xinfo );
if( null == inputStream )
{
//##############################################################//
// Need to upgrade this to handle automated xinfo creation //
// using implemented interfaces for services, no dependecies, //
// no context, etc. //
//##############################################################//
final String message =
REZ.getString( "builder.missing-info.error",
classname );
throw new Exception( message );
}
//
// build the extension
//
final FacilityCreator xmlFacilityCreator = getXMLFacilityCreator(
classname );
return xmlFacilityCreator.createFacility( classname, inputStream );
}
/**
* Utility to get xml info builder, else throw
* an exception if missing descriptor.
*
* @return the FacilityCreator
*/
private FacilityCreator getXMLFacilityCreator( final String classname )
throws Exception
{
if( null != m_xmlFacilityCreator )
{
return m_xmlFacilityCreator;
}
else
{
final String message =
REZ.getString( "builder.missing-xml-creator.error",
classname );
throw new Exception( message );
}
}
/**
* Utility to get XMLFacilityCreator if XML files are on
* ClassPath.
*
* @return the XML [EMAIL PROTECTED] FacilityCreator}
*/
private static FacilityCreator createXMLFacilityCreator()
{
FacilityCreator xmlFacilityCreator = null;
try
{
xmlFacilityCreator = new XMLFacilityCreator();
}
catch( final Exception e )
{
//Ignore it if ClassNot found due to no
//XML Classes on classpath
}
return xmlFacilityCreator;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/FacilityCreator.java
Index: FacilityCreator.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.meta.info.builder;
import org.apache.excalibur.meta.info.Facility;
import java.io.InputStream;
/**
* Simple interface used to create [EMAIL PROTECTED] Facility}
* from stream. This abstraction was primarily created so
* that the Facility could be built from non-XML
* sources and no XML classes need be in the classpath.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:34 $
*/
public interface FacilityCreator
{
/**
* Create a [EMAIL PROTECTED] Facility} from stream
*
* @param classname the classname of a facility implementation
* @param input the input stream that the resource is loaded from
* @return the newly created [EMAIL PROTECTED] Facility}
* @throws Exception
*/
Facility createFacility( String key, InputStream input )
throws Exception;
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/SerializedFacilityCreator.java
Index: SerializedFacilityCreator.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.meta.info.builder;
import org.apache.excalibur.meta.info.Facility;
import java.io.InputStream;
import java.io.ObjectInputStream;
/**
* Create [EMAIL PROTECTED] Facility} from stream made up of
* serialized object.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:34 $
*/
public class SerializedFacilityCreator
implements FacilityCreator
{
public Facility createFacility( final String key,
final InputStream inputStream )
throws Exception
{
final ObjectInputStream ois = new ObjectInputStream( inputStream );
return (Facility)ois.readObject();
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLFacilityCreator.java
Index: XMLFacilityCreator.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.meta.info.builder;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Properties;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.Version;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.meta.info.ComponentDescriptor;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.ContextDescriptor;
import org.apache.excalibur.meta.info.DependencyDescriptor;
import org.apache.excalibur.meta.info.EntryDescriptor;
import org.apache.excalibur.meta.info.LoggerDescriptor;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.PhaseDescriptor;
import org.apache.excalibur.meta.info.ExtensionDescriptor;
import org.apache.excalibur.meta.info.ReferenceDescriptor;
import org.apache.excalibur.meta.info.Facility;
import org.apache.excalibur.meta.ConfigurationBuilder;
import org.xml.sax.InputSource;
/**
* Handles internalization of an XML based description of a [EMAIL PROTECTED]
Type}
* from a Configuration object. The format for Configuration object
* is specified in the <a href="package-summary.html#external">package
summary</a>.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/29 06:14:34 $
*/
public class XMLFacilityCreator
extends XMLTypeCreator
implements FacilityCreator
{
private static final Resources REZ =
ResourceManager.getPackageResources( XMLFacilityCreator.class );
/**
* Create a [EMAIL PROTECTED] Facility} object for specified
* classname, loaded from specified [EMAIL PROTECTED] InputStream}.
*
* @param classname The classname of the Facility
* @param inputStream the InputStream to load Facility from
* @return the created Facility
* @throws Exception if an error occurs
*/
public Facility createFacility( String implementationKey,
InputStream inputStream )
throws Exception
{
if( inputStream == null )
throw new NullPointerException("input");
final InputSource input = new InputSource( inputStream );
final String classname = implementationKey;
final Configuration xinfo = ConfigurationBuilder.build( input );
return build( classname, xinfo );
}
/**
* Create a [EMAIL PROTECTED] Facility} object for specified classname
from
* specified configuration data.
*
* @param classname The classname of Facility
* @param info the Facility configuration
* @return the created Facility
* @throws ConfigurationException if an error occurs
*/
private Facility build( final String classname, final Configuration info )
throws Exception
{
if( getLogger().isDebugEnabled() )
{
final String message =
REZ.getString( "builder.creating-facility.notice",
classname );
getLogger().debug( message );
}
final String topLevelName = info.getName();
if( !topLevelName.equals( "component-info" ) )
{
final String message =
REZ.getString( "builder.bad-toplevel-element.error",
classname,
topLevelName );
throw new ConfigurationException( message );
}
Configuration configuration = null;
configuration = info.getChild( "component" );
final ComponentDescriptor descriptor =
buildComponentDescriptor( classname, configuration );
configuration = info.getChild( "loggers" );
final LoggerDescriptor[] loggers = buildLoggers( configuration );
configuration = info.getChild( "context" );
final ContextDescriptor context = buildContext( configuration );
configuration = info.getChild( "services" );
final ServiceDescriptor[] services = buildServices( configuration );
configuration = info.getChild( "dependencies" );
final DependencyDescriptor[] dependencies = buildDependencies(
classname, configuration );
configuration = info.getChild( "phases" );
final PhaseDescriptor[] phases = buildPhases( configuration );
configuration = info.getChild( "extensions" );
final ExtensionDescriptor[] extensions = buildExtensions(
configuration );
if( getLogger().isInfoEnabled() )
{
final String message =
REZ.getString( "builder.created-facility.notice",
classname,
new Integer( services.length ),
new Integer( dependencies.length ),
new Integer( context.getEntrys().length ),
new Integer( loggers.length ),
new Integer( phases.length ),
new Integer( extensions.length ) );
getLogger().info( message );
}
return new Facility( descriptor, loggers, context, services,
dependencies, phases, extensions );
}
/**
* Utility function to create a set of phase descriptor from a
configuration.
* @param config a configuration containing 0..n phase elements
* @return an array of phase descriptors
* @exception Exception if a build error occurs
*/
protected ExtensionDescriptor[] buildExtensions( Configuration config )
throws Exception
{
ArrayList list = new ArrayList();
Configuration[] extensions = config.getChildren("extension");
for( int i=0; i<extensions.length; i++ )
{
Configuration extension = extensions[i];
final String name = extension.getChild("name").getValue();
ReferenceDescriptor reference = buildReferenceDescriptor(
extension.getChild("reference") );
final Properties attributes =
super.buildAttributes( extension.getChild( "attributes" ) );
list.add( new ExtensionDescriptor( name, reference, attributes )
);
}
return (ExtensionDescriptor[]) list.toArray( new
ExtensionDescriptor[0] );
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/doc-files/FacilityBuilder.gif
<<Binary file>>
1.7 +56 -49
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/doc-files/Type.gif
<<Binary file>>
1.2 +3 -3 jakarta-avalon-excalibur/assembly/src/xdocs/assembly.xml
Index: assembly.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/xdocs/assembly.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- assembly.xml 21 Jul 2002 05:04:10 -0000 1.1
+++ assembly.xml 29 Jul 2002 06:14:34 -0000 1.2
@@ -149,7 +149,7 @@
<service>
- <service-ref type="<font color="darkred">SimpleService</font>"
version="<font color="darkred">3.2</font>">
+ <reference type="<font color="darkred">SimpleService</font>"
version="<font color="darkred">3.2</font>">
<attributes>
@@ -198,7 +198,7 @@
and the version value where version defaults to 1.0
--></i></font>
- <service-ref type="<font
color="darkred">org.apache.cocoon.api.Transformer</font>" version="<font
color="darkred">1.1</font>"/>
+ <reference type="<font
color="darkred">org.apache.cocoon.api.Transformer</font>" version="<font
color="darkred">1.1</font>"/>
<font color="gray"><i><!-- the set of attributes associated with
the dependecy --></i></font>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>