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 2d151a0dfeaf235a4b07cc4f0f06fcc24bb66311
Author: Georg Kallidis <[email protected]>
AuthorDate: Mon Dec 6 14:25:41 2021 +0100

    enable method annotation for turbine services, with test, not enabled by 
default due to performance penalty
---
 .../turbine/annotation/AnnotationProcessor.java    | 141 +++++++++++++++++----
 .../turbine/annotation/AnnotatedMethodsTest.java   |  99 +++++++++++++++
 .../annotation/AnnotationProcessorTest.java        |   7 +
 3 files changed, 220 insertions(+), 27 deletions(-)

diff --git a/src/java/org/apache/turbine/annotation/AnnotationProcessor.java 
b/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
index 7913dce..aaa384c 100644
--- a/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
+++ b/src/java/org/apache/turbine/annotation/AnnotationProcessor.java
@@ -22,6 +22,8 @@ package org.apache.turbine.annotation;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -227,6 +229,18 @@ public class AnnotationProcessor
      */
     public static void process(Object object) throws TurbineException
     {
+        process(object, false);
+    }
+
+    /**
+     * Search for annotated fields and optionally of method fields of the 
object and inject the appropriate
+     * objects
+     *
+     * @param object the object
+     * @throws TurbineException if the objects could not be injected
+     */
+    public static void process(Object object, Boolean 
hasTurbineServicesInMethodFields) throws TurbineException
+    {
         ServiceManager manager = null;
         Configuration config = null;
         AssemblerBrokerService assembler = null;
@@ -270,10 +284,36 @@ public class AnnotationProcessor
                 }
             }
 
+            if (hasTurbineServicesInMethodFields) {
+                manager = processMethods(object, manager, clazz);
+            }
+
             clazz = clazz.getSuperclass();
         }
     }
 
