Created
August 26, 2014 16:48
-
-
Save fastnsilver/0a78eba1e38f723bbe66 to your computer and use it in GitHub Desktop.
Possible solution to issues 53 and 70 for Vaadin4Spring
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2014 The original authors | |
* | |
* 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 org.vaadin.spring.events; | |
import java.lang.annotation.*; | |
/** | |
* Annotation to be placed on event bus listener methods. A listener method must always conform to one of the following method signatures: | |
* <ol> | |
* <li><code>myMethodName({@link org.vaadin.spring.events.Event Event}<MyPayloadType>)</code></li> | |
* <li><code>myMethodName(MyPayloadType)</code></li> | |
* </ol> | |
* A listener method can have any visibility and any return type. | |
* | |
* @author Petter Holmström ([email protected]) | |
* @see org.vaadin.spring.events.EventBusListener | |
* @see EventBus#subscribe(Object) | |
* @see EventBus#subscribe(Object, boolean) | |
*/ | |
@Target(ElementType.METHOD) | |
@Retention(RetentionPolicy.RUNTIME) | |
@Documented | |
public @interface EventBusListenerMethod { | |
public interface EventBusListenerMethodFilter { | |
boolean filter(Object payload); | |
} | |
public class NoEventBusListenerMethodFilter implements EventBusListenerMethodFilter { | |
@Override | |
public boolean filter(Object payload) { | |
return true; | |
} | |
} | |
/** | |
* The default scope of a listener method is <code>EventScope.APPLICATION</code> | |
*/ | |
EventScope scope() default EventScope.APPLICATION; | |
Class<? extends EventBusListenerMethodFilter> filter() default NoEventBusListenerMethodFilter.class; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2014 The original authors | |
* | |
* 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 org.vaadin.spring.events.internal; | |
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
import java.lang.reflect.ParameterizedType; | |
import org.vaadin.spring.events.Event; | |
import org.vaadin.spring.events.EventBus; | |
import org.vaadin.spring.events.EventBusListenerMethod; | |
import org.vaadin.spring.events.EventBusListenerMethod.EventBusListenerMethodFilter; | |
/** | |
* Implementation of {@link org.vaadin.spring.events.internal.AbstractListenerWrapper} that wraps an object | |
* that contains a method annotated with {@link org.vaadin.spring.events.EventBusListenerMethod}. If the object | |
* contains multiple listener methods, multiple instances of this class should be created. | |
* | |
* @author Petter Holmström ([email protected]) | |
*/ | |
class MethodListenerWrapper extends AbstractListenerWrapper { | |
private final Class<?> payloadType; | |
private final boolean payloadMethod; | |
private transient Method listenerMethod; | |
public MethodListenerWrapper(EventBus owningEventBus, Object listenerTarget, boolean includingPropagatingEvents, Method listenerMethod) { | |
super(owningEventBus, listenerTarget, includingPropagatingEvents); | |
if (listenerMethod.getParameterTypes()[0] == Event.class) { | |
ParameterizedType type = (ParameterizedType) listenerMethod.getGenericParameterTypes()[0]; | |
payloadType = (Class<?>) type.getActualTypeArguments()[0]; | |
payloadMethod = false; | |
} else { | |
payloadType = listenerMethod.getParameterTypes()[0]; | |
payloadMethod = true; | |
} | |
this.listenerMethod = listenerMethod; | |
} | |
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { | |
ois.defaultReadObject(); | |
// TODO Read listener method info and look up method | |
} | |
private void writeObject(ObjectOutputStream oos) throws IOException { | |
oos.defaultWriteObject(); | |
// TODO Write listener method info | |
} | |
@Override | |
public Class<?> getPayloadType() { | |
return payloadType; | |
} | |
@Override | |
public void publish(Event<?> event) { | |
listenerMethod.setAccessible(true); | |
boolean doInvoke = true; | |
try { | |
if (listenerMethod.isAnnotationPresent(EventBusListenerMethod.class)) { | |
EventBusListenerMethod annotation = listenerMethod.getAnnotation(EventBusListenerMethod.class); | |
EventBusListenerMethodFilter filter = annotation.filter().newInstance(); | |
doInvoke = filter.filter(event.getPayload()) && supports(event); | |
} | |
if (doInvoke) { | |
if (payloadMethod) { | |
listenerMethod.invoke(getListenerTarget(), event.getPayload()); | |
} else { | |
listenerMethod.invoke(getListenerTarget(), event); | |
} | |
} | |
} catch (IllegalAccessException e) { | |
throw new RuntimeException("Could not access listener method " + listenerMethod.getName()); | |
} catch (InvocationTargetException e) { | |
Throwable targetException = e.getTargetException(); | |
if (targetException instanceof RuntimeException) { | |
throw (RuntimeException) targetException; | |
} else { | |
throw new RuntimeException("A checked exception occurred while invoking listener method " + listenerMethod.getName(), targetException); | |
} | |
} catch (InstantiationException e) { | |
throw new RuntimeException("Could not instantiate listener method filter"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment