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 2010/07/11 21:05:50 UTC
svn commit: r963124 -
/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
Author: hlship
Date: Sun Jul 11 19:05:50 2010
New Revision: 963124
URL: http://svn.apache.org/viewvc?rev=963124&view=rev
Log:
TAP5-1197: Rebuild ParameterWorker to store cached parameter values in the PerStateManager
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java?rev=963124&r1=963123&r2=963124&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java Sun Jul 11 19:05:50 2010
@@ -25,6 +25,7 @@ import org.apache.tapestry5.internal.bin
import org.apache.tapestry5.internal.services.ComponentClassCache;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
+import org.apache.tapestry5.ioc.services.PerthreadManager;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.services.*;
@@ -56,6 +57,24 @@ public class ParameterWorker implements
}
}
+ /**
+ * Contains the per-thread state about a parameter, as stored (using
+ * a unique key) in the {@link PerthreadManager}. Externalizing such state
+ * is part of Tapestry 5.2's pool-less pages.
+ */
+ private final class ParameterState
+ {
+ boolean cached;
+
+ Object value;
+
+ void reset(Object defaultValue)
+ {
+ cached = false;
+ value = defaultValue;
+ }
+ }
+
private final class InvokeParameterDefaultMethod implements ComponentMethodAdvice
{
private final FieldAccess conduitAccess;
@@ -108,13 +127,16 @@ public class ParameterWorker implements
private final TypeCoercer typeCoercer;
+ private final PerthreadManager perThreadManager;
+
public ParameterWorker(ComponentClassCache classCache, BindingSource bindingSource,
- ComponentDefaultProvider defaultProvider, TypeCoercer typeCoercer)
+ ComponentDefaultProvider defaultProvider, TypeCoercer typeCoercer, PerthreadManager perThreadManager)
{
this.classCache = classCache;
this.bindingSource = bindingSource;
this.defaultProvider = defaultProvider;
this.typeCoercer = typeCoercer;
+ this.perThreadManager = perThreadManager;
}
public void transform(ClassTransformation transformation, MutableComponentModel model)
@@ -198,6 +220,7 @@ public class ParameterWorker implements
addPageLoadAdvice(transformation, pageLoadAdvice);
}
+ @SuppressWarnings("all")
private ComponentValueProvider<ParameterConduit> createParameterConduitProvider(final String parameterName,
final String fieldTypeName, final Parameter annotation)
{
@@ -207,6 +230,8 @@ public class ParameterWorker implements
{
final InternalComponentResources icr = (InternalComponentResources) resources;
+ final String key = String.format("ParameterWorker:%s/%s", resources.getCompleteId(), parameterName);
+
final Class fieldType = classCache.forName(fieldTypeName);
// Rely on some code generation in the component to set the default binding from
@@ -214,9 +239,6 @@ public class ParameterWorker implements
return new ParameterConduit()
{
- // Current cached value for the parameter.
- private Object value;
-
// Default value for parameter, computed *once* at
// page load time.
@@ -228,10 +250,6 @@ public class ParameterWorker implements
private boolean invariant = false;
- // Is the current value of the binding cached in the
- // value field?
- private boolean cached = false;
-
{
// Inform the ComponentResources about the parameter conduit, so it can be
// shared with mixins.
@@ -239,6 +257,20 @@ public class ParameterWorker implements
icr.setParameterConduit(parameterName, this);
}
+ private ParameterState getState()
+ {
+ ParameterState state = (ParameterState) perThreadManager.get(key);
+
+ if (state == null)
+ {
+ state = new ParameterState();
+ state.value = defaultValue;
+ perThreadManager.put(key, state);
+ }
+
+ return state;
+ }
+
private boolean isLoaded()
{
return loaded;
@@ -246,13 +278,15 @@ public class ParameterWorker implements
public void set(Object newValue)
{
+ ParameterState state = getState();
+
// Assignments before the page is loaded ultimately exist to set the
// default value for the field. Often this is from the (original)
// constructor method, which is converted to a real method as part of the transformation.
if (!loaded)
{
- value = newValue;
+ state.value = newValue;
defaultValue = newValue;
return;
}
@@ -261,14 +295,14 @@ public class ParameterWorker implements
writeToBinding(newValue);
- value = newValue;
+ state.value = newValue;
// If caching is enabled for the parameter (the typical case) and the
// component is currently rendering, then the result
// can be cached in this ParameterConduit (until the component finishes
// rendering).
- cached = annotation.cache() && icr.isRendering();
+ state.cached = annotation.cache() && icr.isRendering();
}
private Object readFromBinding()
@@ -284,21 +318,19 @@ public class ParameterWorker implements
catch (RuntimeException ex)
{
throw new TapestryException(String.format(
- "Failure reading parameter '%s' of component %s: %s", parameterName, icr
- .getCompleteId(), InternalUtils.toMessage(ex)), parameterBinding, ex);
+ "Failure reading parameter '%s' of component %s: %s", parameterName,
+ icr.getCompleteId(), InternalUtils.toMessage(ex)), parameterBinding, ex);
}
if (result != null || annotation.allowNull())
return result;
throw new TapestryException(
- String
- .format(
- "Parameter '%s' of component %s is bound to null. This parameter is not allowed to be null.",
- parameterName, icr.getCompleteId()), parameterBinding, null);
+ String.format(
+ "Parameter '%s' of component %s is bound to null. This parameter is not allowed to be null.",
+ parameterName, icr.getCompleteId()), parameterBinding, null);
}
- @SuppressWarnings("unchecked")
private void writeToBinding(Object newValue)
{
// An unbound parameter acts like a simple field
@@ -316,8 +348,8 @@ public class ParameterWorker implements
catch (RuntimeException ex)
{
throw new TapestryException(String.format(
- "Failure writing parameter '%s' of component %s: %s", parameterName, icr
- .getCompleteId(), InternalUtils.toMessage(ex)), icr, ex);
+ "Failure writing parameter '%s' of component %s: %s", parameterName,
+ icr.getCompleteId(), InternalUtils.toMessage(ex)), icr, ex);
}
}
@@ -325,8 +357,7 @@ public class ParameterWorker implements
{
if (!invariant)
{
- value = defaultValue;
- cached = false;
+ getState().reset(defaultValue);
}
}
@@ -360,7 +391,7 @@ public class ParameterWorker implements
invariant = parameterBinding != null && parameterBinding.isInvariant();
- value = defaultValue;
+ getState().value = defaultValue;
}
public boolean isBound()
@@ -368,26 +399,29 @@ public class ParameterWorker implements
return parameterBinding != null;
}
- @SuppressWarnings("unchecked")
public Object get()
{
if (!isLoaded()) { return defaultValue; }
- if (cached || !isBound()) { return value; }
+ ParameterState state = getState();
+
+ if (state.cached || !isBound()) { return state.value; }
// Read the parameter's binding and cast it to the
// field's type.
Object result = readFromBinding();
- // If the value is invariant, we can cache it forever. Otherwise, we
+ // If the value is invariant, we can cache it until at least the end of the request (before
+ // 5.2, it would be cached forever in the pooled instance).
+ // Otherwise, we
// we may want to cache it for the remainder of the component render (if the
// component is currently rendering).
if (invariant || (annotation.cache() && icr.isRendering()))
{
- value = result;
- cached = true;
+ state.value = result;
+ state.cached = true;
}
return result;