| /* ******************************************************************* |
| * 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.InvocationTargetException; |
| import java.lang.reflect.Member; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| |
| import org.aspectj.util.LangUtil; |
| import org.aspectj.weaver.ReferenceType; |
| import org.aspectj.weaver.ResolvedMember; |
| import org.aspectj.weaver.ResolvedMemberImpl; |
| import org.aspectj.weaver.ResolvedType; |
| import org.aspectj.weaver.UnresolvedType; |
| import org.aspectj.weaver.World; |
| |
| /** |
| * @author colyer Creates the appropriate ReflectionBasedReferenceTypeDelegate according to the VM level we are running at. Uses |
| * reflection to avoid 1.5 dependencies in 1.4 and 1.3 code base. |
| */ |
| public class ReflectionBasedReferenceTypeDelegateFactory { |
| |
| public static ReflectionBasedReferenceTypeDelegate createDelegate(ReferenceType forReferenceType, World inWorld, |
| ClassLoader usingClassLoader) { |
| try { |
| Class c = Class.forName(forReferenceType.getName(), false, usingClassLoader); |
| if (LangUtil.is15VMOrGreater()) { |
| ReflectionBasedReferenceTypeDelegate rbrtd = create15Delegate(forReferenceType, c, usingClassLoader, inWorld); |
| if (rbrtd != null) { |
| return rbrtd; // can be null if we didn't find the class the delegate logic loads |
| } |
| } |
| return new ReflectionBasedReferenceTypeDelegate(c, usingClassLoader, inWorld, forReferenceType); |
| } catch (ClassNotFoundException cnfEx) { |
| return null; |
| } |
| } |
| |
| public static ReflectionBasedReferenceTypeDelegate createDelegate(ReferenceType forReferenceType, World inWorld, |
| Class<?> clazz) { |
| if (LangUtil.is15VMOrGreater()) { |
| ReflectionBasedReferenceTypeDelegate rbrtd = create15Delegate(forReferenceType, clazz, clazz.getClassLoader(), inWorld); |
| if (rbrtd != null) { |
| return rbrtd; // can be null if we didn't find the class the delegate logic loads |
| } |
| } |
| return new ReflectionBasedReferenceTypeDelegate(clazz, clazz.getClassLoader(), inWorld, forReferenceType); |
| } |
| |
| public static ReflectionBasedReferenceTypeDelegate create14Delegate(ReferenceType forReferenceType, World inWorld, |
| ClassLoader usingClassLoader) { |
| try { |
| Class c = Class.forName(forReferenceType.getName(), false, usingClassLoader); |
| return new ReflectionBasedReferenceTypeDelegate(c, usingClassLoader, inWorld, forReferenceType); |
| } catch (ClassNotFoundException cnfEx) { |
| return null; |
| } |
| } |
| |
| // can return 'null' if we can't find the class |
| private static ReflectionBasedReferenceTypeDelegate create15Delegate(ReferenceType forReferenceType, Class forClass, |
| ClassLoader usingClassLoader, World inWorld) { |
| try { |
| Class delegateClass = Class.forName("org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate"); |
| ReflectionBasedReferenceTypeDelegate ret = (ReflectionBasedReferenceTypeDelegate) delegateClass.newInstance(); |
| ret.initialize(forReferenceType, forClass, usingClassLoader, inWorld); |
| return ret; |
| } catch (ClassNotFoundException cnfEx) { |
| throw new IllegalStateException( |
| "Attempted to create Java 1.5 reflection based delegate but org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate was not found on classpath"); |
| } catch (InstantiationException insEx) { |
| throw new IllegalStateException("Attempted to create Java 1.5 reflection based delegate but InstantiationException: " |
| + insEx + " occured"); |
| } catch (IllegalAccessException illAccEx) { |
| throw new IllegalStateException("Attempted to create Java 1.5 reflection based delegate but IllegalAccessException: " |
| + illAccEx + " occured"); |
| } |
| } |
| |
| private static GenericSignatureInformationProvider createGenericSignatureProvider(World inWorld) { |
| if (LangUtil.is15VMOrGreater()) { |
| try { |
| Class providerClass = Class.forName("org.aspectj.weaver.reflect.Java15GenericSignatureInformationProvider"); |
| Constructor cons = providerClass.getConstructor(new Class[] { World.class }); |
| GenericSignatureInformationProvider ret = (GenericSignatureInformationProvider) cons |
| .newInstance(new Object[] { inWorld }); |
| return ret; |
| } catch (ClassNotFoundException cnfEx) { |
| // drop through and create a 14 provider... |
| // throw new |
| // IllegalStateException("Attempted to create Java 1.5 generic signature provider but org.aspectj.weaver.reflect.Java15GenericSignatureInformationProvider was not found on classpath"); |
| } catch (NoSuchMethodException nsmEx) { |
| throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but: " + nsmEx |
| + " occured"); |
| } catch (InstantiationException insEx) { |
| throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but: " + insEx |
| + " occured"); |
| } catch (InvocationTargetException invEx) { |
| throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but: " + invEx |
| + " occured"); |
| } catch (IllegalAccessException illAcc) { |
| throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but: " + illAcc |
| + " occured"); |
| } |
| } |
| return new Java14GenericSignatureInformationProvider(); |
| } |
| |
| /** |
| * convert a java.lang.reflect.Member into a resolved member in the world |
| * |
| * @param reflectMember |
| * @param inWorld |
| * @return |
| */ |
| public static ResolvedMember createResolvedMember(Member reflectMember, World inWorld) { |
| if (reflectMember instanceof Method) { |
| return createResolvedMethod((Method) reflectMember, inWorld); |
| } else if (reflectMember instanceof Constructor) { |
| return createResolvedConstructor((Constructor) reflectMember, inWorld); |
| } else { |
| return createResolvedField((Field) reflectMember, inWorld); |
| } |
| } |
| |
| public static ResolvedMember createResolvedMethod(Method aMethod, World inWorld) { |
| ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, |
| toResolvedType(aMethod.getDeclaringClass(), (IReflectionWorld) inWorld), aMethod.getModifiers(), toResolvedType( |
| aMethod.getReturnType(), (IReflectionWorld) inWorld), aMethod.getName(), toResolvedTypeArray( |
| aMethod.getParameterTypes(), inWorld), toResolvedTypeArray(aMethod.getExceptionTypes(), inWorld), aMethod); |
| if (inWorld instanceof IReflectionWorld) { |
| ret.setAnnotationFinder(((IReflectionWorld) inWorld).getAnnotationFinder()); |
| } |
| ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); |
| return ret; |
| } |
| |
| public static ResolvedMember createResolvedAdviceMember(Method aMethod, World inWorld) { |
| ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.ADVICE, |
| toResolvedType(aMethod.getDeclaringClass(), (IReflectionWorld) inWorld), aMethod.getModifiers(), toResolvedType( |
| aMethod.getReturnType(), (IReflectionWorld) inWorld), aMethod.getName(), toResolvedTypeArray( |
| aMethod.getParameterTypes(), inWorld), toResolvedTypeArray(aMethod.getExceptionTypes(), inWorld), aMethod); |
| if (inWorld instanceof IReflectionWorld) { |
| ret.setAnnotationFinder(((IReflectionWorld) inWorld).getAnnotationFinder()); |
| } |
| ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); |
| return ret; |
| } |
| |
| public static ResolvedMember createStaticInitMember(Class forType, World inWorld) { |
| return new ResolvedMemberImpl(org.aspectj.weaver.Member.STATIC_INITIALIZATION, toResolvedType(forType, |
| (IReflectionWorld) inWorld), Modifier.STATIC, UnresolvedType.VOID, "<clinit>", new UnresolvedType[0], |
| new UnresolvedType[0]); |
| } |
| |
| public static ResolvedMember createResolvedConstructor(Constructor aConstructor, World inWorld) { |
| ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.CONSTRUCTOR, |
| toResolvedType(aConstructor.getDeclaringClass(), (IReflectionWorld) inWorld), aConstructor.getModifiers(), |
| // to return what BCEL returns, the return type for ctor is void |
| UnresolvedType.VOID,// toResolvedType(aConstructor.getDeclaringClass(),(IReflectionWorld)inWorld), |
| "<init>", toResolvedTypeArray(aConstructor.getParameterTypes(), inWorld), toResolvedTypeArray( |
| aConstructor.getExceptionTypes(), inWorld), aConstructor); |
| if (inWorld instanceof IReflectionWorld) { |
| ret.setAnnotationFinder(((IReflectionWorld) inWorld).getAnnotationFinder()); |
| } |
| ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); |
| return ret; |
| } |
| |
| public static ResolvedMember createResolvedField(Field aField, World inWorld) { |
| ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.FIELD, |
| toResolvedType(aField.getDeclaringClass(), (IReflectionWorld) inWorld), aField.getModifiers(), toResolvedType( |
| aField.getType(), (IReflectionWorld) inWorld), aField.getName(), new UnresolvedType[0], aField); |
| if (inWorld instanceof IReflectionWorld) { |
| ret.setAnnotationFinder(((IReflectionWorld) inWorld).getAnnotationFinder()); |
| } |
| ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); |
| return ret; |
| } |
| |
| public static ResolvedMember createHandlerMember(Class exceptionType, Class inType, World inWorld) { |
| return new ResolvedMemberImpl(org.aspectj.weaver.Member.HANDLER, toResolvedType(inType, (IReflectionWorld) inWorld), |
| Modifier.STATIC, "<catch>", "(" + inWorld.resolve(exceptionType.getName()).getSignature() + ")V"); |
| } |
| |
| public static ResolvedType resolveTypeInWorld(Class aClass, World aWorld) { |
| // classes that represent arrays return a class name that is the signature of the array type, ho-hum... |
| String className = aClass.getName(); |
| if (aClass.isArray()) { |
| return aWorld.resolve(UnresolvedType.forSignature(className.replace('.', '/'))); |
| } else { |
| return aWorld.resolve(className); |
| } |
| } |
| |
| private static ResolvedType toResolvedType(Class aClass, IReflectionWorld aWorld) { |
| return aWorld.resolve(aClass); |
| } |
| |
| private static ResolvedType[] toResolvedTypeArray(Class[] classes, World inWorld) { |
| ResolvedType[] ret = new ResolvedType[classes.length]; |
| for (int i = 0; i < ret.length; i++) { |
| ret[i] = ((IReflectionWorld) inWorld).resolve(classes[i]); |
| } |
| return ret; |
| } |
| } |