001    // Copyright 2010, 2011 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    // http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.services;
016    
017    import java.lang.annotation.Annotation;
018    
019    import org.apache.tapestry5.ioc.AnnotationProvider;
020    
021    /**
022     * A method defined by (or created within) a {@link ClassTransformation}, allowing
023     * for access and manipulation of the method.
024     * <p>
025     * The natural sorting order of TransformMethods is the same as {@link TransformMethodSignature}.
026     * 
027     * @since 5.2.0
028     */
029    public interface TransformMethod extends AnnotationProvider, Comparable<TransformMethod>
030    {
031        /**
032         * @return the signature for the method, defining name, visibility, return type, parameter types and thrown
033         *         exceptions
034         */
035        TransformMethodSignature getSignature();
036    
037        /** Returns just the name of the method. */
038        String getName();
039    
040        /**
041         * Returns an object that can be used to invoke the method on an instance of the component class (regardless
042         * of the actual visibility of the method).
043         */
044        MethodAccess getAccess();
045    
046        /**
047         * Add advice for the method; the advice will be threaded into method invocations of the indicated method.
048         * A method may be given multiple advice; each advice will receive control in turn (assuming
049         * the previous advice invokes {@link ComponentMethodInvocation#proceed()}) in the order the advice
050         * is added. The last advice will proceed to the original method implementation.
051         * 
052         * @param advice
053         *            to receive control when the method is invoked
054         * @see #addOperationAfter(ComponentInstanceOperation)
055         * @see #addOperationBefore(ComponentInstanceOperation)
056         */
057        void addAdvice(ComponentMethodAdvice advice);
058    
059        /**
060         * Adds an operation that will execute before any
061         * further advice or operations. This is converted into
062         * advice that invokes the operation, then invokes {@link ComponentMethodInvocation#proceed()}.
063         */
064        void addOperationBefore(ComponentInstanceOperation operation);
065    
066        /**
067         * Adds an operation that will execute after any
068         * further advice or operations. This is converted into
069         * advice that invokes {@link ComponentMethodInvocation#proceed()} before invoking the operation.
070         */
071        void addOperationAfter(ComponentInstanceOperation operation);
072    
073        /**
074         * Converts a signature to a string used to identify the method; this consists of the
075         * {@link TransformMethodSignature#getMediumDescription()} appended with source file information
076         * and line number
077         * information (when available).
078         * 
079         * @return a string that identifies the class, method name, types of parameters, source file and
080         *         source line number
081         */
082        String getMethodIdentifier();
083    
084        /**
085         * Returns true if the method is an override of a method from the parent class.
086         * 
087         * @return true if the parent class contains a method with the name signature
088         */
089        boolean isOverride();
090    
091        /**
092         * Gets an annotation on a parameter of the method.
093         * 
094         * @param index
095         *            index of parameter
096         * @param annotationType
097         *            type of annotation to check for
098         * @return the annotation, if found, or null
099         */
100        <A extends Annotation> A getParameterAnnotation(int index, Class<A> annotationType);
101    }