This is an automated email from the ASF dual-hosted git repository. reiern70 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/wicket.git
The following commit(s) were added to refs/heads/master by this push: new 436a7b4322 [WICKET-7080] 1) make default events delivery machinery pluggable 2) allow to disabled sending events 436a7b4322 is described below commit 436a7b4322e6ee074df7636bce4857b769a98a22 Author: reiern70 <reier...@gmail.com> AuthorDate: Mon Oct 16 12:19:53 2023 -0500 [WICKET-7080] 1) make default events delivery machinery pluggable 2) allow to disabled sending events --- .../org/apache/wicket/EventDispatcherTest.java | 310 ++++++++++++--------- .../src/main/java/org/apache/wicket/Component.java | 8 +- .../java/org/apache/wicket/ComponentEvent.java | 2 +- .../main/java/org/apache/wicket/event/IEvent.java | 5 + .../apache/wicket/settings/FrameworkSettings.java | 66 ++++- 5 files changed, 244 insertions(+), 147 deletions(-) diff --git a/wicket-core-tests/src/test/java/org/apache/wicket/EventDispatcherTest.java b/wicket-core-tests/src/test/java/org/apache/wicket/EventDispatcherTest.java index 06c802fa98..2838b73663 100644 --- a/wicket-core-tests/src/test/java/org/apache/wicket/EventDispatcherTest.java +++ b/wicket-core-tests/src/test/java/org/apache/wicket/EventDispatcherTest.java @@ -1,131 +1,179 @@ -/* - * 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 static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -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.markup.html.WebComponent; -import org.apache.wicket.util.tester.WicketTestCase; -import org.junit.jupiter.api.Test; - -/** - * @author Pedro Santos - */ -class EventDispatcherTest extends WicketTestCase -{ - - /** - * Testing DispatchToAnnotatedMethod event dispatchers in frameworksettings. This dispatcher - * invoke the methods annotated with @EvenCallback - * */ - @Test - void dispatchToAnnotatedMethod() - { - tester.getApplication().getFrameworkSettings().add(new DispatchToAnnotatedMethod()); - MockPageWithOneComponent page = new MockPageWithOneComponent(); - TestComponent testComponent = new TestComponent(MockPageWithOneComponent.COMPONENT_ID); - page.add(testComponent); - page.send(page, Broadcast.DEPTH, null); - assertTrue(testComponent.callbackInvoked); - assertEquals(testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes, 2); - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - private @interface EventCallback { - - } - - /** */ - static class DispatchToAnnotatedMethod implements IEventDispatcher - { - @Override - public void dispatchEvent(Object sink, IEvent<?> event, Component component) - { - Method[] sinkMethods = sink.getClass().getMethods(); - for (Method sinkMethod : sinkMethods) - { - if (sinkMethod.isAnnotationPresent(EventCallback.class)) - { - try - { - sinkMethod.invoke(sink); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - } - } - } - - /** */ - public static class TestComponent extends WebComponent - { - private static final long serialVersionUID = 1L; - boolean callbackInvoked; - - /** - * @param id - */ - TestComponent(String id) - { - super(id); - - add(new TestBehavior()); - } - - /** */ - @EventCallback - public void testCallback() - { - callbackInvoked = true; - } - } - - private static class TestBehavior extends Behavior - { - - private static final long serialVersionUID = 1; - - int invocationTimes = 0; - - @Override - public void onEvent(Component component, IEvent<?> event) - { - invocationTimes++; - } - - @EventCallback - public void testCallback() - { - invocationTimes++; - } - } - -} +/* + * 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 static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +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.markup.html.WebComponent; +import org.apache.wicket.util.tester.WicketTestCase; +import org.junit.jupiter.api.Test; + +/** + * @author Pedro Santos + */ +class EventDispatcherTest extends WicketTestCase +{ + + /** + * Testing DispatchToAnnotatedMethod event dispatchers in frameworksettings. This dispatcher + * invoke the methods annotated with @EvenCallback + * */ + @Test + void dispatchToAnnotatedMethod() + { + tester.getApplication().getFrameworkSettings().add(new DispatchToAnnotatedMethod()); + MockPageWithOneComponent page = new MockPageWithOneComponent(); + TestComponent testComponent = new TestComponent(MockPageWithOneComponent.COMPONENT_ID); + page.add(testComponent); + page.send(page, Broadcast.DEPTH, null); + assertTrue(testComponent.callbackInvoked); + assertEquals(testComponent.getBehaviors(TestBehavior.class).get(0).invocationTimes, 2); + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + private @interface EventCallback { + + } + + /** */ + static class DispatchToAnnotatedMethod implements IEventDispatcher + { + @Override + public void dispatchEvent(Object sink, IEvent<?> event, Component component) + { + Method[] sinkMethods = sink.getClass().getMethods(); + for (Method sinkMethod : sinkMethods) + { + if (sinkMethod.isAnnotationPresent(EventCallback.class)) + { + try + { + sinkMethod.invoke(sink); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + } + } + } + + /** */ + public static class TestComponent extends WebComponent + { + private static final long serialVersionUID = 1L; + boolean callbackInvoked; + + /** + * @param id + */ + TestComponent(String id) + { + super(id); + + add(new TestBehavior()); + } + + /** */ + @EventCallback + public void testCallback() + { + callbackInvoked = true; + } + } + + private static class TestBehavior extends Behavior + { + + private static final long serialVersionUID = 1; + + int invocationTimes = 0; + + @Override + public void onEvent(Component component, IEvent<?> event) + { + invocationTimes++; + } + + @EventCallback + public void testCallback() + { + invocationTimes++; + } + } + + @Test + void noEventsDispatch() + { + tester.getApplication().getFrameworkSettings().setDefaultEventDispatcher(null); + MockPageWithOneComponent page = new MockPageWithOneComponent(); + TestComponentI testComponent = new TestComponentI(MockPageWithOneComponent.COMPONENT_ID); + page.add(testComponent); + page.send(page, Broadcast.DEPTH, null); + assertFalse(testComponent.callbackInvoked); + assertEquals(testComponent.getBehaviors(TestBehaviorI.class).get(0).invocationTimes, 0); + } + + public static class TestComponentI extends WebComponent + { + private static final long serialVersionUID = 1L; + boolean callbackInvoked; + + /** + * @param id + */ + TestComponentI(String id) + { + super(id); + + add(new TestBehaviorI()); + } + + @Override + public void onEvent(IEvent<?> event) { + callbackInvoked = true; + } + } + + private static class TestBehaviorI extends Behavior + { + + private static final long serialVersionUID = 1; + + int invocationTimes = 0; + + @Override + public void onEvent(Component component, IEvent<?> event) + { + invocationTimes++; + } + } + +} 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 c288e7977b..ac1c93b5e8 100644 --- a/wicket-core/src/main/java/org/apache/wicket/Component.java +++ b/wicket-core/src/main/java/org/apache/wicket/Component.java @@ -4446,8 +4446,12 @@ public abstract class Component @Override public final <T> void send(IEventSink sink, Broadcast type, T payload) { - new ComponentEventSender(this, getApplication().getFrameworkSettings()).send(sink, type, - payload); + // if there are no event dispatchers then don't even try to send event + if (getApplication().getFrameworkSettings().hasAnyEventDispatchers()) + { + new ComponentEventSender(this, getApplication().getFrameworkSettings()).send(sink, type, + payload); + } } /** diff --git a/wicket-core/src/main/java/org/apache/wicket/ComponentEvent.java b/wicket-core/src/main/java/org/apache/wicket/ComponentEvent.java index d0f613e0dd..bab29ff435 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ComponentEvent.java +++ b/wicket-core/src/main/java/org/apache/wicket/ComponentEvent.java @@ -101,7 +101,7 @@ final class ComponentEvent<T> implements IEvent<T> stop = true; } - boolean isStop() + public boolean isStop() { return stop; } diff --git a/wicket-core/src/main/java/org/apache/wicket/event/IEvent.java b/wicket-core/src/main/java/org/apache/wicket/event/IEvent.java index 89ae35704b..6254f24afe 100644 --- a/wicket-core/src/main/java/org/apache/wicket/event/IEvent.java +++ b/wicket-core/src/main/java/org/apache/wicket/event/IEvent.java @@ -30,6 +30,11 @@ public interface IEvent<T> */ void stop(); + /** + * @return true iff event has been stopped. + */ + boolean isStop(); + /** * Stops the broadcast of this event any deeper into the hierarchy of the current sink */ 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..9f8e02d9e3 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,30 @@ import org.apache.wicket.util.string.Strings; */ public class FrameworkSettings implements IEventDispatcher { + /** + * Does the standard delivery of events. Events can be disabled at application level by setting a <code>null</code> + * {@link IEventDispatcher} via {@link #setDefaultEventDispatcher(IEventDispatcher)} and setting no additional + * {@link IEventDispatcher}s (via {@link #add(IEventDispatcher)}). + */ + 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,12 +90,13 @@ 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> * 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> * <li>major.minor-state for development versions. 1.2-beta2, 1.3-SNAPSHOT are examples</li> * </ul> + *</p> * * @return the Wicket version */ @@ -112,7 +135,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) @@ -129,26 +152,30 @@ public class FrameworkSettings implements IEventDispatcher return this; } + /** + * @return Returns <code>true</code> if there is at least one event dispatcher + */ + public final boolean hasAnyEventDispatchers() + { + if (defaultEventDispatcher != null) + { + return true; + } + return eventDispatchers != null && !eventDispatchers.isEmpty(); + } + /** * 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 +189,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 *