1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.shiro.event.support; 20 21 import org.apache.shiro.event.Subscribe; 22 import org.apache.shiro.util.ClassUtils; 23 24 import java.lang.annotation.Annotation; 25 import java.lang.reflect.Method; 26 import java.util.ArrayList; 27 import java.util.Collections; 28 import java.util.List; 29 30 /** 31 * Inspects an object for annotated methods of interest and creates an {@link EventListener} instance for each method 32 * discovered. An event bus will call the resulting listeners as relevant events arrive. 33 * <p/> 34 * The default {@link #setAnnotationClass(Class) annotationClass} is {@link Subscribe}, indicating each 35 * {@link Subscribe}-annotated method will be represented as an EventListener. 36 * 37 * @see SingleArgumentMethodEventListener 38 * @since 1.3 39 */ 40 public class AnnotationEventListenerResolver implements EventListenerResolver { 41 42 private Class<? extends Annotation> annotationClass; 43 44 public AnnotationEventListenerResolver() { 45 this.annotationClass = Subscribe.class; 46 } 47 48 /** 49 * Returns a new collection of {@link EventListener} instances, each instance corresponding to an annotated 50 * method discovered on the specified {@code instance} argument. 51 * 52 * @param instance the instance to inspect for annotated event handler methods. 53 * @return a new collection of {@link EventListener} instances, each instance corresponding to an annotated 54 * method discovered on the specified {@code instance} argument. 55 */ 56 public List<EventListener> getEventListeners(Object instance) { 57 if (instance == null) { 58 return Collections.emptyList(); 59 } 60 61 List<Method> methods = ClassUtils.getAnnotatedMethods(instance.getClass(), getAnnotationClass()); 62 if (methods == null || methods.isEmpty()) { 63 return Collections.emptyList(); 64 } 65 66 List<EventListener> listeners = new ArrayList<EventListener>(methods.size()); 67 68 for (Method m : methods) { 69 listeners.add(new SingleArgumentMethodEventListener(instance, m)); 70 } 71 72 return listeners; 73 } 74 75 /** 76 * Returns the type of annotation that indicates a method that should be represented as an {@link EventListener}, 77 * defaults to {@link Subscribe}. 78 * 79 * @return the type of annotation that indicates a method that should be represented as an {@link EventListener}, 80 * defaults to {@link Subscribe}. 81 */ 82 public Class<? extends Annotation> getAnnotationClass() { 83 return annotationClass; 84 } 85 86 /** 87 * Sets the type of annotation that indicates a method that should be represented as an {@link EventListener}. 88 * The default value is {@link Subscribe}. 89 * 90 * @param annotationClass the type of annotation that indicates a method that should be represented as an 91 * {@link EventListener}. The default value is {@link Subscribe}. 92 */ 93 public void setAnnotationClass(Class<? extends Annotation> annotationClass) { 94 this.annotationClass = annotationClass; 95 } 96 }