> > Other important points are that a extension provider can
> > declare its own
> > phase dependencies and also classic service dependencies.
> > Merlin will
> > take care of the ordering of component establishment based on
> > the phase
> > and service dependencies that the component publishes.
> >
> > Extension providers must implement the following interface:
> >
> > org.apache.excalibur.merlin.assembly.resource.Extension
> >
> > The interface declares the operation "extend( int stage,
> > Object object,
> > Context context ) which will be invoked by the Merlin
> > container during
> > the appropriate stages. Merlin defines a number of stages
> > that can be
> > associated with an extension provider. Merlin will only
> > invoke extend
> > if the provider declares that it supports the particular stage.
> >
> > Standard stages include the following:
> >
> > CREATE invoked immediately before initialization
> > ACCESS invoked immediate before lookup
> > RELEASE invoked immediately before release
> > DESTROY invoked immediately before dispose
> > INNER equivalent to ACCESS + RELEASE
> > OUTER equivalinet to CREATE + DESTROY
> > ALL equivalent to INNER + OUTER
>
>
> :/
>
> I kind of like Marcus' solution a bit better. We have simple
> methods that have a specific meaning. If a lifecycle event happens
> on more than one type of use (create/destroy/access/release),
> the implementor has the freedom to use OO principles more clearly
> by encapsulating the common elements in a separate method.
what we have here is the flexibility vs simplicity problem.
we could replace all lifecycle interfaces with
public interface LifecycleEnabled
{
// default stages
public final static String STAGE_ENABLE_LOGGING = "LogEnabled";
public final static String STAGE_CONFIGURE = "Configurable";
public final static String STAGE_START = "Start";
public final static String STAGE_STOP = "Stop";
// ...
handleStage( String phase, Object parameters )
throws LifecycleException;
}
public abstract class AbstractLifecycleEnabled
implements LifecycleEnabled
{
public Object handleStage( String phase, Object[] parameters )
throws LifecycleException
{
switch(phase)
{
case STAGE_ENABLE_LOGGING:
logEnabled( (Logger)parameters[0] );
return null;
case STAGE_CONFIGURE:
configure( (Configuration)parameters[0] );
return null;
default:
return ExtensionManager.handleStage( this,
phase, parameters );
}
}
abstract void logEnabled( Logger logger );
abstract void configure( Configuration configuration );
}
public NoopLifecycleEnabled
{
void logEnabled( Logger logger ) {}
void configure( Configuration configuration ) {}
}
public MyComponent extends NoopLifecycleEnabled
{
void configure( Configuration configuration )
{
// do stuff
}
}
which would make working with the standard lifecycle somewhat more
complex but extension easier. It is a matter of where to put the
complexity I guess.
I like Marcus' version as writing an extension is more similar to
writing a component that way. To follow this line of thought completely
it should probably be something like:
class PersistentConfigurableHandler implements
CreationExtensionHandler, DestructionExtensionHandler
{
/** By contract, Other methods are only called if this returns
true. This is defined in ExtensionHandler, the common
superinterface to the implemented interfaces. */
boolean accept( Object obj )
{
if( obj instanceof PersistantConfigurable )
return true;
return false;
}
/** from CreationExtensionHandler */
void create( Object component, Context context )
throws PersistentConfigurationException
{
((PersistantConfigurable)component).configure(
(Configuration)context.get("configuration" ) );
}
/** from DestructionExtensionHandler */
void destroy( Object component, Context context )
throws PersistentConfigurationException
{
Configuration = ((PersistantConfigurable)component)
.saveConfiguration();
}
}
which would make it the extension setup even more similar to the
'normal' avalon framework lifecycle.
cheers,
- Leo
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>