mcconnell 2002/12/15 06:08:56 Modified: assembly/src/java/org/apache/avalon/assembly/appliance Appliance.java ApplianceManager.java DefaultAppliance.java DefaultApplianceManager.java assembly/src/java/org/apache/avalon/assembly/engine Engine.java EngineClassLoader.java assembly/src/java/org/apache/avalon/assembly/engine/model ClasspathDescriptor.java assembly/src/test/org/apache/avalon/playground SimpleComponent.xinfo Added: assembly/src/java/org/apache/avalon/assembly/appliance ApplianceContext.java Removed: assembly/src/java/org/apache/avalon/assembly/appliance ApplianceFactory.java DefaultApplianceFactory.java TestApplianceFactory.java TestApplianceFactory.xinfo Log: Modification to the service management engine and default appliance implementation to support a simpler appliance creation pattern. Revision Changes Path 1.6 +9 -11 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/Appliance.java Index: Appliance.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/Appliance.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Appliance.java 12 Dec 2002 00:32:32 -0000 1.5 +++ Appliance.java 15 Dec 2002 14:08:55 -0000 1.6 @@ -50,6 +50,7 @@ package org.apache.avalon.assembly.appliance; +import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.assembly.lifestyle.LifestyleException; import org.apache.avalon.meta.info.DependencyDescriptor; import org.apache.avalon.meta.info.StageDescriptor; @@ -69,7 +70,13 @@ public interface Appliance { /** - * Release the appliance path. + * Meta-info attribute name under which an alternative appliance class may be declared. + */ + static final String APPLIANCE_CLASS_ATTRIBUTE_NAME = + "urn:assembly:appliance.class"; + + /** + * Get the appliance path. */ String getPath(); @@ -78,15 +85,6 @@ * @return the profile that this appliance is managing */ Profile getProfile(); - - /** - * Set the activation policy for the component. If TRUE, activation - * will occur at startup. If false, activation will be deferred to - * the first lookup invocation if any (i.e. lazy activation). - * - * @param policy TRUE if the appliace is to be activated on startup - */ - void setActivationPolicy( boolean policy ); /** * Return the activation policy for the component. If TRUE, activation 1.7 +1 -8 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/ApplianceManager.java Index: ApplianceManager.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/ApplianceManager.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- ApplianceManager.java 14 Dec 2002 21:04:40 -0000 1.6 +++ ApplianceManager.java 15 Dec 2002 14:08:55 -0000 1.7 @@ -121,11 +121,4 @@ */ Appliance getAppliance( StageDescriptor stage ); - /** - * Return an appliance factory based on a supplied Profile. - * @param profile a deployment profile - * @return an appliance factory - */ - ApplianceFactory getApplianceFactory( Profile profile ); - } 1.9 +57 -141 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/DefaultAppliance.java Index: DefaultAppliance.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/DefaultAppliance.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- DefaultAppliance.java 14 Dec 2002 21:04:40 -0000 1.8 +++ DefaultAppliance.java 15 Dec 2002 14:08:56 -0000 1.9 @@ -79,32 +79,26 @@ * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a> * @version $Revision$ $Date$ */ -public class DefaultAppliance extends AbstractLogEnabled implements Appliance, Serviceable, Contextualizable, Initializable +public class DefaultAppliance implements Appliance { //===================================================================== // state //===================================================================== /** - * The underlying profile that this appliance is managing. + * The appliance context. */ - private Profile m_profile; + private ApplianceContext m_context; /** - * The enabled status of the profile. Normally a profile is enabled however, a - * failure to assemble will result in the disabling of the profile. - */ - private boolean m_enabled = true; - - /** - * The activation policy - TRUE if activation on startup, FALSE to activate on request. + * The lifestyle service from which the appliance lifestyle handler is established. */ - private boolean m_activation = true; + private Engine m_engine; /** - * The lifestyle service from which the appliance lifestyle handler is established. + * The appliance context. */ - private Engine m_engine; + private Context m_system; /** * The lifestyle handler. @@ -112,9 +106,10 @@ private LifestyleHandler m_handler; /** - * The deployment context. + * The enabled status of the profile. Normally a profile is enabled however, a + * failure to assemble will result in the disabling of the profile. */ - private Context m_context; + private boolean m_enabled = true; /** * The dependencies providers keyed by role name. @@ -126,140 +121,63 @@ */ private final Hashtable m_managers = new Hashtable(); - /** - * Flag holding the initialized state of the appliance. - */ - private boolean m_initialized = false; - /** * The base path for the appliance. */ private String m_path; + /** + * The logging channel. + */ + private Logger m_logger; + //============================================================== - // Contextualizable + // constructor //============================================================== - /** - * <p>Application of a runtime context to this appliance. - * Context entries that may be supplied to an appliance manager are - * detailed in the following table.</p> - * <table> - * <tr> - * <td><strong>key</strong></td><td><strong>type</strong></td><td><strong>default</strong></td> - * </tr> - * <tr> - * <td>urn:assembly:appliance.profile</td> - * <td>[EMAIL PROTECTED] Profile}</td> - * <td>The profile backing this appliance.</td> - * </tr> - * <tr> - * <td>urn:assembly:appliance.enabled</td> - * <td>[EMAIL PROTECTED] Boolean}</td> - * <td>The enabled state of the appliance.</td> - * </tr> - * <tr> - * <td>urn:assembly:appliance.base</td> - * <td>[EMAIL PROTECTED] String}</td> - * <td>The base path.</td> - * </tr> - * <tr> - * <td>urn:assembly:appliance.activation</td> - * <td>[EMAIL PROTECTED] Boolean}</td> - * <td>The activation policy for the appliance.</td> - * </tr> - * <tr> - * <td>urn:assembly:appliance.deployment-context</td> - * <td>[EMAIL PROTECTED] Map}</td> - * <td>Supplimentary context entries.</td> - * </tr> - * </table> - * @param context the runtime context - */ - public void contextualize( Context context ) throws ContextException + public DefaultAppliance( + Engine engine, ApplianceContext context, Context system, Logger logger ) + throws ApplianceException { - m_context = context; - m_profile = (Profile)context.get( "urn:assembly:appliance.profile" ); - - try + if( engine == null ) { - m_enabled = ((Boolean)context.get( "urn:assembly:appliance.enabled" )).booleanValue(); + throw new NullPointerException( "engine" ); } - catch( ContextException e ) + if( context == null ) { - m_enabled = true; + throw new NullPointerException( "context" ); } - - try + if( system == null ) { - String base = (String) context.get( "urn:assembly:appliance.base" ); - m_path = base + "/" + m_profile.getName(); + throw new NullPointerException( "system" ); } - catch( ContextException e ) + if( logger == null ) { - m_path = "/" + m_profile.getName(); + throw new NullPointerException( "logger" ); } - try - { - m_activation = ((Boolean)context.get( "urn:assembly:appliance.activation" )).booleanValue(); - } - catch( ContextException e ) - { - m_activation = false; - } - } - - //============================================================== - // Serviceable - //============================================================== - - /** - * Supply of supporting services to this componet by its manager. - * This includes a deployment service that will assigned to the - * lifecycle handler. - * <table> - * <tr> - * <td><strong>key</strong></td><td><strong>type</strong></td><td><strong>default</strong></td> - * </tr> - * <tr> - * <td>urn:assembly:engine.classloader</td> - * <td>[EMAIL PROTECTED] Engine}</td> - * <td>The deployment engine.</td> - * </tr> - * </table> - */ - public void service( ServiceManager manager ) throws ServiceException - { - m_engine = (Engine) manager.lookup( "urn:assembly:engine.classloader" ); - } - - //============================================================== - // Initializable - //============================================================== + m_logger = logger; + m_engine = engine; + m_context = context; + m_enabled = context.getEnabled(); + m_system = system; - /** - * Initialization of the appliance. The implementation verifies - * initial appliance state including verification of logging channel - * assignment and context provision, followed by establishment of a - * lifestyle handler. - * - * @exception if a invalid state is encounter - */ - public void initialize() throws Exception - { - if( getLogger() == null ) + if( context.getPartitionName() != null ) { - throw new ApplianceException("logger"); + m_path = + context.getPartitionName() + + "/" + context.getProfile().getName(); } - if( m_profile == null ) + else { - throw new ApplianceException("context"); + m_path = "/" + context.getProfile().getName(); } try { - m_handler = m_engine.createLifestyleHandler( this, m_context ); + m_handler = + m_engine.createLifestyleHandler( + this, system ); } catch( Throwable e ) { @@ -267,8 +185,6 @@ "Could not initialize appliance due to a lifestyle handler establishment failure."; throw new ApplianceException( error, e ); } - - m_initialized = true; } //===================================================================== @@ -276,6 +192,15 @@ //===================================================================== /** + * Return the loging channel for the appliance. + * @return the logging channel + */ + protected Logger getLogger() + { + return m_logger; + } + + /** * Release the appliance path. */ public String getPath() @@ -290,19 +215,7 @@ */ public Profile getProfile() { - return m_profile; - } - - /** - * Set the activation policy for the component. If TRUE, activation - * will occur at startup. If false, activation will be deferred to - * the first lookup invocation if any (i.e. lazy activation). - * - * @param policy the activation policy - */ - public void setActivationPolicy( boolean policy ) - { - m_activation = policy; + return m_context.getProfile(); } /** @@ -314,7 +227,7 @@ */ public boolean getActivationPolicy() { - return m_activation; + return m_context.getActivationPolicy(); } /** @@ -332,6 +245,7 @@ /** * Set the enabled status of the profile to the supplied value. * @param value the enabled status - TRUE or FALSE + * @see #isEnabled() */ public void setEnabled( boolean value ) { @@ -428,8 +342,10 @@ /** * Release a reference to a service provided by this appliance. + * @param object the object to release + * @exception ApplianceRuntimeException if the lifestyle release error occurs */ - public void release( Object object ) + public void release( Object object ) throws ApplianceRuntimeException { try { 1.7 +11 -8 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/DefaultApplianceManager.java Index: DefaultApplianceManager.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/DefaultApplianceManager.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- DefaultApplianceManager.java 14 Dec 2002 21:04:40 -0000 1.6 +++ DefaultApplianceManager.java 15 Dec 2002 14:08:56 -0000 1.7 @@ -55,6 +55,11 @@ import java.util.Iterator; import java.util.ArrayList; +import org.apache.avalon.assembly.lifestyle.LifestyleService; +import org.apache.avalon.assembly.lifestyle.DefaultLifestyleService; +import org.apache.avalon.assembly.logging.DefaultLoggingManager; +import org.apache.avalon.assembly.logging.LoggingManager; +import org.apache.avalon.assembly.engine.Engine; import org.apache.avalon.framework.Version; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.configuration.Configuration; @@ -73,11 +78,6 @@ import org.apache.avalon.meta.info.ReferenceDescriptor; import org.apache.avalon.meta.model.Profile; import org.apache.avalon.meta.info.InfoDescriptor; -import org.apache.avalon.assembly.lifestyle.LifestyleService; -import org.apache.avalon.assembly.lifestyle.DefaultLifestyleService; -import org.apache.avalon.assembly.logging.DefaultLoggingManager; -import org.apache.avalon.assembly.logging.LoggingManager; -import org.apache.avalon.assembly.engine.Engine; /** * The default appliance manager provides support for [EMAIL PROTECTED] Appliance} @@ -107,7 +107,7 @@ /** * The default appliance factory. */ - private ApplianceFactory m_factory; + //private ApplianceFactory m_factory; /** * The engine. @@ -210,6 +210,7 @@ throw new IllegalStateException( "service" ); } + /* try { DefaultApplianceFactory factory = new DefaultApplianceFactory(); @@ -223,7 +224,7 @@ "Internal error while establishing the default applaince factory."; throw new ApplianceRuntimeException( error, e ); } - + */ m_initialized = true; } @@ -236,6 +237,7 @@ * @param profile a deployment profile * @return an appliance factory */ + /* public ApplianceFactory getApplianceFactory( Profile profile ) { if( !m_initialized ) @@ -293,6 +295,7 @@ throw new ApplianceRuntimeException( error, e ); } } + */ /** * Return the set of appliance istances capable of supporting the supplied dependency. 1.1 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/appliance/ApplianceContext.java Index: ApplianceContext.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.avalon.assembly.appliance; import java.util.Map; import java.util.Hashtable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.framework.logger.AbstractLogEnabled; 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.context.Context; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.DefaultContext; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.service.ServiceManager; import org.apache.avalon.framework.service.Serviceable; import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.assembly.engine.EngineClassLoader; import org.apache.avalon.assembly.lifestyle.LifestyleException; import org.apache.avalon.assembly.lifestyle.LifestyleService; import org.apache.avalon.assembly.lifestyle.LifestyleHandler; import org.apache.avalon.meta.info.DependencyDescriptor; import org.apache.avalon.meta.info.StageDescriptor; import org.apache.avalon.meta.model.Profile; /** * An appliance context aggregates the set of arguments that are supplied to * and appliance instance. * * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a> * @version $Revision: 1.1 $ $Date: 2002/12/15 14:08:55 $ */ public class ApplianceContext { //===================================================================== // static //===================================================================== private static final Map EMPTY_MAP = new Hashtable(); //===================================================================== // state //===================================================================== /** * The underlying profile that this appliance is managing. */ private Profile m_profile; /** * The enabled status of the profile. Normally a profile is enabled however, a * failure to assemble will result in the disabling of the profile. */ private boolean m_enabled = true; /** * The activation policy - TRUE if activation on startup, FALSE to activate on request. */ private boolean m_activation = true; /** * The base path for the appliance. */ private String m_path; /** * The deployment context. */ private Map m_context; //============================================================== // constructor //============================================================== /** * Creation of a new appliance context. */ public ApplianceContext() { } /** * Creation of a new appliance context. * @param profile the profile */ public ApplianceContext( Profile profile ) { if( profile == null ) { throw new NullPointerException( "profile" ); } m_profile = profile; } //============================================================== // parameters //============================================================== /** * Set the appliance profile. * @param profile the profile */ public void setProfile( Profile profile ) { m_profile = profile; } /** * Get the appliance profile. * @return the profile */ public Profile getProfile() { return m_profile; } /** * Set the appliance partition name. * @param name the partition name */ public void setPartitionName( String name ) { m_path = name; } /** * Get the partition name * @return the name */ public String getPartitionName() { return m_path; } /** * Set the activation policy for the component. If TRUE, activation * will occur at startup. If false, activation will be deferred to * the first lookup invocation if any (i.e. lazy activation). * * @param policy the activation policy */ public void setActivationPolicy( boolean policy ) { m_activation = policy; } /** * Return the activation policy for the component. If TRUE, activation * will occur at startup. If false, activation will be deferred to * the first lookup invocation if any (i.e. lazy activation). * * @return the activation policy */ public boolean getActivationPolicy() { return m_activation; } /** * Return the enabled state of the appliance. A appliance is enabled * unless explicitly disabled by an assembly directive, or implicity * disabled as a result of an assembly failure. * * @return TRUE if the profile is enabled. * @see #setEnabled( boolean ) */ public boolean getEnabled() { return m_enabled; } /** * Set the enabled status of the profile to the supplied value. * @param value the enabled status - TRUE or FALSE * @see #getEnabled() */ public void setEnabled( boolean value ) { m_enabled = value; } /** * Set the deployment context. * @param map the deployment context * @see #getDeploymentContext() */ public void setDeploymentContext( Map map ) { m_context = map; } /** * Get the deployment context. * @return the deployment context */ public Map getDeploymentContext() { if( m_context == null ) { return EMPTY_MAP; } return m_context; } } 1.7 +5 -4 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/Engine.java Index: Engine.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/Engine.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Engine.java 14 Dec 2002 21:04:40 -0000 1.6 +++ Engine.java 15 Dec 2002 14:08:56 -0000 1.7 @@ -58,6 +58,8 @@ import org.apache.avalon.framework.service.ServiceManager; import org.apache.avalon.meta.model.Profile; import org.apache.avalon.assembly.appliance.Appliance; +import org.apache.avalon.assembly.appliance.ApplianceException; +import org.apache.avalon.assembly.appliance.ApplianceContext; import org.apache.avalon.assembly.engine.model.ClasspathDescriptor; import org.apache.avalon.assembly.lifestyle.LifestyleService; import org.apache.avalon.assembly.lifestyle.LifestyleHandler; @@ -89,12 +91,11 @@ /** * Create a new appliance. - * @param profile the component profile - * @param map a map of supplimentary deployment context entries + * @param context the appliance context * @param shared TRUE if this appliance may be shared * @return the appliance */ - Appliance createAppliance( Profile profile, Map map, boolean shared ) throws Exception; + Appliance createAppliance( ApplianceContext context, boolean shared ) throws ApplianceException; /** * Resolve an appliance capable of supporting a service 1.8 +150 -67 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/EngineClassLoader.java Index: EngineClassLoader.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/EngineClassLoader.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- EngineClassLoader.java 14 Dec 2002 21:04:40 -0000 1.7 +++ EngineClassLoader.java 15 Dec 2002 14:08:56 -0000 1.8 @@ -51,26 +51,44 @@ package org.apache.avalon.assembly.engine; import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.JarURLConnection; import java.util.Map; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.List; -import java.net.URL; -import java.net.URLClassLoader; import java.util.jar.Manifest; import java.util.jar.Attributes; -import java.net.JarURLConnection; import java.util.ArrayList; -import java.io.IOException; -import org.apache.avalon.excalibur.extension.Extension; -import org.apache.avalon.excalibur.i18n.ResourceManager; -import org.apache.avalon.excalibur.i18n.Resources; -import org.apache.avalon.excalibur.packagemanager.OptionalPackage; -import org.apache.avalon.excalibur.packagemanager.PackageManager; -import org.apache.avalon.excalibur.packagemanager.ExtensionManager; -import org.apache.avalon.excalibur.packagemanager.impl.DefaultExtensionManager; -import org.apache.avalon.excalibur.packagemanager.impl.DelegatingExtensionManager; +import org.apache.avalon.assembly.type.TypeManager; +import org.apache.avalon.assembly.profile.ProfileManager; +import org.apache.avalon.assembly.appliance.Appliance; +import org.apache.avalon.assembly.appliance.ApplianceContext; +import org.apache.avalon.assembly.appliance.ApplianceException; +import org.apache.avalon.assembly.appliance.ApplianceManager; +import org.apache.avalon.assembly.appliance.DefaultAppliance; +import org.apache.avalon.assembly.appliance.DefaultApplianceManager; +import org.apache.avalon.assembly.appliance.DependencyGraph; +import org.apache.avalon.assembly.appliance.MappedServiceManager; +import org.apache.avalon.assembly.lifecycle.DeploymentService; +import org.apache.avalon.assembly.lifecycle.DefaultDeploymentService; +import org.apache.avalon.assembly.lifestyle.LifestyleException; +import org.apache.avalon.assembly.lifestyle.LifestyleService; +import org.apache.avalon.assembly.lifestyle.DefaultLifestyleService; +import org.apache.avalon.assembly.lifestyle.LifestyleHandler; +import org.apache.avalon.assembly.logging.LoggingDescriptor; +import org.apache.avalon.assembly.logging.DefaultLoggingManager; +import org.apache.avalon.assembly.logging.LoggingManager; +import org.apache.avalon.assembly.logging.TargetDescriptor; +import org.apache.avalon.assembly.engine.model.LibraryDescriptor; +import org.apache.avalon.assembly.engine.model.ClasspathDescriptor; +import org.apache.avalon.assembly.engine.model.FilesetDescriptor; +import org.apache.avalon.assembly.engine.model.IncludeDescriptor; +import org.apache.avalon.assembly.engine.model.ClasspathDescriptor; import org.apache.avalon.framework.Version; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.logger.Logger; @@ -90,33 +108,19 @@ import org.apache.avalon.meta.info.DependencyDescriptor; import org.apache.avalon.meta.info.StageDescriptor; import org.apache.avalon.meta.info.ReferenceDescriptor; +import org.apache.avalon.meta.info.InfoDescriptor; import org.apache.avalon.meta.info.Type; import org.apache.avalon.meta.model.Profile; import org.apache.avalon.meta.model.LoggingDirective; import org.apache.avalon.meta.model.Category; -import org.apache.avalon.assembly.type.TypeManager; -import org.apache.avalon.assembly.profile.ProfileManager; -import org.apache.avalon.assembly.appliance.Appliance; -import org.apache.avalon.assembly.appliance.ApplianceManager; -import org.apache.avalon.assembly.appliance.ApplianceFactory; -import org.apache.avalon.assembly.appliance.DefaultApplianceManager; -import org.apache.avalon.assembly.appliance.DependencyGraph; -import org.apache.avalon.assembly.appliance.MappedServiceManager; -import org.apache.avalon.assembly.lifecycle.DeploymentService; -import org.apache.avalon.assembly.lifecycle.DefaultDeploymentService; -import org.apache.avalon.assembly.lifestyle.LifestyleException; -import org.apache.avalon.assembly.lifestyle.LifestyleService; -import org.apache.avalon.assembly.lifestyle.DefaultLifestyleService; -import org.apache.avalon.assembly.lifestyle.LifestyleHandler; -import org.apache.avalon.assembly.logging.LoggingDescriptor; -import org.apache.avalon.assembly.logging.DefaultLoggingManager; -import org.apache.avalon.assembly.logging.LoggingManager; -import org.apache.avalon.assembly.logging.TargetDescriptor; -import org.apache.avalon.assembly.engine.model.LibraryDescriptor; -import org.apache.avalon.assembly.engine.model.ClasspathDescriptor; -import org.apache.avalon.assembly.engine.model.FilesetDescriptor; -import org.apache.avalon.assembly.engine.model.IncludeDescriptor; -import org.apache.avalon.assembly.engine.model.ClasspathDescriptor; +import org.apache.avalon.excalibur.extension.Extension; +import org.apache.avalon.excalibur.i18n.ResourceManager; +import org.apache.avalon.excalibur.i18n.Resources; +import org.apache.avalon.excalibur.packagemanager.OptionalPackage; +import org.apache.avalon.excalibur.packagemanager.PackageManager; +import org.apache.avalon.excalibur.packagemanager.ExtensionManager; +import org.apache.avalon.excalibur.packagemanager.impl.DefaultExtensionManager; +import org.apache.avalon.excalibur.packagemanager.impl.DelegatingExtensionManager; import org.apache.excalibur.mpool.DefaultPoolManager; import org.apache.excalibur.mpool.PoolManager; import org.apache.excalibur.event.command.CommandManager; @@ -142,6 +146,11 @@ //============================================================== /** + * Constructor supplied urls. + */ + private URL[] m_urls = new URL[0]; + + /** * The supplied configuration. The configuration may be empty * as defaults are provided for all values. */ @@ -252,7 +261,7 @@ } /** - * Creation of a new engine with a partner + * Creation of a new engine with a parent. */ public EngineClassLoader( EngineClassLoader parent ) { @@ -260,6 +269,16 @@ m_graph = new DependencyGraph( parent.getDependencyGraph() ); } + /** + * Creation of a new engine with a partner and URL array. + */ + public EngineClassLoader( URL[] urls, EngineClassLoader parent ) + { + super( new URL[ 0 ], parent ); + m_graph = new DependencyGraph( parent.getDependencyGraph() ); + m_urls = urls; + } + //======================================================================= // LogEnabled //======================================================================= @@ -474,7 +493,7 @@ { final String warning = "The extension directory path: '" + token - + "' deas not refer to a directory."; + + "' does not refer to a directory."; getLogger().warn( warning ); } } @@ -495,6 +514,7 @@ { m_extensions = new DefaultExtensionManager( files ); } + m_packages = new PackageManager( m_extensions ); // @@ -530,6 +550,17 @@ } // + // load the explicit URLs + // + + for( int i=0; i<m_urls.length; i++ ) + { + URL url = m_urls[i]; + getLogger().debug("processing: '" + url + "'." ); + addURL( url ); + } + + // // load the classpath // @@ -822,7 +853,7 @@ } else { - return createAppliance( profile ); + appliance = createAppliance( new ApplianceContext( profile ), true ); } } return appliance; @@ -859,50 +890,102 @@ } else { - appliance = createAppliance( profile ); + appliance = createAppliance( new ApplianceContext( profile ), true ); } } return appliance; } /** - * Create a new shared appliance. - * @param profile the component profile + * Create and assemble a new appliance. + * @param context the appliance creation context + * @param shared TRUE if this appliance can be shared * @return the appliance */ - public Appliance createAppliance( Profile profile ) throws Exception + public Appliance createAppliance( ApplianceContext context, boolean shared ) throws ApplianceException { - return createAppliance( profile, null ); - } + Appliance appliance; + try + { + String name = context.getProfile().getType().getInfo().getName(); + Logger logger = getLogger().getChildLogger( name ); + appliance = buildAppliance( context, getSystemContext(), logger ); + assemble( appliance ); + } + catch( Throwable e ) + { + final String error = + "Error while attempting to create standard appliance" + + " from the profile: " + + context.getProfile(); + throw new ApplianceException( error, e ); + } + if( shared ) + { + m_appliances.addAppliance( appliance ); + } - /** - * Create a new shared appliance. - * @param profile the component profile - * @param map supplimentary deployment context entries - * @return the appliance - */ - public Appliance createAppliance( Profile profile, Map map ) throws Exception - { - return createAppliance( profile, map, true ); + return appliance; } - /** - * Create a new appliance. - * @param profile the component profile - * @param map supplimentary deployment context entries - * @param shared TRUE if this appliance may be shared - * @return the appliance - */ - public Appliance createAppliance( Profile profile, Map map, boolean shared ) throws Exception + private Appliance buildAppliance( ApplianceContext context, Context system, Logger logger ) + throws ClassNotFoundException, ApplianceException { - ApplianceFactory factory = m_appliances.getApplianceFactory( profile ); - Appliance appliance = factory.createAppliance( this, profile, true, true, getSystemContext(), map ); - if( shared ) + InfoDescriptor info = context.getProfile().getType().getInfo(); + String classname = info.getAttribute( Appliance.APPLIANCE_CLASS_ATTRIBUTE_NAME ); + + if( classname != null ) { - m_appliances.addAppliance( appliance ); + Class clazz; + try + { + clazz = loadClass( classname ); + } + catch( ClassNotFoundException cnfe ) + { + throw new ClassNotFoundException( + "Could not find appliance class " + classname, cnfe ); + } + + try + { + Constructor constructor = clazz.getConstructor( + new Class[]{ Engine.class, ApplianceContext.class, Context.class, Logger.class } ); + Object[] args = new Object[]{ this, context, system, logger }; + return (Appliance) constructor.newInstance( args ); + } + catch( NoSuchMethodException nsme ) + { + throw new ApplianceException( + "The supplied classname: '" + + classname + + "' does not implement a constructor matching the pattern: ( " + + Engine.class.getName() + + ", " + ApplianceContext.class.getName() + + ", " + Context.class.getName() + + ", " + Logger.class.getName() + + " )." ); + } + catch( ClassCastException cce ) + { + throw new ApplianceException( + "The supplied classname: '" + + classname + + "' does not implement the interface: " + + Appliance.class.getName() ); + } + catch( Throwable e ) + { + throw new ApplianceException( + "Unexpected exception while creating appliance from " + + classname, e ); + } + } + else + { + return new DefaultAppliance( this, context, system, logger ); } - return appliance; } //============================================================== 1.3 +2 -6 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/model/ClasspathDescriptor.java Index: ClasspathDescriptor.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/model/ClasspathDescriptor.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ClasspathDescriptor.java 9 Dec 2002 12:09:40 -0000 1.2 +++ ClasspathDescriptor.java 15 Dec 2002 14:08:56 -0000 1.3 @@ -166,11 +166,7 @@ String inc = includes[ j ].getFile(); try { - URL url = new File( anchor, inc ).toURL(); - if( inc.endsWith( ".jar" ) ) - { - url = new URL( "jar:" + url.toString() + "!/" ); - } + URL url = new File( anchor, inc ).getCanonicalFile().toURL(); list.add( url ); } catch( Throwable e ) 1.4 +2 -6 avalon-sandbox/assembly/src/test/org/apache/avalon/playground/SimpleComponent.xinfo Index: SimpleComponent.xinfo =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/test/org/apache/avalon/playground/SimpleComponent.xinfo,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- SimpleComponent.xinfo 7 Dec 2002 09:34:29 -0000 1.3 +++ SimpleComponent.xinfo 15 Dec 2002 14:08:56 -0000 1.4 @@ -18,8 +18,8 @@ <info> <name>simple</name> <attributes> - <attribute key="urn:assembly:appliance.factory-service" - value="org.apache.avalon.assembly.appliance.ApplianceFactory"/> + <attribute key="urn:assembly:appliance.class" + value="org.apache.avalon.assembly.appliance.DefaultAppliance"/> <attribute key="urn:assembly:appliance.factory-version" value="2.0"/> </attributes> @@ -27,10 +27,6 @@ <services> <service> - <attributes> - <attribute key="urn:avalon:service.servlet" - value="simple.jsp"/> - </attributes> <reference type="org.apache.avalon.playground.SimpleService"/> </service> </services>
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>