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}