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]>