View Javadoc
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  
23  /**
24   * MethodInterceptor that inspects a specific annotation on the method invocation before continuing
25   * its execution.
26   * </p>
27   * The annotation is acquired from the {@link MethodInvocation MethodInvocation} via a
28   * {@link AnnotationResolver AnnotationResolver} instance that may be configured.  Unless
29   * overridden, the default {@code AnnotationResolver} is a
30   *
31   * @since 0.9
32   */
33  public abstract class AnnotationMethodInterceptor extends MethodInterceptorSupport {
34  
35      private AnnotationHandler handler;
36  
37      /**
38       * The resolver to use to find annotations on intercepted methods.
39       *
40       * @since 1.1
41       */
42      private AnnotationResolver resolver;
43  
44      /**
45       * Constructs an <code>AnnotationMethodInterceptor</code> with the
46       * {@link AnnotationHandler AnnotationHandler} that will be used to process annotations of a
47       * corresponding type.
48       *
49       * @param handler the handler to delegate to for processing the annotation.
50       */
51      public AnnotationMethodInterceptor(AnnotationHandler handler) {
52          this(handler, new DefaultAnnotationResolver());
53      }
54  
55      /**
56       * Constructs an <code>AnnotationMethodInterceptor</code> with the
57       * {@link AnnotationHandler AnnotationHandler} that will be used to process annotations of a
58       * corresponding type, using the specified {@code AnnotationResolver} to acquire annotations
59       * at runtime.
60       *
61       * @param handler  the handler to use to process any discovered annotation
62       * @param resolver the resolver to use to locate/acquire the annotation
63       * @since 1.1
64       */
65      public AnnotationMethodInterceptor(AnnotationHandler handler, AnnotationResolver resolver) {
66          if (handler == null) {
67              throw new IllegalArgumentException("AnnotationHandler argument cannot be null.");
68          }
69          setHandler(handler);
70          setResolver(resolver != null ? resolver : new DefaultAnnotationResolver());
71      }
72  
73      /**
74       * Returns the {@code AnnotationHandler} used to perform authorization behavior based on
75       * an annotation discovered at runtime.
76       *
77       * @return the {@code AnnotationHandler} used to perform authorization behavior based on
78       *         an annotation discovered at runtime.
79       */
80      public AnnotationHandler getHandler() {
81          return handler;
82      }
83  
84      /**
85       * Sets the {@code AnnotationHandler} used to perform authorization behavior based on
86       * an annotation discovered at runtime.
87       *
88       * @param handler the {@code AnnotationHandler} used to perform authorization behavior based on
89       *                an annotation discovered at runtime.
90       */
91      public void setHandler(AnnotationHandler handler) {
92          this.handler = handler;
93      }
94  
95      /**
96       * Returns the {@code AnnotationResolver} to use to acquire annotations from intercepted
97       * methods at runtime.  The annotation is then used by the {@link #getHandler handler} to
98       * perform authorization logic.
99       *
100      * @return the {@code AnnotationResolver} to use to acquire annotations from intercepted
101      *         methods at runtime.
102      * @since 1.1
103      */
104     public AnnotationResolver getResolver() {
105         return resolver;
106     }
107 
108     /**
109      * Returns the {@code AnnotationResolver} to use to acquire annotations from intercepted
110      * methods at runtime.  The annotation is then used by the {@link #getHandler handler} to
111      * perform authorization logic.
112      *
113      * @param resolver the {@code AnnotationResolver} to use to acquire annotations from intercepted
114      *                 methods at runtime.
115      * @since 1.1
116      */
117     public void setResolver(AnnotationResolver resolver) {
118         this.resolver = resolver;
119     }
120 
121     /**
122      * Returns <code>true</code> if this interceptor supports, that is, should inspect, the specified
123      * <code>MethodInvocation</code>, <code>false</code> otherwise.
124      * <p/>
125      * The default implementation simply does the following:
126      * <p/>
127      * <code>return {@link #getAnnotation(MethodInvocation) getAnnotation(mi)} != null</code>
128      *
129      * @param mi the <code>MethodInvocation</code> for the method being invoked.
130      * @return <code>true</code> if this interceptor supports, that is, should inspect, the specified
131      *         <code>MethodInvocation</code>, <code>false</code> otherwise.
132      */
133     public boolean supports(MethodInvocation mi) {
134         return getAnnotation(mi) != null;
135     }
136 
137     /**
138      * Returns the Annotation that this interceptor will process for the specified method invocation.
139      * <p/>
140      * The default implementation acquires the annotation using an annotation
141      * {@link #getResolver resolver} using the internal annotation {@link #getHandler handler}'s
142      * {@link org.apache.shiro.aop.AnnotationHandler#getAnnotationClass() annotationClass}.
143      *
144      * @param mi the MethodInvocation wrapping the Method from which the Annotation will be acquired.
145      * @return the Annotation that this interceptor will process for the specified method invocation.
146      */
147     protected Annotation getAnnotation(MethodInvocation mi) {
148         return getResolver().getAnnotation(mi, getHandler().getAnnotationClass());
149     }
150 }