All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bushe.swing.event.annotation.AnnotationProcessor Maven / Gradle / Ivy

Go to download

Nifty GUI is a Java Library that supports the building of interactive user interfaces for games or similar applications. It utilizes OpenGL for rendering and it can be easily integrated into many rendering systems. The configuration of the GUI is stored in xml files with little supporting Java code. In short Nifty helps you to layout stuff, display it in a cool way and interact with it :)

The newest version!
package org.bushe.swing.event.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Pattern;
import java.util.Arrays;

import org.bushe.swing.event.EventService;
import org.bushe.swing.event.EventServiceExistsException;
import org.bushe.swing.event.EventServiceLocator;
import org.bushe.swing.event.Logger;

/**
 * Enhances classes that use EventService Annotations.
 * 

* This class makes the EventService annotations "come alive." This can be used in code like so: *

 * 
 * public class MyAppController {
 *   public MyAppController {
 *       AnnotationProcessor.process(this);//this line can be avoided with a compile-time tool or an Aspect
 *   }
 *   @EventSubscriber
 *   public void onAppStartingEvent(AppStartingEvent appStartingEvent) {
 *      //do something
 *   }
 *   @EventSubscriber
 *   public void onAppClosingEvent(AppClosingEvent appClosingEvent) {
 *      //do something
 *   }
 * }
 * ... some other place, needed in some cases when the like a window disposal before it's garbage collected ....
 * AnnotationProcessor.unprocess(this);
 * 
 * 
*

* This class can be leveraged in outside of source code in other ways in which Annotations are used:

  • In an * Aspect-Oriented tool
  • In a Swing Framework classloader that wants to load and understand events.
  • In other * Inversion of Control containers, such as Spring or PicoContainer.
  • In the apt tool, though this does not generate * code.
  • In a Annotation Processing Tool plugin, when it becomes available.
Support for these other methods * are not yet implemented. */ public class AnnotationProcessor { protected static final Logger LOG = Logger.getLogger(EventService.class.getName()); /** * Add the appropriate subscribers to one or more EventServices for an instance of a class with * EventBus annotations. * @param obj the instance that may or may not have annotations */ public static void process(Object obj) { processOrUnprocess(obj, true); } /** * Remove the appropriate subscribers from one or more EventServices for an instance of a class with * EventBus annotations. * @param obj the instance that may or may not have annotations */ public static void unprocess(Object obj) { processOrUnprocess(obj, false); } private static void processOrUnprocess(Object obj, boolean add) { if (obj == null) { return; } Class cl = obj.getClass(); Method[] methods = cl.getMethods(); if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Looking for EventBus annotations for class " + cl + ", methods:" + Arrays.toString(methods)); } for (Method method : methods) { EventSubscriber classAnnotation = method.getAnnotation(EventSubscriber.class); if (classAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found EventSubscriber:"+classAnnotation +" on method:" + method); } process(classAnnotation, obj, method, add); } EventTopicSubscriber topicAnnotation = method.getAnnotation(EventTopicSubscriber.class); if (topicAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found EventTopicSubscriber: "+topicAnnotation +" on method:" + method); } process(topicAnnotation, obj, method, add); } EventTopicPatternSubscriber topicPatternAnnotation = method.getAnnotation(EventTopicPatternSubscriber.class); if (topicPatternAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found EventTopicPatternSubscriber: "+topicPatternAnnotation+" on method:" + method); } process(topicPatternAnnotation, obj, method, add); } RuntimeTopicEventSubscriber runtimeTopicAnnotation = method.getAnnotation(RuntimeTopicEventSubscriber.class); if (runtimeTopicAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found RuntimeTopicEventSubscriber: "+runtimeTopicAnnotation+" on method:" + method); } process(runtimeTopicAnnotation, obj, method, add); } RuntimeTopicPatternEventSubscriber annotation = method.getAnnotation(RuntimeTopicPatternEventSubscriber.class); if (annotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found RuntimeTopicPatternEventSubscriber:"+annotation+" on method:" + method); } process(annotation, obj, method, add); } VetoSubscriber vetoClassAnnotation = method.getAnnotation(VetoSubscriber.class); if (vetoClassAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found VetoSubscriber:"+vetoClassAnnotation +" on method:" + method); } process(vetoClassAnnotation, obj, method, add); } VetoTopicSubscriber vetoTopicAnnotation = method.getAnnotation(VetoTopicSubscriber.class); if (vetoTopicAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found VetoTopicSubscriber: "+vetoTopicAnnotation +" on method:" + method); } process(vetoTopicAnnotation, obj, method, add); } VetoTopicPatternSubscriber vetoTopicPatternAnnotation = method.getAnnotation(VetoTopicPatternSubscriber.class); if (vetoTopicPatternAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found VetoTopicPatternSubscriber: "+vetoTopicPatternAnnotation+" on method:" + method); } process(vetoTopicPatternAnnotation, obj, method, add); } VetoRuntimeTopicSubscriber vetoRuntimeTopicAnnotation = method.getAnnotation(VetoRuntimeTopicSubscriber.class); if (vetoRuntimeTopicAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found VetoRuntimeTopicSubscriber: "+vetoRuntimeTopicAnnotation+" on method:" + method); } process(vetoRuntimeTopicAnnotation, obj, method, add); } VetoRuntimeTopicPatternSubscriber vetoAnnotation = method.getAnnotation(VetoRuntimeTopicPatternSubscriber.class); if (vetoAnnotation != null) { if (LOG.isLoggable(Logger.Level.DEBUG)) { LOG.debug("Found VetoRuntimeTopicPatternSubscriber:"+vetoAnnotation+" on method:" + method); } process(vetoAnnotation, obj, method, add); } } } private static void process(EventTopicPatternSubscriber topicPatternAnnotation, Object obj, Method method, boolean add) { //Check args String topicPattern = topicPatternAnnotation.topicPattern(); if (topicPattern == null) { throw new IllegalArgumentException("Topic pattern cannot be null for EventTopicPatternSubscriber annotation"); } //Get event service Class eventServiceClass = topicPatternAnnotation.autoCreateEventServiceClass(); String eventServiceName = topicPatternAnnotation.eventServiceName(); EventService eventService = getEventServiceFromAnnotation(eventServiceName, eventServiceClass); int priority = topicPatternAnnotation.priority(); //Create proxy and subscribe Pattern pattern = Pattern.compile(topicPattern); //See Issue #18 //Also note that this post is wrong: https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 //Since two WeakReferences are not treated as one. So this always has to be strong and we'll have to clean up occasionally. if (add) { ProxyTopicPatternSubscriber subscriber = new ProxyTopicPatternSubscriber(obj, method, topicPatternAnnotation.referenceStrength(), priority, eventService, topicPattern, pattern, false); eventService.subscribeStrongly(pattern, subscriber); } else { eventService.unsubscribe(pattern, obj); } } private static void process(EventTopicSubscriber topicAnnotation, Object obj, Method method, boolean add) { //Check args String topic = topicAnnotation.topic(); if (topic == null) { throw new IllegalArgumentException("Topic cannot be null for EventTopicSubscriber annotation"); } //Get event service Class eventServiceClass = topicAnnotation.autoCreateEventServiceClass(); String eventServiceName = topicAnnotation.eventServiceName(); EventService eventService = getEventServiceFromAnnotation(eventServiceName, eventServiceClass); int priority = topicAnnotation.priority(); //See Issue #18 //Also note that this post is wrong: https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 //Since two WeakReferences are not treated as one. So this always has to be strong and we'll have to clean up occasionally. if (add) { //Create proxy and subscribe ProxyTopicSubscriber subscriber = new ProxyTopicSubscriber(obj, method, topicAnnotation.referenceStrength(), priority, eventService, topic, false); eventService.subscribeStrongly(topic, subscriber); } else { eventService.unsubscribe(topic, obj); } } private static void process(EventSubscriber annotation, Object obj, Method method, boolean add) { //Check args Class eventClass = annotation.eventClass(); if (eventClass == null) { throw new IllegalArgumentException("Event class cannot be null for EventSubscriber annotation"); } else if (UseTheClassOfTheAnnotatedMethodsParameter.class.equals(eventClass)) { Class[] params = method.getParameterTypes(); if (params.length < 1) { throw new RuntimeException("Expected annotated method to have one parameter."); } else { eventClass = params[0]; } } //Get event service Class eventServiceClass = annotation.autoCreateEventServiceClass(); String eventServiceName = annotation.eventServiceName(); EventService eventService = getEventServiceFromAnnotation(eventServiceName, eventServiceClass); if (add) { int priority = annotation.priority(); //Create proxy and subscribe //See https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 BaseProxySubscriber subscriber = new BaseProxySubscriber(obj, method, annotation.referenceStrength(), priority, eventService, eventClass, false); if (annotation.exact()) { //See Issue #18 //Also note that this post is wrong: https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 //Since two WeakReferences are not treated as one. So this always has to be strong and we'll have to clean up occasionally. eventService.subscribeExactlyStrongly(eventClass, subscriber); } else { //See Issue #18 //Also note that this post is wrong: https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 //Since two WeakReferences are not treated as one. So this always has to be strong and we'll have to clean up occasionally. eventService.subscribeStrongly(eventClass, subscriber); } } else { if (annotation.exact()) { eventService.unsubscribeExactly(eventClass, obj); } else { eventService.unsubscribe(eventClass, obj); } } } private static void process(final RuntimeTopicEventSubscriber annotation, final Object subscriber, final Method method, boolean add) { EventTopicSubscriber eventTopicSubscriber = new EventTopicSubscriber() { //TODO uncomment when language level is set to 1.6 (2.0) @Override public Class autoCreateEventServiceClass() { return annotation.autoCreateEventServiceClass(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public String eventServiceName() { return annotation.eventServiceName(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public ReferenceStrength referenceStrength() { return annotation.referenceStrength(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public int priority() { return annotation.priority(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public String topic() { return getTopic(annotation.methodName(), subscriber, method); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public Class annotationType() { return annotation.annotationType(); } }; process(eventTopicSubscriber, subscriber, method, add); } private static void process(final RuntimeTopicPatternEventSubscriber annotation, final Object subscriber, final Method method, boolean add) { EventTopicPatternSubscriber eventTopicPatternSubscriber = new EventTopicPatternSubscriber() { //TODO uncomment when language level is set to 1.6 (2.0) @Override public Class autoCreateEventServiceClass() { return annotation.autoCreateEventServiceClass(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public String eventServiceName() { return annotation.eventServiceName(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public ReferenceStrength referenceStrength() { return annotation.referenceStrength(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public int priority() { return annotation.priority(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public boolean exact() { return annotation.exact(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public String topicPattern() { return getTopic(annotation.methodName(), subscriber, method); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public Class annotationType() { return annotation.annotationType(); } }; process(eventTopicPatternSubscriber, subscriber, method, add); } /* This is a cut and paste from above practically, sure which Annotations could be extended. * TODO: When Java 7 comes out, or whatever JSR-308 is delivered, reduce this file by 70% */ private static void process(VetoTopicPatternSubscriber topicPatternAnnotation, Object obj, Method method, boolean add) { //Check args String topicPattern = topicPatternAnnotation.topicPattern(); if (topicPattern == null) { throw new IllegalArgumentException("Topic pattern cannot be null for VetoTopicPatternSubscriber annotation"); } //Get event service Class eventServiceClass = topicPatternAnnotation.autoCreateEventServiceClass(); String eventServiceName = topicPatternAnnotation.eventServiceName(); EventService eventService = getEventServiceFromAnnotation(eventServiceName, eventServiceClass); int priority = topicPatternAnnotation.priority(); //Create proxy and subscribe Pattern pattern = Pattern.compile(topicPattern); ProxyTopicPatternSubscriber subscriber = new ProxyTopicPatternSubscriber(obj, method, topicPatternAnnotation.referenceStrength(), priority, eventService, topicPattern, pattern, true); //See Issue #18 //Also note that this post is wrong: https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 //Since two WeakReferences are not treated as one. So this always has to be strong and we'll have to clean up occasionally. if (add) { eventService.subscribeVetoListenerStrongly(pattern, subscriber); } else { eventService.unsubscribeVeto(pattern, obj); } } private static void process(VetoTopicSubscriber topicAnnotation, Object obj, Method method, boolean add) { //Check args String topic = topicAnnotation.topic(); if (topic == null) { throw new IllegalArgumentException("Topic cannot be null for VetoTopicSubscriber annotation"); } //Get event service Class eventServiceClass = topicAnnotation.autoCreateEventServiceClass(); String eventServiceName = topicAnnotation.eventServiceName(); EventService eventService = getEventServiceFromAnnotation(eventServiceName, eventServiceClass); int priority = topicAnnotation.priority(); //Create proxy and subscribe ProxyTopicSubscriber subscriber = new ProxyTopicSubscriber(obj, method, topicAnnotation.referenceStrength(), priority, eventService, topic, true); //See Issue #18 //Also note that this post is wrong: https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 //Since two WeakReferences are not treated as one. So this always has to be strong and we'll have to clean up occasionally. if (add) { eventService.subscribeVetoListenerStrongly(topic, subscriber); } else { eventService.unsubscribeVeto(topic, obj); } } private static void process(VetoSubscriber annotation, Object obj, Method method, boolean add) { //Check args Class eventClass = annotation.eventClass(); if (eventClass == null) { throw new IllegalArgumentException("Event class cannot be null for VetoSubscriber annotation"); } else if (UseTheClassOfTheAnnotatedMethodsParameter.class.equals(eventClass)) { Class[] params = method.getParameterTypes(); if (params.length < 1) { throw new RuntimeException("Expected annotated method to have one parameter."); } else { eventClass = params[0]; } } //Get event service Class eventServiceClass = annotation.autoCreateEventServiceClass(); String eventServiceName = annotation.eventServiceName(); EventService eventService = getEventServiceFromAnnotation(eventServiceName, eventServiceClass); int priority = annotation.priority(); //Create proxy and subscribe //See https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 BaseProxySubscriber subscriber = new BaseProxySubscriber(obj, method, annotation.referenceStrength(), priority, eventService, eventClass, true); if (add) { if (annotation.exact()) { //See Issue #18 //Also note that this post is wrong: https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 //Since two WeakReferences are not treated as one. So this always has to be strong and we'll have to clean up occasionally. eventService.subscribeVetoListenerExactlyStrongly(eventClass, subscriber); } else { //See Issue #18 //Also note that this post is wrong: https://eventbus.dev.java.net/servlets/ProjectForumMessageView?messageID=19499&forumID=1834 //Since two WeakReferences are not treated as one. So this always has to be strong and we'll have to clean up occasionally. eventService.subscribeVetoListenerStrongly(eventClass, subscriber); } } else { if (annotation.exact()) { eventService.unsubscribeVetoExactly(eventClass, obj); } else { eventService.unsubscribeVeto(eventClass, obj); } } } private static void process(final VetoRuntimeTopicSubscriber annotation, final Object subscriber, final Method method, boolean add) { VetoTopicSubscriber eventTopicSubscriber = new VetoTopicSubscriber() { //TODO uncomment when language level is set to 1.6 (2.0) @Override public Class autoCreateEventServiceClass() { return annotation.autoCreateEventServiceClass(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public String eventServiceName() { return annotation.eventServiceName(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public ReferenceStrength referenceStrength() { return annotation.referenceStrength(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public int priority() { return annotation.priority(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public String topic() { return getTopic(annotation.methodName(), subscriber, method); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public Class annotationType() { return annotation.annotationType(); } }; process(eventTopicSubscriber, subscriber, method, add); } private static void process(final VetoRuntimeTopicPatternSubscriber annotation, final Object subscriber, final Method method, boolean add) { VetoTopicPatternSubscriber eventTopicPatternSubscriber = new VetoTopicPatternSubscriber() { //TODO uncomment when language level is set to 1.6 (2.0) @Override public Class autoCreateEventServiceClass() { return annotation.autoCreateEventServiceClass(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public String eventServiceName() { return annotation.eventServiceName(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public ReferenceStrength referenceStrength() { return annotation.referenceStrength(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public int priority() { return annotation.priority(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public boolean exact() { return annotation.exact(); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public String topicPattern() { return getTopic(annotation.methodName(), subscriber, method); } //TODO uncomment when language level is set to 1.6 (2.0) @Override public Class annotationType() { return annotation.annotationType(); } }; process(eventTopicPatternSubscriber, subscriber, method, add); } private static String getTopic(String methodName, Object subscriber, Method method) { try { Method runtimeEvalMethod = subscriber.getClass().getMethod(methodName, new Class[0]); //necessary in case the method does not have public access or if the class it belongs //to isn't public runtimeEvalMethod.setAccessible(true); return runtimeEvalMethod.invoke(subscriber, new Object[0]).toString(); } catch (SecurityException e) { throw new RuntimeException("Could not retrieve method for subscription. Method: " + methodName, e); } catch (NoSuchMethodException e) { throw new RuntimeException("Could not retrieve method for subscription. Method: " + methodName, e); } catch (InvocationTargetException e) { e.getTargetException().printStackTrace(); throw new RuntimeException("Could not invoke method for subscription. Method: " + methodName, e); } catch (IllegalAccessException e) { throw new RuntimeException("Could not invoke method for subscription. Method: " + methodName, e); } } private static EventService getEventServiceFromAnnotation(String eventServiceName, Class eventServiceClass) { EventService eventService = EventServiceLocator.getEventService(eventServiceName); if (eventService == null) { if (EventServiceLocator.SERVICE_NAME_EVENT_BUS.equals(eventServiceName)) { //This may be the first time the EventBus is accessed. eventService = EventServiceLocator.getSwingEventService(); } else { //The event service does not yet exist, create it try { eventService = eventServiceClass.newInstance(); } catch (InstantiationException e) { throw new RuntimeException("Could not instance of create EventService class " + eventServiceClass, e); } catch (IllegalAccessException e) { throw new RuntimeException("Could not instance of create EventService class " + eventServiceClass, e); } try { EventServiceLocator.setEventService(eventServiceName, eventService); } catch (EventServiceExistsException e) { //ignore it, it's OK eventService = EventServiceLocator.getEventService(eventServiceName); } } } return eventService; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy