    001// Copyright 2011, 2012, 2023 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.commons.services;
    016
    017import java.lang.reflect.Constructor;
    018import java.lang.reflect.Method;
    019
    020import org.apache.tapestry5.commons.Location;
    021import org.apache.tapestry5.commons.ObjectCreator;
    022import org.apache.tapestry5.ioc.annotations.IncompatibleChange;
    023import org.apache.tapestry5.plastic.ClassInstantiator;
    024import org.apache.tapestry5.plastic.PlasticClassListenerHub;
    025import org.apache.tapestry5.plastic.PlasticClassTransformation;
    026import org.apache.tapestry5.plastic.PlasticClassTransformer;
    027import org.apache.tapestry5.plastic.PlasticManager;
    028
    029/**
    030 * A service used to create proxies of varying types. As a secondary concern, manages to identify the
    031 * location of methods and constructors, which is important for exception reporting.
    032 *
    033 * @since 5.3
    034 */
    035public interface PlasticProxyFactory extends PlasticClassListenerHub
    036{
    037    /**
    038     * Returns the class loader used when creating new classes, this is a child class loader
    039     * of another class loader (usually, the thread's context class loader).
    040     */
    041    ClassLoader getClassLoader();
    042
    043    /**
    044     * Creates a proxy object that implements the indicated interface, then invokes the callback to further
    045     * configure the proxy.
    046     *
    047     * @param interfaceType
    048     *         interface implemented by proxy
    049     * @param callback
    050     *         configures the proxy
    051     * @return instantiator that can be used to create an instance of the proxy class
    052     */
    053    <T> ClassInstantiator<T> createProxy(Class<T> interfaceType, PlasticClassTransformer callback);
    054
    055    /**
    056     * Creates a proxy object that implements the indicated interface and indicated service implementation type,
    057     * then invokes the callback to further configure the proxy.
    058     *
    059     * @param interfaceType
    060     *         interface implemented by proxy
    061     * @param implementationType
    062     *         a class that implements the interfaceType. It can be null.
    063     * @param callback
    064     *         configures the proxy
    065     * @return instantiator that can be used to create an instance of the proxy class
    066     */
    067    @IncompatibleChange(release = "5.4.5", details = "TAP5-2528")
    068    <T> ClassInstantiator<T> createProxy(Class<T> interfaceType, Class<? extends T> implementationType, PlasticClassTransformer callback, boolean introduceInterface);
    069
    070    /**
    071     * Same as <code>createProxy(interfacetype, implementationType, callback, true)</code>
    072     *
    073     * @param interfaceType
    074     *         interface implemented by proxy
    075     * @param implementationType
    076     *         a class that implements the interfaceType. It can be null.
    077     * @param callback
    078     *         configures the proxy
    079     * @return instantiator that can be used to create an instance of the proxy class
    080     */
    081    @IncompatibleChange(release = "5.4", details = "TAP5-2029")
    082    <T> ClassInstantiator<T> createProxy(Class<T> interfaceType, Class<? extends T> implementationType, PlasticClassTransformer callback);
    083
    084    /**
    085     * Creates the underlying {@link PlasticClassTransformation} for an interface proxy. This should only be
    086     * used in the cases where encapsulating the PlasticClass construction into a {@linkplain PlasticClassTransformer
    087     * callback} is not feasible (which is the case for some of the older APIs inside Tapestry IoC).
    088     *
    089     * @param interfaceType
    090     *         class proxy will extend from
    091     * @return transformation from which an instantiator may be created
    092     */
    093    <T> PlasticClassTransformation<T> createProxyTransformation(Class<T> interfaceType);
    094
    095    /**
    096     * Creates the underlying {@link PlasticClassTransformation} for an interface proxy with a given
    097     * implementation class. This should only be
    098     * used in the cases where encapsulating the PlasticClass construction into a {@linkplain PlasticClassTransformer
    099     * callback} is not feasible (which is the case for some of the older APIs inside Tapestry IoC).
    100     *
    101     * @param interfaceType
    102     *         class proxy will extend from
    103     * @param implementationType
    104     *         a class that implements the interfaceType. It can be null.
    105     * @return transformation from which an instantiator may be created
    106     */
    107    @IncompatibleChange(release = "5.4", details = "TAP5-2029")
    108    <T> PlasticClassTransformation<T> createProxyTransformation(Class<T> interfaceType, Class<? extends T> implementationType);
    109
    110    /**
    111     * Creates a proxy instance that delegates all methods through a corresponding
    112     * ObjectCreator. Each method invocation on the proxy will route through {@link ObjectCreator#createObject()} (the
    113     * creator implementation may decide to
    114     * cache the return value as appropriate).
    115     *
    116     * @param <T>
    117     *         type of proxy
    118     * @param interfaceType
    119     *         interface class for proxy
    120     * @param creator
    121     *         object responsible for creating the real object
    122     * @param description
    123     *         the <code>toString()</code> of the proxy
    124     * @return proxy instance
    125     */
    126    <T> T createProxy(Class<T> interfaceType, ObjectCreator<T> creator, String description);
    127
    128    /**
    129     * Creates a proxy instance that delegates all methods through a corresponding
    130     * ObjectCreator. Each method invocation on the proxy will route through {@link ObjectCreator#createObject()} (the
    131     * creator implementation may decide to
    132     * cache the return value as appropriate).
    133     *
    134     * @param <T>
    135     *         type of proxy
    136     * @param interfaceType
    137     *         interface class for proxy
    138     * @param implementationType
    139     *         class that implements the interface type. It may be null
    140     * @param creator
    141     *         object responsible for creating the real object
    142     * @param description
    143     *         the <code>toString()</code> of the proxy
    144     * @return proxy instance
    145     */
    146    @IncompatibleChange(release = "5.4", details = "Added for TAP5-2029")
    147    <T> T createProxy(Class<T> interfaceType, Class<? extends T> implementationType, ObjectCreator<T> creator, String description);
    148
    149    /**
    150     * Converts a method to a {@link Location}, which includes information about the source file name and line number.
    151     *
    152     * @param method
    153     *         to look up
    154     * @return the location (identifying the method and possibly, the line number within the method)
    155     */
    156    Location getMethodLocation(Method method);
    157
    158    /**
    159     * Return a string representation for the constructor (including class and parameters) and (if available) file name
    160     * and line number.
    161     *
    162     * @return the location (identifying the constructor and possibly, the line number within the method)
    163     */
    164    Location getConstructorLocation(Constructor constructor);
    165
    166    /**
    167     * Clears any cached information stored by the proxy factory; this is useful in Tapestry development mode
    168     * when a class loader may have been discarded (because the proxy factory may indirectly keep references
    169     * to classes loaded by the old class loader).
    170     *
    171     * @since 5.3.3
    172     */
    173    @IncompatibleChange(release = "5.3.3", details = "Added method")
    174    void clearCache();
    175
    176    /**
    177     * Returns the {@linkplain PlasticManager} instance used by this PlasticProxyFactory.
    178     * @since 5.8.3
    179     */
    180    @IncompatibleChange(release = "5.8.3", details = "Added method")
    181    PlasticManager getPlasticManager();
    182
    183    /**
    184     * Returns the {@linkplain PlasticProxyFactory} instance to be used for a given class.
    185     * Default implementation returns <code>this</code>.
    186     * @since 5.8.3
    187     */
    188    default PlasticProxyFactory getProxyFactory(String className)
    189    {
    190        return this;
    191    }
    192
    193}