Author: ivaynberg
Date: Sat May  7 22:33:15 2011
New Revision: 1100644

URL: http://svn.apache.org/viewvc?rev=1100644&view=rev
Log:
Introduce IComponentAwareEventSink which will pass the behavior's component as 
context to onEvent
Issue: WICKET-3684

Added:
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IComponentAwareEventSink.java
   (with props)
Modified:
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ComponentEventSender.java
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IEventDispatcher.java
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java
    
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/settings/def/FrameworkSettings.java
    
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/ComponentEventsTest.java
    
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/EventDispatcherTest.java

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ComponentEventSender.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ComponentEventSender.java?rev=1100644&r1=1100643&r2=1100644&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ComponentEventSender.java
 (original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ComponentEventSender.java
 Sat May  7 22:33:15 2011
@@ -70,7 +70,8 @@ final class ComponentEventSender impleme
                                depth(event);
                                break;
                        case EXACT :
-                               dispatcher.dispatchEvent(event.getSink(), 
event);
+                               dispatcher.dispatchEvent(event.getSink(), 
event, ((sink instanceof Component)
+                                       ? (Component)sink : null));
                                break;
                }
        }
@@ -91,13 +92,13 @@ final class ComponentEventSender impleme
 
                if (!targetsComponent && !targetsCycle)
                {
-                       dispatcher.dispatchEvent(sink, event);
+                       dispatcher.dispatchEvent(sink, event, null);
                        return;
                }
 
                if (targetsApplication)
                {
-                       dispatcher.dispatchEvent(source.getApplication(), 
event);
+                       dispatcher.dispatchEvent(source.getApplication(), 
event, null);
                }
                if (event.isStop())
                {
@@ -105,7 +106,7 @@ final class ComponentEventSender impleme
                }
                if (targetsSession)
                {
-                       dispatcher.dispatchEvent(source.getSession(), event);
+                       dispatcher.dispatchEvent(source.getSession(), event, 
null);
                }
                if (event.isStop())
                {
@@ -113,7 +114,7 @@ final class ComponentEventSender impleme
                }
                if (targetsCycle)
                {
-                       dispatcher.dispatchEvent(source.getRequestCycle(), 
event);
+                       dispatcher.dispatchEvent(source.getRequestCycle(), 
event, null);
                }
                if (event.isStop())
                {
@@ -122,7 +123,7 @@ final class ComponentEventSender impleme
 
                Component cursor = targetsCycle ? source.getPage() : 
(Component)sink;
 
-               dispatcher.dispatchEvent(cursor, event);
+               dispatchToComponent(dispatcher, cursor, event);
 
                if (event.isStop())
                {
@@ -150,11 +151,11 @@ final class ComponentEventSender impleme
                boolean targetsApplication = sink instanceof Application;
                boolean targetsSession = targetsApplication || sink instanceof 
Session;
                boolean targetsCycle = targetsSession || sink instanceof 
RequestCycle;
-               boolean targetsComponnet = sink instanceof Component;
+               boolean targetsComponent = sink instanceof Component;
 
-               if (!targetsComponnet && !targetsCycle)
+               if (!targetsComponent && !targetsCycle)
                {
-                       dispatcher.dispatchEvent(sink, event);
+                       dispatcher.dispatchEvent(sink, event, null);
                        return;
                }
 
@@ -166,7 +167,7 @@ final class ComponentEventSender impleme
                }
                else
                {
-                       dispatcher.dispatchEvent(cursor, event);
+                       dispatchToComponent(dispatcher, cursor, event);
                }
                if (event.isStop())
                {
@@ -174,7 +175,7 @@ final class ComponentEventSender impleme
                }
                if (targetsCycle)
                {
-                       dispatcher.dispatchEvent(source.getRequestCycle(), 
event);
+                       dispatcher.dispatchEvent(source.getRequestCycle(), 
event, null);
                }
                if (event.isStop())
                {
@@ -182,7 +183,7 @@ final class ComponentEventSender impleme
                }
                if (targetsSession)
                {
-                       dispatcher.dispatchEvent(source.getSession(), event);
+                       dispatcher.dispatchEvent(source.getSession(), event, 
null);
                }
                if (event.isStop())
                {
@@ -190,7 +191,7 @@ final class ComponentEventSender impleme
                }
                if (targetsApplication)
                {
-                       dispatcher.dispatchEvent(source.getApplication(), 
event);
+                       dispatcher.dispatchEvent(source.getApplication(), 
event, null);
                }
        }
 
