Updated Branches:
  refs/heads/wicket-1.5.x 76cdc84ca -> cfe75499a

WICKET-4468 Stateful components which are invisible force page to be stateful


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/cfe75499
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/cfe75499
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/cfe75499

Branch: refs/heads/wicket-1.5.x
Commit: cfe75499a7607c11e1aa4463cdf1779eb6da1bc5
Parents: 76cdc84
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Mon Mar 26 12:00:03 2012 +0200
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Mon Mar 26 12:01:23 2012 +0200

----------------------------------------------------------------------
 .../src/main/java/org/apache/wicket/Component.java |   15 ++++-
 .../java/org/apache/wicket/behavior/Behavior.java  |    4 +-
 .../org/apache/wicket/markup/html/image/Image.java |    2 +-
 .../test/java/org/apache/wicket/ComponentTest.java |   59 +++++++++++++++
 4 files changed, 77 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/cfe75499/wicket-core/src/main/java/org/apache/wicket/Component.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/Component.java 
b/wicket-core/src/main/java/org/apache/wicket/Component.java
index ac48d28..60fce2b 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -2078,6 +2078,18 @@ public abstract class Component
                        return false;
                }
 
+               if (
+                       // the component is either invisible or disabled
+                       (isVisibleInHierarchy() && isEnabledInHierarchy()) == 
false &&
+
+                       // and it can't call listener interfaces
+                       canCallListenerInterface(null) == false
+               )
+               {
+                       // then pretend the component is stateless
+                       return true;
+               }
+
                for (Behavior behavior : getBehaviors())
                {
                        if (!behavior.getStatelessHint(this))
@@ -4431,7 +4443,8 @@ public abstract class Component
         * </p>
         * 
         * @param method
-        *            listener method about to be invoked on this component
+        *            listener method about to be invoked on this component. 
Could be {@code null} - in this
+        *            case it means <em>any</em> method.
         * 
         * @return {@literal true} iff the listener method can be invoked on 
this component
         */

http://git-wip-us.apache.org/repos/asf/wicket/blob/cfe75499/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java 
b/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java
index 366c176..7f7b160 100644
--- a/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java
+++ b/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java
@@ -122,7 +122,9 @@ public abstract class Behavior
        }
 
        /**
-        * In case an unexpected exception happened anywhere between 
onComponentTag() and rendered(),
+        * In case an unexpected exception happened anywhere between
+        * {@linkplain #onComponentTag(org.apache.wicket.Component, 
org.apache.wicket.markup.ComponentTag)} and
+        * {@linkplain #afterRender(org.apache.wicket.Component)},
         * onException() will be called for any behavior. Typically, if you 
clean up resources in
         * {@link #afterRender(Component)}, you should do the same in the 
implementation of this method.
         * 

http://git-wip-us.apache.org/repos/asf/wicket/blob/cfe75499/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java 
b/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
index b41bec9..b7f78a8 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/image/Image.java
@@ -296,7 +296,7 @@ public class Image extends WebComponent implements 
IResourceListener
        @Override
        public boolean canCallListenerInterface(Method method)
        {
-               boolean isResource = 
IResourceListener.class.isAssignableFrom(method.getDeclaringClass());
+               boolean isResource = method != null && 
IResourceListener.class.isAssignableFrom(method.getDeclaringClass());
                if (isResource && isVisibleInHierarchy())
                {
                        // when the image data is requested we do not care if 
this component is enabled in

http://git-wip-us.apache.org/repos/asf/wicket/blob/cfe75499/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java 
b/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
index 04f5d06..f0961ef 100644
--- a/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
@@ -16,7 +16,12 @@
  */
 package org.apache.wicket;
 
+import java.lang.reflect.Method;
+
 import org.apache.wicket.ajax.AjaxEventBehavior;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.html.WebComponent;
+import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.junit.Test;
 
 /**
@@ -89,4 +94,58 @@ public class ComponentTest extends WicketTestCase
        {
                executeTest(TestPage_1.class, "TestPageExpectedResult_1.html");
        }
+
+       /**
+        * https://issues.apache.org/jira/browse/WICKET-4468
+        *
+        * Verifies that a stateful component can pretend to be stateless if 
both conditions are
+        * fulfilled:
+        * <ol>
+        *     <li>it is either invisible or disabled (or both)</li>
+        *     <li>it cannot call any listener interface method while 
invisible/disabled</li>
+        * </ol>
+        */
+       @Test
+       public void isStateless()
+       {
+               Behavior statefulBehavior = new Behavior()
+               {
+                       @Override
+                       public boolean getStatelessHint(Component component)
+                       {
+                               return false;
+                       }
+               };
+
+               WebComponent component = new WebComponent("someId");
+
+               // by default every component is stateless
+               assertTrue(component.isStateless());
+
+               // make the component stateful
+               component.add(statefulBehavior);
+               assertFalse(component.isStateless());
+
+               // invisible component cannot be requested by default so it
+               // can pretend being stateless
+               component.setVisible(false);
+               assertTrue(component.isStateless());
+
+               // same for disabled component
+               component.setVisible(true).setEnabled(false);
+               assertTrue(component.isStateless());
+
+               // make the component such that it can call listener interface
+               // methods no matter whether it is visible or enabled
+               component = new WebComponent("someId") {
+                       @Override
+                       public boolean canCallListenerInterface(Method method)
+                       {
+                               return true;
+                       }
+               };
+               component.add(statefulBehavior);
+               component.setVisible(false);
+               assertFalse(component.isStateless());
+       }
 }

Reply via email to