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

Reply via email to