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

reiern70 pushed a commit to branch reiern70/WICKET-7080
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit 6fd7ce97b8276bf2522ad550e1240e234886d5c7
Author: reiern70 <[email protected]>
AuthorDate: Mon Oct 16 12:19:53 2023 -0500

    [WICKET-7080] 1) make default events delivery machinery pluggable 2) allow 
to disabled sending events 3) define reflection based machinery to deliver 
events
---
 .../org/apache/wicket/event/EventAwareObject.java  |  34 +++
 .../org/apache/wicket/event/IEventAwareObject.java |  23 ++
 .../main/java/org/apache/wicket/event/OnEvent.java |  40 +++
 .../wicket/event/ReflectionEventDispatcher.java    | 104 +++++++
 .../apache/wicket/settings/FrameworkSettings.java  |  51 +++-
 .../event/ReflectionEventDispatcherTest.java       | 328 +++++++++++++++++++++
 6 files changed, 567 insertions(+), 13 deletions(-)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/event/EventAwareObject.java 
b/wicket-core/src/main/java/org/apache/wicket/event/EventAwareObject.java
new file mode 100644
index 0000000000..7214312e9d
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/event/EventAwareObject.java
@@ -0,0 +1,34 @@
+/*
+ * 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.event;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used to mark a component, a session or application as aware of 
annotated events
+ *
+ *  See {@link ReflectionEventDispatcher}
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.TYPE_USE, ElementType.TYPE })
+public @interface EventAwareObject
+{
+
+}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/event/IEventAwareObject.java 
b/wicket-core/src/main/java/org/apache/wicket/event/IEventAwareObject.java
new file mode 100644
index 0000000000..710847b13b
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/event/IEventAwareObject.java
@@ -0,0 +1,23 @@
+/*
+ * 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.event;
+
+/**
+ * To mark an object as able to react to annotated event handler methods
+ */
+public interface IEventAwareObject {
+}
diff --git a/wicket-core/src/main/java/org/apache/wicket/event/OnEvent.java 
b/wicket-core/src/main/java/org/apache/wicket/event/OnEvent.java
new file mode 100644
index 0000000000..18ab9b07a4
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/event/OnEvent.java
@@ -0,0 +1,40 @@
+/*
+ * 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.event;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used to mark a public method (on a component) or on {@link 
org.apache.wicket.behavior.Behavior}
+ * as a handler of an Event.
+ * <p></p>
+ *  See {@link ReflectionEventDispatcher}
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface OnEvent
+{
+
+    /**
+     * @return The class of the payload
+     */
+    Class<?> value();
+
+}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/event/ReflectionEventDispatcher.java
 
