1 /* *******************************************************************
2 * Copyright (c) 2005 Contributors.
4 * This program and the accompanying materials are made available
5 * under the terms of the Eclipse Public License v 2.0
6 * which accompanies this distribution and is available at
7 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
10 * Adrian Colyer Initial implementation
11 * ******************************************************************/
12 package org.aspectj.weaver.reflect;
14 import java.lang.reflect.Constructor;
15 import java.lang.reflect.Field;
16 import java.lang.reflect.Member;
17 import java.lang.reflect.Method;
19 import java.net.URLClassLoader;
20 import java.util.Collection;
21 import java.util.Collections;
23 import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
24 import org.aspectj.weaver.AnnotationAJ;
25 import org.aspectj.weaver.AnnotationTargetKind;
26 import org.aspectj.weaver.ConcreteTypeMunger;
27 import org.aspectj.weaver.ISourceContext;
28 import org.aspectj.weaver.ReferenceType;
29 import org.aspectj.weaver.ReferenceTypeDelegate;
30 import org.aspectj.weaver.ResolvedMember;
31 import org.aspectj.weaver.ResolvedType;
32 import org.aspectj.weaver.SourceContextImpl;
33 import org.aspectj.weaver.TypeVariable;
34 import org.aspectj.weaver.UnresolvedType;
35 import org.aspectj.weaver.WeakClassLoaderReference;
36 import org.aspectj.weaver.WeaverStateInfo;
37 import org.aspectj.weaver.World;
38 import org.aspectj.weaver.patterns.Declare;
39 import org.aspectj.weaver.patterns.PerClause;
42 * @author colyer A delegate for a resolved type that uses runtime type information (java.lang.reflect) to answer questions. This
43 * class uses only Java 1.4 features to answer questions. In a Java 1.5 environment use the
44 * Java5ReflectionBasedReferenceTypeDelegate subtype.
46 public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelegate {
48 private static final ClassLoader bootClassLoader = new URLClassLoader(new URL[0]);// ReflectionBasedReferenceTypeDelegate.class.
51 protected Class myClass = null;
52 protected WeakClassLoaderReference classLoaderReference = null;
53 protected World world;
54 private ReferenceType resolvedType;
55 private ResolvedMember[] fields = null;
56 private ResolvedMember[] methods = null;
57 private ResolvedType[] interfaces = null;
59 public ReflectionBasedReferenceTypeDelegate(Class forClass, ClassLoader aClassLoader, World inWorld, ReferenceType resolvedType) {
60 initialize(resolvedType, forClass, aClassLoader, inWorld);
63 /** for reflective construction only */
64 public ReflectionBasedReferenceTypeDelegate() {
67 public void initialize(ReferenceType aType, Class<?> aClass, ClassLoader aClassLoader, World aWorld) {
68 this.myClass = aClass;
69 this.resolvedType = aType;
71 this.classLoaderReference = new WeakClassLoaderReference((aClassLoader != null) ? aClassLoader : bootClassLoader);
74 public Class<?> getClazz() {
78 protected Class getBaseClass() {
82 protected World getWorld() {
86 public ReferenceType buildGenericType() {
87 throw new UnsupportedOperationException("Shouldn't be asking for generic type at 1.4 source level or lower");
90 public boolean isAspect() {
91 // we could do better than this in Java 5 by looking at the annotations
99 * @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationStyleAspect()
101 public boolean isAnnotationStyleAspect() {
102 // we could do better than this in Java 5 by looking at the annotations
107 public boolean isInterface() {
108 return this.myClass.isInterface();
111 public boolean isEnum() {
112 // cant be an enum in Java 1.4 or prior
119 * @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationWithRuntimeRetention ()
121 public boolean isAnnotationWithRuntimeRetention() {
122 // cant be an annotation in Java 1.4 or prior
126 public boolean isAnnotation() {
127 // cant be an annotation in Java 1.4 or prior
131 public String getRetentionPolicy() {
132 // cant be an annotation in Java 1.4 or prior
136 public boolean canAnnotationTargetType() {
140 public AnnotationTargetKind[] getAnnotationTargetKinds() {
144 public boolean isClass() {
145 return !this.myClass.isInterface() && !this.myClass.isPrimitive() && !this.myClass.isArray();
151 * @see org.aspectj.weaver.ReferenceTypeDelegate#isGeneric()
153 public boolean isGeneric() {
154 // cant be generic in 1.4
158 public boolean isAnonymous() {
159 // this isn't in < Java 1.5 but I think we are moving beyond the need to support those levels
160 return this.myClass.isAnonymousClass();
163 public boolean isNested() {
164 // this isn't in < Java 1.5 but I think we are moving beyond the need to support those levels
165 return this.myClass.isMemberClass();
168 public ResolvedType getOuterClass() {
169 // this isn't in < Java 1.5 but I think we are moving beyond the need to support those levels
170 return ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(
171 myClass.getEnclosingClass(),world);
177 * @see org.aspectj.weaver.ReferenceTypeDelegate#isExposedToWeaver()
179 public boolean isExposedToWeaver() {
180 // reflection based types are never exposed to the weaver
187 * @see org.aspectj.weaver.ReferenceTypeDelegate#hasAnnotation(org.aspectj.weaver .UnresolvedType)
189 public boolean hasAnnotation(UnresolvedType ofType) {
190 // in Java 1.4 we cant have an annotation
197 * @see org.aspectj.weaver.ReferenceTypeDelegate#getAnnotations()
199 public AnnotationAJ[] getAnnotations() {
200 // no annotations in Java 1.4
201 return AnnotationAJ.EMPTY_ARRAY;
204 public boolean hasAnnotations() {
211 * @see org.aspectj.weaver.ReferenceTypeDelegate#getAnnotationTypes()
213 public ResolvedType[] getAnnotationTypes() {
214 // no annotations in Java 1.4
215 return new ResolvedType[0];
221 * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredFields()
223 public ResolvedMember[] getDeclaredFields() {
224 if (fields == null) {
225 Field[] reflectFields = this.myClass.getDeclaredFields();
226 ResolvedMember[] rFields = new ResolvedMember[reflectFields.length];
227 for (int i = 0; i < reflectFields.length; i++) {
228 rFields[i] = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectFields[i], world);
230 this.fields = rFields;
238 * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredInterfaces()
240 public ResolvedType[] getDeclaredInterfaces() {
241 if (interfaces == null) {
242 Class[] reflectInterfaces = this.myClass.getInterfaces();
243 ResolvedType[] rInterfaces = new ResolvedType[reflectInterfaces.length];
244 for (int i = 0; i < reflectInterfaces.length; i++) {
245 rInterfaces[i] = ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(reflectInterfaces[i], world);
247 this.interfaces = rInterfaces;
252 public boolean isCacheable() {
259 * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredMethods()
261 public ResolvedMember[] getDeclaredMethods() {
262 if (methods == null) {
263 Method[] reflectMethods = this.myClass.getDeclaredMethods();
264 Constructor[] reflectCons = this.myClass.getDeclaredConstructors();
265 ResolvedMember[] rMethods = new ResolvedMember[reflectMethods.length + reflectCons.length];
266 for (int i = 0; i < reflectMethods.length; i++) {
267 rMethods[i] = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectMethods[i], world);
269 for (int i = 0; i < reflectCons.length; i++) {
270 rMethods[i + reflectMethods.length] = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(
271 reflectCons[i], world);
273 this.methods = rMethods;
281 * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredPointcuts()
283 public ResolvedMember[] getDeclaredPointcuts() {
284 return new ResolvedMember[0];
290 * @see org.aspectj.weaver.ReferenceTypeDelegate#getTypeVariables()
292 public TypeVariable[] getTypeVariables() {
293 // no type variables in Java 1.4
294 return new TypeVariable[0];
300 * @see org.aspectj.weaver.ReferenceTypeDelegate#getPerClause()
302 public PerClause getPerClause() {
307 public Collection<Declare> getDeclares() {
308 return Collections.emptySet();
311 public Collection<ConcreteTypeMunger> getTypeMungers() {
312 return Collections.emptySet();
318 * @see org.aspectj.weaver.ReferenceTypeDelegate#getPrivilegedAccesses()
320 public Collection getPrivilegedAccesses() {
321 // no aspect members..., not used for weaving
322 return Collections.EMPTY_SET;
328 * @see org.aspectj.weaver.ReferenceTypeDelegate#getModifiers()
330 public int getModifiers() {
331 return this.myClass.getModifiers();
337 * @see org.aspectj.weaver.ReferenceTypeDelegate#getSuperclass()
339 public ResolvedType getSuperclass() {
340 if (this.myClass.getSuperclass() == null) {
341 if (myClass == Object.class) {
344 return world.resolve(UnresolvedType.OBJECT);
346 return ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(this.myClass.getSuperclass(), world);
352 * @see org.aspectj.weaver.ReferenceTypeDelegate#getWeaverState()
354 public WeaverStateInfo getWeaverState() {
358 public ReferenceType getResolvedTypeX() {
359 return this.resolvedType;
362 public boolean doesNotExposeShadowMungers() {
366 public String getDeclaredGenericSignature() {
367 // no generic sig in 1.4
371 public ReflectionBasedResolvedMemberImpl createResolvedMemberFor(Member aMember) {
375 public String getSourcefilename() {
377 return resolvedType.getName() + ".class";
380 public ISourceContext getSourceContext() {
381 return SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
384 public boolean copySourceContext() {
388 public int getCompilerVersion() {
389 return WeaverVersionInfo.getCurrentWeaverMajorVersion();
392 public void ensureConsistent() {
396 public boolean isWeavable() {
400 public boolean hasBeenWoven() {