This is an automated email from the ASF dual-hosted git repository.

gk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/turbine-core.git

commit 84d70b620c521127965d06ab7a073f2cc46c1735
Author: Georg Kallidis <[email protected]>
AuthorDate: Tue Nov 14 13:00:39 2023 +0100

    Turbine Services annotation: allow class level declaration as an 
alternative to set the service identifier and the ability to 'inherit' turbine 
services  in fields and methods.
    
    Add ready to use Field- and MethodAnnotatedTurbineBaseService to allow for 
referencing dependent Turbine Services.
    
    Remove role field in DateTimeFormatterService, which might result in wrong 
service name (in AnnotationProcessor checkServiceOrRoleInField method).
    
    Test: Adding three level dependency Turbine Service classes: 
VelocityActionWithExtendedServiceInjection -> ServiceWithServiceInjection -> 
ServiceWithServiceInjection2. Added test class 
VelocityActionWithExtendedServiceInjection with field 
ServiceWithServiceInjection. Adapt test configurations.
---
 conf/test/CompleteTurbineResources.properties      |  8 ++
 conf/test/fulcrumComponentConfiguration.xml        |  2 +
 conf/test/fulcrumRoleConfiguration.xml             |  6 ++
 .../turbine/annotation/AnnotationProcessor.java    | 63 ++++++++++++++--
 .../apache/turbine/annotation/TurbineService.java  |  6 +-
 .../services/FieldAnnotatedTurbineBaseService.java | 56 ++++++++++++++
 .../MethodAnnotatedTurbineBaseService.java         | 57 ++++++++++++++
 .../localization/DateTimeFormatterService.java     |  9 +--
 .../apache/turbine/modules/ActionLoaderTest.java   | 21 ++++++
 ...VelocityActionWithExtendedServiceInjection.java | 61 +++++++++++++++
 .../services/ServiceWithServiceInjection.java      | 88 ++++++++++++++++++++++
 .../services/ServiceWithServiceInjection2.java     | 61 +++++++++++++++
 12 files changed, 426 insertions(+), 12 deletions(-)

diff --git a/conf/test/CompleteTurbineResources.properties 
b/conf/test/CompleteTurbineResources.properties
index c8cbc016..4df93ad8 100644
--- a/conf/test/CompleteTurbineResources.properties
+++ b/conf/test/CompleteTurbineResources.properties
@@ -679,3 +679,11 @@ 
services.URLMapperService.classname=org.apache.turbine.services.urlmapper.Turbin
 #tool.request.mlink=org.apache.turbine.services.urlmapper.MappedTemplateLink
 
 services.URLMapperService.configFile = conf/turbine-url-mapping.xml
+
+#
+#
+# Additional Services 
+#
+#
+services.ServiceWithService.classname=org.apache.turbine.services.ServiceWithServiceInjection
+services.ServiceWithService2.classname=org.apache.turbine.services.ServiceWithServiceInjection2
diff --git a/conf/test/fulcrumComponentConfiguration.xml 
b/conf/test/fulcrumComponentConfiguration.xml
index c45ee5bf..30003e01 100644
--- a/conf/test/fulcrumComponentConfiguration.xml
+++ b/conf/test/fulcrumComponentConfiguration.xml
@@ -110,5 +110,7 @@
             </properties>
         </configuration>
     </quartz>
+    
+    <serviceWithServiceInjection/>
 
 </componentConfig>
diff --git a/conf/test/fulcrumRoleConfiguration.xml 
b/conf/test/fulcrumRoleConfiguration.xml
index 531c364c..dd2468f9 100644
--- a/conf/test/fulcrumRoleConfiguration.xml
+++ b/conf/test/fulcrumRoleConfiguration.xml
@@ -121,6 +121,12 @@
         name="org.apache.fulcrum.security.model.ACLFactory"
         shorthand="aclFactory"
         
default-class="org.apache.fulcrum.security.model.turbine.TurbineACLFactory"/>
+        
+    <role
+        name="org.apache.turbine.services.ServiceWithServiceInjection"
+        shorthand="serviceWithServiceInjection"
+        default-class="org.apache.turbine.services.ServiceWithServiceInjection"
+     /> 
 
 </role-list>
 
