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
015package org.apache.tapestry5.services;
016
017import java.lang.annotation.Annotation;
018
019import 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 */
029public 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}