001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019 package org.apache.shiro.aop;
020
021 import java.lang.annotation.Annotation;
022 import java.lang.reflect.Method;
023
024
025 /**
026 * MethodInterceptor that inspects a specific annotation on the method invocation before continuing
027 * its execution.
028 *
029 * @author Les Hazlewood
030 * @since 0.9
031 */
032 public abstract class AnnotationMethodInterceptor extends MethodInterceptorSupport {
033
034 private AnnotationHandler handler;
035
036 /**
037 * Constructs an <code>AnnotationMethodInterceptor</code> with the
038 * {@link AnnotationHandler AnnotationHandler} that will be used to process annotations of a corresponding
039 * type.
040 *
041 * @param handler the handler to delegate to for processing the annotation.
042 */
043 public AnnotationMethodInterceptor(AnnotationHandler handler) {
044 setHandler(handler);
045 }
046
047 public AnnotationHandler getHandler() {
048 return handler;
049 }
050
051 public void setHandler(AnnotationHandler handler) {
052 this.handler = handler;
053 }
054
055 /**
056 * Returns <code>true</code> if this interceptor supports, that is, should inspect, the specified
057 * <code>MethodInvocation</code>, <code>false</code> otherwise.
058 * <p/>
059 * The default implementation simply does the following:
060 * <p/>
061 * <code>return {@link #getAnnotation(MethodInvocation) getAnnotation(mi)} != null</code>
062 *
063 * @param mi the <code>MethodInvocation</code> for the method being invoked.
064 * @return <code>true</code> if this interceptor supports, that is, should inspect, the specified
065 * <code>MethodInvocation</code>, <code>false</code> otherwise.
066 */
067 public boolean supports(MethodInvocation mi) {
068 return getAnnotation(mi) != null;
069 }
070
071 /**
072 * Returns the Annotation that this interceptor will process for the specified method invocation.
073 * <p/>
074 * The default implementation merely gets the underlying {@link Method Method} from the supplied
075 * <code>MethodInvocation</code> argument, and returns:
076 * <p/>
077 * <code>mi.{@link Method#getAnnotation(Class) getAnnotation}({@link org.apache.shiro.aop.AnnotationHandler#getAnnotationClass() handler.getAnnotationClass()});</code>
078 *
079 * @param mi the MethodInvocation wrapping the Method from which the Annotation will be acquired.
080 * @return the Annotation that this interceptor will process for the specified method invocation.
081 * @throws IllegalArgumentException if the supplied <code>MethodInvocation</code> argument is <code>null</code> or
082 * its underlying <code>Method</code> is <code>null</code>.
083 */
084 protected Annotation getAnnotation(MethodInvocation mi) throws IllegalArgumentException {
085 if (mi == null) {
086 throw new IllegalArgumentException("method argument cannot be null");
087 }
088 Method m = mi.getMethod();
089 if (m == null) {
090 String msg = MethodInvocation.class.getName() + " parameter incorrectly constructed. getMethod() returned null";
091 throw new IllegalArgumentException(msg);
092
093 }
094 return m.getAnnotation(getHandler().getAnnotationClass());
095 }
096
097 }