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


Reply via email to