+    private static ServiceManager processMethods(Object object, ServiceManager 
manager, Class<?> clazz) throws TurbineException {
+        Method[] methods = clazz.getMethods();
+
+        for (Method method : methods)
+        {
+            Annotation[] annotations = getAnnotations(method);
+            for (Annotation a : annotations)
+            {
+                if (a instanceof TurbineService)
+                {
+
+                    if (manager == null)
+                    {
+                        manager = TurbineServices.getInstance();
+                    }
+                    injectTurbineService(object, manager, method, 
(TurbineService) a);
+                }
+            }
+        }
+        return manager;
+    }
+
     /**
      * Inject Turbine configuration into field of object
      *
@@ -451,33 +491,7 @@ public class AnnotationProcessor
         else
         {
             Field[] typeFields = field.getType().getFields();
-            for (Field f : typeFields)
-            {
-                if (TurbineService.SERVICE_NAME.equals(f.getName()))
-                {
-                    try
-                    {
-                        serviceName = (String)f.get(null);
-                    }
-                    catch (IllegalArgumentException | IllegalAccessException e)
-                    {
-                        continue;
-                    }
-                    break;
-                }
-                else if (TurbineService.ROLE.equals(f.getName()))
-                {
-                    try
-                    {
-                        serviceName = (String)f.get(null);
-                    }
-                    catch (IllegalArgumentException | IllegalAccessException e)
-                    {
-                        continue;
-                    }
-                    break;
-                }
-            }
+            serviceName = checkServiceOrRoleInField(serviceName, typeFields);
         }
 
         if (StringUtils.isEmpty(serviceName))
@@ -503,4 +517,77 @@ public class AnnotationProcessor
                     + serviceName + " into object " + object, e);
         }
     }
+
+    private static void injectTurbineService(Object object, ServiceManager 
manager, Method method, TurbineService annotation) throws TurbineException
+    {
+        String serviceName = null;
+        // Check for annotation value
+        if (StringUtils.isNotEmpty(annotation.value()))
+        {
+            serviceName = annotation.value();
+        }
+        else
+        {
+            Class<?>[] classes = method.getParameterTypes();
+            for (Class c : classes)
+            {
+                Field[] fields = c.getFields();
+                // Check for fields SERVICE_NAME and ROLE
+                serviceName = checkServiceOrRoleInField(serviceName, fields);
+            }
+        }
+
+        log.debug("Looking up service for injection: {} for object {}", 
serviceName, object);
+        if (StringUtils.isEmpty(serviceName))
+        {
+            // Try interface class name
+            serviceName = method.getName();
+        }
+
+        Object service = manager.getService(serviceName); // throws Exception 
on unknown service
+        method.setAccessible(true);
+
+        try
+        {
+            log.debug("Injection of {} into object {}", serviceName, object);
+
+            Object[] paramValues = new Object[1];
+            paramValues[0] = service;
+            method.invoke(object, paramValues);
+        }
+        catch (IllegalArgumentException | IllegalAccessException | 
InvocationTargetException e)
+        {
+            throw new TurbineException("Could not inject service "
+                    + serviceName + " into object " + object, e);
+        }
+    }
+
+    private static String checkServiceOrRoleInField(String serviceName, 
Field[] fields) {
+        for (Field f : fields)
+            if (TurbineService.SERVICE_NAME.equals(f.getName()))
+            {
+                try
+                {
+                    serviceName = (String)f.get(null);
+                }
+                catch (IllegalArgumentException | IllegalAccessException e)
+                {
+                    continue;
+                }
+                break;
+            }
+            else if (TurbineService.ROLE.equals(f.getName()))
+            {
+                try
+                {
+                    serviceName = (String)f.get(null);
+                }
+                catch (IllegalArgumentException | IllegalAccessException e)
+                {
+                    continue;
+                }
+                break;
+            }
+        return serviceName;
+    }
 }
diff --git a/src/test/org/apache/turbine/annotation/AnnotatedMethodsTest.java 
b/src/test/org/apache/turbine/annotation/AnnotatedMethodsTest.java
new file mode 100644
index 0000000..b75d79d
--- /dev/null
+++ b/src/test/org/apache/turbine/annotation/AnnotatedMethodsTest.java
@@ -0,0 +1,99 @@
+package org.apache.turbine.annotation;
+
+
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
+import org.apache.turbine.services.localization.DateTimeFormatterInterface;
+import org.apache.turbine.services.localization.DateTimeFormatterService;
+import org.apache.turbine.services.pull.PullService;
+import org.apache.turbine.services.pull.util.DateTimeFormatterTool;
+import org.apache.turbine.util.TurbineConfig;
+import org.apache.turbine.util.TurbineException;
+import org.apache.velocity.context.Context;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestFactory;
+import org.junit.jupiter.api.function.ThrowingConsumer;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAccessor;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test class for AnnotatedMethodsTest to test method fields annotation
+ *
+ */
+public class AnnotatedMethodsTest {
+
+    private static AssemblerBrokerService asb;
+    private static TurbineConfig tc = null;
+    private static PullService pullService;
+
+    @BeforeAll
+    public static void setup()
+    {
+        // required to initialize defaults
+        tc = new TurbineConfig(
+                        ".",
+                        "/conf/test/CompleteTurbineResources.properties");
+        tc.initialize();
+    }
+
+    @AfterAll
+    public static void tearDown()
+    {
+        tc.dispose();
+    }
+
+    @TurbineService
+    public void setAssemblerBrokerService(AssemblerBrokerService df)
+    {
+        AnnotatedMethodsTest.asb = df;
+    }
+
+    @TurbineService
+    public static void setPullService(PullService pullService) {
+        AnnotatedMethodsTest.pullService = pullService;
+    }
+
+    /*
+     * Class under test for String format(Date, String)
+     */
+    @Test
+    void testTool() throws TurbineException
+    {
+        AnnotationProcessor.process(this, true);
+        assertNotNull(pullService);
+        assertNotNull(asb);
+    }
+
+    @Tag("performance") // ignore in surefire, activating seems to be still 
buggy ?
+    @Test
+    public void testProcessingPerformance() throws TurbineException
+    {
+        long startTime = System.currentTimeMillis();
+
+        for (int i = 0; i < 100000; i++)
+        {
+            AnnotationProcessor.process(this, true);
+        }
+
+        System.out.println(System.currentTimeMillis() - startTime);
+    }
+
+}
diff --git 
a/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java 
b/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java
index 3444b8c..c69fdc3 100644
--- a/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java
+++ b/src/test/org/apache/turbine/annotation/AnnotationProcessorTest.java
@@ -39,6 +39,8 @@ import 
org.apache.turbine.annotation.AnnotationProcessor.ConditionType;
 import org.apache.turbine.modules.Screen;
 import org.apache.turbine.modules.ScreenLoader;
 import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
+import org.apache.turbine.services.localization.DateTimeFormatterService;
+import org.apache.turbine.services.localization.DateTimeFormatterServiceTest;
 import org.apache.turbine.util.RunData;
 import org.apache.turbine.util.TurbineConfig;
 import org.apache.turbine.util.TurbineException;
@@ -219,4 +221,9 @@ public class AnnotationProcessorTest
 
         System.out.println(System.currentTimeMillis() - startTime);
     }
+
+    @TurbineService
+    private DateTimeFormatterService df;
+
+
 }

Reply via email to