You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2009/02/01 01:19:41 UTC

svn commit: r739666 - in /wicket/trunk/wicket/src/main/java/org/apache/wicket: Component.java RequestCycle.java request/target/component/listener/BehaviorRequestTarget.java

Author: ivaynberg
Date: Sun Feb  1 00:19:41 2009
New Revision: 739666

URL: http://svn.apache.org/viewvc?rev=739666&view=rev
Log:
WICKET-1483

Modified:
    wicket/trunk/wicket/src/main/java/org/apache/wicket/Component.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/RequestCycle.java
    wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/listener/BehaviorRequestTarget.java

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/Component.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/Component.java?rev=739666&r1=739665&r2=739666&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/Component.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/Component.java Sun Feb  1 00:19:41 2009
@@ -30,6 +30,7 @@
 import org.apache.wicket.authorization.IAuthorizationStrategy;
 import org.apache.wicket.authorization.UnauthorizedActionException;
 import org.apache.wicket.behavior.IBehavior;
+import org.apache.wicket.behavior.IBehaviorListener;
 import org.apache.wicket.feedback.FeedbackMessage;
 import org.apache.wicket.feedback.IFeedback;
 import org.apache.wicket.markup.ComponentTag;
@@ -973,10 +974,11 @@
 	}
 
 	/**
+	 * FOR INTERNAL USE ONLY
 	 * 
-	 * @return list of behaviors
+	 * @return unmodified list of behaviors which may contain null entries
 	 */
