diff options
author | Aleksi Hietanen <aleksi@vaadin.com> | 2016-09-23 13:14:52 +0300 |
---|---|---|
committer | Denis Anisimov <denis@vaadin.com> | 2016-09-29 13:14:35 +0000 |
commit | 2bee988272657df4d886ea79b04be9fbc54d3928 (patch) | |
tree | 6825ec60243faac7fd4114928090e115e2e11d01 /compatibility-server | |
parent | 599b61bc8598db35fa111880dd4db57f9da2adda (diff) | |
download | vaadin-framework-2bee988272657df4d886ea79b04be9fbc54d3928.tar.gz vaadin-framework-2bee988272657df4d886ea79b04be9fbc54d3928.zip |
Unify listeners on the server side
This patch updates server side add*Listener methods to return
a registration object and deprecates their corresponding
remove*Listener methods.
Additionally this patch removes add/removeListener methods which were
deprecated in 7.0.
Change-Id: I26ac5f11882512288fbbf601c7cb2aaff653ec76
Diffstat (limited to 'compatibility-server')
7 files changed, 253 insertions, 7 deletions
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java b/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java index 2eeeb4c2ee..7a745fa464 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java @@ -20,6 +20,9 @@ import java.io.Serializable; import java.lang.reflect.Method; import com.vaadin.event.ConnectorEventListener; +import com.vaadin.event.FieldEvents.BlurEvent; +import com.vaadin.event.FieldEvents.BlurListener; +import com.vaadin.event.FieldEvents.FocusListener; import com.vaadin.ui.Component; import com.vaadin.util.ReflectTools; import com.vaadin.v7.ui.Field; @@ -33,6 +36,68 @@ import com.vaadin.v7.ui.TextField; public interface FieldEvents { /** + * The interface for adding and removing <code>FocusEvent</code> listeners. + * By implementing this interface a class explicitly announces that it will + * generate a <code>FocusEvent</code> when it receives keyboard focus. + * + * @since 6.2 + * @see FocusListener + * @see FocusEvent + */ + @Deprecated + public interface FocusNotifier extends Serializable { + /** + * Adds a <code>FocusListener</code> to the Component which gets fired + * when a <code>Field</code> receives keyboard focus. + * + * @param listener + * @see FocusListener + * @since 6.2 + */ + public void addFocusListener(FocusListener listener); + + /** + * Removes a <code>FocusListener</code> from the Component. + * + * @param listener + * @see FocusListener + * @since 6.2 + */ + public void removeFocusListener(FocusListener listener); + } + + /** + * The interface for adding and removing <code>BlurEvent</code> listeners. + * By implementing this interface a class explicitly announces that it will + * generate a <code>BlurEvent</code> when it loses keyboard focus. + * + * @since 6.2 + * @see BlurListener + * @see BlurEvent + */ + @Deprecated + public interface BlurNotifier extends Serializable { + /** + * Adds a <code>BlurListener</code> to the Component which gets fired + * when a <code>Field</code> loses keyboard focus. + * + * @param listener + * @see BlurListener + * @since 6.2 + */ + public void addBlurListener(BlurListener listener); + + /** + * Removes a <code>BlurListener</code> from the Component. + * + * @param listener + * @see BlurListener + * @since 6.2 + */ + public void removeBlurListener(BlurListener listener); + } + + /** * TextChangeEvents are fired when the user is editing the text content of a * field. Most commonly text change events are triggered by typing text with * keyboard, but e.g. pasting content from clip board to a text field also diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java index d2b4665bda..8a6b4849f8 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java @@ -24,15 +24,15 @@ import org.jsoup.nodes.Element; import com.vaadin.event.FieldEvents.BlurEvent; import com.vaadin.event.FieldEvents.BlurListener; -import com.vaadin.event.FieldEvents.BlurNotifier; import com.vaadin.event.FieldEvents.FocusEvent; import com.vaadin.event.FieldEvents.FocusListener; -import com.vaadin.event.FieldEvents.FocusNotifier; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.ui.LegacyComponent; import com.vaadin.ui.declarative.DesignAttributeHandler; import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.v7.event.FieldEvents.BlurNotifier; +import com.vaadin.v7.event.FieldEvents.FocusNotifier; import com.vaadin.v7.event.FieldEvents.TextChangeEvent; import com.vaadin.v7.event.FieldEvents.TextChangeListener; import com.vaadin.v7.event.FieldEvents.TextChangeNotifier; diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/ComboBox.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/ComboBox.java index 37d427b503..0ecfa9657f 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/ComboBox.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/ComboBox.java @@ -24,7 +24,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import com.vaadin.event.FieldEvents; import com.vaadin.event.FieldEvents.BlurEvent; import com.vaadin.event.FieldEvents.BlurListener; import com.vaadin.event.FieldEvents.FocusEvent; @@ -34,6 +33,7 @@ import com.vaadin.server.PaintTarget; import com.vaadin.server.Resource; import com.vaadin.v7.data.Container; import com.vaadin.v7.data.util.filter.SimpleStringFilter; +import com.vaadin.v7.event.FieldEvents; import com.vaadin.v7.shared.ui.combobox.ComboBoxConstants; import com.vaadin.v7.shared.ui.combobox.ComboBoxState; import com.vaadin.v7.shared.ui.combobox.FilteringMode; diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java index 4ee2ee4648..14d0145730 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java @@ -28,7 +28,6 @@ import java.util.logging.Logger; import org.jsoup.nodes.Element; -import com.vaadin.event.FieldEvents; import com.vaadin.event.FieldEvents.BlurEvent; import com.vaadin.event.FieldEvents.BlurListener; import com.vaadin.event.FieldEvents.FocusEvent; @@ -45,6 +44,7 @@ import com.vaadin.v7.data.Validator; import com.vaadin.v7.data.Validator.InvalidValueException; import com.vaadin.v7.data.util.converter.Converter; import com.vaadin.v7.data.validator.DateRangeValidator; +import com.vaadin.v7.event.FieldEvents; import com.vaadin.v7.shared.ui.datefield.DateFieldConstants; import com.vaadin.v7.shared.ui.datefield.TextualDateFieldState; @@ -73,7 +73,7 @@ public class DateField extends AbstractField<Date> implements /** * Resolution identifier: seconds. - * + * * @deprecated As of 7.0, use {@link Resolution#SECOND} */ @Deprecated diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/NativeSelect.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/NativeSelect.java index 752884663f..3d535f2584 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/NativeSelect.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/NativeSelect.java @@ -18,13 +18,13 @@ package com.vaadin.v7.ui; import java.util.Collection; -import com.vaadin.event.FieldEvents; import com.vaadin.event.FieldEvents.BlurEvent; import com.vaadin.event.FieldEvents.BlurListener; import com.vaadin.event.FieldEvents.FocusAndBlurServerRpcImpl; import com.vaadin.event.FieldEvents.FocusEvent; import com.vaadin.event.FieldEvents.FocusListener; import com.vaadin.v7.data.Container; +import com.vaadin.v7.event.FieldEvents; /** * This is a simple drop-down select without, for instance, support for diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/OptionGroup.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/OptionGroup.java index 0dba641909..2cf1f57962 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/OptionGroup.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/OptionGroup.java @@ -23,7 +23,6 @@ import java.util.Set; import org.jsoup.nodes.Element; -import com.vaadin.event.FieldEvents; import com.vaadin.event.FieldEvents.BlurEvent; import com.vaadin.event.FieldEvents.BlurListener; import com.vaadin.event.FieldEvents.FocusEvent; @@ -33,6 +32,7 @@ import com.vaadin.server.PaintTarget; import com.vaadin.ui.declarative.DesignContext; import com.vaadin.ui.declarative.DesignFormatter; import com.vaadin.v7.data.Container; +import com.vaadin.v7.event.FieldEvents; import com.vaadin.v7.shared.ui.optiongroup.OptionGroupConstants; import com.vaadin.v7.shared.ui.optiongroup.OptionGroupState; diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/component/AbstractListenerMethodsTestBase.java b/compatibility-server/src/test/java/com/vaadin/tests/server/component/AbstractListenerMethodsTestBase.java new file mode 100644 index 0000000000..0d6166b2d9 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/tests/server/component/AbstractListenerMethodsTestBase.java @@ -0,0 +1,181 @@ +package com.vaadin.tests.server.component; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.easymock.EasyMock; +import org.junit.Assert; + +import com.vaadin.tests.VaadinClasses; +import com.vaadin.ui.Component; + +public abstract class AbstractListenerMethodsTestBase { + + public static void main(String[] args) { + findAllListenerMethods(); + } + + private static void findAllListenerMethods() { + Set<Class<?>> classes = new HashSet<>(); + for (Class<?> c : VaadinClasses.getAllServerSideClasses()) { + while (c != null && c.getName().startsWith("com.vaadin.")) { + classes.add(c); + c = c.getSuperclass(); + } + } + + for (Class<?> c : classes) { + boolean found = false; + for (Method m : c.getDeclaredMethods()) { + String methodName = m.getName(); + if (methodName.startsWith("add") + && methodName.endsWith("Listener") + && !"addListener".equals(methodName)) { + if (m.getParameterTypes().length != 1) { + continue; + } + String packageName = "com.vaadin.tests.server"; + if (Component.class.isAssignableFrom(c)) { + packageName += ".component." + + c.getSimpleName().toLowerCase(); + continue; + } + + if (!found) { + found = true; + System.out.println("package " + packageName + ";"); + + System.out.println("import " + + AbstractListenerMethodsTestBase.class + .getName() + + ";"); + System.out.println("import " + c.getName() + ";"); + System.out + .println( + "public class " + c.getSimpleName() + + "Listeners extends " + + AbstractListenerMethodsTestBase.class + .getSimpleName() + + " {"); + } + + String listenerClassName = m.getParameterTypes()[0] + .getSimpleName(); + String eventClassName = listenerClassName + .replaceFirst("Listener$", "Event"); + System.out.println("public void test" + listenerClassName + + "() throws Exception {"); + System.out.println(" testListener(" + c.getSimpleName() + + ".class, " + eventClassName + ".class, " + + listenerClassName + ".class);"); + System.out.println("}"); + } + } + if (found) { + System.out.println("}"); + System.out.println(); + } + } + } + + protected void testListenerAddGetRemove(Class<?> testClass, + Class<?> eventClass, Class<?> listenerClass) throws Exception { + // Create a component for testing + Object c = testClass.newInstance(); + testListenerAddGetRemove(testClass, eventClass, listenerClass, c); + + } + + protected void testListenerAddGetRemove(Class<?> cls, Class<?> eventClass, + Class<?> listenerClass, Object c) throws Exception { + + Object mockListener1 = EasyMock.createMock(listenerClass); + Object mockListener2 = EasyMock.createMock(listenerClass); + + // Verify we start from no listeners + verifyListeners(c, eventClass); + + // Add one listener and verify + addListener(c, mockListener1, listenerClass); + verifyListeners(c, eventClass, mockListener1); + + // Add another listener and verify + addListener(c, mockListener2, listenerClass); + verifyListeners(c, eventClass, mockListener1, mockListener2); + + // Ensure we can fetch using parent class also + if (eventClass.getSuperclass() != null) { + verifyListeners(c, eventClass.getSuperclass(), mockListener1, + mockListener2); + } + + // Remove the first and verify + removeListener(c, mockListener1, listenerClass); + verifyListeners(c, eventClass, mockListener2); + + // Remove the remaining and verify + removeListener(c, mockListener2, listenerClass); + verifyListeners(c, eventClass); + + } + + private void removeListener(Object c, Object listener, + Class<?> listenerClass) throws IllegalArgumentException, + IllegalAccessException, InvocationTargetException, + SecurityException, NoSuchMethodException { + Method method = getRemoveListenerMethod(c.getClass(), listenerClass); + method.invoke(c, listener); + + } + + private void addListener(Object c, Object listener1, Class<?> listenerClass) + throws IllegalArgumentException, IllegalAccessException, + InvocationTargetException, SecurityException, + NoSuchMethodException { + Method method = getAddListenerMethod(c.getClass(), listenerClass); + method.invoke(c, listener1); + } + + private Collection<?> getListeners(Object c, Class<?> eventType) + throws IllegalArgumentException, IllegalAccessException, + InvocationTargetException, SecurityException, + NoSuchMethodException { + Method method = getGetListenersMethod(c.getClass()); + return (Collection<?>) method.invoke(c, eventType); + } + + private Method getGetListenersMethod(Class<? extends Object> cls) + throws SecurityException, NoSuchMethodException { + return cls.getMethod("getListeners", Class.class); + } + + private Method getAddListenerMethod(Class<?> cls, Class<?> listenerClass) + throws SecurityException, NoSuchMethodException { + return cls.getMethod("add" + listenerClass.getSimpleName(), + listenerClass); + + } + + private Method getRemoveListenerMethod(Class<?> cls, Class<?> listenerClass) + throws SecurityException, NoSuchMethodException { + return cls.getMethod("remove" + listenerClass.getSimpleName(), + listenerClass); + + } + + private void verifyListeners(Object c, Class<?> eventClass, + Object... expectedListeners) throws IllegalArgumentException, + SecurityException, IllegalAccessException, + InvocationTargetException, NoSuchMethodException { + Collection<?> registeredListeners = getListeners(c, eventClass); + Assert.assertEquals("Number of listeners", expectedListeners.length, + registeredListeners.size()); + + Assert.assertArrayEquals(expectedListeners, + registeredListeners.toArray()); + + } +}
\ No newline at end of file |