package play.modules.origo.core; import play.Play; import play.PlayPlugin; import play.classloading.ApplicationClasses; import play.modules.origo.core.annotations.Decorates; import play.modules.origo.core.annotations.OnLoad; import play.modules.origo.core.annotations.Provides; import play.modules.origo.core.annotations.forms.*; import play.utils.Java; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.List; /** * Scans classes that are compiled for methods annotated with trigger/add-ons/listener annotations and caches them. * At startup it scans all classes in the classpath. */ public class CoreAnnotationsPlugin extends PlayPlugin { @Override public void onApplicationStart() { onClassesChange(Play.classes.all()); } @Override public List<ApplicationClasses.ApplicationClass> onClassesChange(List<ApplicationClasses.ApplicationClass> modifiedClasses) { //TODO: Should only have to look at modified classes but the invalidation isn't working so for now we reload all classes List<Class> modifiedJavaClasses = AnnotationPluginHelper.getJavaClasses(Play.classes.all()); Listeners.invalidate(); //List<Class> modifiedJavaClasses = AnnotationPluginHelper.getJavaClasses(modifiedClasses); findAndAddListenerAnnotation(Provides.class, modifiedJavaClasses); findAndAddListenerAnnotation(Decorates.class, modifiedJavaClasses); findAndAddListenerAnnotation(OnLoad.class, modifiedJavaClasses); findAndAddListenerAnnotation(OnSubmit.class, modifiedJavaClasses); findAndAddListenerAnnotation(SubmitHandler.class, modifiedJavaClasses); findAndAddListenerAnnotation(SubmitState.class, modifiedJavaClasses); findAndAddListenerAnnotation(OnLoadForm.class, modifiedJavaClasses); findAndAddListenerAnnotation(ProvidesForm.class, modifiedJavaClasses); return super.onClassesChange(modifiedClasses); } /** * Finds all methods annotated with the specified annotationClass and adds it to the cache. * * @param annotationClass a method annotation that provides a hook/trigger/listener. * @param modifiedClasses all classes modified in this compile (or on startup). */ // TODO: should take a method to be triggered for additional checks of validity (checking return type, checking parameter types, etc). private void findAndAddListenerAnnotation(Class<? extends Annotation> annotationClass, List<Class> modifiedClasses) { List<Method> annotatedMethods = Java.findAllAnnotatedMethods(modifiedClasses, annotationClass); for (Method m : annotatedMethods) { Listeners.addListener(m.getAnnotation(annotationClass), m); } } }