-	private List<IBehavior> getBehaviorsImpl()
+	public final List<IBehavior> getBehaviorsRawList()
 	{
 		if (data != null)
 		{
@@ -990,7 +992,7 @@
 				for (int i = startIndex; i < length; ++i)
 				{
 					Object o = data_get(i);
-					if (o instanceof IBehavior)
+					if (o == null || o instanceof IBehavior)
 					{
 						result.add((IBehavior)o);
 					}
@@ -1180,7 +1182,7 @@
 	 */
 	public final void detachBehaviors()
 	{
-		List<IBehavior> behaviors = getBehaviorsImpl();
+		List<IBehavior> behaviors = getBehaviors();
 		if (behaviors != null)
 		{
 			for (Iterator<IBehavior> i = behaviors.iterator(); i.hasNext();)
@@ -2306,12 +2308,50 @@
 	private boolean removeBehavior(final IBehavior behavior)
 	{
 		final int start = getFlag(FLAG_MODEL_SET) ? 1 : 0;
-		for (int i = start; i < data_length(); ++i)
+		final int len = data_length();
+		for (int i = start; i < len; ++i)
 		{
 			Object o = data_get(i);
-			if (o.equals(behavior))
+			if (o != null && o.equals(behavior))
 			{
-				data_remove(i);
+				// behaviors that produce urls depend on their index in the behaviors list,
+				// therefore we cannot blindly shrink the array by removing this behavior's slot.
+				// Instead we check if there are any behaviors downstream that will be affected by
+				// this, and if there are we set this behavior's slot to null instead of removing it
+				// to preserve indexes of behaviors downstream.
+				boolean listenersAfter = false;
+				for (int j = i + 1; j < len; j++)
+				{
+					if (data_get(j) instanceof IBehaviorListener)
+					{
+						listenersAfter = true;
+						break;
+					}
+				}
+
+				if (listenersAfter)
+				{
+					data_set(i, null);
+				}
+				else
+				{
+					data_remove(i);
+
+					if (o instanceof IBehaviorListener)
+					{
+						// this was a listener which mightve caused holes in the array, see if we
+						// can clean them up. notice: at this point we already know there are no
+						// listeners that can be affected by index change downstream because this is
+						// the last one in the array
+						for (int j = i - 1; j >= start; j--)
+						{
+							if (data_get(j) == null)
+							{
+								data_remove(j);
+							}
+						}
+					}
+				}
 				return true;
 			}
 		}
@@ -2392,7 +2432,7 @@
 			{
 				// Call each behaviors onException() to allow the
 				// behavior to clean up
-				List<IBehavior> behaviors = getBehaviorsImpl();
+				List<IBehavior> behaviors = getBehaviors();
 				if (behaviors != null)
 				{
 					for (Iterator<IBehavior> i = behaviors.iterator(); i.hasNext();)
@@ -2632,7 +2672,7 @@
 
 			// Ask all behaviors if they have something to contribute to the
 			// header or body onLoad tag.
-			List<IBehavior> behaviors = getBehaviorsImpl();
+			List<IBehavior> behaviors = getBehaviors();
 			if (behaviors != null)
 			{
 				final Iterator<IBehavior> iter = behaviors.iterator();
@@ -3348,7 +3388,7 @@
 	 */
 	private void notifyBehaviorsComponentBeforeRender()
 	{
-		List<IBehavior> behaviors = getBehaviorsImpl();
+		List<IBehavior> behaviors = getBehaviors();
 		if (behaviors != null)
 		{
 			for (Iterator<IBehavior> i = behaviors.iterator(); i.hasNext();)
@@ -3369,7 +3409,7 @@
 	private void notifyBehaviorsComponentRendered()
 	{
 		// notify the behaviors that component has been rendered
-		List<IBehavior> behaviors = getBehaviorsImpl();
+		List<IBehavior> behaviors = getBehaviors();
 		if (behaviors != null)
 		{
 			for (Iterator<IBehavior> i = behaviors.iterator(); i.hasNext();)
@@ -3535,7 +3575,7 @@
 	 */
 	protected List<IBehavior> getBehaviors(Class<? extends IBehavior> type)
 	{
-		List<IBehavior> behaviors = getBehaviorsImpl();
+		List<IBehavior> behaviors = getBehaviorsRawList();
 		if (behaviors == null)
 		{
 			return Collections.emptyList();
@@ -3545,7 +3585,7 @@
 		for (Iterator<IBehavior> i = behaviors.iterator(); i.hasNext();)
 		{
 			Object behavior = i.next();
-			if (type == null || type.isAssignableFrom(behavior.getClass()))
+			if (behavior != null && (type == null || type.isAssignableFrom(behavior.getClass())))
 			{
 				subset.add((IBehavior)behavior);
 			}
@@ -3926,7 +3966,7 @@
 		if (!(tag instanceof WicketTag) || !stripWicketTags)
 		{
 			// Apply behavior modifiers
-			List<IBehavior> behaviors = getBehaviorsImpl();
+			List<IBehavior> behaviors = getBehaviors();
 			if ((behaviors != null) && !behaviors.isEmpty() && !tag.isClose() &&
 				(isIgnoreAttributeModifier() == false))
 			{

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/RequestCycle.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/RequestCycle.java?rev=739666&r1=739665&r2=739666&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/RequestCycle.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/RequestCycle.java Sun Feb  1 00:19:41 2009
@@ -802,7 +802,7 @@
 	public final CharSequence urlFor(final Component component, final IBehavior behaviour,
 		final RequestListenerInterface listener)
 	{
-		int index = component.getBehaviors().indexOf(behaviour);
+		int index = component.getBehaviorsRawList().indexOf(behaviour);
 		if (index == -1)
 		{
 			throw new IllegalArgumentException("Behavior " + this +

Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/listener/BehaviorRequestTarget.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/listener/BehaviorRequestTarget.java?rev=739666&r1=739665&r2=739666&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/listener/BehaviorRequestTarget.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/target/component/listener/BehaviorRequestTarget.java Sun Feb  1 00:19:41 2009
@@ -16,10 +16,13 @@
  */
 package org.apache.wicket.request.target.component.listener;
 
+import java.util.List;
+
 import org.apache.wicket.Component;
 import org.apache.wicket.Page;
 import org.apache.wicket.RequestCycle;
 import org.apache.wicket.RequestListenerInterface;
+import org.apache.wicket.behavior.IBehavior;
 import org.apache.wicket.behavior.IBehaviorListener;
 import org.apache.wicket.request.RequestParameters;
 
@@ -42,7 +45,7 @@
 	 *            the listener method
 	 */
 	public BehaviorRequestTarget(final Page page, final Component component,
-			final RequestListenerInterface listener)
+		final RequestListenerInterface listener)
 	{
 		this(page, component, listener, null);
 	}
@@ -60,7 +63,7 @@
 	 *            the request parameters
 	 */
 	public BehaviorRequestTarget(final Page page, final Component component,
-			final RequestListenerInterface listener, final RequestParameters requestParameters)
+		final RequestListenerInterface listener, final RequestParameters requestParameters)
 	{
 		super(page, component, listener, requestParameters);
 	}
@@ -80,20 +83,22 @@
 		if (id == null)
 		{
 			throw new IllegalStateException(
-					"Parameter behaviorId was not provided: unable to locate listener. Component: " +
-							component.toString());
+				"Parameter behaviorId was not provided: unable to locate listener. Component: " +
+					component.toString());
 		}
 
 		final int idAsInt = Integer.parseInt(id);
+		final List<IBehavior> behaviors = component.getBehaviorsRawList();
 		IBehaviorListener behaviorListener = null;
-		if (component.getBehaviors().size() > idAsInt)
+
+		if (behaviors.size() > idAsInt)
 		{
-			behaviorListener = (IBehaviorListener)component.getBehaviors().get(idAsInt);
+			behaviorListener = (IBehaviorListener)behaviors.get(idAsInt);
 		}
 		if (behaviorListener == null)
 		{
 			throw new IllegalStateException("No behavior listener found with behaviorId " + id +
-					"; Component: " + component.toString());
+				"; Component: " + component.toString());
 		}
 
 		// Invoke the interface method