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 2020/09/15 08:51:29 UTC

[wicket] branch wicket-8.x updated: WICKET-6830 Convert `Behaviors` into a static utility class to avoid allocating a new object on every invocation

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

mgrigorov pushed a commit to branch wicket-8.x
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/wicket-8.x by this push:
     new ef6963c  WICKET-6830 Convert `Behaviors` into a static utility class to avoid allocating a new object on every invocation
ef6963c is described below

commit ef6963c32086212871d0e2ef118a0bc82797f2dc
Author: Thomas Heigl <th...@gmail.com>
AuthorDate: Sun Sep 13 11:21:25 2020 +0200

    WICKET-6830 Convert `Behaviors` into a static utility class to avoid allocating a new object on every invocation
    
    (cherry picked from commit 887cc751158df571d5778afb61484bbb564a8309)
---
 .../src/main/java/org/apache/wicket/Behaviors.java | 52 ++++++++++------------
 .../src/main/java/org/apache/wicket/Component.java | 28 ++++++------
 2 files changed, 38 insertions(+), 42 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/Behaviors.java b/wicket-core/src/main/java/org/apache/wicket/Behaviors.java
index 0573ec5..fc99c6c 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Behaviors.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Behaviors.java
@@ -22,25 +22,22 @@ import java.util.List;
 
 import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.behavior.InvalidBehaviorIdException;
-import org.apache.wicket.model.IDetachable;
 import org.apache.wicket.util.lang.Args;
 
 /**
- * Manages behaviors in a {@link Component} instance
+ * Manages behaviors for {@link Component} instances
  * 
  * @author igor
  */
