You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2011/12/01 19:38:09 UTC

svn commit: r1209175 - in /tapestry/tapestry5/trunk/tapestry-ioc/src: main/java/org/apache/tapestry5/ioc/internal/ main/java/org/apache/tapestry5/ioc/internal/util/ test/java/org/apache/tapestry5/ioc/

Author: hlship
Date: Thu Dec  1 18:38:08 2011
New Revision: 1209175

URL: http://svn.apache.org/viewvc?rev=1209175&view=rev
Log:
TAP5-1765: PerThread scope is not honored when service is created using autobuild

Modified:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ConstructorInvoker.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MethodInvoker.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/PerThreadModule.java

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java?rev=1209175&r1=1209174&r2=1209175&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java Thu Dec  1 18:38:08 2011
@@ -114,10 +114,10 @@ public class ContributionDefImpl impleme
 
         try
         {
-            Object[] parameters = InternalUtils.calculateParametersForMethod(contributorMethod, resources,
+            ObjectCreator[] parameters = InternalUtils.calculateParametersForMethod(contributorMethod, resources,
                     injectionResources, resources.getTracker());
 
-            contributorMethod.invoke(moduleInstance, parameters);
+            contributorMethod.invoke(moduleInstance, InternalUtils.realizeObjects(parameters));
         } catch (InvocationTargetException ex)
         {
             fail = ex.getTargetException();

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java?rev=1209175&r1=1209174&r2=1209175&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java Thu Dec  1 18:38:08 2011
@@ -422,11 +422,13 @@ public class ModuleImpl implements Modul
         {
             insideConstructor = true;
 
-            Object[] parameterValues = InternalUtils.calculateParameters(locator, resources,
+            ObjectCreator[] parameterValues = InternalUtils.calculateParameters(locator, resources,
                     constructor.getParameterTypes(), constructor.getGenericParameterTypes(),
                     constructor.getParameterAnnotations(), registry);
 
-            Object result = constructor.newInstance(parameterValues);
+            Object[] realized = InternalUtils.realizeObjects(parameterValues);
+
+            Object result = constructor.newInstance(realized);
 
             InternalUtils.injectIntoFields(result, locator, resources, registry);
 

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ConstructorInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ConstructorInvoker.java?rev=1209175&r1=1209174&r2=1209175&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ConstructorInvoker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/ConstructorInvoker.java Thu Dec  1 18:38:08 2011
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.ioc.internal.util;
 
 import org.apache.tapestry5.ioc.Invokable;
+import org.apache.tapestry5.ioc.ObjectCreator;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -28,9 +29,9 @@ public class ConstructorInvoker<T> imple
 {
     private final Constructor<T> constructor;
 
-    private final Object[] constructorParameters;
+    private final ObjectCreator[] constructorParameters;
 
-    public ConstructorInvoker(Constructor constructor, Object[] constructorParameters)
+    public ConstructorInvoker(Constructor constructor, ObjectCreator[] constructorParameters)
     {
         this.constructor = constructor;
         this.constructorParameters = constructorParameters;
@@ -40,9 +41,11 @@ public class ConstructorInvoker<T> imple
     {
         Throwable fail;
 
+        Object[] realized = InternalUtils.realizeObjects(constructorParameters);
+
         try
         {
-            return constructor.newInstance(constructorParameters);
+            return constructor.newInstance(realized);
         } catch (InvocationTargetException ex)
         {
             fail = ex.getTargetException();

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java?rev=1209175&r1=1209174&r2=1209175&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java Thu Dec  1 18:38:08 2011
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry5.ioc.internal.util;
 
+import org.apache.tapestry5.func.F;
 import org.apache.tapestry5.func.Mapper;
 import org.apache.tapestry5.func.Predicate;
 import org.apache.tapestry5.internal.plastic.PlasticInternalUtils;
@@ -175,10 +176,21 @@ public class InternalUtils
         return null;
     }
 
-    private static Object calculateInjection(Class injectionType, Type genericType, final Annotation[] annotations,
-                                             ObjectLocator locator, InjectionResources resources)
+    private static ObjectCreator<Object> asObjectCreator(final Object fixedValue)
     {
-        AnnotationProvider provider = new AnnotationProvider()
+        return new ObjectCreator<Object>()
+        {
+            public Object createObject()
+            {
+                return fixedValue;
+            }
+        };
+    }
+
+    private static ObjectCreator calculateInjection(final Class injectionType, Type genericType, final Annotation[] annotations,
+                                                    final ObjectLocator locator, InjectionResources resources)
+    {
+        final AnnotationProvider provider = new AnnotationProvider()
         {
             public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
             {
@@ -195,14 +207,14 @@ public class InternalUtils
         {
             String serviceId = is.value();
 
-            return locator.getService(serviceId, injectionType);
+            return asObjectCreator(locator.getService(serviceId, injectionType));
         }
 
         Named named = provider.getAnnotation(Named.class);
 
         if (named != null)
         {
-            return locator.getService(named.value(), injectionType);
+            return asObjectCreator(locator.getService(named.value(), injectionType));
         }
 
         // In the absence of @InjectService, try some autowiring. First, does the
@@ -213,30 +225,47 @@ public class InternalUtils
             Object result = resources.findResource(injectionType, genericType);
 
             if (result != null)
-                return result;
+            {
+                return asObjectCreator(result);
+            }
+        }
+
+        // TAP5-1765: For @Autobuild, special case where we always compute a fresh value
+        // for the injection on every use.  Elsewhere, we compute once when generating the
+        // construction plan and just use the singleton value repeatedly.
+
+        if (provider.getAnnotation(Autobuild.class) != null)
+        {
+            return new ObjectCreator()
+            {
+                public Object createObject()
+                {
+                    return locator.getObject(injectionType, provider);
+                }
+            };
         }
 
         // Otherwise, make use of the MasterObjectProvider service to resolve this type (plus
         // any other information gleaned from additional annotation) into the correct object.
 
-        return locator.getObject(injectionType, provider);
+        return asObjectCreator(locator.getObject(injectionType, provider));
     }
 
-    public static Object[] calculateParametersForMethod(Method method, ObjectLocator locator,
-                                                        InjectionResources resources, OperationTracker tracker)
+    public static ObjectCreator[] calculateParametersForMethod(Method method, ObjectLocator locator,
+                                                               InjectionResources resources, OperationTracker tracker)
     {
 
         return calculateParameters(locator, resources, method.getParameterTypes(), method.getGenericParameterTypes(),
                 method.getParameterAnnotations(), tracker);
     }
 
-    public static Object[] calculateParameters(final ObjectLocator locator, final InjectionResources resources,
-                                               Class[] parameterTypes, final Type[] genericTypes, Annotation[][] parameterAnnotations,
-                                               OperationTracker tracker)
+    public static ObjectCreator[] calculateParameters(final ObjectLocator locator, final InjectionResources resources,
+                                                      Class[] parameterTypes, final Type[] genericTypes, Annotation[][] parameterAnnotations,
+                                                      OperationTracker tracker)
     {
         int parameterCount = parameterTypes.length;
 
-        Object[] parameters = new Object[parameterCount];
+        ObjectCreator[] parameters = new ObjectCreator[parameterCount];
 
         for (int i = 0; i < parameterCount; i++)
         {
@@ -247,9 +276,9 @@ public class InternalUtils
             String description = String.format("Determining injection value for parameter #%d (%s)", i + 1,
                     PlasticUtils.toTypeName(type));
 
-            final Invokable<Object> operation = new Invokable<Object>()
+            final Invokable<ObjectCreator> operation = new Invokable<ObjectCreator>()
             {
-                public Object invoke()
+                public ObjectCreator invoke()
                 {
                     return calculateInjection(type, genericType, annotations, locator, resources);
                 }
@@ -1352,7 +1381,7 @@ public class InternalUtils
             {
                 validateConstructorForAutobuild(constructor);
 
-                Object[] constructorParameters = calculateParameters(locator, resources, constructor.getParameterTypes(), constructor.getGenericParameterTypes(), constructor.getParameterAnnotations(), tracker);
+                ObjectCreator[] constructorParameters = calculateParameters(locator, resources, constructor.getParameterTypes(), constructor.getGenericParameterTypes(), constructor.getParameterAnnotations(), tracker);
 
                 Invokable<T> core = new ConstructorInvoker<T>(constructor, constructorParameters);
 
@@ -1492,7 +1521,7 @@ public class InternalUtils
                 {
                     public void run()
                     {
-                        final Object[] parameters = InternalUtils.calculateParametersForMethod(method, locator,
+                        final ObjectCreator[] parameters = InternalUtils.calculateParametersForMethod(method, locator,
                                 resources, tracker);
 
                         plan.add(new InitializationPlan<Object>()
@@ -1506,9 +1535,11 @@ public class InternalUtils
                             {
                                 Throwable fail = null;
 
+                                Object[] realized = realizeObjects(parameters);
+
                                 try
                                 {
-                                    method.invoke(instance, parameters);
+                                    method.invoke(instance, realized);
                                 } catch (InvocationTargetException ex)
                                 {
                                     fail = ex.getTargetException();
@@ -1541,7 +1572,7 @@ public class InternalUtils
         {
             public ObjectCreator<T> invoke()
             {
-                Object[] methodParameters = calculateParametersForMethod(method, locator, resources, tracker);
+                ObjectCreator[] methodParameters = calculateParametersForMethod(method, locator, resources, tracker);
 
                 Invokable<T> core = new MethodInvoker<T>(instance, method, methodParameters);
 
@@ -1552,4 +1583,22 @@ public class InternalUtils
         });
     }
 
+    /**
+     * @since 5.3.1, 5.4
+     */
+    public static Mapper<ObjectCreator, Object> CREATE_OBJECT = new Mapper<ObjectCreator, Object>()
+    {
+        public Object map(ObjectCreator element)
+        {
+            return element.createObject();
+        }
+    };
+
+    /**
+     * @since 5.3.1, 5.4
+     */
+    public static Object[] realizeObjects(ObjectCreator[] creators)
+    {
+        return F.flow(creators).map(CREATE_OBJECT).toArray(Object.class);
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MethodInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MethodInvoker.java?rev=1209175&r1=1209174&r2=1209175&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MethodInvoker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/MethodInvoker.java Thu Dec  1 18:38:08 2011
@@ -16,6 +16,7 @@
 package org.apache.tapestry5.ioc.internal.util;
 
 import org.apache.tapestry5.ioc.Invokable;
+import org.apache.tapestry5.ioc.ObjectCreator;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -29,9 +30,9 @@ public class MethodInvoker<T> implements
 
     private final Method method;
 
-    private final Object[] methodParameters;
+    private final ObjectCreator[] methodParameters;
 
-    public MethodInvoker(Object instance, Method method, Object[] methodParameters)
+    public MethodInvoker(Object instance, Method method, ObjectCreator[] methodParameters)
     {
         this.instance = instance;
         this.method = method;
@@ -42,9 +43,11 @@ public class MethodInvoker<T> implements
     {
         Throwable fail;
 
+        Object[] realized = InternalUtils.realizeObjects(methodParameters);
+
         try
         {
-            Object result = method.invoke(instance, methodParameters);
+            Object result = method.invoke(instance, realized);
 
             return (T) result;
         } catch (InvocationTargetException ex)

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/PerThreadModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/PerThreadModule.java?rev=1209175&r1=1209174&r2=1209175&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/PerThreadModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/PerThreadModule.java Thu Dec  1 18:38:08 2011
@@ -14,13 +14,14 @@
 
 package org.apache.tapestry5.ioc;
 
+import org.apache.tapestry5.ioc.annotations.Autobuild;
 import org.apache.tapestry5.ioc.annotations.Scope;
 
 public class PerThreadModule
 {
     @Scope(ScopeConstants.PERTHREAD)
-    public StringHolder buildStringHolder()
+    public StringHolder buildStringHolder(@Autobuild StringHolderImpl impl)
     {
-        return new StringHolderImpl();
+        return impl;
     }
 }