@@ -211,14 +212,14 @@ final class ComponentEventSender impleme
 
                if (!targetsApplication && !targetsComponent)
                {
-                       dispatcher.dispatchEvent(sink, event);
+                       dispatcher.dispatchEvent(sink, event, null);
                        return;
                }
 
                if (targetsComponent)
                {
                        Component cursor = (Component)sink;
-                       dispatcher.dispatchEvent(cursor, event);
+                       dispatchToComponent(dispatcher, cursor, event);
                        if (event.isStop())
                        {
                                return;
@@ -232,7 +233,7 @@ final class ComponentEventSender impleme
                }
                if (targetsCycle)
                {
-                       dispatcher.dispatchEvent(source.getRequestCycle(), 
event);
+                       dispatcher.dispatchEvent(source.getRequestCycle(), 
event, null);
                }
                if (event.isStop())
                {
@@ -240,7 +241,7 @@ final class ComponentEventSender impleme
                }
                if (targetsSession)
                {
-                       dispatcher.dispatchEvent(source.getSession(), event);
+                       dispatcher.dispatchEvent(source.getSession(), event, 
null);
                }
                if (event.isStop())
                {
@@ -248,10 +249,32 @@ final class ComponentEventSender impleme
                }
                if (targetsApplication)
                {
-                       dispatcher.dispatchEvent(source.getApplication(), 
event);
+                       dispatcher.dispatchEvent(source.getApplication(), 
event, null);
                }
        }
 
