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.aop; 20 21 import java.lang.annotation.Annotation; 22 import java.lang.reflect.Method; 23 24 /** 25 * Default {@code AnnotationResolver} implementation that merely inspects the 26 * {@link MethodInvocation MethodInvocation}'s {@link MethodInvocation#getMethod() target method}, 27 * and returns {@code targetMethod}.{@link Method#getAnnotation(Class) getAnnotation(class)}. 28 * <p/> 29 * Unfortunately Java's default reflection API for Annotations is not very robust, and this logic 30 * may not be enough - if the incoming method invocation represents a method from an interface, 31 * this default logic would not discover the annotation if it existed on the method implementation 32 * directly (as opposed to being defined directly in the interface definition). 33 * <p/> 34 * More complex class hierarchy traversal logic is required to exhaust a method's target object's 35 * classes, parent classes, interfaces and parent interfaces. That logic will likely be added 36 * to this implementation in due time, but for now, this implementation relies on the JDK's default 37 * {@link Method#getAnnotation(Class) Method.getAnnotation(class)} logic. 38 * 39 * @since 1.1 40 */ 41 public class DefaultAnnotationResolver implements AnnotationResolver { 42 43 /** 44 * Returns {@code methodInvocation.}{@link org.apache.shiro.aop.MethodInvocation#getMethod() getMethod()}.{@link Method#getAnnotation(Class) getAnnotation(clazz)}. 45 * 46 * @param mi the intercepted method to be invoked. 47 * @param clazz the annotation class to use to find an annotation instance on the method. 48 * @return the discovered annotation or {@code null} if an annotation instance could not be 49 * found. 50 */ 51 public Annotation getAnnotation(MethodInvocation mi, Class<? extends Annotation> clazz) { 52 if (mi == null) { 53 throw new IllegalArgumentException("method argument cannot be null"); 54 } 55 Method m = mi.getMethod(); 56 if (m == null) { 57 String msg = MethodInvocation.class.getName() + " parameter incorrectly constructed. getMethod() returned null"; 58 throw new IllegalArgumentException(msg); 59 60 } 61 Annotation annotation = m.getAnnotation(clazz); 62 if (annotation == null ) { 63 Object miThis = mi.getThis(); 64 //SHIRO-473 - miThis could be null for static methods, just return null 65 annotation = miThis != null ? miThis.getClass().getAnnotation(clazz) : null; 66 } 67 return annotation; 68 } 69 }