mcconnell 2002/11/29 07:16:18 Modified: assembly/src/java/org/apache/avalon/assembly/lifecycle/context AbstractContextHandler.java assembly/src/java/org/apache/avalon/assembly/lifecycle/disposal ExtendedDisposalService.java assembly/src/java/org/apache/avalon/assembly/lifecycle/initialization ExtendedInitializationService.java assembly/src/java/org/apache/avalon/assembly/lifestyle AbstractLifestyleHandler.java meta/src/java/org/apache/avalon/meta/info DependencyDescriptor.java StageDescriptor.java meta/src/java/org/apache/avalon/meta/model Profile.java Log: Addition of inner stage extension handling. Revision Changes Path 1.2 +17 -1 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/lifecycle/context/AbstractContextHandler.java Index: AbstractContextHandler.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/lifecycle/context/AbstractContextHandler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- AbstractContextHandler.java 29 Nov 2002 13:04:55 -0000 1.1 +++ AbstractContextHandler.java 29 Nov 2002 15:16:18 -0000 1.2 @@ -66,6 +66,7 @@ import org.apache.avalon.meta.model.ContextDirective; import org.apache.avalon.meta.info.ContextDescriptor; import org.apache.avalon.meta.info.EntryDescriptor; +import org.apache.avalon.meta.info.ExtensionDescriptor; /** * The context service provides support for the contextualization of a @@ -271,6 +272,21 @@ } return result; + } + + /** + * Create a new Context for an extension. + * + * @param extension the extension descriptor + * @param context a supplimentary context used during import resolution + * @return a new Context for service + * @throws Exception if unable to create context + */ + protected Context createContext( ExtensionDescriptor extension, Context context ) + throws Exception + { + ContextDescriptor descriptor = extension.getContext(); + return buildContext( descriptor, null, context ); } /** 1.2 +1 -16 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/lifecycle/disposal/ExtendedDisposalService.java Index: ExtendedDisposalService.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/lifecycle/disposal/ExtendedDisposalService.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ExtendedDisposalService.java 29 Nov 2002 13:04:55 -0000 1.1 +++ ExtendedDisposalService.java 29 Nov 2002 15:16:18 -0000 1.2 @@ -229,19 +229,4 @@ } } } - - /** - * Create a new Context for an extension. - * - * @param extension the extension descriptor - * @param context a supplimentary context used during import resolution - * @return a new Context for service - * @throws Exception if unable to create context - */ - private Context createContext( ExtensionDescriptor extension, Context context ) - throws Exception - { - ContextDescriptor descriptor = extension.getContext(); - return buildContext( descriptor, null, context ); - } } 1.2 +1 -30 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/lifecycle/initialization/ExtendedInitializationService.java Index: ExtendedInitializationService.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/lifecycle/initialization/ExtendedInitializationService.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ExtendedInitializationService.java 29 Nov 2002 13:04:55 -0000 1.1 +++ ExtendedInitializationService.java 29 Nov 2002 15:16:18 -0000 1.2 @@ -215,33 +215,4 @@ } } } - - /** - * Create a new Context for an extension. - * - * @param extension the extension descriptor - * @param context a supplimentary context used during import resolution - * @return a new Context for service - * @throws Exception if unable to create context - */ - private Context createContext( ExtensionDescriptor extension, Context context ) - throws Exception - { - ContextDescriptor descriptor = extension.getContext(); - return buildContext( descriptor, null, context ); - } - - - /** - * Gat the context for a extension stage. - * - * @param map the map of context entries keyed by stage - * @param stage the stage descriptor - * @return a the Context for the extension - */ - protected Context getContext( Map map, StageDescriptor stage ) - { - return (Context) map.get( stage ); - } - } 1.2 +211 -2 avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/lifestyle/AbstractLifestyleHandler.java Index: AbstractLifestyleHandler.java =================================================================== RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/lifestyle/AbstractLifestyleHandler.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- AbstractLifestyleHandler.java 29 Nov 2002 13:04:56 -0000 1.1 +++ AbstractLifestyleHandler.java 29 Nov 2002 15:16:18 -0000 1.2 @@ -50,6 +50,9 @@ package org.apache.avalon.assembly.lifestyle; +import java.util.Map; +import java.util.Hashtable; + import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.context.Context; @@ -61,9 +64,14 @@ import org.apache.avalon.framework.logger.Logger; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.meta.info.DependencyDescriptor; +import org.apache.avalon.meta.info.ExtensionDescriptor; import org.apache.avalon.meta.info.StageDescriptor; +import org.apache.avalon.meta.info.Type; +import org.apache.avalon.meta.model.Profile; import org.apache.avalon.assembly.appliance.Appliance; import org.apache.avalon.assembly.lifecycle.DeploymentService; +import org.apache.avalon.assembly.lifecycle.context.AbstractContextHandler; +import org.apache.avalon.lifecycle.Accessor; /** * The abstract lifestyle handler provides support for object instantiation and @@ -72,7 +80,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a> * @version $Revision$ $Date$ */ -public abstract class AbstractLifestyleHandler extends AbstractLogEnabled implements Contextualizable, Serviceable, Initializable, Disposable, LifestyleHandler +public abstract class AbstractLifestyleHandler extends AbstractContextHandler implements Serviceable, Initializable, Disposable, LifestyleHandler { //============================================================== // state @@ -105,6 +113,13 @@ */ private Context m_context; + /** + * The implementation class. + */ + private Class m_class; + + private Map m_map; + //============================================================== // Contextualizable //============================================================== @@ -127,6 +142,7 @@ */ public void contextualize( Context context ) throws ContextException { + super.contextualize( context ); m_logger = (Logger) context.get( "avalon:logger" ); m_classloader = (ClassLoader) context.get( "avalon:classloader" ); m_appliance = (Appliance) context.get( "assembly:appliance.target" ); @@ -250,5 +266,198 @@ + m_appliance; throw new LifestyleException( error, e ); } + } + + /** + * Handle the access phase extensions as declared by the profile type. + * @param object the object to process + * @exception Exception if a stage procesing exception occurs + */ + protected void processAccessStage( Object object ) throws Exception + { + StageDescriptor[] phases = m_appliance.getProfile().getType().getStages(); + for( int i = 0; i < phases.length; i++ ) + { + StageDescriptor stage = phases[ i ]; + processExtension( stage, object, true ); + } + } + + /** + * Handle the access phase extensions as declared by the profile type. + * @param object the object to process + */ + protected void processReleaseStage( Object object ) + { + StageDescriptor[] phases = m_appliance.getProfile().getType().getStages(); + for( int i = ( phases.length - 1 ); i > -1; i-- ) + { + StageDescriptor stage = phases[ i ]; + try + { + processExtension( stage, object, false ); + } + catch( Throwable e ) + { + if( getLogger().isWarnEnabled() ) + { + final String warning = + "Ignoring release exception."; + getLogger().warn( warning, e ); + } + } + } + } + + /** + * Invoke an extension handler for a lifecycle stage. + * + * @param stage the stage descriptor describing the stage dependency + * @param object the object to be processed + * @param access TRUE if this is ACCESS otherwise its RELEASE mode + * + * @exception Exception if an error occurs during stage execution + */ + private void processExtension( + StageDescriptor stage, + Object object, + boolean access ) + throws Exception + { + Appliance provider = m_appliance.getExtensionProvider( stage ); + if( provider == null ) + { + final String error = + "Null provider returned from appliance: " + m_appliance + + " stage: " + stage; + throw new IllegalStateException( error ); + } + + if( Accessor.class.isAssignableFrom( getImplementationClass( provider ) ) ) + { + Accessor extension = (Accessor) provider.access( stage ); + try + { + Context context = getStageContext( stage ); + if( access ) + { + extension.access( object, context ); + } + else + { + extension.release( object, context ); + } + provider.release( extension ); + } + catch( Throwable e ) + { + final String error = + "Extension provider appliance: " + provider + + " raised a execution exception while processing an inner stage: " + stage + + " in appliance: " + m_appliance; + throw new LifestyleException( error, e ); + } + } + } + + private Context getStageContext( StageDescriptor stage ) + { + if( m_map == null ) + { + try + { + m_map = createExtensionContextMap( m_appliance, m_context ); + } + catch( Throwable e ) + { + final String error = + "Internal error while attempting to construct the extension context map for appliance: " + + m_appliance; + throw new LifestyleRuntimeException( error, e ); + } + } + Context context = (Context) m_map.get( stage ); + if( context == null ) + { + final String error = + "Null context returned in appliance: " + m_appliance + + " for the stage: " + stage; + throw new NullPointerException( error ); + } + return context; + } + + private Class getImplementationClass( Appliance appliance ) + { + try + { + String classname = m_appliance.getProfile().getType().getInfo().getClassname(); + return m_classloader.loadClass( classname ); + } + catch( Throwable e ) + { + final String error = + "Internal error while attempting to load the implementation class for an appliance: " + + m_appliance; + throw new LifestyleRuntimeException( error, e ); + } + } + + /** + * Handles creation of a map of context entries keyed by extension stage. Context + * entries are built using the supplied deployment context argument together + * with profile directives relative to type constraints. + * + * @param profile the profile + * @param context the deployment context + * @return the map of context entries keyed by stage + * @exception LifestyleException if an error occurs while preparing the map + */ + private Map createExtensionContextMap( Appliance appliance, Context context ) + throws LifestyleException + { + if( appliance == null ) + { + throw new NullPointerException( "appliance" ); + } + if( context == null ) + { + throw new NullPointerException( "context" ); + } + + // + // build the set of extension context instances + // + + Profile profile = appliance.getProfile(); + Hashtable table = new Hashtable(); + StageDescriptor[] stages = profile.getType().getStages(); + for( int i = 0; i < stages.length; i++ ) + { + StageDescriptor stage = stages[ i ]; + Appliance provider = appliance.getExtensionProvider( stage ); + if( provider == null ) + { + throw new NullPointerException( "provider" ); + } + + Type type = provider.getProfile().getType(); + final ExtensionDescriptor ext = type.getExtension( stage ); + try + { + Context extensionContext = createContext( ext, context ); + table.put( stage, extensionContext ); + } + catch( Throwable e ) + { + final String error = + "Unexpected error while creating context for extension: " + + provider.getProfile().getName() + + " in appliance " + provider.getProfile().getName() + + " for stage: " + stage; + throw new LifestyleException( error, e ); + } + } + return table; } } 1.2 +5 -1 avalon-sandbox/meta/src/java/org/apache/avalon/meta/info/DependencyDescriptor.java Index: DependencyDescriptor.java =================================================================== RCS file: /home/cvs/avalon-sandbox/meta/src/java/org/apache/avalon/meta/info/DependencyDescriptor.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- DependencyDescriptor.java 24 Nov 2002 12:58:26 -0000 1.1 +++ DependencyDescriptor.java 29 Nov 2002 15:16:18 -0000 1.2 @@ -189,4 +189,8 @@ return !isOptional(); } + public String toString() + { + return "[dependency: '" + getReference() + " key: '" + getRole() + "']"; + } } 1.2 +6 -1 avalon-sandbox/meta/src/java/org/apache/avalon/meta/info/StageDescriptor.java Index: StageDescriptor.java =================================================================== RCS file: /home/cvs/avalon-sandbox/meta/src/java/org/apache/avalon/meta/info/StageDescriptor.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- StageDescriptor.java 24 Nov 2002 12:58:26 -0000 1.1 +++ StageDescriptor.java 29 Nov 2002 15:16:18 -0000 1.2 @@ -114,4 +114,9 @@ { return getReference().hashCode(); } + + public String toString() + { + return "[stage " + getReference() + "]"; + } } 1.3 +5 -4 avalon-sandbox/meta/src/java/org/apache/avalon/meta/model/Profile.java Index: Profile.java =================================================================== RCS file: /home/cvs/avalon-sandbox/meta/src/java/org/apache/avalon/meta/model/Profile.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Profile.java 26 Nov 2002 17:12:14 -0000 1.2 +++ Profile.java 29 Nov 2002 15:16:18 -0000 1.3 @@ -392,9 +392,10 @@ */ public String toString() { - return "Profile name: " + getName() - + ", type: " + getType().getInfo().getName() - + ", mode: " + getMode(); + return "[profile name: " + + getName() + + ", type: " + getType().getInfo().getClassname() + + "]"; } /**
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>