+       private static void dispatchToComponent(IEventDispatcher dispatcher, 
Component object,
+               ComponentEvent<?> e)
+       {
+               dispatcher.dispatchEvent(object, e, null);
+
+               if (e.isStop())
+               {
+                       return;
+               }
+
+               List<? extends Behavior> behaviors = object.getBehaviors();
+               for (Behavior behavior : behaviors)
+               {
+                       dispatcher.dispatchEvent(behavior, e, object);
+                       if (e.isStop())
+                       {
+                               break;
+                       }
+               }
+       }
+
+
        /**
         * Visitor used to broadcast events to components
         * 
@@ -279,26 +302,13 @@ final class ComponentEventSender impleme
                /** {@inheritDoc} */
                public void component(Component object, IVisit<Void> visit)
                {
-                       dispatcher.dispatchEvent(object, e);
+                       dispatchToComponent(dispatcher, object, e);
 
                        if (e.isStop())
                        {
                                visit.stop();
                        }
 
-                       List<? extends Behavior> behaviors = 
object.getBehaviors();
-                       for (Behavior behavior : behaviors)
-                       {
-                               IEventSink behaviorSink = behavior;
-                               dispatcher.dispatchEvent(behaviorSink, e);
-                               if (e.isStop())
-                               {
-                                       visit.stop();
-                                       break;
-                               }
-                       }
-
-
                        if (e.isShallow())
                        {
                                visit.dontGoDeeper();

Added: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IComponentAwareEventSink.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IComponentAwareEventSink.java?rev=1100644&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IComponentAwareEventSink.java
 (added)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IComponentAwareEventSink.java
 Sat May  7 22:33:15 2011
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket;
+
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.event.IEventSink;
+
+/**
+ * A specialization of {@link IEventSink} that adds component as an additional 
parameter to the
+ * {@link #onEvent(IEvent, Component)} method. This interface is useful for 
component plugins which
+ * wish to participate in event processing, for example {@link Behavior}s
+ * 
+ * @author igor
+ */
+public interface IComponentAwareEventSink
+{
+       /**
+        * Called when an event is sent to this behavior sink
+        * 
+        * @param component
+        *            component that owns this sink. For example, if the 
implementation of this
+        *            interface is a {@link Behavior} then component parameter 
will contain the
+        *            component to which the behavior is attached.
+        * @param event
+        */
+       void onEvent(Component component, IEvent<?> event);
+}

Propchange: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IComponentAwareEventSink.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IEventDispatcher.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IEventDispatcher.java?rev=1100644&r1=1100643&r2=1100644&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IEventDispatcher.java 
(original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/IEventDispatcher.java 
Sat May  7 22:33:15 2011
@@ -16,6 +16,7 @@
  */
 package org.apache.wicket;
 
+import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.event.IEvent;
 import org.apache.wicket.event.IEventSink;
 import org.apache.wicket.settings.IFrameworkSettings;
@@ -24,6 +25,9 @@ import org.apache.wicket.settings.IFrame
  * Delivers an event to a component. Developers can implement and register 
their dispatchers in
  * {@link IFrameworkSettings} to create custom strategies for how events get 
delivered to components
  * 
+ * @see IEventSink
+ * @see IComponentAwareEventSink
+ * 
  * @author Igor Vaynberg (ivaynberg)
  */
 public interface IEventDispatcher
@@ -32,7 +36,16 @@ public interface IEventDispatcher
         * Dispatches the even to the target component
         * 
         * @param sink
+        *            the sink for the event. Sinks usually implement {@link 
IEventSink} or
+        *            {@link IComponentAwareEventSink}. See the {@code 
component} parameter described
+        *            below.
         * @param event
+        * @param component
+        *            provides context to the sink. Some sinks are owned by the 
component, eg
+        *            {@link Behavior}s, and thus it is useful for them to have 
a reference to their
+        *            owning component. If this method is not {@code null} the 
dispatcher should try to
+        *            look for an alternative sink method which takes a 
component reference as an
+        *            additional parameter, one such implementation is {@link 
IComponentAwareEventSink}.
         */
-       void dispatchEvent(IEventSink sink, IEvent<?> event);
+       void dispatchEvent(Object sink, IEvent<?> event, Component component);
 }

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java?rev=1100644&r1=1100643&r2=1100644&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java 
(original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/behavior/Behavior.java 
Sat May  7 22:33:15 2011
@@ -18,8 +18,8 @@ package org.apache.wicket.behavior;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.IClusterable;
+import org.apache.wicket.IComponentAwareEventSink;
 import org.apache.wicket.event.IEvent;
-import org.apache.wicket.event.IEventSink;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.IHeaderContributor;
 import org.apache.wicket.markup.html.IHeaderResponse;
@@ -44,7 +44,11 @@ import org.apache.wicket.markup.html.IHe
  * @author Eelco Hillenius
  * @author Igor Vaynberg (ivaynberg)
  */
-public abstract class Behavior implements IClusterable, IEventSink, 
IHeaderContributor
+public abstract class Behavior
+       implements
+               IClusterable,
+               IComponentAwareEventSink,
+               IHeaderContributor
 {
        private static final long serialVersionUID = 1L;
 
@@ -208,7 +212,13 @@ public abstract class Behavior implement
        {
        }
 
-       public void onEvent(IEvent<?> event)
+       /**
+        * Called to notify the behavior about any events sent to the component
+        * 
+        * @see 
org.apache.wicket.IComponentAwareEventSink#onEvent(org.apache.wicket.Component,
+        *      org.apache.wicket.event.IEvent)
+        */
+       public void onEvent(Component component, IEvent<?> event)
        {
        }
 

Modified: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/settings/def/FrameworkSettings.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/settings/def/FrameworkSettings.java?rev=1100644&r1=1100643&r2=1100644&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/settings/def/FrameworkSettings.java
 (original)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/settings/def/FrameworkSettings.java
 Sat May  7 22:33:15 2011
@@ -19,6 +19,8 @@ package org.apache.wicket.settings.def;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.wicket.Component;
+import org.apache.wicket.IComponentAwareEventSink;
 import org.apache.wicket.IDetachListener;
 import org.apache.wicket.IEventDispatcher;
 import org.apache.wicket.event.IEvent;
@@ -87,11 +89,24 @@ public class FrameworkSettings implement
 
        /**
         * Dispatches event to registered dispatchers
+        * 
+        * @see IEventDispatcher#dispatchEvent(Object, IEvent, Component)
+        * 
+        * @param sink
+        * @param event
+        * @param component
         */
-       public void dispatchEvent(IEventSink sink, IEvent<?> event)
+       public void dispatchEvent(Object sink, IEvent<?> event, Component 
component)
        {
                // direct delivery
-               sink.onEvent(event);
+               if (component != null && sink instanceof 
IComponentAwareEventSink)
+               {
+                       ((IComponentAwareEventSink)sink).onEvent(component, 
event);
+               }
+               else if (sink instanceof IEventSink)
+               {
+                       ((IEventSink)sink).onEvent(event);
+               }
 
                // additional dispatchers delivery
                if (eventDispatchers == null)
@@ -100,7 +115,7 @@ public class FrameworkSettings implement
                }
                for (IEventDispatcher dispatcher : eventDispatchers)
                {
-                       dispatcher.dispatchEvent(sink, event);
+                       dispatcher.dispatchEvent(sink, event, component);
                }
        }
 }

Modified: 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/ComponentEventsTest.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/ComponentEventsTest.java?rev=1100644&r1=1100643&r2=1100644&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/ComponentEventsTest.java
 (original)
+++ 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/ComponentEventsTest.java
 Sat May  7 22:33:15 2011
@@ -16,10 +16,13 @@
  */
 package org.apache.wicket;
 
+import static org.junit.Assert.assertEquals;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.event.IEvent;
 import org.apache.wicket.markup.html.WebComponent;
@@ -359,6 +362,42 @@ public class ComponentEventsTest
                assertPath(c135, c13, c1, page, cycle, session);
        }
 
+       @Test
+       public void testBehavior()
+       {
+               TestComponent c = new TestComponent("c");
+               TestBehavior b1 = new TestBehavior();
+               TestBehavior b2 = new TestBehavior();
+               c.add(b1, b2);
+
+               c.send(c, Broadcast.BREADTH, new Payload());
+               assertEquals(0, c.sequence);
+               assertEquals(1, b1.sequence);
+               assertEquals(2, b2.sequence);
+       }
+
+       @Test
+       public void testBehavior_stop()
+       {
+               TestComponent c = new TestComponent("c");
+               TestBehavior b1 = new TestBehavior()
+               {
+                       @Override
+                       public void onEvent(Component component, IEvent<?> 
event)
+                       {
+                               super.onEvent(component, event);
+                               event.stop();
+                       }
+               };
+               TestBehavior b2 = new TestBehavior();
+               c.add(b1, b2);
+
+               c.send(c, Broadcast.BREADTH, new Payload());
+               assertEquals(0, c.sequence);
+               assertEquals(1, b1.sequence);
+               assertEquals(-1, b2.sequence);
+       }
+
 
        private void assertPath(Testable... testables)
        {
@@ -582,6 +621,36 @@ public class ComponentEventsTest
                }
        }
 
