You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by th...@apache.org on 2020/10/23 13:46:11 UTC

[wicket] branch master updated: WICKET-6839 Use request flag for caching `isVisibleInHierarchy`

This is an automated email from the ASF dual-hosted git repository.

theigl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/master by this push:
     new 931c873  WICKET-6839 Use request flag for caching `isVisibleInHierarchy`
     new 50a5514  Merge pull request #459 from theigl/WICKET-6839-visible-hierarchy-cache
931c873 is described below

commit 931c873e84ebefc1cbb96b5b62e94fce3de6fc0b
Author: Thomas Heigl <th...@gmail.com>
AuthorDate: Fri Oct 23 11:31:10 2020 +0200

    WICKET-6839 Use request flag for caching `isVisibleInHierarchy`
---
 .../src/main/java/org/apache/wicket/Component.java | 48 +++++++++++-----
 .../java/org/apache/wicket/MarkupContainer.java    | 12 +---
 .../test/java/org/apache/wicket/ComponentTest.java | 65 +++++++++++++++++++++-
 3 files changed, 100 insertions(+), 25 deletions(-)

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 779eb61..31b1baa 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -421,26 +421,34 @@ public abstract class Component
 	private int flags = FLAG_VISIBLE | FLAG_ESCAPE_MODEL_STRINGS | FLAG_VERSIONED | FLAG_ENABLED |
 		FLAG_IS_RENDER_ALLOWED | FLAG_VISIBILITY_ALLOWED | FLAG_RESERVED5 /* page's stateless hint */;
 
-	private static final short RFLAG_ENABLED_IN_HIERARCHY_VALUE = 0x1;
-	private static final short RFLAG_ENABLED_IN_HIERARCHY_SET = 0x2;
-	private static final short RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED = 0x4;
-	private static final short RFLAG_VISIBLE_IN_HIERARCHY_SET = 0x8;
+	// @formatter:off	
+	private static final short RFLAG_ENABLED_IN_HIERARCHY_VALUE        = 0x1;
+	private static final short RFLAG_ENABLED_IN_HIERARCHY_SET          = 0x2;
+	private static final short RFLAG_VISIBLE_IN_HIERARCHY_VALUE        = 0x4;
+	private static final short RFLAG_VISIBLE_IN_HIERARCHY_SET          = 0x8;
 	/** onconfigure has been called */
-	private static final short RFLAG_CONFIGURED = 0x10;
+	private static final short RFLAG_CONFIGURED                        = 0x10;
 	private static final short RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED = 0x20;
-	private static final short RFLAG_INITIALIZE_SUPER_CALL_VERIFIED = 0x40;
-	protected static final short RFLAG_CONTAINER_DEQUEING = 0x80;
-	private static final short RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED = 0x100;
+	private static final short RFLAG_INITIALIZE_SUPER_CALL_VERIFIED    = 0x40;
+	protected static final short RFLAG_CONTAINER_DEQUEING              = 0x80;
+	private static final short RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED     = 0x100;
 	/**
 	 * Flag that makes we are in before-render callback phase Set after component.onBeforeRender is
 	 * invoked (right before invoking beforeRender on children)
 	 */
-	private static final short RFLAG_RENDERING = 0x200;
-	private static final short RFLAG_PREPARED_FOR_RENDER = 0x400;
-	private static final short RFLAG_AFTER_RENDER_SUPER_CALL_VERIFIED = 0x800;
-	private static final short RFLAG_DETACHING = 0x1000;	
+	private static final short RFLAG_RENDERING                         = 0x200;
+	private static final short RFLAG_PREPARED_FOR_RENDER               = 0x400;
+	private static final short RFLAG_AFTER_RENDER_SUPER_CALL_VERIFIED  = 0x800;
+	private static final short RFLAG_DETACHING                         = 0x1000;
 	/** True when a component is being removed from the hierarchy */
