import com.vaadin.data.util.converter.Converter; | import com.vaadin.data.util.converter.Converter; | ||||
import com.vaadin.data.util.converter.StringToIntegerConverter; | import com.vaadin.data.util.converter.StringToIntegerConverter; | ||||
import com.vaadin.data.util.converter.ValueContext; | import com.vaadin.data.util.converter.ValueContext; | ||||
import com.vaadin.event.EventRouter; | |||||
import com.vaadin.event.SimpleEventRouter; | |||||
import com.vaadin.server.ErrorMessage; | import com.vaadin.server.ErrorMessage; | ||||
import com.vaadin.server.SerializableBiConsumer; | import com.vaadin.server.SerializableBiConsumer; | ||||
import com.vaadin.server.SerializableFunction; | import com.vaadin.server.SerializableFunction; | ||||
private final Map<HasValue<?>, ConverterDelegate<?>> initialConverters = new IdentityHashMap<>(); | private final Map<HasValue<?>, ConverterDelegate<?>> initialConverters = new IdentityHashMap<>(); | ||||
private EventRouter eventRouter; | |||||
private SimpleEventRouter<StatusChangeEvent> eventRouter; | |||||
private Label statusLabel; | private Label statusLabel; | ||||
*/ | */ | ||||
private List<ValidationResult> validateBean(BEAN bean) { | private List<ValidationResult> validateBean(BEAN bean) { | ||||
Objects.requireNonNull(bean, "bean cannot be null"); | Objects.requireNonNull(bean, "bean cannot be null"); | ||||
List<ValidationResult> results = Collections | |||||
.unmodifiableList(validators.stream() | |||||
.map(validator -> validator.apply(bean, | |||||
new ValueContext())) | |||||
.collect(Collectors.toList())); | |||||
List<ValidationResult> results = Collections.unmodifiableList(validators | |||||
.stream() | |||||
.map(validator -> validator.apply(bean, new ValueContext())) | |||||
.collect(Collectors.toList())); | |||||
return results; | return results; | ||||
} | } | ||||
* @return a registration for the listener | * @return a registration for the listener | ||||
*/ | */ | ||||
public Registration addStatusChangeListener(StatusChangeListener listener) { | public Registration addStatusChangeListener(StatusChangeListener listener) { | ||||
return getEventRouter().addListener(StatusChangeEvent.class, listener, | |||||
StatusChangeListener.class.getDeclaredMethods()[0]); | |||||
return getEventRouter().addListener(listener); | |||||
} | } | ||||
/** | /** | ||||
* | * | ||||
* @return the event router, not null | * @return the event router, not null | ||||
*/ | */ | ||||
protected EventRouter getEventRouter() { | |||||
private SimpleEventRouter getEventRouter() { | |||||
if (eventRouter == null) { | if (eventRouter == null) { | ||||
eventRouter = new EventRouter(); | |||||
eventRouter = new SimpleEventRouter(); | |||||
} | } | ||||
return eventRouter; | return eventRouter; | ||||
} | } |
*/ | */ | ||||
package com.vaadin.data; | package com.vaadin.data; | ||||
import java.io.Serializable; | |||||
import com.vaadin.event.Listener; | |||||
/** | /** | ||||
* Listener interface for {@link StatusChangeEvent}s. | * Listener interface for {@link StatusChangeEvent}s. | ||||
* | |||||
* | |||||
* @see StatusChangeEvent | * @see StatusChangeEvent | ||||
* @author Vaadin Ltd | * @author Vaadin Ltd | ||||
* | * | ||||
*/ | */ | ||||
@FunctionalInterface | @FunctionalInterface | ||||
public interface StatusChangeListener extends Serializable { | |||||
public interface StatusChangeListener extends Listener<StatusChangeEvent> { | |||||
/** | /** | ||||
* Notifies the listener about status change {@code event}. | * Notifies the listener about status change {@code event}. | ||||
* | |||||
* | |||||
* @param event | * @param event | ||||
* a status change event, not null | * a status change event, not null | ||||
*/ | */ | ||||
void statusChange(StatusChangeEvent event); | |||||
@Override | |||||
void onEvent(StatusChangeEvent event); | |||||
} | } |
import java.util.LinkedHashSet; | import java.util.LinkedHashSet; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Objects; | import java.util.Objects; | ||||
import java.util.logging.Logger; | |||||
import com.vaadin.server.ErrorEvent; | import com.vaadin.server.ErrorEvent; | ||||
import com.vaadin.server.ErrorHandler; | import com.vaadin.server.ErrorHandler; | ||||
* @since 3.0 | * @since 3.0 | ||||
*/ | */ | ||||
@SuppressWarnings("serial") | @SuppressWarnings("serial") | ||||
public class EventRouter implements MethodEventSource { | |||||
public class EventRouter { | |||||
/** | /** | ||||
* List of registered listeners. | * List of registered listeners. | ||||
*/ | */ | ||||
private LinkedHashSet<ListenerMethod> listenerList = null; | private LinkedHashSet<ListenerMethod> listenerList = null; | ||||
/* | |||||
* Registers a new listener with the specified activation method to listen | |||||
* events generated by this component. Don't add a JavaDoc comment here, we | |||||
* use the default documentation from implemented interface. | |||||
/** | |||||
* <p> | |||||
* Registers a new event listener with the specified activation method to | |||||
* listen events generated by this component. If the activation method does | |||||
* not have any arguments the event object will not be passed to it when | |||||
* it's called. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the type of the listened event. Events of this type or its | |||||
* subclasses activate the listener. | |||||
* @param object | |||||
* the object instance who owns the activation method. | |||||
* @param method | |||||
* the activation method. | |||||
* @return a registration object for removing the listener | |||||
* @throws java.lang.IllegalArgumentException | |||||
* unless <code>method</code> has exactly one match in | |||||
* <code>object</code> | |||||
* @throws NullPointerException | |||||
* if {@code object} is {@code null} | |||||
*/ | */ | ||||
@Override | |||||
public Registration addListener(Class<?> eventType, Object object, | public Registration addListener(Class<?> eventType, Object object, | ||||
Method method) { | Method method) { | ||||
Objects.requireNonNull(object, "Listener must not be null."); | Objects.requireNonNull(object, "Listener must not be null."); | ||||
return () -> listenerList.remove(listenerMethod); | return () -> listenerList.remove(listenerMethod); | ||||
} | } | ||||
/* | |||||
* Registers a new listener with the specified named activation method to | |||||
* listen events generated by this component. Don't add a JavaDoc comment | |||||
* here, we use the default documentation from implemented interface. | |||||
*/ | |||||
@Override | |||||
public Registration addListener(Class<?> eventType, Object object, | |||||
String methodName) { | |||||
Objects.requireNonNull(object, "Listener must not be null."); | |||||
if (listenerList == null) { | |||||
listenerList = new LinkedHashSet<>(); | |||||
} | |||||
ListenerMethod listenerMethod = new ListenerMethod(eventType, object, | |||||
methodName); | |||||
listenerList.add(listenerMethod); | |||||
return () -> listenerList.remove(listenerMethod); | |||||
} | |||||
/* | |||||
* Removes all registered listeners matching the given parameters. Don't add | |||||
* a JavaDoc comment here, we use the default documentation from implemented | |||||
* interface. | |||||
/** | |||||
* Removes all registered listeners matching the given parameters. Since | |||||
* this method receives the event type and the listener object as | |||||
* parameters, it will unregister all <code>object</code>'s methods that are | |||||
* registered to listen to events of type <code>eventType</code> generated | |||||
* by this component. | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the exact event type the <code>object</code> listens to. | |||||
* @param target | |||||
* the target object that has registered to listen to events of | |||||
* type <code>eventType</code> with one or more methods. | |||||
*/ | */ | ||||
@Override | |||||
public void removeListener(Class<?> eventType, Object target) { | public void removeListener(Class<?> eventType, Object target) { | ||||
if (listenerList != null) { | if (listenerList != null) { | ||||
final Iterator<ListenerMethod> i = listenerList.iterator(); | final Iterator<ListenerMethod> i = listenerList.iterator(); | ||||
} | } | ||||
} | } | ||||
/* | |||||
* Removes the event listener methods matching the given given paramaters. | |||||
* Don't add a JavaDoc comment here, we use the default documentation from | |||||
* implemented interface. | |||||
/** | |||||
* Removes one registered listener method. The given method owned by the | |||||
* given object will no longer be called when the specified events are | |||||
* generated by this component. | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the exact event type the <code>object</code> listens to. | |||||
* @param target | |||||
* the target object that has registered to listen to events of | |||||
* type eventType with one or more methods. | |||||
* @param method | |||||
* the method owned by the target that's registered to listen to | |||||
* events of type eventType. | |||||
* @deprecated use a {@link Registration} returned by | |||||
* {@link #addListener(Class, Object, Method)} | |||||
*/ | */ | ||||
@Override | |||||
@Deprecated | |||||
public void removeListener(Class<?> eventType, Object target, | public void removeListener(Class<?> eventType, Object target, | ||||
Method method) { | Method method) { | ||||
if (listenerList != null) { | if (listenerList != null) { | ||||
} | } | ||||
} | } | ||||
/* | |||||
* Removes the event listener method matching the given given parameters. | |||||
* Don't add a JavaDoc comment here, we use the default documentation from | |||||
* implemented interface. | |||||
*/ | |||||
@Override | |||||
public void removeListener(Class<?> eventType, Object target, | |||||
String methodName) { | |||||
// Find the correct method | |||||
final Method[] methods = target.getClass().getMethods(); | |||||
Method method = null; | |||||
for (int i = 0; i < methods.length; i++) { | |||||
if (methods[i].getName().equals(methodName)) { | |||||
method = methods[i]; | |||||
} | |||||
} | |||||
if (method == null) { | |||||
throw new IllegalArgumentException(); | |||||
} | |||||
// Remove the listeners | |||||
if (listenerList != null) { | |||||
final Iterator<ListenerMethod> i = listenerList.iterator(); | |||||
while (i.hasNext()) { | |||||
final ListenerMethod lm = i.next(); | |||||
if (lm.matches(eventType, target, method)) { | |||||
i.remove(); | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
/** | /** | ||||
* Removes all listeners from event router. | * Removes all listeners from event router. | ||||
*/ | */ | ||||
return listeners; | return listeners; | ||||
} | } | ||||
private Logger getLogger() { | |||||
return Logger.getLogger(EventRouter.class.getName()); | |||||
} | |||||
} | } |
/* | |||||
* Copyright 2000-2016 Vaadin Ltd. | |||||
* | |||||
* Licensed 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 com.vaadin.event; | |||||
import java.io.Serializable; | |||||
/** | |||||
* Generic Listener interface. | |||||
* | |||||
* @author Vaadin Ltd. | |||||
* @since 8.0 | |||||
*/ | |||||
@FunctionalInterface | |||||
public interface Listener<E extends Serializable> extends Serializable { | |||||
public void onEvent(E event); | |||||
} |
/* | |||||
* Copyright 2000-2016 Vaadin Ltd. | |||||
* | |||||
* Licensed 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 com.vaadin.event; | |||||
import java.io.Serializable; | |||||
import java.lang.reflect.Method; | |||||
import com.vaadin.shared.Registration; | |||||
/** | |||||
* <p> | |||||
* Interface for classes supporting registration of methods as event receivers. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @author Vaadin Ltd. | |||||
* @since 3.0 | |||||
*/ | |||||
public interface MethodEventSource extends Serializable { | |||||
/** | |||||
* <p> | |||||
* Registers a new event listener with the specified activation method to | |||||
* listen events generated by this component. If the activation method does | |||||
* not have any arguments the event object will not be passed to it when | |||||
* it's called. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the type of the listened event. Events of this type or its | |||||
* subclasses activate the listener. | |||||
* @param object | |||||
* the object instance who owns the activation method. | |||||
* @param method | |||||
* the activation method. | |||||
* @return a registration object for removing the listener | |||||
* @throws java.lang.IllegalArgumentException | |||||
* unless <code>method</code> has exactly one match in | |||||
* <code>object</code> | |||||
* @throws NullPointerException | |||||
* if {@code object} is {@code null} | |||||
*/ | |||||
public Registration addListener(Class<?> eventType, Object object, | |||||
Method method); | |||||
/** | |||||
* <p> | |||||
* Registers a new listener with the specified activation method to listen | |||||
* events generated by this component. If the activation method does not | |||||
* have any arguments the event object will not be passed to it when it's | |||||
* called. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* This version of <code>addListener</code> gets the name of the activation | |||||
* method as a parameter. The actual method is reflected from | |||||
* <code>object</code>, and unless exactly one match is found, | |||||
* <code>java.lang.IllegalArgumentException</code> is thrown. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the type of the listened event. Events of this type or its | |||||
* subclasses activate the listener. | |||||
* @param object | |||||
* the object instance who owns the activation method. | |||||
* @param methodName | |||||
* the name of the activation method. | |||||
* @return a registration object for removing the listener | |||||
* @throws java.lang.IllegalArgumentException | |||||
* unless <code>method</code> has exactly one match in | |||||
* <code>object</code> | |||||
* @throws NullPointerException | |||||
* if {@code object} is {@code null} | |||||
*/ | |||||
public Registration addListener(Class<?> eventType, Object object, | |||||
String methodName); | |||||
/** | |||||
* Removes all registered listeners matching the given parameters. Since | |||||
* this method receives the event type and the listener object as | |||||
* parameters, it will unregister all <code>object</code>'s methods that are | |||||
* registered to listen to events of type <code>eventType</code> generated | |||||
* by this component. | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the exact event type the <code>object</code> listens to. | |||||
* @param target | |||||
* the target object that has registered to listen to events of | |||||
* type <code>eventType</code> with one or more methods. | |||||
*/ | |||||
public void removeListener(Class<?> eventType, Object target); | |||||
/** | |||||
* Removes one registered listener method. The given method owned by the | |||||
* given object will no longer be called when the specified events are | |||||
* generated by this component. | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the exact event type the <code>object</code> listens to. | |||||
* @param target | |||||
* the target object that has registered to listen to events of | |||||
* type eventType with one or more methods. | |||||
* @param method | |||||
* the method owned by the target that's registered to listen to | |||||
* events of type eventType. | |||||
* @deprecated use a {@link Registration} returned by | |||||
* {@link #addListener(Class, Object, Method)} | |||||
*/ | |||||
@Deprecated | |||||
public void removeListener(Class<?> eventType, Object target, | |||||
Method method); | |||||
/** | |||||
* <p> | |||||
* Removes one registered listener method. The given method owned by the | |||||
* given object will no longer be called when the specified events are | |||||
* generated by this component. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* This version of <code>removeListener</code> gets the name of the | |||||
* activation method as a parameter. The actual method is reflected from the | |||||
* target, and unless exactly one match is found, | |||||
* <code>java.lang.IllegalArgumentException</code> is thrown. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the exact event type the <code>object</code> listens to. | |||||
* @param target | |||||
* the target object that has registered to listen to events of | |||||
* type <code>eventType</code> with one or more methods. | |||||
* @param methodName | |||||
* the name of the method owned by <code>target</code> that's | |||||
* registered to listen to events of type <code>eventType</code>. | |||||
* @deprecated use a {@link Registration} returned by | |||||
* {@link #addListener(Class, Object, String)} | |||||
*/ | |||||
@Deprecated | |||||
public void removeListener(Class<?> eventType, Object target, | |||||
String methodName); | |||||
} |
/* | |||||
* Copyright 2000-2016 Vaadin Ltd. | |||||
* | |||||
* Licensed 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 com.vaadin.event; | |||||
import java.io.Serializable; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import java.util.LinkedHashSet; | |||||
import com.vaadin.shared.Registration; | |||||
public class SimpleEventRouter<E extends Serializable> { | |||||
private Collection<Listener<E>> listeners = null; | |||||
public Registration addListener(Listener<E> listener) { | |||||
if (listeners == null) { | |||||
listeners = new LinkedHashSet<>(); | |||||
} | |||||
listeners.add(listener); | |||||
return () -> listeners.remove(listener); | |||||
} | |||||
public void fireEvent(E event) { | |||||
if (listeners == null) { | |||||
return; | |||||
} | |||||
for (Listener<E> listener : new ArrayList<>(listeners)) { | |||||
// very few callers have been doing error handling here, so not | |||||
// complicating the basic event list with it | |||||
listener.onEvent(event); | |||||
} | |||||
} | |||||
public boolean hasListeners() { | |||||
return listeners != null && !listeners.isEmpty(); | |||||
} | |||||
} |
import java.util.logging.Logger; | import java.util.logging.Logger; | ||||
import com.vaadin.event.EventRouter; | import com.vaadin.event.EventRouter; | ||||
import com.vaadin.event.MethodEventSource; | |||||
import com.vaadin.shared.Registration; | import com.vaadin.shared.Registration; | ||||
import com.vaadin.shared.communication.ClientRpc; | import com.vaadin.shared.communication.ClientRpc; | ||||
import com.vaadin.shared.communication.ServerRpc; | import com.vaadin.shared.communication.ServerRpc; | ||||
* @author Vaadin Ltd | * @author Vaadin Ltd | ||||
* @since 7.0.0 | * @since 7.0.0 | ||||
*/ | */ | ||||
public abstract class AbstractClientConnector | |||||
implements ClientConnector, MethodEventSource { | |||||
public abstract class AbstractClientConnector implements ClientConnector { | |||||
/** | /** | ||||
* A map from client to server RPC interface class name to the RPC call | * A map from client to server RPC interface class name to the RPC call | ||||
* manager that handles incoming RPC calls for that interface. | * manager that handles incoming RPC calls for that interface. | ||||
* the activation method. | * the activation method. | ||||
* @return a registration object for removing the listener | * @return a registration object for removing the listener | ||||
*/ | */ | ||||
@Override | |||||
public Registration addListener(Class<?> eventType, Object target, | public Registration addListener(Class<?> eventType, Object target, | ||||
Method method) { | Method method) { | ||||
if (eventRouter == null) { | if (eventRouter == null) { | ||||
return eventRouter.addListener(eventType, target, method); | return eventRouter.addListener(eventType, target, method); | ||||
} | } | ||||
/** | |||||
* <p> | |||||
* Convenience method for registering a new listener with the specified | |||||
* activation method to listen events generated by this component. If the | |||||
* activation method does not have any arguments the event object will not | |||||
* be passed to it when it's called. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* This version of <code>addListener</code> gets the name of the activation | |||||
* method as a parameter. The actual method is reflected from | |||||
* <code>object</code>, and unless exactly one match is found, | |||||
* <code>java.lang.IllegalArgumentException</code> is thrown. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* Note: Using this method is discouraged because it cannot be checked | |||||
* during compilation. Use {@link #addListener(Class, Object, Method)} or | |||||
* {@link #addListener(com.vaadin.ui.Component.Listener)} instead. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the type of the listened event. Events of this type or its | |||||
* subclasses activate the listener. | |||||
* @param target | |||||
* the object instance who owns the activation method. | |||||
* @param methodName | |||||
* the name of the activation method. | |||||
* @return a registration object for removing the listener | |||||
* @deprecated As of 7.0. This method should be avoided. Use | |||||
* {@link #addListener(Class, Object, Method)} or | |||||
* {@link #addListener(String, Class, Object, Method)} instead. | |||||
*/ | |||||
@Override | |||||
@Deprecated | |||||
public Registration addListener(Class<?> eventType, Object target, | |||||
String methodName) { | |||||
if (eventRouter == null) { | |||||
eventRouter = new EventRouter(); | |||||
} | |||||
return eventRouter.addListener(eventType, target, methodName); | |||||
} | |||||
/** | /** | ||||
* Removes all registered listeners matching the given parameters. Since | * Removes all registered listeners matching the given parameters. Since | ||||
* this method receives the event type and the listener object as | * this method receives the event type and the listener object as | ||||
* the target object that has registered to listen to events of | * the target object that has registered to listen to events of | ||||
* type <code>eventType</code> with one or more methods. | * type <code>eventType</code> with one or more methods. | ||||
*/ | */ | ||||
@Override | |||||
public void removeListener(Class<?> eventType, Object target) { | public void removeListener(Class<?> eventType, Object target) { | ||||
if (eventRouter != null) { | if (eventRouter != null) { | ||||
eventRouter.removeListener(eventType, target); | eventRouter.removeListener(eventType, target); | ||||
* {@link #addListener(Class, Object, Method)} to remove a | * {@link #addListener(Class, Object, Method)} to remove a | ||||
* listener | * listener | ||||
*/ | */ | ||||
@Override | |||||
@Deprecated | @Deprecated | ||||
public void removeListener(Class<?> eventType, Object target, | public void removeListener(Class<?> eventType, Object target, | ||||
Method method) { | Method method) { | ||||
} | } | ||||
} | } | ||||
/** | |||||
* <p> | |||||
* Removes one registered listener method. The given method owned by the | |||||
* given object will no longer be called when the specified events are | |||||
* generated by this component. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* This version of <code>removeListener</code> gets the name of the | |||||
* activation method as a parameter. The actual method is reflected from | |||||
* <code>target</code>, and unless exactly one match is found, | |||||
* <code>java.lang.IllegalArgumentException</code> is thrown. | |||||
* </p> | |||||
* | |||||
* <p> | |||||
* For more information on the inheritable event mechanism see the | |||||
* {@link com.vaadin.event com.vaadin.event package documentation}. | |||||
* </p> | |||||
* | |||||
* @param eventType | |||||
* the exact event type the <code>object</code> listens to. | |||||
* @param target | |||||
* the target object that has registered to listen to events of | |||||
* type <code>eventType</code> with one or more methods. | |||||
* @param methodName | |||||
* the name of the method owned by <code>target</code> that's | |||||
* registered to listen to events of type <code>eventType</code>. | |||||
* @deprecated As of 7.0. This method should be avoided. Use | |||||
* {@link #removeListener(Class, Object, Method)} instead. | |||||
*/ | |||||
@Deprecated | |||||
@Override | |||||
public void removeListener(Class<?> eventType, Object target, | |||||
String methodName) { | |||||
if (eventRouter != null) { | |||||
eventRouter.removeListener(eventType, target, methodName); | |||||
} | |||||
} | |||||
/** | /** | ||||
* Returns all listeners that are registered for the given event type or one | * Returns all listeners that are registered for the given event type or one | ||||
* of its subclasses. | * of its subclasses. |
*/ | */ | ||||
package com.vaadin.server.data; | package com.vaadin.server.data; | ||||
import java.lang.reflect.Method; | |||||
import java.util.EventObject; | |||||
import com.vaadin.event.EventRouter; | |||||
import com.vaadin.event.SimpleEventRouter; | |||||
import com.vaadin.shared.Registration; | import com.vaadin.shared.Registration; | ||||
/** | /** | ||||
*/ | */ | ||||
public abstract class AbstractDataProvider<T, F> implements DataProvider<T, F> { | public abstract class AbstractDataProvider<T, F> implements DataProvider<T, F> { | ||||
private EventRouter eventRouter; | |||||
private SimpleEventRouter<DataChangeEvent> eventRouter = new SimpleEventRouter<>(); | |||||
@Override | @Override | ||||
public Registration addDataProviderListener(DataProviderListener listener) { | public Registration addDataProviderListener(DataProviderListener listener) { | ||||
return addListener(DataChangeEvent.class, listener, | |||||
DataProviderListener.class.getMethods()[0]); | |||||
return eventRouter.addListener(listener); | |||||
} | } | ||||
@Override | @Override | ||||
fireEvent(new DataChangeEvent(this)); | fireEvent(new DataChangeEvent(this)); | ||||
} | } | ||||
/** | |||||
* Registers a new listener with the specified activation method to listen | |||||
* events generated by this component. If the activation method does not | |||||
* have any arguments the event object will not be passed to it when it's | |||||
* called. | |||||
* | |||||
* @param eventType | |||||
* the type of the listened event. Events of this type or its | |||||
* subclasses activate the listener. | |||||
* @param listener | |||||
* the object instance who owns the activation method. | |||||
* @param method | |||||
* the activation method. | |||||
* @return a registration for the listener | |||||
*/ | |||||
protected Registration addListener(Class<?> eventType, | |||||
DataProviderListener listener, Method method) { | |||||
if (eventRouter == null) { | |||||
eventRouter = new EventRouter(); | |||||
} | |||||
return eventRouter.addListener(eventType, listener, method); | |||||
} | |||||
/** | /** | ||||
* Sends the event to all listeners. | * Sends the event to all listeners. | ||||
* | * | ||||
* @param event | * @param event | ||||
* the Event to be sent to all listeners. | |||||
* the event to be sent to all listeners. | |||||
*/ | */ | ||||
protected void fireEvent(EventObject event) { | |||||
if (eventRouter != null) { | |||||
eventRouter.fireEvent(event); | |||||
} | |||||
protected void fireEvent(DataChangeEvent event) { | |||||
eventRouter.fireEvent(event); | |||||
} | } | ||||
} | } |
*/ | */ | ||||
package com.vaadin.server.data; | package com.vaadin.server.data; | ||||
import java.io.Serializable; | |||||
import com.vaadin.event.Listener; | |||||
/** | /** | ||||
* Interface for listening for a data change events fired by a | * Interface for listening for a data change events fired by a | ||||
* {@link DataProvider}. | * {@link DataProvider}. | ||||
* | |||||
* | |||||
* @author Vaadin Ltd | * @author Vaadin Ltd | ||||
* @since 8.0 | * @since 8.0 | ||||
*/ | */ | ||||
@FunctionalInterface | @FunctionalInterface | ||||
public interface DataProviderListener extends Serializable { | |||||
public interface DataProviderListener extends Listener<DataChangeEvent> { | |||||
/** | /** | ||||
* Invoked when this listener receives a data change event from a data | * Invoked when this listener receives a data change event from a data | ||||
* @param event | * @param event | ||||
* the received event, not null | * the received event, not null | ||||
*/ | */ | ||||
void onDataChange(DataChangeEvent event); | |||||
@Override | |||||
void onEvent(DataChangeEvent event); | |||||
} | } |
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.event.EventRouter; | import com.vaadin.event.EventRouter; | ||||
import com.vaadin.event.MethodEventSource; | |||||
import com.vaadin.server.data.AbstractDataProvider; | import com.vaadin.server.data.AbstractDataProvider; | ||||
import com.vaadin.shared.Registration; | import com.vaadin.shared.Registration; | ||||
import com.vaadin.tests.VaadinClasses; | import com.vaadin.tests.VaadinClasses; | ||||
ALLOW_REMOVE_LISTENER | ALLOW_REMOVE_LISTENER | ||||
.add(RemoveListenersDeprecatedTest::acceptAbstractDataProvider); | .add(RemoveListenersDeprecatedTest::acceptAbstractDataProvider); | ||||
ALLOW_REMOVE_LISTENER | ALLOW_REMOVE_LISTENER | ||||
.add(RemoveListenersDeprecatedTest::acceptMethodEventSource); | |||||
.add(RemoveListenersDeprecatedTest::acceptEventRouter); | |||||
} | } | ||||
@Test | @Test | ||||
Assert.assertTrue(count > 0); | Assert.assertTrue(count > 0); | ||||
} | } | ||||
private static boolean acceptMethodEventSource(Method method) { | |||||
return method.getDeclaringClass().equals(MethodEventSource.class) | |||||
private static boolean acceptEventRouter(Method method) { | |||||
return method.getDeclaringClass().equals(EventRouter.class) | |||||
&& method.getParameterCount() == 2; | && method.getParameterCount() == 2; | ||||
} | } | ||||
private int counter = 0; | private int counter = 0; | ||||
@Override | @Override | ||||
public void onDataChange(DataChangeEvent event) { | |||||
public void onEvent(DataChangeEvent event) { | |||||
++counter; | ++counter; | ||||
} | } | ||||