KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > proxy > ProxySubclassingStrategy


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.aspectwerkz.proxy;
5
6
7 import com.tc.aspectwerkz.definition.SystemDefinition;
8 import com.tc.aspectwerkz.exception.WrappedRuntimeException;
9
10 import java.util.Map JavaDoc;
11 import java.util.WeakHashMap JavaDoc;
12
13 /**
14  * Get proxy classes from target classes and weaves in all matching aspects deployed in the class loader
15  * and defined by the <code>META-INF/aop.xml</code> file.
16  *
17  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
18  */

19 public class ProxySubclassingStrategy {
20
21   /**
22    * The suffix for the compiled proxy classes.
23    */

24   public static final String JavaDoc PROXY_SUFFIX = "$$ProxiedByAWSubclassing$$";
25
26   /**
27    * Cache for the compiled proxy classes. Target class is key.
28    */

29   private static final Map JavaDoc PROXY_CLASS_CACHE = new WeakHashMap JavaDoc();
30
31   /**
32    * Creates a new proxy instance based for the class specified and instantiates it using its default no-argument
33    * constructor. <p/> The proxy will be cached and non-advisable.
34    *
35    * @param clazz the target class to make a proxy for
36    * @return the proxy instance
37    */

38   static Object JavaDoc newInstance(
39           final Class JavaDoc clazz, final SystemDefinition definition) {
40     try {
41       Class JavaDoc proxyClass = getProxyClassFor(clazz, true, false, definition);
42       return proxyClass.newInstance();
43     } catch (Throwable JavaDoc t) {
44       throw new WrappedRuntimeException(t);
45     }
46   }
47
48   /**
49    * Creates a new proxy instance for the class specified and instantiates it using the constructor matching
50    * the argument type array specified.
51    * <p/>
52    * The proxy will be cached and non-advisable.
53    *
54    * @param clazz the target class to make a proxy for
55    * @param argumentTypes the argument types matching the signature of the constructor to use when instantiating the proxy
56    * @param argumentValues the argument values to use when instantiating the proxy
57    * @return the proxy instance
58    */

59   static Object JavaDoc newInstance(
60           final Class JavaDoc clazz, final Class JavaDoc[] argumentTypes, final Object JavaDoc[] argumentValues,
61           final SystemDefinition definition) {
62     try {
63       Class JavaDoc proxyClass = getProxyClassFor(clazz, true, false, definition);
64       return proxyClass.getDeclaredConstructor(argumentTypes).newInstance(argumentValues);
65     } catch (Throwable JavaDoc t) {
66       throw new WrappedRuntimeException(t);
67     }
68   }
69
70   /**
71    * Creates a new proxy instance based for the class specified and instantiates it using its default no-argument
72    * constructor.
73    *
74    * @param clazz the target class to make a proxy for
75    * @param useCache true if a cached instance of the proxy classed should be used
76    * @param makeAdvisable true if the proxy class should implement the <code>Advisable</code> interface,
77    * e.g. be prepared for programmatic, runtime, per instance hot deployement of advice
78    * @return the proxy instance
79    */

80   static Object JavaDoc newInstance(
81           final Class JavaDoc clazz, final boolean useCache, final boolean makeAdvisable,
82           final SystemDefinition definition) {
83     try {
84       Class JavaDoc proxyClass = getProxyClassFor(clazz, useCache, makeAdvisable, definition);
85       return proxyClass.newInstance();
86     } catch (Throwable JavaDoc t) {
87       throw new WrappedRuntimeException(t);
88     }
89   }
90
91   /**
92    * Creates a new proxy instance for the class specified and instantiates it using the constructor matching
93    * the argument type array specified.
94    *
95    * @param clazz the target class to make a proxy for
96    * @param argumentTypes the argument types matching the signature of the constructor to use when instantiating the proxy
97    * @param argumentValues the argument values to use when instantiating the proxy
98    * @param useCache true if a cached instance of the proxy classed should be used
99    * @param makeAdvisable true if the proxy class should implement the <code>Advisable</code> interface,
100    * e.g. be prepared for programmatic, runtime, per instance hot deployement of advice
101    * @return the proxy instance
102    */

103   static Object JavaDoc newInstance(
104           final Class JavaDoc clazz, final Class JavaDoc[] argumentTypes, final Object JavaDoc[] argumentValues,
105           final boolean useCache, final boolean makeAdvisable,
106           final SystemDefinition definition) {
107     try {
108       Class JavaDoc proxyClass = getProxyClassFor(clazz, useCache, makeAdvisable, definition);
109       return proxyClass.getDeclaredConstructor(argumentTypes).newInstance(argumentValues);
110     } catch (Throwable JavaDoc t) {
111       throw new WrappedRuntimeException(t);
112     }
113   }
114
115   /**
116    * Compiles and returns a proxy class for the class specified.
117    *
118    * @param clazz the target class to make a proxy for
119    * @param useCache true if a cached instance of the proxy classed should be used
120    * @param makeAdvisable true if the proxy class should implement the <code>Advisable</code> interface,
121    * e.g. be prepared for programmatic, runtime, per instance hot deployement of advice
122    * @return the proxy class
123    */

124   static Class JavaDoc getProxyClassFor(
125           final Class JavaDoc clazz, final boolean useCache, final boolean makeAdvisable,
126           final SystemDefinition definition) {
127
128     // TODO - add support for proxying java.* classes
129
if (clazz.getName().startsWith("java.")) {
130       throw new RuntimeException JavaDoc(
131               "can not create proxies from system classes (java.*)");
132     }
133     final Class JavaDoc proxyClass;
134     if (!useCache) {
135       proxyClass = getNewProxyClassFor(clazz, makeAdvisable, definition);
136     } else {
137       synchronized (PROXY_CLASS_CACHE) {
138         Object JavaDoc cachedProxyClass = PROXY_CLASS_CACHE.get(clazz);
139         if (cachedProxyClass != null) {
140           return (Class JavaDoc) cachedProxyClass;
141         }
142         proxyClass = getNewProxyClassFor(clazz, makeAdvisable, definition);
143         PROXY_CLASS_CACHE.put(clazz, proxyClass);
144       }
145     }
146     ProxyCompilerHelper.compileJoinPoint(proxyClass, definition);
147     return proxyClass;
148   }
149
150   /**
151    * Compiles and returns a proxy class for the class specified.
152    * No cache is used, but compiles a new one each invocation.
153    *
154    * @param clazz
155    * @param makeAdvisable true if the proxy class should implement the <code>Advisable</code> interface,
156    * e.g. be prepared for programmatic, runtime, per instance hot deployement of advice
157    * @return the proxy class
158    */

159   private static Class JavaDoc getNewProxyClassFor(
160           final Class JavaDoc clazz, final boolean makeAdvisable,
161           final SystemDefinition definition) {
162     ClassLoader JavaDoc loader = clazz.getClassLoader();
163     String JavaDoc proxyClassName = definition.getUuid();
164     if (makeAdvisable) {
165       Proxy.makeProxyAdvisable(proxyClassName, loader, definition);
166     }
167     final byte[] bytes = ProxySubclassingCompiler.compileProxyFor(clazz, proxyClassName);
168     return ProxyCompilerHelper.weaveAndDefineProxyClass(
169             bytes, loader, proxyClassName.replace('/', '.'), definition);
170   }
171
172   /**
173    * Returns a unique name for the proxy class.
174    *
175    * @param proxyClassName
176    * @return the class name beeing proxied
177    */

178   static String JavaDoc getUniqueClassNameFromProxy(
179           final String JavaDoc proxyClassName) {
180     int index = proxyClassName.lastIndexOf(PROXY_SUFFIX);
181     if (index > 0) {
182       return proxyClassName.substring(0, index);
183     } else {
184       return null;
185     }
186   }
187 }
188
Popular Tags