diff --git a/src/java/org/apache/turbine/annotation/AnnotationProcessor.java 
b/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
index 8979f51f..ad5ad9f6 100644
--- a/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
+++ b/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
@@ -37,6 +37,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.turbine.Turbine;
 import org.apache.turbine.modules.Loader;
+import org.apache.turbine.services.Service;
 import org.apache.turbine.services.ServiceManager;
 import org.apache.turbine.services.TurbineServices;
 import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
@@ -249,6 +250,13 @@ public class AnnotationProcessor
         AssemblerBrokerService assembler = null;
         PoolService pool= null;
         Class<?> clazz = object.getClass();
+        
+        boolean isTurbineService = false;
+        if ( clazz.isAnnotationPresent(TurbineService.class)) {
+            TurbineService service = clazz.getAnnotation(TurbineService.class);
+            log.debug("retrieved class annotation: "+ service);
+            isTurbineService = true;
+        } 
 
         while (clazz != null)
         {
@@ -295,17 +303,29 @@ public class AnnotationProcessor
                         injectTurbineTool(object, pool, field, (TurbineTool) 
a);
                     }
                 }
+                if (isTurbineService)
+                {
+                    if 
(field.getType().isAnnotationPresent(TurbineService.class)) {
+                        TurbineService service = 
field.getType().getAnnotation(TurbineService.class);
+                        log.debug("retrieved implicit class annotation: "+ 
service);
+                        if (manager == null)
+                        {
+                            manager = TurbineServices.getInstance();
+                        }
+                        injectTurbineService(object, manager, field, service);
+                    }    
+                }
             }
 
             if (hasTurbineServicesInMethodFields) {
-                manager = processMethods(object, manager, clazz);
+                manager = processMethods(object, manager, clazz, 
isTurbineService);
             }
 
             clazz = clazz.getSuperclass();
         }
     }
 
-    private static ServiceManager processMethods(Object object, ServiceManager 
manager, Class<?> clazz) throws TurbineException {
+    private static ServiceManager processMethods(Object object, ServiceManager 
manager, Class<?> clazz, boolean isTurbineService) throws TurbineException {
         Method[] methods = clazz.getMethods();
 
         for (Method method : methods)
@@ -323,6 +343,23 @@ public class AnnotationProcessor
                     injectTurbineService(object, manager, method, 
(TurbineService) a);
                 }
             }
+            if (isTurbineService)
+            {
+                if (manager == null)
+                {
+                    manager = TurbineServices.getInstance();
+                }
+                Class<?>[] classes = method.getParameterTypes();
+                for (Class<?> c : classes)
+                {
+                    if ( c.isAnnotationPresent(TurbineService.class)) {
+                        TurbineService service = 
c.getAnnotation(TurbineService.class);
+                        log.debug("retrieved implicit service in Turbien 
service: "+ service);
+                        injectTurbineService(object, manager, method, service);
+                    } 
+                    
+                }
+            }
         }
         return manager;
     }
