You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@turbine.apache.org by gk...@apache.org on 2023/11/17 08:53:38 UTC

(turbine-core) branch trunk updated (ba1d39ce -> 306fff6b)

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

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


    from ba1d39ce Refactored and Fixed Date time formatter: extend with zoneId, use locale in tool, if available, add debug log in RundataLocalizationService
     new 84d70b62 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.
     new 557dd58b Update changes.xml and javadoc, add debug logging
     new 306fff6b Ignore eclipse annotation generated folders. Disable (comment) experimental settings in test classes. Adjust changes.xml.

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .gitignore                                         |  2 +
 conf/test/CompleteTurbineResources.properties      |  8 ++
 conf/test/fulcrumComponentConfiguration.xml        |  2 +
 conf/test/fulcrumRoleConfiguration.xml             |  6 ++
 src/changes/changes.xml                            |  8 ++
 .../turbine/annotation/AnnotationProcessor.java    | 65 ++++++++++++++--
 .../apache/turbine/annotation/TurbineService.java  |  6 +-
 .../services/FieldAnnotatedTurbineBaseService.java | 63 ++++++++++++++++
 .../MethodAnnotatedTurbineBaseService.java         | 59 +++++++++++++++
 .../localization/DateTimeFormatterService.java     |  9 +--
 .../apache/turbine/modules/ActionLoaderTest.java   | 21 ++++++
 ...elocityActionWithExtendedServiceInjection.java} | 38 +++++-----
 .../services/ServiceWithServiceInjection.java      | 88 ++++++++++++++++++++++
 .../services/ServiceWithServiceInjection2.java     | 61 +++++++++++++++
 14 files changed, 402 insertions(+), 34 deletions(-)
 create mode 100644 src/java/org/apache/turbine/services/FieldAnnotatedTurbineBaseService.java
 create mode 100644 src/java/org/apache/turbine/services/MethodAnnotatedTurbineBaseService.java
 copy src/test/org/apache/turbine/modules/actions/{VelocityActionWithServiceInjection.java => VelocityActionWithExtendedServiceInjection.java} (59%)
 create mode 100644 src/test/org/apache/turbine/services/ServiceWithServiceInjection.java
 create mode 100644 src/test/org/apache/turbine/services/ServiceWithServiceInjection2.java


(turbine-core) 01/03: 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.

Posted by gk...@apache.org.
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 <gk...@apache.org>
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:gk@apache.org">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:gk@apache.org">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);
+    }
+}


(turbine-core) 02/03: Update changes.xml and javadoc, add debug logging

Posted by gk...@apache.org.
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 557dd58b8e8da7a5b08813f2ccfc168881658cd6
Author: Georg Kallidis <gk...@apache.org>
AuthorDate: Tue Nov 14 14:23:10 2023 +0100

    Update changes.xml and javadoc, add debug logging
---
 src/changes/changes.xml                                          | 9 +++++++++
 src/java/org/apache/turbine/annotation/AnnotationProcessor.java  | 2 +-
 .../turbine/services/FieldAnnotatedTurbineBaseService.java       | 9 ++++++++-
 .../turbine/services/MethodAnnotatedTurbineBaseService.java      | 4 +++-
 .../actions/VelocityActionWithExtendedServiceInjection.java      | 2 +-
 5 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 9c009851..9db804c2 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -25,6 +25,15 @@
 
   <body>
      <release version="5.2-SNAPSHOT" date="in Git">
+       <action type="add" dev="gk">
+        Provide mechanism to allow auto loading of Turbine (and Fulcrum) services.
+        If a "known" service is extending FieldAnnotatedTurbineBaseService and MethodAnnotatedTurbineBaseService this service could declare in fields and methods more Turbine services 
+        either by annotating them with @TurbineService or autoload a service, which has class level annotation @TurbineService, if itself is annotated as TurbineService.
+        This allows for delegated calls to Turbine services.
+      </action>
+       <action type="add" dev="gk">
+        New  service DateTimeFormatterService and tool DateTimeFormatterTool, which allow date time formatting with locale and zone configuration.
+      </action>
        <action type="update" dev="gk">
         Minor version update to Torque 5.1, Jackson to 2.14.0-rc2, docker-testcontainers to 1.17.5.
       </action>