b/wicket-core/src/main/java/org/apache/wicket/event/ReflectionEventDispatcher.java
new file mode 100644
index 0000000000..0e060065f7
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/event/ReflectionEventDispatcher.java
@@ -0,0 +1,104 @@
+/*
+ * 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.event;
+
+import java.lang.reflect.Method;
+import org.apache.wicket.Component;
+import org.apache.wicket.IEventDispatcher;
+import org.apache.wicket.WicketRuntimeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * IEventDispatcher that uses reflection in order to locate events methods.
+ */
+public class ReflectionEventDispatcher implements IEventDispatcher {
+
+       private static final Logger LOGGER = 
LoggerFactory.getLogger(ReflectionEventDispatcher.class);
+
+       /**
+        * If set to true then only sinks annotated with @{@link 
EventAwareObject} will be injected.
+        * Probably, this should be set to true in most applications and 
enforce the use of either @{@link EventAwareObject}
+        * annotation or the marker interface @{@link IEventAwareObject}
+        */
+       private final boolean restrictToEventAware;
+
+       public ReflectionEventDispatcher(boolean restrictToEventAware)
+       {
+               this.restrictToEventAware = restrictToEventAware;
+       }
+
+       @Override
+       public final void dispatchEvent(Object sink, IEvent<?> event, Component 
component)
+       {
+               if (restrictToEventAware)
+               {
+                       Class<?> clazz = sink.getClass();
+                       if (!clazz.isAnnotationPresent(EventAwareObject.class) 
&& !(sink instanceof IEventAwareObject))
+                       {
+                               // object does not receives events
+                               return;
+                       }
+               }
+               executeEvent(sink, event);
+       }
+
+       private void executeEvent(Object sink, IEvent<?> event)
+       {
+               Class<?> clazz = sink.getClass();
+               // TODO: allow for private protected methods?
+               for (Method method : clazz.getMethods())
+               {
+                       if (isMethodAnEventMethod(method, event))
+                       {
+                               method.setAccessible(true);
+                               try
+                               {
+                                       // we try to inject IEvent
+                                       method.invoke(sink, event);
+                               }
+                               catch (Exception e)
+                               {
+                                       try
+                                       {
+                                               // we try to inject payload 
directly
+                                               method.invoke(sink, 
event.getPayload());
+                                       }
+                                       catch (Exception e1)
+                                       {
+                                               LOGGER.error("Wrong signature 
of event method: sink {} and method {}", clazz, method);
+                                               throw new 
WicketRuntimeException("Wrong signature of event method: " + method.getName());
+                                       }
+                               }
+                       }
+               }
+       }
+
+       protected boolean isMethodAnEventMethod(Method method, IEvent<?> event)
+       {
+               Class<?> payloadClass = event.getPayload().getClass();
+               // we look for annotation
+               if (method.isAnnotationPresent(OnEvent.class))
+               {
+                       OnEvent onEvent = method.getAnnotation(OnEvent.class);
+                       Class<?> eventClass = onEvent.value();
+                       // and we check payload if of the right type
+                       return eventClass.isAssignableFrom(payloadClass);
+               }
+               return false;
+       }
+}
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/settings/FrameworkSettings.java 
b/wicket-core/src/main/java/org/apache/wicket/settings/FrameworkSettings.java
index d193ca6a1b..a1eb9b3d84 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/settings/FrameworkSettings.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/settings/FrameworkSettings.java
@@ -45,8 +45,28 @@ import org.apache.wicket.util.string.Strings;
  */
 public class FrameworkSettings implements IEventDispatcher
 {
+       /**
+        *  Does the standard delivery of events. Override and do nothing if 
you want to disable it.
+        */
+       private static class DefaultEventDispatcher implements IEventDispatcher
+       {
+               @Override
+               public void dispatchEvent(Object sink, IEvent<?> event, 
Component component)
+               {
+                       // direct delivery
+                       if (component != null && sink instanceof 
IComponentAwareEventSink)
+                       {
+                               
((IComponentAwareEventSink)sink).onEvent(component, event);
+                       }
+                       else if (sink instanceof IEventSink)
+                       {
+                               ((IEventSink)sink).onEvent(event);
+                       }
+               }
+       }
        private IDetachListener detachListener;
 
+       private IEventDispatcher defaultEventDispatcher = new 
DefaultEventDispatcher();
        private List<IEventDispatcher> eventDispatchers = null;
 
        /**
@@ -68,7 +88,7 @@ public class FrameworkSettings implements IEventDispatcher
         * Gets the Wicket version. The Wicket version is in the same format as 
the version element in
         * the pom.xml file (project descriptor). The version is generated by 
maven in the build/release
         * cycle and put in the /META-INF/MANIFEST.MF file located in the root 
folder of the Wicket jar.
-        *
+        * <p></p>
         * The version usually follows one of the following formats:
         * <ul>
         * <li>major.minor[.bug] for stable versions. 1.1, 1.2, 1.2.1 are 
examples</li>
@@ -112,7 +132,7 @@ public class FrameworkSettings implements IEventDispatcher
        /**
         * Registers a new event dispatcher
         *
-        * @param dispatcher
+        * @param dispatcher {@link IEventDispatcher}
         * @return {@code this} object for chaining
         */
        public FrameworkSettings add(IEventDispatcher dispatcher)
@@ -133,22 +153,14 @@ public class FrameworkSettings implements IEventDispatcher
         * Dispatches event to registered dispatchers
         * 
         * @see IEventDispatcher#dispatchEvent(Object, IEvent, Component)
-        * 
-        * @param sink
-        * @param event
-        * @param component
+        *
         */
        @Override
        public void dispatchEvent(Object sink, IEvent<?> event, Component 
component)
        {
-               // direct delivery
-               if (component != null && sink instanceof 
IComponentAwareEventSink)
+               if (defaultEventDispatcher != null)
                {
-                       ((IComponentAwareEventSink)sink).onEvent(component, 
event);
-               }
-               else if (sink instanceof IEventSink)
-               {
-                       ((IEventSink)sink).onEvent(event);
+                       defaultEventDispatcher.dispatchEvent(sink, event, 
component);
                }
 
                // additional dispatchers delivery
@@ -162,6 +174,19 @@ public class FrameworkSettings implements IEventDispatcher
                }
        }
 
+       /**
+        * Allows to set the default events dispatcher
+        *
+        * @param defaultEventDispatcher
+        *                      IEventDispatcher
+        * @return {@code this} object for chaining
+        */
+       public FrameworkSettings setDefaultEventDispatcher(IEventDispatcher 
defaultEventDispatcher)
+       {
+               this.defaultEventDispatcher = defaultEventDispatcher;
+               return this;
+       }
+
        /**
         * Sets the {@link ISerializer} that will be used to convert objects 
to/from byte arrays
         *
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/event/ReflectionEventDispatcherTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/event/ReflectionEventDispatcherTest.java
new file mode 100644
index 0000000000..ed6b232176
--- /dev/null
+++ 
b/wicket-core/src/test/java/org/apache/wicket/event/ReflectionEventDispatcherTest.java
@@ -0,0 +1,328 @@
+/*
+ * 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.event;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import org.apache.wicket.Component;
+import org.apache.wicket.MockPageWithOneComponent;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.html.WebComponent;
+import org.apache.wicket.util.tester.WicketTestCase;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author reiern70
+ */
+class ReflectionEventDispatcherTest extends WicketTestCase
+{
+
+       private static class TestPayload {
+
+       }
+
+       // we just disable event dispatching at application level
+       @Test
+       void testEventsDeliveryDisable()
+       {
+               
tester.getApplication().getFrameworkSettings().setDefaultEventDispatcher(null);
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponent testComponent = new 
TestComponent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               assertEquals(0, testComponent.invocationTimes);
+               assertEquals(0, 
testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes);
+       }
+
+
+       /**
+        * Testing ReflectionEventDispatcher event dispatchers in 
frameworksettings. This dispatcher
+        * invoke the methods annotated with @OnEvent
+        * */
+       @Test
+       void dispatchToAnnotatedMethodNoRestrictions()
+       {
+               tester.getApplication().getFrameworkSettings().add(new 
ReflectionEventDispatcher(false));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponent testComponent = new 
TestComponent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               assertEquals( 2, testComponent.invocationTimes);
+               assertEquals( 2, 
testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes);
+       }
+
+       /**
+        * The same as the above but injecting IEvent.
+        */
+       @Test
+       void dispatchToAnnotatedMethodNoRestrictionsReceivesIEvent()
+       {
+               tester.getApplication().getFrameworkSettings().add(new 
ReflectionEventDispatcher(false));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponentIEvent testComponent = new 
TestComponentIEvent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               assertEquals(2, testComponent.invocationTimes);
+               assertEquals(2, 
testComponent.getBehaviors(TestBehaviorIEvent.class).get(0).invocationTimes);
+       }
+
+       /**
+        * Testing ReflectionEventDispatcher event dispatchers in 
frameworksettings. This dispatcher
+        * invoke the methods annotated with @OnEvent
+        * */
+       @Test
+       void dispatchToAnnotatedMethodToAnnotatedObjects()
+       {
+               tester.getApplication().getFrameworkSettings().add(new 
ReflectionEventDispatcher(true));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponent testComponent = new 
TestComponent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               // as component and behavior are not annotated with 
@EventAwareObject only default event system will work
+               assertEquals(1, testComponent.invocationTimes);
+               assertEquals(1, 
testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes);
+       }
+
+       @Test
+       void dispatchToAnnotatedMethodToAnnotatedObjectsAnonymous()
+       {
+               tester.getApplication().getFrameworkSettings().add(new 
ReflectionEventDispatcher(false));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponent testComponent = new 
TestComponent(MockPageWithOneComponent.COMPONENT_ID) {
+                       @OnEvent(TestPayload.class)
+                       @SuppressWarnings("unused")
+                       public void testCallbackEvent(IEvent<TestPayload> event)
+                       {
+                               assertNotNull(event);
+                               assertNotNull(event.getPayload());
+                               invocationTimes++;
+                       }
+
+                       @Override
+                       protected void addBehavior() {
+                               add(new TestBehavior(){
+                                       @OnEvent(TestPayload.class)
+                                       @SuppressWarnings("unused")
+                                       public void 
testCallbackEvent(IEvent<TestPayload> event)
+                                       {
+                                               assertNotNull(event);
+                                               
assertNotNull(event.getPayload());
+                                               invocationTimes++;
+                                       }
+                               });
+                       }
+               };
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               // as component and behavior  are not annotated with 
@EventAwareObject only default event system will work
+               assertEquals(3, testComponent.invocationTimes);
+               assertEquals(3, 
testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes);
+       }
+
+       /**
+        * The same as the above but injecting IEvent.
+        */
+       @Test
+       void dispatchToAnnotatedMethodToAnnotatedEventAwareObject()
+       {
+               // both events will arrive
+               tester.getApplication().getFrameworkSettings().add(new 
ReflectionEventDispatcher(false));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponentIEvent testComponent = new 
TestComponentIEvent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               assertEquals(2, testComponent.invocationTimes);
+               assertEquals(2, 
testComponent.getBehaviors(TestBehaviorIEvent.class).get(0).invocationTimes);
+       }
+
+       /**
+        * The same as the above but injecting IEvent.
+        */
+       @Test
+       void 
dispatchToAnnotatedMethodInOnjectImplementingEventAwareObjectTestBehavior()
+       {
+               // both events will arrive
+               tester.getApplication().getFrameworkSettings().add(new 
ReflectionEventDispatcher(false));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               EventAwareObjectTestComponent testComponent = new 
EventAwareObjectTestComponent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               assertEquals(2, testComponent.invocationTimes);
+               assertEquals(2, 
testComponent.getBehaviors(EventAwareObjectTestBehavior.class).get(0).invocationTimes);
+       }
+
+       @Test
+       void replaceDefaultEvents()
+       {
+               // both events will arrive
+               
tester.getApplication().getFrameworkSettings().setDefaultEventDispatcher(new 
ReflectionEventDispatcher(false));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponentIEvent testComponent = new 
TestComponentIEvent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               assertEquals(1, testComponent.invocationTimes);
+               assertEquals(1, 
testComponent.getBehaviors(TestBehaviorIEvent.class).get(0).invocationTimes);
+       }
+
+       @Test
+       void replaceDefaultEventsIEvent()
+       {
+               // both events will arrive
+               
tester.getApplication().getFrameworkSettings().setDefaultEventDispatcher(new 
ReflectionEventDispatcher(false));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponent testComponent = new 
TestComponent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               assertEquals( 1, testComponent.invocationTimes);
+               assertEquals( 1, 
testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes);
+       }
+
+       @Test
+       void replaceDefaultEventsAnnotatedNoDelivery()
+       {
+               
tester.getApplication().getFrameworkSettings().setDefaultEventDispatcher(new 
ReflectionEventDispatcher(true));
+               MockPageWithOneComponent page = new MockPageWithOneComponent();
+               TestComponent testComponent = new 
TestComponent(MockPageWithOneComponent.COMPONENT_ID);
+               page.add(testComponent);
+               page.send(page, Broadcast.DEPTH, new TestPayload());
+               // no events will arrive as component is not annoated
+               assertEquals(0, testComponent.invocationTimes);
+               assertEquals( 0, 
testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes);
+       }
+
+       /** */
+       public static class TestComponent extends WebComponent
+       {
+               private static final long serialVersionUID = 1L;
+               int invocationTimes = 0;
+
+               TestComponent(String id)
+               {
+                       super(id);
+                       addBehavior();
+               }
+
+               protected void addBehavior() {
+                       add(new TestBehavior());
+               }
+
+               /** */
+               @OnEvent(TestPayload.class)
+               @SuppressWarnings("unused")
+               public void testCallback(TestPayload payload)
+               {
+                       assertNotNull(payload);
+                       invocationTimes++;
+               }
+
+               @Override
+               public void onEvent(IEvent<?> event) {
+                       invocationTimes++;
+               }
+       }
+
+       private static class TestBehavior extends Behavior
+       {
+
+               private static final long serialVersionUID = 1;
+
+               int invocationTimes = 0;
+
+               @Override
+               public void onEvent(Component component, IEvent<?> event)
+               {
+                       invocationTimes++;
+               }
+
+               @OnEvent(TestPayload.class)
+               @SuppressWarnings("unused")
+               public void testCallback(TestPayload payload)
+               {
+                       assertNotNull(payload);
+                       invocationTimes++;
+               }
+       }
+
+       public static class EventAwareObjectTestComponent extends TestComponent 
implements IEventAwareObject {
+
+               EventAwareObjectTestComponent(String id) {
+                       super(id);
+               }
+
+               @Override
+               protected void addBehavior() {
+                       add(new EventAwareObjectTestBehavior());
+               }
+       }
+
+       private static class EventAwareObjectTestBehavior extends TestBehavior 
implements IEventAwareObject{
+
+       }
+
+       @EventAwareObject
+       public static class TestComponentIEvent extends WebComponent
+       {
+               private static final long serialVersionUID = 1L;
+               int invocationTimes = 0;
+
+               TestComponentIEvent(String id)
+               {
+                       super(id);
+
+                       add(new TestBehaviorIEvent());
+               }
+
+               @Override
+               public void onEvent(IEvent<?> event) {
+                       invocationTimes++;
+               }
+
+               /** */
+               @OnEvent(TestPayload.class)
+               @SuppressWarnings("unused")
+               public void testCallback(IEvent<TestPayload> event)
+               {
+                       assertNotNull(event);
+                       assertNotNull(event.getPayload());
+                       invocationTimes++;
+               }
+       }
+
+       @EventAwareObject
+       private static class TestBehaviorIEvent extends Behavior
+       {
+
+               private static final long serialVersionUID = 1;
+
+               int invocationTimes = 0;
+
+               @Override
+               public void onEvent(Component component, IEvent<?> event)
+               {
+                       invocationTimes++;
+               }
+
+               @OnEvent(TestPayload.class)
+               @SuppressWarnings("unused")
+               public void testCallback(IEvent<TestPayload> event)
+               {
+                       assertNotNull(event);
+                       assertNotNull(event.getPayload());
+                       invocationTimes++;
+               }
+       }
+}

Reply via email to