001    /*
002     * ============================================================================
003     * GNU Lesser General Public License
004     * ============================================================================
005     *
006     * Beanlet - JSE Application Container.
007     * Copyright (C) 2006  Leon van Zantvoort
008     * 
009     * This library is free software; you can redistribute it and/or
010     * modify it under the terms of the GNU Lesser General Public
011     * License as published by the Free Software Foundation; either
012     * version 2.1 of the License, or (at your option) any later version.
013     * 
014     * This library is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
017     * Lesser General Public License for more details.
018     * 
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
022     * 
023     * Leon van Zantvoort
024     * 243 Acalanes Drive #11
025     * Sunnyvale, CA 94086
026     * USA
027     *
028     * zantvoort@users.sourceforge.net
029     * http://beanlet.org
030     */
031    package org.beanlet;
032    
033    import java.lang.annotation.ElementType;
034    import java.lang.annotation.Retention;
035    import java.lang.annotation.RetentionPolicy;
036    import java.lang.annotation.Target;
037    
038    /**
039     * <p>Designates a method to intercept invocations on a beanlet. A class that
040     * declares a method marked with the {@code ArroundInvoke} annotation is said to
041     * be an interceptor class. Interceptor classes are instantiated either by their
042     * (typically implicit) sole constructor, or by contructor injection.
043     * Example (A) shows how to implement an interceptor using this annotation.</p>
044     * 
045     * <p><h3>Inner Interceptors</h3>
046     * The {@code ArroundInvoke} annotation can be applied on methods of any class,
047     * including classes implementing a beanlet. Such interceptors are so-called
048     * inner interceptors. An inner interceptor is <u>automatically</u>
049     * installed for all business methods of a beanlet. It is placed at the tail of 
050     * the interceptor chain. It cannot be excluded by the 
051     * {@code ExcludeClassInterceptors} annotation. An example of an inner
052     * interceptor can be found at example (B).</p>
053     * 
054     * <p><h3>Hierarchical Interceptors</h3>
055     * Interceptor classes may declare only one interceptor method. However 
056     * interceptor methods may be defined on any of its superclasses. The 
057     * interceptor methods defined by these superclasses are invoked before the 
058     * interceptor method defined by the interceptor class, most general superclass
059     * first. This is demonstrated by example (C).<br>
060     * If a interceptor method is overridden by another method (regardless whether 
061     * that method is itself an interceptor method), it will not be invoked. An
062     * example of such an interceptor is listed at (D).<br>
063     * </p>
064     *
065     * <p><h3>Method Constraints</h3>
066     * The method on which the {@code AroundInvoke} annotation is applied MUST 
067     * fulfill all of the following criteria:
068     * <ul>
069     * <li>The method MUST have the {@code InterceptorContext} object as parameter.
070     * <li>The return type of the method MUST NOT be {@code void}
071     * <li>The method MAY throw a checked exception.
072     * <li>The method on which {@code AroundInvoke} is applied MAY be 
073     * {@code public}, {@code protected}, package private or {@code private}. 
074     * <li>The method MUST NOT be {@code static}.
075     * <li>The method MAY be {@code final}. 
076     * </ul>
077     * </p>
078     *
079     * <p><h3>Examples</h3>
080     * <b>(A)</b> Example of an interceptor class using the {@code ArroundInvoke} 
081     * annotation:
082     * <pre>
083     * public class BaseInterceptor {
084     *
085     *     &#064;AroundInvoke
086     *     public Object wrap(InvocationContext ctx) throws Exception {
087     *         try {
088     *             // Run code before the invocation...
089     *             return ctx.proceed();
090     *         } finally {
091     *             // Run code after the invocation...
092     *         }
093     *     }
094     * }
095     * </pre>
096     * 
097     * <b>(B)</b> Example of a beanlet with an inner interceptor:
098     * <pre>
099     * public class ExampleBeanlet {
100     *     
101     *     &#64;Factory
102     *     public Object getInstance() {
103     *         return new Object();
104     *     }
105     *
106     *     &#64;ArroundInvoke 
107     *     public Object intercept(InvocationContext ctx) throws Exception {
108     *         try {
109     *             // Run code before the invocation...
110     *             return ctx.proceed();
111     *         } finally {
112     *             // Run code after the invocation...
113     *         }
114     *     }
115     * }
116     * </pre>
117     *
118     * <b>(C)</b> Example of an interceptor class that extends the interceptor class
119     * listed at example (A). The {@code BaseInterceptor.wrap()} method preceeds
120     * the {@code ExtendedInterceptor.wrapToo()} method in the interceptor chain:
121     * <pre>
122     * public class ExtendedInterceptor extends BaseInterceptor {
123     *
124     *     &#064;AroundInvoke 
125     *     public Object wrapToo(InvocationContext ctx) throws Exception {
126     *         try {
127     *             // Run code before the invocation...
128     *             return ctx.proceed();
129     *         } finally {
130     *             // Run code after the invocation...
131     *         }
132     *     }
133     * }
134     * </pre>
135     *
136     * <b>(D)</b> Example of an extended interceptor class of which the interceptor
137     * method overrides the interceptor method of its superclass (listed at (A)). 
138     * The {@code BaseInterceptor.wrap()} method is excluded from the interceptor
139     * chain, it is not invoked. The {@code ExtendedInterceptor.wrap()} method 
140     * however, is included in the interceptor chain.
141     * <pre>
142     * public class ExtendedInterceptor extends BaseInterceptor {
143     *
144     *     &#064;AroundInvoke 
145     *     public Object wrap(InvocationContext ctx) throws Exception {
146     *         try {
147     *             // Run code before the invocation...
148     *             return ctx.proceed();
149     *         } finally {
150     *             // Run code after the invocation...
151     *         }
152     *     }
153     * }
154     * </pre>
155     * </p>
156     *
157     * <p>More information on how to apply interceptors can be found at the 
158     * javadoc of the {@link Interceptor} interface.</p>
159     *
160     * {@beanlet.annotation}
161     *
162     * @see Interceptor
163     * @see Interceptors
164     * @author Leon van Zantvoort
165     */
166    @Retention(RetentionPolicy.RUNTIME)
167    @Target(ElementType.METHOD)
168    public @interface AroundInvoke {
169        
170    }