-	private static final short RFLAG_REMOVING_FROM_HIERARCHY = 0x2000;
+	private static final short RFLAG_REMOVING_FROM_HIERARCHY           = 0x2000;
+	/**
+	 * This flag tracks if removals have been set on this component. Clearing this key is an
+	 * expensive operation. With this flag this expensive call can be avoided.
+	 */
+	protected static final short RFLAG_CONTAINER_HAS_REMOVALS          = 0x4000;
+	private static final short RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED  = (short) 0x8000;
+	// @formatter:on
 
 	/**
 	 * Flags that only keep their value during the request. Useful for cache markers, etc. At the
@@ -2099,15 +2107,25 @@ public abstract class Component
 	 */
 	public final boolean isVisibleInHierarchy()
 	{
+		if (getRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_SET))
+		{
+			return getRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_VALUE);
+		}
+
+		final boolean state;
 		Component parent = getParent();
 		if (parent != null && !parent.isVisibleInHierarchy())
 		{
-			return false;
+			state = false;
 		}
 		else
 		{
-			return determineVisibility();
+			state = determineVisibility();
 		}
+
+		setRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_SET, true);
+		setRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_VALUE, state);
+		return state;
 	}
 
 	/**
diff --git a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
index 6af95d1..d2531a5 100644
--- a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
@@ -133,12 +133,6 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
 	{
 		private static final long serialVersionUID = 1L;
 	};
-	
-	/**
-	 * This flag tracks if the {@link #REMOVALS_KEY} has been set on this component. Clearing this
-	 * key is an expensive operation. With this flag this expensive call can be avoided.
-	 */
-	private static final short RFLAG_HAS_REMOVALS = 0x4000;
 
 	/**
 	 * Administrative class for detecting removed children during child iteration. Not intended to
@@ -1328,7 +1322,7 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
 	 */
 	private LinkedList<RemovedChild> removals_get()
 	{
-		return getRequestFlag(RFLAG_HAS_REMOVALS) ? getMetaData(REMOVALS_KEY) : null;
+		return getRequestFlag(RFLAG_CONTAINER_HAS_REMOVALS) ? getMetaData(REMOVALS_KEY) : null;
 	}
 
 	/**
@@ -1340,7 +1334,7 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
 	 */
 	private void removals_set(LinkedList<RemovedChild> removals)
 	{
-		setRequestFlag(RFLAG_HAS_REMOVALS, removals != null);
+		setRequestFlag(RFLAG_CONTAINER_HAS_REMOVALS, removals != null);
 		setMetaData(REMOVALS_KEY, removals);
 	}
 
@@ -1349,7 +1343,7 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
 	 */
 	private void removals_clear()
 	{
-		if (getRequestFlag(RFLAG_HAS_REMOVALS))
+		if (getRequestFlag(RFLAG_CONTAINER_HAS_REMOVALS))
 		{
 			removals_set(null);
 		}
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 12ba73e..2095090 100644
--- a/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.wicket;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -247,6 +248,38 @@ class ComponentTest extends WicketTestCase
 		assertTrue(component.getFlagReserved5());
 	}
 
+	@Test
+	void isEnabledInHierarchyCachesResult()
+	{
+		final SpyComponent c = new SpyComponent("test");
+
+		c.isEnabledInHierarchy();
+		c.isEnabledInHierarchy();
+		assertEquals(1, c.isEnabledCallCount);
+
+		c.setEnabled(false);
+
+		c.isEnabledInHierarchy();
+		c.isEnabledInHierarchy();
+		assertEquals(2, c.isEnabledCallCount);
+	}
+
+	@Test
+	void isVisibleInHierarchyCachesResult()
+	{
+		final SpyComponent c = new SpyComponent("test");
+		
+		c.isVisibleInHierarchy();
+		c.isVisibleInHierarchy();
+		assertEquals(1, c.isVisibleCallCount);
+		
+		c.setVisible(false);
+		
+		c.isVisibleInHierarchy();
+		c.isVisibleInHierarchy();
+		assertEquals(2, c.isVisibleCallCount);
+	}
+
 	/**
 	 * Component#FLAG_RESERVED5 (Page's STATELESS_HINT) must be initially set to true
 	 */
@@ -266,4 +299,34 @@ class ComponentTest extends WicketTestCase
 		protected void onRender() {
 		}
 	}
-}
\ No newline at end of file
+
+	private static class SpyComponent extends Component
+	{
+
+		int isEnabledCallCount;
+		int isVisibleCallCount;
+
+		public SpyComponent(final String id)
+		{
+			super(id);
+		}
+
+		@Override
+		public boolean isEnabled()
+		{
+			isEnabledCallCount++;
+			return super.isEnabled();
+		}
+
+		@Override
+		public boolean isVisible()
+		{
+			isVisibleCallCount++;
+			return super.isVisible();
+		}
+
+		@Override
+		protected void onRender() {
+		}
+	}
+}