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