avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leo Simons <leosim...@apache.org>
Subject circumventing the lifecycle (was: Re: [RT:A5] What are the _real_ concern areas?)
Date Fri, 20 Dec 2002 10:27:24 GMT
Hi all,

getting started on my e-mail backlog. Still have to finish reading this
thread (on avalon-dev), but I saw some complaints about having to
remember contracts that make no sense (they do make sense but that's not
the point I want to make ;).

Well, you don't have to remember anything if you really don't want to.
Below some sample code that allows you to not think about most contracts
at all. This code itself adheres to avalon contracts (in 4.1 not the
distant future) and it should run (though untested) in just about all
containers.

You could expand on this code a little more by keeping a list of
services in the code, then getting each service from the servicemanager
and throwing it into the context. You could also serialize all possible
context values and put those in the configuration, retrieve all
configuration entries and put them into the context using urns, etc.

You could be forced to use some other logging setup (let us assume you
want to use commons-logging), so you add some code into initialize()
that checks if commons logging is available, then gets the
commons-logger from the factory, puts it into a protected property, and
wraps it as an o.a.a.f.l.Logger and stuffs it into m_logger.

You could be forced to work within a container where ServiceManager and
JNDI concepts are not merged, and you want them to be. So you create a
JNDIAwareServiceManager and replace the DefaultServiceManager in the
example code below with that one.

etc etc. You can customize all you want.

Now throw the finished class and assorted utility code into an
lazy-avalon-framework-hack.jar, add it to the classpath of all your apps
(ie drop into phoenix's lib/ directory). tadah: instant braindead
lifecycle support.

What you loose is the granularity, efficiency, clarity, etc. You're also
loosing proper seperation of concerns (for example, what you want in the
JNDI case is a modified container/service manager that is JNDI-aware),
but it's mostly braindead simple to do. Just to show it is quite easy to
circumvent most of the though contracts imposed on you by avalon and do
things your way.

cheers,

- Leo Simons


/**
 * For those that hate typing "implements" and that don't want the
 * lifecycle granularity, here's a simple (untested!) class that gets
 * rid of it all for you. There's a bit of error-checking left to be
 * done and some trivial services to implement, but otherwise this is
 * usable.
 */
public abstract class AbstractService
        implements LogEnabled, Contextualizable, Configurable,
                Servicable, Initializable, Startable, Disposable
        extends AbstractLogEnabled
{
        // use these in your components to access relevant info
	protected Logger m_logger;
        protected Configuration m_configuration;
        protected Context m_context;
        protected ServiceManager m_serviceManager;

        // you could check these in a runner thread you create
        protected boolean m_initialized = false;
        protected boolean m_started = false;
        protected boolean m_stopped = false;
        protected boolean m_disposed = false;

        // lifecycle interfaces

	public void enableLogging( Logger logger )
	{
		m_logger = logger;
	}
        public void configure( Configuration configuration )
                throws ConfigurationException
        {
                m_configuration = configuration;
        }
        public void contextualize( Context context )
                throws ContextException
        {
                m_context = context;
        }
        public void service( ServiceManager serviceManager )
                throws ServiceException
        {
                m_serviceManager = serviceManager;
        }
        public void initialize()
                throws Exception
        {
		// throw 'services' based on other lifecycle steps into
		// services
		LoggingService ls = new DefaultLoggingService(
				m_logger );
		ConfigurationService confs =
				new DefaultConfigurationService(
						m_configuration );
		ContextService contexts = new DefaultContextService(
				m_context );
		DefaultServiceManager sm = new DefaultServiceManager(
				m_serviceManager );
		sm.put( ls.ROLE, ls );
		sm.put( confs.ROLE, confs );
		sm.put( contexts.ROLE, contexts );

		// throw everything into the same context
		DefaultContext c = new DefaultContext( m_context );
		c.put( "configuration", m_configuration );
		c.put( "services", m_serviceManager );
		c.put( "log", m_logger );

		// call chosen convenience method
		initialize( sm );
		initialize( c );

                m_initialized = true;
        }

        public void start()
                throws Exception
        {
                m_started = true;
        }
        public void stop()
                throws Exception
        {
                m_stopped = true;
        }
        public void dispose()
        {
                m_disposed = true;
        }

	/**
	 * has access to all lifecycle resources; you can override this
	 * to access everything through a context mechanism
	 */
	public void initialize( Context c ) throws Exception
	{ /* empty default implementation */ }

	/**
	 * has access to all lifecycle resources; you can override this
	 * to access everything through a service mechanism
	 */
	public void initialize( ServiceManager sm ) throws Exception
	{ /* empty default implementation */ }
}


example component that doesn't care for thinking about its lifecycle:

interface MyService
{
	public final static ROLE = "MyService";

	public String businessMethod();
}
class MyServiceImpl extends AbstractService implements MyService
{
	MyServiceB myServiceB;

	public MyComponent() {}

	public void initialize( Context c ) throws Exception
	{
		super();

		// don't need to do this. already done
		// m_logger = (Logger)c.get( "logger" );

		// don't need to do this. already done
		// m_serviceManager = (ServiceManager)c.get(
				"services" );

		// want a different name!
		sm = (ServiceManager)c.get( "services" );

		myServiceB = (MyServiceB)sm.lookup(MyServiceB.ROLE);
	}

	public String businessMethod()
	{
		return "what are you doing for christmas this year?";
	}
}



--
To unsubscribe, e-mail:   <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-dev-help@jakarta.apache.org>


Mime
View raw message