| <?xml version="1.0"?> |
| <!-- |
| /* |
| * Copyright 2001-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| --> |
| |
| <document> |
| |
| <properties> |
| <title>Services Howto</title> |
| </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 |
| 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> |