You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2012/03/26 12:00:52 UTC

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

Updated Branches:
  refs/heads/master dafd8055e -> 5afefe147


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/5afefe14
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/5afefe14
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/5afefe14

Branch: refs/heads/master
Commit: 5afefe1475db62c44f747179488611b109ae5dac
Parents: dafd805
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Mon Mar 26 12:00:03 2012 +0200
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Mon Mar 26 12:00:03 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/5afefe14/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 df0955a..fb56254 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -2080,6 +2080,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))
@@ -4412,7 +4424,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/5afefe14/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 22115f1..c916b7d 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/5afefe14/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 eaf8c64..c024985 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
@@ -297,7 +297,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/5afefe14/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());
+	}
 }