+
+       private class TestBehavior extends Behavior implements Testable
+       {
+               private static final long serialVersionUID = 1L;
+
+               int sequence = -1;
+               Component component;
+
+               @Override
+               public void onEvent(Component component, IEvent<?> event)
+               {
+                       super.onEvent(component, event);
+                       Payload payload = (Payload)event.getPayload();
+                       sequence = payload.next();
+                       this.component = component;
+                       // System.out.println(getId());
+                       if (stop == this)
+                       {
+                               event.stop();
+                       }
+               }
+
+
+               public int getSequence()
+               {
+                       return sequence;
+               }
+       }
+
+
        private static class Payload
        {
                private int counter;

Modified: 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/EventDispatcherTest.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/EventDispatcherTest.java?rev=1100644&r1=1100643&r2=1100644&view=diff
==============================================================================
--- 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/EventDispatcherTest.java
 (original)
+++ 
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/EventDispatcherTest.java
 Sat May  7 22:33:15 2011
@@ -25,7 +25,6 @@ import java.lang.reflect.Method;
 import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.event.Broadcast;
 import org.apache.wicket.event.IEvent;
-import org.apache.wicket.event.IEventSink;
 import org.apache.wicket.markup.html.WebComponent;
 
 /**
@@ -46,7 +45,7 @@ public class EventDispatcherTest extends
                page.add(testComponent);
                page.send(page, Broadcast.DEPTH, null);
                assertTrue(testComponent.callbackInvoked);
-               
assertEquals(testComponent.getBehaviors(TestBehavior.class).get(0).invokationTimes,
 2);
+               
assertEquals(testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes,
 2);
        }
 
        @Retention(RetentionPolicy.RUNTIME)
@@ -58,7 +57,7 @@ public class EventDispatcherTest extends
        /** */
        public static class DispatchToAnnotatedMethod implements 
IEventDispatcher
        {
-               public void dispatchEvent(IEventSink sink, IEvent<?> event)
+               public void dispatchEvent(Object sink, IEvent<?> event, 
Component component)
                {
                        Method[] sinkMethods = sink.getClass().getMethods();
                        for (Method sinkMethod : sinkMethods)
@@ -102,22 +101,23 @@ public class EventDispatcherTest extends
                }
        }
 
-       private static class TestBehavior extends Behavior implements IEventSink
+       private static class TestBehavior extends Behavior
        {
 
                private static final long serialVersionUID = 1;
 
-               int invokationTimes = 0;
+               int invocationTimes = 0;
 
-               public void onEvent(IEvent<?> event)
+               @Override
+               public void onEvent(Component component, IEvent<?> event)
                {
-                       invokationTimes++;
+                       invocationTimes++;
                }
 
                @EventCallback
                public void testCallback()
                {
-                       invokationTimes++;
+                       invocationTimes++;
                }
        }
 


Reply via email to