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;