Henning had written a post to the list that made that start of a good how-to
so I, with his additional help, made a how to out of it. I had meant to do a
bit more work on it but time has been short of late so I thought it was best
to just get it posted for approval.

Matt Koranda
<?xml version="1.0"?>

<document>

 <properties>
  <title>Services Howto</title>
  <author email="[EMAIL PROTECTED]">Henning P. Schmiedehausen</author>
  <author email="[EMAIL PROTECTED]">Matt Koranda</author>
 </properties>

 <body>
  <section name="Turbine Services Creation">
	<p>
	Adding your own services to Turbine is an easy task. Simply make your class extend <b>org.apache.turbine.services.TurbineBaseService</b>. This is necessary so that the Turbine Service Broker can start up your service.
        </p>

        <p>To make it known to the Turbine itself, you must configure it in the TurbineResources.properties like this:

	<source>
	services.MyServiceName.classname = full.class.name.of.your.service
	</source>
	</p>
	
	<p>
	and you're set, Turbine will now initialize the service if it is requested by an application. Please be aware that 
        your service is <b>not</b> initialized right at Startup. This is called lazy init. If you need your Service to start
        up right away, you must add another property to the TurbineResources.properties:

        <source>
	services.MyServiceName.earlyInit = true
	</source>
	</p>

	<p>
	If you look at the examples of the simple services like
	db/TurbinePoolBrokerService or servlet/TurbineServletService you'll
	get on speed pretty fast.
	</p>
</section>
<section name="In a Nutshell">
	<p>
	  <ul>
	    <li>You must not try to provide a constructor with parameters, best is not to
	  provide any constructor at all, because nothing should be done at
	  construction time (You'll get the default constructor which is fine for us).</li>

	    <li>Your Service will be instantiated exactly once. So it must be threadsafe and 
	  must not use class global variables for session-dependend information.</li>

	    <li>You should provide an init() method which is called when your service is requested for the first
	  time (or at startup if you set earlyInit = true) and should initialize your service dependent code.
          There is lots of confusion of how this init() method should look like because Turbine used different
          methods of Service initialization. Beginning with Turbine 2.2, you should only use the 
	  parameterless variant:</li>
	  </ul>
	</p>
	<source>
	   public void init() throws InitializationException
	   {
	   }
	</source>
	<p>
	 <ul>
	   <li>You <b>must</b> call setInit(true) if your service initializes correctly. Otherwise
	   no user of your service can request it. Right after this, your service might
	   be queried and used by other sessions, so you should not call setInit()
	   prematurely.</li>

	  <li>You might provide a shutdown() method which is called when Turbine shuts
	  down. You can clean up your internal data in this method. You should call
	  setInit(false) as the last thing in shutdown().</li>
	 </ul>
	</p>
</section>
<section name="Style">
	<p>
	  It is good style, that if you build the FooService, to provide <b>your.package.FooService.java</b>
	  with an Interface definition of your service which extends <b>org.apache.turbine.services.Service</b>
	  It should contain a constant SERVICE_NAME with the Turbine visible name of your service like this:
	  
	<source>
        package your.package;

        import org.apache.turbine.services.Service;   

	public interface FooService extends Service
	{
	    /**
	     * The service identifier
	     */
	    public String SERVICE_NAME = "FooService";
	    
	    [...]

	}
	</source>

	</p>
	
	<p>
	  <b>your.package.TurbineFooService.java</b> which extends the <b>org.apache.turbine.services.TurbineBaseService</b> class and implements <b>your.package.FooService</b> and provides the actual code:
	</p>
    
	<source>
        package your.package;

        import org.apache.turbine.services.TurbineBaseService;

	public class TurbineFooService 
		extends TurbineBaseService
		implements FooService
	{
	    /**
	     * Service logic here
	     */
	    [...]

	}
	</source>
	<p>
	<b>your.package.TurbineFoo.java</b> which contains static facade methods for your service along the following lines:

	<source>

          import org.apache.turbine.services.TurbineServices;

	  public class TurbineFoo
	  {
	    protected static FooService getService()
	    {
		return (FooService) TurbineServices
		    .getInstance().getService(FooService.SERVICE_NAME);
	    }

	    [...]

	    public static void fooMethod1()
	    {
	      getService().fooMethod1();
	    }

	    public static int fooMethod2(int bar)
	    {
	      return getService().fooMethod2(bar);
	    }

	    [...]
	  }    
	</source>
	</p>
	<p>
	  to give users of your service the ability to simply write:

	<source>
	  TurbineFoo.fooMethod1();
	</source>
	</p>
	<p>
	  in their code and not to care about which actual Implementation of FooService
	  is running.
        </p>

        <p>
	init() and shutdown() applies to Turbine 2.1/2.2 This might change
	with the lifecycle interfaces in a later release.
	</p>
  </section>

 </body>
</document>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to