-final class Behaviors implements IDetachable
+final class Behaviors
 {
-	private static final long serialVersionUID = 1L;
-	private final Component component;
 
-	public Behaviors(Component component)
+	private Behaviors()
 	{
-		this.component = component;
+		// utility class
 	}
 
-	public void add(Behavior... behaviors)
+	public static void add(Component component, Behavior... behaviors)
 	{
 		Args.notNull(behaviors, "behaviors");
 
@@ -48,7 +45,7 @@ final class Behaviors implements IDetachable
 		{
 			Args.notNull(behavior, "behavior");
 
-			internalAdd(behavior);
+			internalAdd(component, behavior);
 
 			if (!behavior.isTemporary(component))
 			{
@@ -60,17 +57,17 @@ final class Behaviors implements IDetachable
 		}
 	}
 
-	private void internalAdd(final Behavior behavior)
+	private static void internalAdd(Component component, Behavior behavior)
 	{
 		component.data_add(behavior);
 		if (behavior.getStatelessHint(component) == false)
 		{
-			getBehaviorId(behavior);
+			getBehaviorId(component, behavior);
 		}
 	}
 
 	@SuppressWarnings("unchecked")
-	public <M extends Behavior> List<M> getBehaviors(Class<M> type)
+	public static <M extends Behavior> List<M> getBehaviors(Component component, Class<M> type)
 	{
 		int len = component.data_length();
 		if (len == 0)
@@ -110,11 +107,11 @@ final class Behaviors implements IDetachable
 	}
 
 
-	public void remove(Behavior behavior)
+	public static void remove(Component component, Behavior behavior)
 	{
 		Args.notNull(behavior, "behavior");
 
-		if (internalRemove(behavior))
+		if (internalRemove(component, behavior))
 		{
 			if (!behavior.isTemporary(component))
 			{
@@ -138,8 +135,7 @@ final class Behaviors implements IDetachable
 	 * component's behaviors after header contribution has been done (which is separated from
 	 * component render).
 	 */
-	@Override
-	public final void detach()
+	public static void detach(Component component)
 	{
 		int len = component.data_length();
 		if (len == 0)
@@ -162,7 +158,7 @@ final class Behaviors implements IDetachable
 
 				if (behavior.isTemporary(component))
 				{
-					internalRemove(behavior);
+					internalRemove(component, behavior);
 					i--;
 					len--;
 				}
@@ -170,7 +166,7 @@ final class Behaviors implements IDetachable
 		}
 	}
 
-	private boolean internalRemove(final Behavior behavior)
+	private static boolean internalRemove(Component component, Behavior behavior)
 	{
 		final int len = component.data_length();
 		for (int i = component.data_start(); i < len; i++)
@@ -182,7 +178,7 @@ final class Behaviors implements IDetachable
 				behavior.unbind(component);
 
 				// remove behavior from behavior-ids
-				ArrayList<Behavior> ids = getBehaviorsIdList(false);
+				ArrayList<Behavior> ids = getBehaviorsIdList(component, false);
 				if (ids != null)
 				{
 					int idx = ids.indexOf(behavior);
@@ -198,7 +194,7 @@ final class Behaviors implements IDetachable
 
 					if (ids.isEmpty())
 					{
-						removeBehaviorsIdList();
+						removeBehaviorsIdList(component);
 					}
 
 				}
@@ -208,7 +204,7 @@ final class Behaviors implements IDetachable
 		return false;
 	}
 
-	private void removeBehaviorsIdList()
+	private static void removeBehaviorsIdList(Component component)
 	{
 		for (int i = component.data_start(); i < component.data_length(); i++)
 		{
@@ -221,7 +217,7 @@ final class Behaviors implements IDetachable
 		}
 	}
 
-	private BehaviorIdList getBehaviorsIdList(boolean createIfNotFound)
+	private static BehaviorIdList getBehaviorsIdList(Component component, boolean createIfNotFound)
 	{
 		int len = component.data_length();
 		for (int i = component.data_start(); i < len; i++)
@@ -248,7 +244,7 @@ final class Behaviors implements IDetachable
 	 * @param component
 	 *      the component that will be removed from its parent
 	 */
-	public void onRemove(Component component)
+	public static void onRemove(Component component)
 	{
 		int len = component.data_length();
 		if (len == 0)
@@ -282,7 +278,7 @@ final class Behaviors implements IDetachable
 		}
 	}
 
-	public final int getBehaviorId(Behavior behavior)
+	public static int getBehaviorId(Component component, Behavior behavior)
 	{
 		Args.notNull(behavior, "behavior");
 
@@ -299,10 +295,10 @@ final class Behaviors implements IDetachable
 		{
 			throw new IllegalStateException(
 				"Behavior must be added to component before its id can be generated. Behavior: " +
-					behavior + ", Component: " + this);
+					behavior + ", Component: " + component);
 		}
 
-		ArrayList<Behavior> ids = getBehaviorsIdList(true);
+		ArrayList<Behavior> ids = getBehaviorsIdList(component, true);
 
 		int id = ids.indexOf(behavior);
 
@@ -331,11 +327,11 @@ final class Behaviors implements IDetachable
 		return id;
 	}
 
-	public final Behavior getBehaviorById(int id)
+	public static Behavior getBehaviorById(Component component, int id)
 	{
 		Behavior behavior = null;
 
-		ArrayList<Behavior> ids = getBehaviorsIdList(false);
+		ArrayList<Behavior> ids = getBehaviorsIdList(component, false);
 		if (ids != null)
 		{
 			if (id >= 0 && id < ids.size())
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 89e31a4..2a1d639 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -133,7 +133,7 @@ import org.slf4j.LoggerFactory;
  * unlikely for a web application and even the need to implement a listener interface directly is
  * highly discouraged. Instead, calls to listeners are routed through logic specific to the event,
  * resulting in calls to user code through other overridable methods. See {@link Form} for an
- * example of a component which listens for events via {@link IFormSubmitListener}.</li>
+ * example of a component which listens for events via {@link IRequestListener}.</li>
  * <li><b>Rendering </b>- Before a page or part of a page (in case of Ajax updates) is rendered, all
  * containing components are able to prepare for rendering via two hook methods:
  * {@link #onConfigure()} (regardless whether they are visible or not) and {@link #onBeforeRender()}
@@ -1085,11 +1085,11 @@ public abstract class Component
 		if (getRequestFlag(RFLAG_REMOVING_FROM_HIERARCHY))
 		{
 			throw new IllegalStateException(Component.class.getName() +
-				" has not been properly removed from hierachy. Something in the hierarchy of " +
+				" has not been properly removed from hierarchy. Something in the hierarchy of " +
 				getClass().getName() +
 				" has not called super.onRemove() in the override of onRemove() method");
 		}
-		new Behaviors(this).onRemove(this);
+		Behaviors.onRemove(this);
 		removeChildren();
 	}
 
@@ -1118,7 +1118,7 @@ public abstract class Component
 			detachModels();
 
 			// detach any behaviors
-			new Behaviors(this).detach();
+			Behaviors.detach(this);
 		}
 		catch (Exception x)
 		{
@@ -2115,8 +2115,6 @@ public abstract class Component
 	 * @param setRenderingFlag
 	 *            if this is false only the PREPARED_FOR_RENDER flag is removed from component, the
 	 *            RENDERING flag is not set.
-	 * 
-	 * @see #internalPrepareForRender(boolean)
 	 */
 	public final void markRendering(boolean setRenderingFlag)
 	{
@@ -3622,7 +3620,7 @@ public abstract class Component
 	 */
 	public <M extends Behavior> List<M> getBehaviors(Class<M> type)
 	{
-		return new Behaviors(this).getBehaviors(type);
+		return Behaviors.getBehaviors(this, type);
 	}
 
 	/**
@@ -4431,26 +4429,28 @@ public abstract class Component
 	 */
 	public Component remove(final Behavior... behaviors)
 	{
-		Behaviors helper = new Behaviors(this);
 		for (Behavior behavior : behaviors)
 		{
-			helper.remove(behavior);
+			Behaviors.remove(this, behavior);
 		}
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final Behavior getBehaviorById(int id)
 	{
-		return new Behaviors(this).getBehaviorById(id);
+		return Behaviors.getBehaviorById(this, id);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final int getBehaviorId(Behavior behavior)
 	{
-		return new Behaviors(this).getBehaviorId(behavior);
+		if (behavior.isTemporary(this))
+		{
+			throw new IllegalArgumentException(
+				"Cannot get a stable id for temporary behavior " + behavior);
+		}
+		return Behaviors.getBehaviorId(this, behavior);
 	}
 
 	/**
@@ -4462,7 +4462,7 @@ public abstract class Component
 	 */
 	public Component add(final Behavior... behaviors)
 	{
-		new Behaviors(this).add(behaviors);
+		Behaviors.add(this, behaviors);
 		return this;
 	}