@@ -538,15 +575,23 @@ public class AnnotationProcessor
     {
         String serviceName = null;
         // Check for annotation value
-        if (StringUtils.isNotEmpty(annotation.value()))
+        if (annotation != null && StringUtils.isNotEmpty(annotation.value()))
         {
             serviceName = annotation.value();
         }
         // Check for fields SERVICE_NAME and ROLE
         else
-        {
+        { 
+            // check field level annotation
             Field[] typeFields = field.getType().getFields();
             serviceName = checkServiceOrRoleInField(serviceName, typeFields);
+            // if it is the default Service, we check class level annotation
+            if ( (serviceName == null || 
serviceName.equals(Service.SERVICE_NAME)) &&
+                    field.getType().isAnnotationPresent(TurbineService.class)) 
{
+                TurbineService service = 
field.getType().getAnnotation(TurbineService.class);
+                log.debug("retrieved class annotation: "+ service);
+                serviceName = service.value();
+            } 
         }
 
         if (StringUtils.isEmpty(serviceName))
@@ -586,7 +631,7 @@ public class AnnotationProcessor
     {
         String serviceName = null;
         // Check for annotation value
-        if (StringUtils.isNotEmpty(annotation.value()))
+        if (annotation != null && StringUtils.isNotEmpty(annotation.value()))
         {
             serviceName = annotation.value();
         }
@@ -598,6 +643,14 @@ public class AnnotationProcessor
                 Field[] fields = c.getFields();
                 // Check for fields SERVICE_NAME and ROLE
                 serviceName = checkServiceOrRoleInField(serviceName, fields);
+                
+                if ( (serviceName == null || 
serviceName.equals(Service.SERVICE_NAME)) &&
+                        c.isAnnotationPresent(TurbineService.class)) {
+                    TurbineService service = 
c.getAnnotation(TurbineService.class);
+                    log.debug("retrieved class annotation: "+ service);
+                    serviceName = service.value();
+                } 
+                
             }
         }
 
diff --git a/src/java/org/apache/turbine/annotation/TurbineService.java 
b/src/java/org/apache/turbine/annotation/TurbineService.java
index 453d8b27..e9d653d2 100644
--- a/src/java/org/apache/turbine/annotation/TurbineService.java
+++ b/src/java/org/apache/turbine/annotation/TurbineService.java
@@ -26,10 +26,12 @@ import java.lang.annotation.Target;
 
 
 /**
- * Annotation to mark fields in modules that require a service to be injected
+ * Annotation to mark class and fields in modules that require a service to be 
injected
+ * 
+ * Explicit field annotation of {@link #SERVICE_NAME} will take precedence of 
class annotation. 
  */
 @Retention( RetentionPolicy.RUNTIME )
-@Target( {ElementType.FIELD, ElementType.METHOD} )
+@Target( {ElementType.TYPE, ElementType.FIELD, ElementType.METHOD} )
 public @interface TurbineService
 {
     /**
diff --git 
a/src/java/org/apache/turbine/services/FieldAnnotatedTurbineBaseService.java 
b/src/java/org/apache/turbine/services/FieldAnnotatedTurbineBaseService.java
new file mode 100644
index 00000000..11248d3f
--- /dev/null
+++ b/src/java/org/apache/turbine/services/FieldAnnotatedTurbineBaseService.java
@@ -0,0 +1,56 @@
+package org.apache.turbine.services;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.turbine.annotation.AnnotationProcessor;
+import org.apache.turbine.util.TurbineException;
+
+/**
+ * <p>This class provides a <code>Service</code> implementation that
+ * Services used in Turbine are required to extend. 
+ * This class provides the ability to process field annotation {@link 
TurbineServices} in a Turbine service. 
+ * </p>
+ *
+ */
+public abstract class FieldAnnotatedTurbineBaseService
+        extends TurbineBaseService
+{
+    
+    /**
+     * Performs late initialization.
+     *
+     * If your class relies on early initialization, and the object it
+     * expects was not received, you can use late initialization to
+     * throw an exception and complain.
+     *
+     * @throws InitializationException if initialization of this
+     * class was not successful.
+     */
+    @Override
+    public void init() throws InitializationException
+    {
+        try {
+            AnnotationProcessor.process(this, false);
+        } catch (TurbineException e) {
+            throw new InitializationException(e.getMessage(), e);
+        }
+        setInit(true);
+    }
+}
diff --git 
a/src/java/org/apache/turbine/services/MethodAnnotatedTurbineBaseService.java 
b/src/java/org/apache/turbine/services/MethodAnnotatedTurbineBaseService.java
new file mode 100644
index 00000000..5fcd9212
--- /dev/null
+++ 
b/src/java/org/apache/turbine/services/MethodAnnotatedTurbineBaseService.java
@@ -0,0 +1,57 @@
+package org.apache.turbine.services;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.turbine.annotation.AnnotationProcessor;
+import org.apache.turbine.util.TurbineException;
+
+/**
+ * <p>This class provides a <code>Service</code> implementation that
+ * Services used in Turbine are required to extend. 
+ *  This class provides the ability to process field and method annotations 
{@link TurbineServices} in a Turbine service.  
+ * </p>
+ *
+ */
+public abstract class MethodAnnotatedTurbineBaseService
+        extends TurbineBaseService
+{
+    
+    /**
+     * Performs late initialization.
+     *
+     * If your class relies on early initialization, and the object it
+     * expects was not received, you can use late initialization to
+     * throw an exception and complain.
+     *
+     * @throws InitializationException if initialization of this
+     * class was not successful.
+     */
+    @Override
+    public void init() throws InitializationException
+    {
+        setInit(true);
+        try {
+            // if second parameter is true, we get into an endless loop if 
setInit is done last
+            AnnotationProcessor.process(this, true);
+        } catch (TurbineException e) {
+            throw new InitializationException(e.getMessage(), e);
+        }
+    }
+}
diff --git 
a/src/java/org/apache/turbine/services/localization/DateTimeFormatterService.java
 
b/src/java/org/apache/turbine/services/localization/DateTimeFormatterService.java
index 9733be0b..33659901 100644
--- 
a/src/java/org/apache/turbine/services/localization/DateTimeFormatterService.java
+++ 
b/src/java/org/apache/turbine/services/localization/DateTimeFormatterService.java
@@ -11,6 +11,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.turbine.Turbine;
+import org.apache.turbine.annotation.TurbineService;
 import org.apache.turbine.services.TurbineBaseService;
 import org.apache.turbine.util.LocaleUtils;
 
@@ -24,12 +25,10 @@ import org.apache.turbine.util.LocaleUtils;
  * if the source and the target format do not match appropriately.
  *
  */
+@TurbineService("DateTimeFormatterService")
 public class DateTimeFormatterService
-        extends TurbineBaseService implements DateTimeFormatterInterface {
-
-    public static final String SERVICE_NAME = "DateTimeFormatterService";
-
-    public static final String ROLE = DateTimeFormatterService.class.getName();
+        extends TurbineBaseService implements DateTimeFormatterInterface 
+{
 
     private String formatPattern = null;
 
diff --git a/src/test/org/apache/turbine/modules/ActionLoaderTest.java 
b/src/test/org/apache/turbine/modules/ActionLoaderTest.java
index 3f06d316..fc5a4be6 100644
--- a/src/test/org/apache/turbine/modules/ActionLoaderTest.java
+++ b/src/test/org/apache/turbine/modules/ActionLoaderTest.java
@@ -332,4 +332,25 @@ public class ActionLoaderTest extends BaseTestCase
             fail("Should not have thrown an exception.");
         }
     }
+    
+    @Test
+    public void testDoPerformWithExtendedServiceInjection() throws Exception
+    {
+        RunData data = getRunData(request, response, config);
+        PipelineData pipelineData = data;
+        data.setAction("VelocityActionWithExtendedServiceInjection");
+
+        try
+        {
+            ActionLoader.getInstance().exec(pipelineData, data.getAction());
+            Context context = (Context)
+                            
data.getTemplateInfo().getTemplateContext(VelocityService.CONTEXT);
+            assertTrue( context.get( "mykey" ) != null );
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            fail("Should not have thrown an exception.");
+        }
+    }
 }
diff --git 
a/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
 
b/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
new file mode 100644
index 00000000..0e3700cb
--- /dev/null
+++ 
b/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
@@ -0,0 +1,61 @@
+package org.apache.turbine.modules.actions;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.turbine.annotation.TurbineService;
+import org.apache.turbine.pipeline.PipelineData;
+import org.apache.turbine.services.ServiceWithServiceInjection;
+import org.apache.velocity.context.Context;
+
+/**
+ * Annnotating even an assembler as TurbineService on class level we could 
omit annotations for dependent Turbine services.
+ */
+@TurbineService
+public class VelocityActionWithExtendedServiceInjection extends VelocityAction
+{
+    private static Log log = 
LogFactory.getLog(VelocityActionWithExtendedServiceInjection.class);
+
+    // Test for class level SERVICE_NAME in ServiceWithServiceInjection
+    // Annotation could be omitted as the class is annotated
+    // @TurbineService
+    private ServiceWithServiceInjection serviceWithServiceInjection;
+    
+
+    /**
+     *  Default action is nothing.
+     *
+     * @param  pipelineData           Current RunData information
+     * @param  context        Context to populate
+     * @throws  Exception  Thrown on error
+     */
+    @Override
+    public void doPerform(PipelineData pipelineData, Context context) throws 
Exception
+    {
+        log.debug("Calling doPerform(PipelineData)");
+        assertNotNull("field injected serviceWithServiceInjection object was 
Null.", serviceWithServiceInjection);
+        serviceWithServiceInjection.callService();
+        context.put("mykey","x");
+    }
+}
diff --git 
a/src/test/org/apache/turbine/services/ServiceWithServiceInjection.java 
b/src/test/org/apache/turbine/services/ServiceWithServiceInjection.java
new file mode 100644
index 00000000..5ab0b64d
--- /dev/null
+++ b/src/test/org/apache/turbine/services/ServiceWithServiceInjection.java
@@ -0,0 +1,88 @@
+package org.apache.turbine.services;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fulcrum.localization.LocalizationService;
+import org.apache.turbine.annotation.TurbineService;
+/**
+ * This service is used for testing injection of services in fields and 
methods and class level declaration of 
+ * {@link TurbineService} without interface. 
+ *
+ * @author <a href="mailto:[email protected]";>Georg Kallidis</a>
+ */
+@TurbineService( ServiceWithServiceInjection.SERVICE_NAME )
+public class ServiceWithServiceInjection extends 
MethodAnnotatedTurbineBaseService implements Initializable /* 
ServiceWithService */
+{
+
+    String ROLE = ServiceWithServiceInjection.class.getName();
+    
+    static final String SERVICE_NAME = "ServiceWithService";
+    
+    private static Log log = 
LogFactory.getLog(ServiceWithServiceInjection.class);
+    
+    // Test for implicit SERVICE_NAME
+    // we need the declaration as this is not by default a Turbine Service
+    @TurbineService
+    private LocalizationService localizationService;
+    
+    static private ServiceWithServiceInjection2 serviceWithServiceInjection2;
+    
+ 
+    // Test for method injected class level SERVICE_NAME
+    // Annotation could be omitted as the class is annotated
+    //  @TurbineService
+    public void setServiceWithServiceInjection2(ServiceWithServiceInjection2 
serviceWithServiceInjection) {
+        serviceWithServiceInjection2 = serviceWithServiceInjection;
+    }
+    
+    /**
+     * Initializes the service.
+     */
+    @Override
+    public void initialize() throws Exception 
+    {
+        log.debug("Calling initializable()");
+        // do not call  AnnotationProcessor.process(this); here as it will 
result in an endless looping;
+    }
+    
+    /**
+     * Initializes the service.
+     */
+    @Override
+    public void init() throws InitializationException
+    {
+        super.init();
+        log.info("localizationService is: " + localizationService);
+//        setInit(true);
+    }
+    
+    public void callService() 
+    {
+        assertNotNull("field injected localizationService object was Null.", 
localizationService);
+        assertNotNull("method injected service serviceWithServiceInjection2 
object was Null.", serviceWithServiceInjection2);
+        ServiceWithServiceInjection.serviceWithServiceInjection2.callService();
+    }
+}
diff --git 
a/src/test/org/apache/turbine/services/ServiceWithServiceInjection2.java 
b/src/test/org/apache/turbine/services/ServiceWithServiceInjection2.java
new file mode 100644
index 00000000..1e5b96f9
--- /dev/null
+++ b/src/test/org/apache/turbine/services/ServiceWithServiceInjection2.java
@@ -0,0 +1,61 @@
+package org.apache.turbine.services;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fulcrum.localization.LocalizationService;
+import org.apache.turbine.annotation.TurbineService;
+/**
+ * This service is used for testing 2nd level injection of services and class 
level declaration of 
+ * {@link TurbineService} (interface is optional). 
+ *
+ * @author <a href="mailto:[email protected]";>Georg Kallidis</a>
+ */
+@TurbineService( ServiceWithServiceInjection2.SERVICE_NAME )
+public class ServiceWithServiceInjection2 extends 
FieldAnnotatedTurbineBaseService 
+{
+    
+    static final String SERVICE_NAME = "ServiceWithService2";
+    
+    private static Log log = 
LogFactory.getLog(ServiceWithServiceInjection2.class);
+    
+    // Test for implicit SERVICE_NAME
+    @TurbineService
+    private LocalizationService localizationService2;
+    
+    /**
+     * Initializes the service.
+     */
+    @Override
+    public void init() throws InitializationException
+    {
+        super.init();
+        log.info("localizationService2 is: " + localizationService2);
+//        setInit(true);
+    }
+    
+    public void callService() 
+    {
+        assertNotNull("localizationService2 object was Null.", 
localizationService2);
+    }
+}

Reply via email to