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.ioc.services;
016
017import org.apache.tapestry5.ioc.Location;
018import org.apache.tapestry5.ioc.ObjectCreator;
019import org.apache.tapestry5.ioc.annotations.IncompatibleChange;
020import org.apache.tapestry5.plastic.ClassInstantiator;
021import org.apache.tapestry5.plastic.PlasticClassListenerHub;
022import org.apache.tapestry5.plastic.PlasticClassTransformation;
023import org.apache.tapestry5.plastic.PlasticClassTransformer;
024
025import java.lang.reflect.Constructor;
026import java.lang.reflect.Method;
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", details = "TAP5-2029")
067    <T> ClassInstantiator<T> createProxy(Class<T> interfaceType, Class<? extends T> implementationType, PlasticClassTransformer callback);
068
069    /**
070     * Creates the underlying {@link PlasticClassTransformation} for an interface proxy. This should only be
071     * used in the cases where encapsulating the PlasticClass construction into a {@linkplain PlasticClassTransformer
072     * callback} is not feasible (which is the case for some of the older APIs inside Tapestry IoC).
073     *
074     * @param interfaceType
075     *         class proxy will extend from
076     * @return transformation from which an instantiator may be created
077     */
078    <T> PlasticClassTransformation<T> createProxyTransformation(Class<T> interfaceType);
079
080    /**
081     * Creates the underlying {@link PlasticClassTransformation} for an interface proxy with a given
082     * implementation class. This should only be
083     * used in the cases where encapsulating the PlasticClass construction into a {@linkplain PlasticClassTransformer
084     * callback} is not feasible (which is the case for some of the older APIs inside Tapestry IoC).
085     *
086     * @param interfaceType
087     *         class proxy will extend from
088     * @param implementationType
089     *         a class that implements the interfaceType. It can be null.
090     * @return transformation from which an instantiator may be created
091     */
092    @IncompatibleChange(release = "5.4", details = "TAP5-2029")
093    <T> PlasticClassTransformation<T> createProxyTransformation(Class<T> interfaceType, Class<? extends T> implementationType);
094
095    /**
096     * Creates a proxy instance that delegates all methods through a corresponding
097     * ObjectCreator. Each method invocation on the proxy will route through {@link ObjectCreator#createObject()} (the
098     * creator implementation may decide to
099     * cache the return value as appropriate).
100     *
101     * @param <T>
102     *         type of proxy
103     * @param interfaceType
104     *         interface class for proxy
105     * @param creator
106     *         object responsible for creating the real object
107     * @param description
108     *         the <code>toString()</code> of the proxy
109     * @return proxy instance
110     */
111    <T> T createProxy(Class<T> interfaceType, ObjectCreator<T> creator, String description);
112    
113    /**
114     * Creates a proxy instance that delegates all methods through a corresponding
115     * ObjectCreator. Each method invocation on the proxy will route through {@link ObjectCreator#createObject()} (the
116     * creator implementation may decide to
117     * cache the return value as appropriate).
118     *
119     * @param <T>
120     *         type of proxy
121     * @param interfaceType
122     *         interface class for proxy
123     * @param implementationType
124     *         class that implements the interface type. It may be null
125     * @param creator
126     *         object responsible for creating the real object
127     * @param description
128     *         the <code>toString()</code> of the proxy
129     * @return proxy instance
130     */
131    @IncompatibleChange(release = "5.4", details = "Added for TAP5-2029")
132    <T> T createProxy(Class<T> interfaceType, Class<? extends T> implementationType, ObjectCreator<T> creator, String description);
133
134    /**
135     * Converts a method to a {@link Location}, which includes information about the source file name and line number.
136     *
137     * @param method
138     *         to look up
139     * @return the location (identifying the method and possibly, the line number within the method)
140     */
141    Location getMethodLocation(Method method);
142
143    /**
144     * Return a string representation for the constructor (including class and parameters) and (if available) file name
145     * and line number.
146     *
147     * @return the location (identifying the constructor and possibly, the line number within the method)
148     */
149    Location getConstructorLocation(Constructor constructor);
150
151    /**
152     * Clears any cached information stored by the proxy factory; this is useful in Tapestry development mode
153     * when a class loader may have been discarded (because the proxy factory may indirectly keep references
154     * to classes loaded by the old class loader).
155     *
156     * @since 5.3.3
157     */
158    void clearCache();
159}