blob: 6110e6cebccbcf2e6045e4089fce6d1004776ee4 [file] [log] [blame]
/* *******************************************************************
* Copyright (c) 2005 Contributors.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
*
* Contributors:
* Adrian Colyer Initial implementation
* ******************************************************************/
package org.aspectj.weaver.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.Collections;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.AnnotationAJ;
import org.aspectj.weaver.AnnotationTargetKind;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ReferenceTypeDelegate;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.SourceContextImpl;
import org.aspectj.weaver.TypeVariable;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeakClassLoaderReference;
import org.aspectj.weaver.WeaverStateInfo;
import org.aspectj.weaver.World;
import org.aspectj.weaver.patterns.PerClause;
/**
* @author colyer A delegate for a resolved type that uses runtime type information (java.lang.reflect) to answer questions. This
* class uses only Java 1.4 features to answer questions. In a Java 1.5 environment use the
* Java5ReflectionBasedReferenceTypeDelegate subtype.
*/
public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelegate {
private static final ClassLoader bootClassLoader = new URLClassLoader(new URL[0]);// ReflectionBasedReferenceTypeDelegate.class.
// getClassLoader();
protected Class myClass = null;
protected WeakClassLoaderReference classLoaderReference = null;
protected World world;
private ReferenceType resolvedType;
private ResolvedMember[] fields = null;
private ResolvedMember[] methods = null;
private ResolvedType[] interfaces = null;
public ReflectionBasedReferenceTypeDelegate(Class forClass, ClassLoader aClassLoader, World inWorld, ReferenceType resolvedType) {
initialize(resolvedType, forClass, aClassLoader, inWorld);
}
/** for reflective construction only */
public ReflectionBasedReferenceTypeDelegate() {
}
public void initialize(ReferenceType aType, Class aClass, ClassLoader aClassLoader, World aWorld) {
this.myClass = aClass;
this.resolvedType = aType;
this.world = aWorld;
this.classLoaderReference = new WeakClassLoaderReference((aClassLoader != null) ? aClassLoader : bootClassLoader);
}
public Class<?> getClazz() {
return this.myClass;
}
protected Class getBaseClass() {
return this.myClass;
}
protected World getWorld() {
return this.world;
}
public ReferenceType buildGenericType() {
throw new UnsupportedOperationException("Shouldn't be asking for generic type at 1.4 source level or lower");
}
public boolean isAspect() {
// we could do better than this in Java 5 by looking at the annotations
// on the type...
return false;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationStyleAspect()
*/
public boolean isAnnotationStyleAspect() {
// we could do better than this in Java 5 by looking at the annotations
// on the type...
return false;
}
public boolean isInterface() {
return this.myClass.isInterface();
}
public boolean isEnum() {
// cant be an enum in Java 1.4 or prior
return false;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationWithRuntimeRetention ()
*/
public boolean isAnnotationWithRuntimeRetention() {
// cant be an annotation in Java 1.4 or prior
return false;
}
public boolean isAnnotation() {
// cant be an annotation in Java 1.4 or prior
return false;
}
public String getRetentionPolicy() {
// cant be an annotation in Java 1.4 or prior
return null;
}
public boolean canAnnotationTargetType() {
return false;
}
public AnnotationTargetKind[] getAnnotationTargetKinds() {
return null;
}
public boolean isClass() {
return !this.myClass.isInterface() && !this.myClass.isPrimitive() && !this.myClass.isArray();
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isGeneric()
*/
public boolean isGeneric() {
// cant be generic in 1.4
return false;
}
public boolean isAnonymous() {
// this isn't in < Java 1.5 but I think we are moving beyond the need to support those levels
return this.myClass.isAnonymousClass();
}
public boolean isNested() {
// this isn't in < Java 1.5 but I think we are moving beyond the need to support those levels
return this.myClass.isMemberClass();
}
public ResolvedType getOuterClass() {
// this isn't in < Java 1.5 but I think we are moving beyond the need to support those levels
return ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(
myClass.getEnclosingClass(),world);
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#isExposedToWeaver()
*/
public boolean isExposedToWeaver() {
// reflection based types are never exposed to the weaver
return false;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#hasAnnotation(org.aspectj.weaver .UnresolvedType)
*/
public boolean hasAnnotation(UnresolvedType ofType) {
// in Java 1.4 we cant have an annotation
return false;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getAnnotations()
*/
public AnnotationAJ[] getAnnotations() {
// no annotations in Java 1.4
return AnnotationAJ.EMPTY_ARRAY;
}
public boolean hasAnnotations() {
return false;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getAnnotationTypes()
*/
public ResolvedType[] getAnnotationTypes() {
// no annotations in Java 1.4
return new ResolvedType[0];
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredFields()
*/
public ResolvedMember[] getDeclaredFields() {
if (fields == null) {
Field[] reflectFields = this.myClass.getDeclaredFields();
ResolvedMember[] rFields = new ResolvedMember[reflectFields.length];
for (int i = 0; i < reflectFields.length; i++) {
rFields[i] = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectFields[i], world);
}
this.fields = rFields;
}
return fields;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredInterfaces()
*/
public ResolvedType[] getDeclaredInterfaces() {
if (interfaces == null) {
Class[] reflectInterfaces = this.myClass.getInterfaces();
ResolvedType[] rInterfaces = new ResolvedType[reflectInterfaces.length];
for (int i = 0; i < reflectInterfaces.length; i++) {
rInterfaces[i] = ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(reflectInterfaces[i], world);
}
this.interfaces = rInterfaces;
}
return interfaces;
}
public boolean isCacheable() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredMethods()
*/
public ResolvedMember[] getDeclaredMethods() {
if (methods == null) {
Method[] reflectMethods = this.myClass.getDeclaredMethods();
Constructor[] reflectCons = this.myClass.getDeclaredConstructors();
ResolvedMember[] rMethods = new ResolvedMember[reflectMethods.length + reflectCons.length];
for (int i = 0; i < reflectMethods.length; i++) {
rMethods[i] = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectMethods[i], world);
}
for (int i = 0; i < reflectCons.length; i++) {
rMethods[i + reflectMethods.length] = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(
reflectCons[i], world);
}
this.methods = rMethods;
}
return methods;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredPointcuts()
*/
public ResolvedMember[] getDeclaredPointcuts() {
return new ResolvedMember[0];
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getTypeVariables()
*/
public TypeVariable[] getTypeVariables() {
// no type variables in Java 1.4
return new TypeVariable[0];
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getPerClause()
*/
public PerClause getPerClause() {
// no per clause...
return null;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclares()
*/
public Collection getDeclares() {
// no declares
return Collections.EMPTY_SET;
}
/*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getTypeMungers()
*/
public Collection getTypeMungers() {
// no type mungers
return Collections.EMPTY_SET;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getPrivilegedAccesses()
*/
public Collection getPrivilegedAccesses() {
// no aspect members..., not used for weaving
return Collections.EMPTY_SET;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getModifiers()
*/
public int getModifiers() {
return this.myClass.getModifiers();
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getSuperclass()
*/
public ResolvedType getSuperclass() {
if (this.myClass.getSuperclass() == null) {
if (myClass == Object.class) {
return null;
}
return world.resolve(UnresolvedType.OBJECT);
}
return ReflectionBasedReferenceTypeDelegateFactory.resolveTypeInWorld(this.myClass.getSuperclass(), world);
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getWeaverState()
*/
public WeaverStateInfo getWeaverState() {
return null;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getResolvedTypeX()
*/
public ReferenceType getResolvedTypeX() {
return this.resolvedType;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#doesNotExposeShadowMungers()
*/
public boolean doesNotExposeShadowMungers() {
return false;
}
/*
* (non-Javadoc)
*
* @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredGenericSignature()
*/
public String getDeclaredGenericSignature() {
// no generic sig in 1.4
return null;
}
public ReflectionBasedResolvedMemberImpl createResolvedMemberFor(Member aMember) {
return null;
}
public String getSourcefilename() {
// crappy guess..
return resolvedType.getName() + ".class";
}
public ISourceContext getSourceContext() {
return SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
}
public boolean copySourceContext() {
return true;
}
public int getCompilerVersion() {
return WeaverVersionInfo.getCurrentWeaverMajorVersion();
}
public void ensureConsistent() {
}
public boolean isWeavable() {
return false;
}
public boolean hasBeenWoven() {
return false;
}
}