diff --git a/src/java/org/apache/turbine/annotation/AnnotationProcessor.java b/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
index ad5ad9f6..be1a1873 100644
--- a/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
+++ b/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
@@ -596,7 +596,7 @@ public class AnnotationProcessor
 
         if (StringUtils.isEmpty(serviceName))
         {
-            // Try interface class name
+            // Try interface class name (e.g. used by Fulcrum)
             serviceName = field.getType().getName();
         }
 
diff --git a/src/java/org/apache/turbine/services/FieldAnnotatedTurbineBaseService.java b/src/java/org/apache/turbine/services/FieldAnnotatedTurbineBaseService.java
index 11248d3f..b8037a44 100644
--- a/src/java/org/apache/turbine/services/FieldAnnotatedTurbineBaseService.java
+++ b/src/java/org/apache/turbine/services/FieldAnnotatedTurbineBaseService.java
@@ -1,5 +1,8 @@
 package org.apache.turbine.services;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -25,7 +28,9 @@ 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. 
+ * This class provides the ability to process field annotation {@link TurbineServices} in a Turbine service.
+ * You could enable scanning globally by annotating the class (service) with the annotation {@link TurbineServices}.
+ * Field annotation could then be omitted, if the field class is {@link TurbineServices} annotated.
  * </p>
  *
  */
