123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- /* *******************************************************************
- * 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.util.HashMap;
- import java.util.Map;
-
- import org.aspectj.bridge.AbortException;
- import org.aspectj.bridge.IMessage;
- import org.aspectj.bridge.IMessageHandler;
- import org.aspectj.util.LangUtil;
- import org.aspectj.weaver.BCException;
- import org.aspectj.weaver.IWeavingSupport;
- import org.aspectj.weaver.ReferenceType;
- import org.aspectj.weaver.ReferenceTypeDelegate;
- import org.aspectj.weaver.ResolvedType;
- import org.aspectj.weaver.UnresolvedType;
- import org.aspectj.weaver.WeakClassLoaderReference;
- import org.aspectj.weaver.World;
-
- /**
- * A ReflectionWorld is used solely for purposes of type resolution based on the runtime classpath (java.lang.reflect). It does not
- * support weaving operations (creation of mungers etc..).
- *
- */
- public class ReflectionWorld extends World implements IReflectionWorld {
-
- private WeakClassLoaderReference classLoaderReference;
- private AnnotationFinder annotationFinder;
- private boolean mustUseOneFourDelegates = false; // for testing
- private Map<String,Class<?>> inProgressResolutionClasses = new HashMap<String,Class<?>>();
-
- private ReflectionWorld() {
- // super();
- // this.setMessageHandler(new ExceptionBasedMessageHandler());
- // setBehaveInJava5Way(LangUtil.is15VMOrGreater());
- // this.classLoaderReference = new
- // WeakClassLoaderReference(ReflectionWorld.class.getClassLoader());
- // this.annotationFinder =
- // makeAnnotationFinderIfAny(classLoaderReference.getClassLoader(),
- // this);
- }
-
- public ReflectionWorld(ClassLoader aClassLoader) {
- super();
- this.setMessageHandler(new ExceptionBasedMessageHandler());
- setBehaveInJava5Way(LangUtil.is15VMOrGreater());
- classLoaderReference = new WeakClassLoaderReference(aClassLoader);
- annotationFinder = makeAnnotationFinderIfAny(classLoaderReference.getClassLoader(), this);
- }
-
- public ReflectionWorld(boolean forceUseOf14Delegates, ClassLoader aClassLoader) {
- this(aClassLoader);
- this.mustUseOneFourDelegates = forceUseOf14Delegates;
- if (forceUseOf14Delegates) {
- // Dont use 1.4 delegates and yet allow autoboxing
- this.setBehaveInJava5Way(false);
- }
- }
-
- public static AnnotationFinder makeAnnotationFinderIfAny(ClassLoader loader, World world) {
- AnnotationFinder annotationFinder = null;
- try {
- if (LangUtil.is15VMOrGreater()) {
- Class java15AnnotationFinder = Class.forName("org.aspectj.weaver.reflect.Java15AnnotationFinder");
- annotationFinder = (AnnotationFinder) java15AnnotationFinder.newInstance();
- annotationFinder.setClassLoader(loader);
- annotationFinder.setWorld(world);
- }
- } catch (ClassNotFoundException ex) {
- // must be on 1.4 or earlier
- } catch (IllegalAccessException ex) {
- // not so good
- throw new BCException("AspectJ internal error", ex);
- } catch (InstantiationException ex) {
- throw new BCException("AspectJ internal error", ex);
- }
- return annotationFinder;
- }
-
- public ClassLoader getClassLoader() {
- return classLoaderReference.getClassLoader();
- }
-
- public AnnotationFinder getAnnotationFinder() {
- return annotationFinder;
- }
-
- public ResolvedType resolve(Class aClass) {
- return resolve(this, aClass);
- }
-
- public static ResolvedType resolve(World world, Class aClass) {
- // 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 world.resolve(UnresolvedType.forSignature(className.replace('.', '/')));
- } else {
- return world.resolve(className);
- }
- }
-
- /**
- * Resolve a type using the specified class. Normal resolution in a reflection
- * world uses Class.forName() via the classloader (attached to this world)
- * in order to find a named type then builds a reference type and a reference
- * type delegate based on that. For some classes generated at runtime (e.g.
- * proxy or lambda representation) the forName() call will not work. In those
- * situations we should just use the clazz we have.
- *
- * Should the whole thing switch from using forName() to using the clazz objects?
- * Possibly but that introduces a lot of change and we don't have a lot
- * of test coverage for this scenario (reflection world). What we are doing
- * right now is that this can optionally be used if the regular resolution
- * scheme did not work.
- *
- * Although AspectJ is *not* multi threaded or re-entrant, Spring doesn't
- * always respect that. There might be an issue here if two attempts are
- * made to resolve the same thing at the same time via this method.
- *
- * @param clazz the class to use as the delegate for the resolved type
- */
- public ResolvedType resolveUsingClass(Class<?> clazz) {
- String signature = UnresolvedType.forName(clazz.getName()).getSignature();
- try {
- inProgressResolutionClasses.put(signature, clazz);
- return resolve(clazz.getName());
- } finally {
- inProgressResolutionClasses.remove(signature);
- }
- }
-
- protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) {
- ReferenceTypeDelegate result;
- if (mustUseOneFourDelegates) {
- result = ReflectionBasedReferenceTypeDelegateFactory.create14Delegate(ty, this, classLoaderReference.getClassLoader());
- } else {
- result = ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty, this, classLoaderReference.getClassLoader());
- }
- if (result == null && inProgressResolutionClasses.size() != 0) {
- // Is it a class that cannot be loaded (i.e. it was generated) but we already know about?
- Class<?> clazz = inProgressResolutionClasses.get(ty.getSignature());
- if (clazz != null) {
- result = ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty,this,clazz);
- }
- }
- return result;
- }
-
- public static class ReflectionWorldException extends RuntimeException {
-
- private static final long serialVersionUID = -3432261918302793005L;
-
- public ReflectionWorldException(String message) {
- super(message);
- }
- }
-
- private static class ExceptionBasedMessageHandler implements IMessageHandler {
-
- public boolean handleMessage(IMessage message) throws AbortException {
- throw new ReflectionWorldException(message.toString());
- }
-
- public boolean isIgnoring(org.aspectj.bridge.IMessage.Kind kind) {
- if (kind == IMessage.INFO) {
- return true;
- } else {
- return false;
- }
- }
-
- public void dontIgnore(org.aspectj.bridge.IMessage.Kind kind) {
- // empty
- }
-
- public void ignore(org.aspectj.bridge.IMessage.Kind kind) {
- // empty
- }
-
- }
-
- public IWeavingSupport getWeavingSupport() {
- return null;
- }
-
- public boolean isLoadtimeWeaving() {
- return true;
- }
-
- }
|