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;
}
}