@@ -33,6 +38,7 @@ public abstract class FieldAnnotatedTurbineBaseService
         extends TurbineBaseService
 {
     
+    private static Logger log = LogManager.getLogger(FieldAnnotatedTurbineBaseService.class);
     /**
      * Performs late initialization.
      *
@@ -47,6 +53,7 @@ public abstract class FieldAnnotatedTurbineBaseService
     public void init() throws InitializationException
     {
         try {
+            log.debug("parsing annotations for {}", this.getClass());
             AnnotationProcessor.process(this, false);
         } catch (TurbineException e) {
             throw new InitializationException(e.getMessage(), e);
diff --git a/src/java/org/apache/turbine/services/MethodAnnotatedTurbineBaseService.java b/src/java/org/apache/turbine/services/MethodAnnotatedTurbineBaseService.java
index 5fcd9212..97c0aba8 100644
--- a/src/java/org/apache/turbine/services/MethodAnnotatedTurbineBaseService.java
+++ b/src/java/org/apache/turbine/services/MethodAnnotatedTurbineBaseService.java
@@ -25,7 +25,9 @@ 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.  
+ * This class provides the ability to process field and method annotations {@link TurbineServices} in a Turbine service.
+ * You could also enable scanning globally by annotating the class (service) with the annotation {@link TurbineServices}, 
+ * then method annotation could be omitted, if the argument class is {@link TurbineServices} annotated.  
  * </p>
  *
  */
diff --git a/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java b/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
index 0e3700cb..75a16f47 100644
--- a/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
+++ b/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
@@ -30,7 +30,7 @@ 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.
+ * Annnotating even an assembler as TurbineService on class level we could omit annotations for fields if class is a Turbine service.
  */
 @TurbineService
 public class VelocityActionWithExtendedServiceInjection extends VelocityAction


(turbine-core) 03/03: Ignore eclipse annotation generated folders. Disable (comment) experimental settings in test classes. Adjust changes.xml.

Posted by gk...@apache.org.
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 306fff6b7e7221fd73b1f223054aefe2756a9a26
Author: Georg Kallidis <gk...@apache.org>
AuthorDate: Thu Nov 16 16:05:13 2023 +0100

    Ignore eclipse annotation generated folders.
    Disable (comment) experimental settings in test classes.
    Adjust changes.xml.
---
 .gitignore                                                    |  2 ++
 src/changes/changes.xml                                       |  7 +++----
 .../actions/VelocityActionWithExtendedServiceInjection.java   | 11 +++++++----
 .../apache/turbine/services/ServiceWithServiceInjection.java  |  8 ++++----
 4 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6a849b47..74171835 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,5 @@ logs
 *.ser
 
 *torque.usersettings.properties
+/.apt_generated/
+/.apt_generated_tests/
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 9db804c2..cddcf8fd 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -26,10 +26,9 @@
   <body>
      <release version="5.2-SNAPSHOT" date="in Git">
        <action type="add" dev="gk">
-        Provide mechanism to allow auto loading of Turbine (and Fulcrum) services.
-        If a "known" service is extending FieldAnnotatedTurbineBaseService and MethodAnnotatedTurbineBaseService this service could declare in fields and methods more Turbine services 
-        either by annotating them with @TurbineService or autoload a service, which has class level annotation @TurbineService, if itself is annotated as TurbineService.
-        This allows for delegated calls to Turbine services.
+        Provide mechanism to allow auto loading of Turbine (and Fulcrum) services. If a "known" service is extending FieldAnnotatedTurbineBaseService or 
+        MethodAnnotatedTurbineBaseService it could declare fields and methods with more Turbine annotations. 
+        Examples are  annotating a service with @TurbineService or autoload a service, which has class level annotation @TurbineService, if the callingclass itself is TurbineService annotated.
       </action>
        <action type="add" dev="gk">
         New  service DateTimeFormatterService and tool DateTimeFormatterTool, which allow date time formatting with locale and zone configuration.
diff --git a/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java b/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
index 75a16f47..9aec0ba3 100644
--- a/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
+++ b/src/test/org/apache/turbine/modules/actions/VelocityActionWithExtendedServiceInjection.java
@@ -30,16 +30,19 @@ 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 fields if class is a Turbine service.
+ * Annnotating even an assembler as TurbineService on class level we could omit 
+ * annotations for fields if class is a Turbine service.
+ * 
+ * This would be quite experimental.
  */
-@TurbineService
+//@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
+    // Annotation could be omitted as the class is annotated could be omitted 
+    @TurbineService
     private ServiceWithServiceInjection serviceWithServiceInjection;
     
 
diff --git a/src/test/org/apache/turbine/services/ServiceWithServiceInjection.java b/src/test/org/apache/turbine/services/ServiceWithServiceInjection.java
index 5ab0b64d..0b801ea4 100644
--- a/src/test/org/apache/turbine/services/ServiceWithServiceInjection.java
+++ b/src/test/org/apache/turbine/services/ServiceWithServiceInjection.java
@@ -36,11 +36,11 @@ import org.apache.turbine.annotation.TurbineService;
 @TurbineService( ServiceWithServiceInjection.SERVICE_NAME )
 public class ServiceWithServiceInjection extends MethodAnnotatedTurbineBaseService implements Initializable /* ServiceWithService */
 {
-
-    String ROLE = ServiceWithServiceInjection.class.getName();
-    
+    // will be checked before ROLE
     static final String SERVICE_NAME = "ServiceWithService";
     
+    String ROLE = ServiceWithServiceInjection.class.getName();
+    
     private static Log log = LogFactory.getLog(ServiceWithServiceInjection.class);
     
     // Test for implicit SERVICE_NAME
@@ -53,7 +53,7 @@ public class ServiceWithServiceInjection extends MethodAnnotatedTurbineBaseServi
  
     // Test for method injected class level SERVICE_NAME
     // Annotation could be omitted as the class is annotated
-    //  @TurbineService
+    @TurbineService
     public void setServiceWithServiceInjection2(ServiceWithServiceInjection2 serviceWithServiceInjection) {
         serviceWithServiceInjection2 = serviceWithServiceInjection;
     }