Lines 11-28
Link Here
|
11 |
* ******************************************************************/ |
11 |
* ******************************************************************/ |
12 |
package org.aspectj.weaver.ltw; |
12 |
package org.aspectj.weaver.ltw; |
13 |
|
13 |
|
14 |
import org.aspectj.weaver.Advice; |
14 |
import java.lang.ref.WeakReference; |
15 |
import org.aspectj.weaver.ConcreteTypeMunger; |
15 |
import java.lang.reflect.InvocationTargetException; |
16 |
import org.aspectj.weaver.Member; |
16 |
import java.lang.reflect.Method; |
|
|
17 |
import java.util.Collections; |
18 |
import java.util.HashSet; |
19 |
import java.util.Iterator; |
20 |
import java.util.Map; |
21 |
import java.util.Set; |
22 |
import java.util.WeakHashMap; |
23 |
|
24 |
import org.aspectj.bridge.IMessageHandler; |
25 |
import org.aspectj.weaver.ICrossReferenceHandler; |
17 |
import org.aspectj.weaver.ReferenceType; |
26 |
import org.aspectj.weaver.ReferenceType; |
18 |
import org.aspectj.weaver.ReferenceTypeDelegate; |
27 |
import org.aspectj.weaver.ReferenceTypeDelegate; |
19 |
import org.aspectj.weaver.ResolvedMember; |
28 |
import org.aspectj.weaver.UnresolvedType; |
20 |
import org.aspectj.weaver.ResolvedType; |
29 |
import org.aspectj.weaver.bcel.BcelWorld; |
21 |
import org.aspectj.weaver.ResolvedTypeMunger; |
30 |
import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegateFactory; |
22 |
import org.aspectj.weaver.World; |
31 |
import org.aspectj.weaver.reflect.ReflectionWorld; |
23 |
import org.aspectj.weaver.AjAttribute.AdviceAttribute; |
|
|
24 |
import org.aspectj.weaver.patterns.Pointcut; |
25 |
import org.aspectj.weaver.patterns.PerClause.Kind; |
26 |
|
32 |
|
27 |
/** |
33 |
/** |
28 |
* @author adrian |
34 |
* @author adrian |
Lines 40-76
Link Here
|
40 |
* |
46 |
* |
41 |
* Create by passing in a classloader, message handler |
47 |
* Create by passing in a classloader, message handler |
42 |
*/ |
48 |
*/ |
43 |
public class LTWWorld extends World { |
49 |
public class LTWWorld extends BcelWorld { |
44 |
|
50 |
private ReflectionWorld reflectionWorld; |
|
|
51 |
private ClassLoader loader; |
52 |
//optimizations: use ConcurrentMap for Java 1.5... |
53 |
private static Map/*<ClassLoader, LTWWorld>*/ worlds = Collections.synchronizedMap(new WeakHashMap()); |
54 |
|
55 |
private Set/*<WeakReference<LTWWorld>>*/ children = Collections.synchronizedSet(new HashSet()); |
56 |
|
57 |
/** |
58 |
* Build a World from a ClassLoader, for LTW support |
59 |
* |
60 |
* @param loader |
61 |
* @param handler |
62 |
* @param xrefHandler |
63 |
*/ |
64 |
public LTWWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { |
65 |
super(loader, handler, xrefHandler); |
66 |
this.loader = loader; |
67 |
reflectionWorld = new ReflectionWorld(loader); |
68 |
worlds.put(loader, this); |
69 |
if (loader.getParent() != null) { |
70 |
WeakReference ref = (WeakReference)worlds.get(loader.getParent()); |
71 |
if (ref != null) { |
72 |
LTWWorld parentWorld = (LTWWorld)ref.get(); |
73 |
if (parentWorld != null) { |
74 |
parentWorld.children.add(new WeakReference(this)); |
75 |
} |
76 |
} |
77 |
} |
78 |
} |
79 |
|
80 |
/** |
81 |
* Reflective method to find a loaded class without loading if not found. |
82 |
*/ |
83 |
private final static Method findLoadedClassMethod = getLoadedClassMethod(); |
84 |
private static Method getLoadedClassMethod() { |
85 |
try { |
86 |
Method findLoadedClassMethod = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[] { String.class }); |
87 |
findLoadedClassMethod.setAccessible(true); |
88 |
return findLoadedClassMethod; |
89 |
} catch (Throwable t) { |
90 |
//swallow |
91 |
return null; |
92 |
} |
93 |
} |
94 |
|
95 |
/** |
96 |
* ThreadLocal holder of single argument array to hold class name, for efficiency. |
97 |
*/ |
98 |
private final static ThreadLocal/*<String[]>*/ nameHolderHolder = new ThreadLocal() { |
99 |
public Object initialValue() { |
100 |
return new String[1]; |
101 |
} |
102 |
}; |
103 |
|
104 |
/** |
105 |
* @Override |
106 |
*/ |
45 |
protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { |
107 |
protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { |
46 |
// TODO Auto-generated method stub |
|
|
47 |
return null; |
48 |
|
108 |
|
|
|
109 |
String name = ty.getName(); |
110 |
|
111 |
// first check for anything available in the bootstrap loader should be just defined from that without allowing nondelegation? |
112 |
ReferenceTypeDelegate bootstrapLoaderDelegate = resolveReflectionTypeDelegate(ty, null); |
113 |
if (bootstrapLoaderDelegate != null) { |
114 |
// it's always fine to load these bytes: there's no weaving from them |
115 |
// and since the class isn't initialized, all we are doing at this point is loading the bytes |
116 |
return bootstrapLoaderDelegate; |
117 |
} |
118 |
// indeed for ANY class loader with a disabled weaver, this is fine too! |
119 |
// this is a potentially BIG optimization: just loading a reflection delegate for any type that can't be woven |
120 |
|
121 |
// failing this, we look to see whether the class has already been loaded |
122 |
ClassLoader resolutionLoader = loader; |
123 |
String asRes = name.replace('.', '/').concat(".class"); |
124 |
java.net.URL resURL = resolutionLoader.getResource(asRes); |
125 |
boolean tryAgain; |
126 |
String[] arg = (String[])nameHolderHolder.get(); |
127 |
arg[0] = name; |
128 |
|
129 |
do { |
130 |
try { |
131 |
Class clazz = (Class)findLoadedClassMethod.invoke(resolutionLoader, arg); |
132 |
if (clazz != null) { |
133 |
return resolveReflectionTypeDelegate(ty, resolutionLoader); |
134 |
} |
135 |
|
136 |
} catch (IllegalArgumentException e) { |
137 |
} catch (IllegalAccessException e) { |
138 |
} catch (InvocationTargetException e) { |
139 |
} |
140 |
|
141 |
if (resolutionLoader != null) { |
142 |
// can my parent resolve this? |
143 |
// will I resolve this by delegating to my parent? |
144 |
java.net.URL parentURL = resolutionLoader.getParent().getResource(asRes); |
145 |
tryAgain = (parentURL != null && parentURL.equals(resURL)); |
146 |
resolutionLoader = resolutionLoader.getParent(); |
147 |
} else { |
148 |
tryAgain = false; |
149 |
} |
150 |
|
151 |
} while (tryAgain); |
152 |
//TODO: can we somehow avoid creating many aliases, one per child ClassLoader? |
153 |
return super.resolveDelegate(ty); |
154 |
} |
155 |
|
156 |
/** |
157 |
* Helper method to resolve the delegate from the reflection delegate factory. |
158 |
*/ |
159 |
private ReferenceTypeDelegate resolveReflectionTypeDelegate(ReferenceType ty, ClassLoader resolutionLoader) { |
160 |
ReferenceTypeDelegate res = ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty, reflectionWorld, resolutionLoader); |
161 |
return res; |
162 |
} |
163 |
|
164 |
/** |
165 |
* Remove this class from the typeMap. |
166 |
* When next needed, a reflective proxy will be created: no need to create it eagerly... |
167 |
* TODO: test |
168 |
* |
169 |
* @param clazz |
170 |
*/ |
171 |
public void loadedClass(Class clazz) { |
172 |
// evict it from the parent |
173 |
typeMap.remove(UnresolvedType.forName(clazz.getName()).getSignature()); |
174 |
|
175 |
// and all the children... |
176 |
for (Iterator it = children.iterator(); it.hasNext();) { |
177 |
WeakReference ref = (WeakReference)it.next(); |
178 |
if (ref != null) { |
179 |
LTWWorld world = (LTWWorld)ref.get(); |
180 |
if (world != null) { |
181 |
world.loadedClass(clazz); |
182 |
} |
183 |
} |
184 |
} |
49 |
} |
185 |
} |
50 |
|
186 |
|
51 |
public Advice createAdviceMunger(AdviceAttribute attribute, Pointcut pointcut, Member signature) { |
187 |
private static final long serialVersionUID = 1; |
52 |
// TODO Auto-generated method stub |
|
|
53 |
return null; |
54 |
} |
55 |
|
56 |
public ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField) { |
57 |
// TODO Auto-generated method stub |
58 |
return null; |
59 |
} |
60 |
|
61 |
public ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField) { |
62 |
// TODO Auto-generated method stub |
63 |
return null; |
64 |
} |
65 |
|
66 |
public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, Kind kind) { |
67 |
// TODO Auto-generated method stub |
68 |
return null; |
69 |
} |
70 |
|
71 |
public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) { |
72 |
// TODO Auto-generated method stub |
73 |
return null; |
74 |
} |
75 |
|
76 |
} |
188 |
} |