/* *******************************************************************
* 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.Method;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.Var;
import org.aspectj.weaver.tools.MatchingContext;
/**
* @author colyer
*
*/
public class ReflectionShadow extends Shadow {
private final World world;
private final ResolvedType enclosingType;
private final ResolvedMember enclosingMember;
private final MatchingContext matchContext;
private Var thisVar = null;
private Var targetVar = null;
private Var[] argsVars = null;
private Var atThisVar = null;
private Var atTargetVar = null;
private Map atArgsVars = new HashMap();
private Map withinAnnotationVar = new HashMap();
private Map withinCodeAnnotationVar = new HashMap();
private Map annotationVar = new HashMap();
private AnnotationFinder annotationFinder;
public static Shadow makeExecutionShadow(World inWorld, java.lang.reflect.Member forMethod, MatchingContext withContext) {
Kind kind = (forMethod instanceof Method) ? Shadow.MethodExecution : Shadow.ConstructorExecution;
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forMethod, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
public static Shadow makeAdviceExecutionShadow(World inWorld, java.lang.reflect.Method forMethod, MatchingContext withContext) {
Kind kind = Shadow.AdviceExecution;
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedAdviceMember(forMethod, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, java.lang.reflect.Member withinCode, MatchingContext withContext) {
Shadow enclosingShadow = makeExecutionShadow(inWorld,withinCode,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(aMember, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(withinCode, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = aMember instanceof Method ? Shadow.MethodCall : Shadow.ConstructorCall;
return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, Class thisClass, MatchingContext withContext) {
Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, thisClass,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(aMember, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(thisClass, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = aMember instanceof Method ? Shadow.MethodCall : Shadow.ConstructorCall;
return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
public static Shadow makeStaticInitializationShadow(World inWorld, Class forType, MatchingContext withContext) {
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(forType, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.StaticInitialization;
return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
public static Shadow makePreInitializationShadow(World inWorld, Constructor forConstructor, MatchingContext withContext) {
Kind kind = Shadow.PreInitialization;
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forConstructor, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
public static Shadow makeInitializationShadow(World inWorld, Constructor forConstructor, MatchingContext withContext) {
Kind kind = Shadow.Initialization;
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forConstructor, inWorld);
ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null,withContext);
}
public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, Class withinType, MatchingContext withContext) {
Kind kind = Shadow.ExceptionHandler;
Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, withinType,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createHandlerMember(exceptionType, withinType, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(withinType, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, java.lang.reflect.Member withinCode, MatchingContext withContext) {
Kind kind = Shadow.ExceptionHandler;
Shadow enclosingShadow = makeExecutionShadow(inWorld, withinCode,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createHandlerMember(exceptionType, withinCode.getDeclaringClass(), inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(withinCode, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
public static Shadow makeFieldGetShadow(World inWorld, Field forField, Class callerType, MatchingContext withContext) {
Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(callerType, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.FieldGet;
return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
public static Shadow makeFieldGetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember, MatchingContext withContext) {
Shadow enclosingShadow = makeExecutionShadow(inWorld,inMember,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(inMember, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.FieldGet;
return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
public static Shadow makeFieldSetShadow(World inWorld, Field forField, Class callerType, MatchingContext withContext) {
Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType, withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(callerType, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.FieldSet;
return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
public static Shadow makeFieldSetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember, MatchingContext withContext) {
Shadow enclosingShadow = makeExecutionShadow(inWorld,inMember,withContext);
Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(inMember, inWorld);
ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
Kind kind = Shadow.FieldSet;
return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember,withContext);
}
public ReflectionShadow(World world, Kind kind, Member signature, Shadow enclosingShadow, ResolvedType enclosingType, ResolvedMember enclosingMember, MatchingContext withContext) {
super(kind,signature,enclosingShadow);
this.world = world;
this.enclosingType = enclosingType;
this.enclosingMember = enclosingMember;
this.matchContext = withContext;
if (world instanceof IReflectionWorld) {
this.annotationFinder = ((IReflectionWorld)world).getAnnotationFinder();
}
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getIWorld()
*/
public World getIWorld() {
return world;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getThisVar()
*/
public Var getThisVar() {
if (thisVar == null && hasThis()) {
thisVar = ReflectionVar.createThisVar(getThisType().resolve(world),this.annotationFinder);
}
return thisVar;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getTargetVar()
*/
public Var getTargetVar() {
if (targetVar == null && hasTarget()) {
targetVar = ReflectionVar.createTargetVar(getThisType().resolve(world),this.annotationFinder);
}
return targetVar;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getEnclosingType()
*/
public UnresolvedType getEnclosingType() {
return this.enclosingType;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getArgVar(int)
*/
public Var getArgVar(int i) {
if (argsVars == null) {
this.argsVars = new Var[this.getArgCount()];
for (int j = 0; j < this.argsVars.length; j++) {
this.argsVars[j] = ReflectionVar.createArgsVar(getArgType(j).resolve(world), j,this.annotationFinder);
}
}
if (i < argsVars.length) {
return argsVars[i];
} else {
return null;
}
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getThisJoinPointVar()
*/
public Var getThisJoinPointVar() {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getThisJoinPointStaticPartVar()
*/
public Var getThisJoinPointStaticPartVar() {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getThisEnclosingJoinPointStaticPartVar()
*/
public Var getThisEnclosingJoinPointStaticPartVar() {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getKindedAnnotationVar(org.aspectj.weaver.UnresolvedType)
*/
public Var getKindedAnnotationVar(UnresolvedType forAnnotationType) {
ResolvedType annType = forAnnotationType.resolve(world);
if (annotationVar.get(annType) == null) {
Var v = ReflectionVar.createAtAnnotationVar(annType,this.annotationFinder);
annotationVar.put(annType,v);
}
return (Var) annotationVar.get(annType);
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getWithinAnnotationVar(org.aspectj.weaver.UnresolvedType)
*/
public Var getWithinAnnotationVar(UnresolvedType forAnnotationType) {
ResolvedType annType = forAnnotationType.resolve(world);
if (withinAnnotationVar.get(annType) == null) {
Var v = ReflectionVar.createWithinAnnotationVar(annType,this.annotationFinder);
withinAnnotationVar.put(annType,v);
}
return (Var) withinAnnotationVar.get(annType);
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getWithinCodeAnnotationVar(org.aspectj.weaver.UnresolvedType)
*/
public Var getWithinCodeAnnotationVar(UnresolvedType forAnnotationType) {
ResolvedType annType = forAnnotationType.resolve(world);
if (withinCodeAnnotationVar.get(annType) == null) {
Var v = ReflectionVar.createWithinCodeAnnotationVar(annType,this.annotationFinder);
withinCodeAnnotationVar.put(annType,v);
}
return (Var) withinCodeAnnotationVar.get(annType);
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getThisAnnotationVar(org.aspectj.weaver.UnresolvedType)
*/
public Var getThisAnnotationVar(UnresolvedType forAnnotationType) {
if (atThisVar == null) {
atThisVar = ReflectionVar.createThisAnnotationVar(forAnnotationType.resolve(world),this.annotationFinder);
}
return atThisVar;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getTargetAnnotationVar(org.aspectj.weaver.UnresolvedType)
*/
public Var getTargetAnnotationVar(UnresolvedType forAnnotationType) {
if (atTargetVar == null) {
atTargetVar = ReflectionVar.createTargetAnnotationVar(forAnnotationType.resolve(world),this.annotationFinder);
}
return atTargetVar;
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getArgAnnotationVar(int, org.aspectj.weaver.UnresolvedType)
*/
public Var getArgAnnotationVar(int i, UnresolvedType forAnnotationType) {
ResolvedType annType = forAnnotationType.resolve(world);
if (atArgsVars.get(annType) == null) {
Var[] vars = new Var[getArgCount()];
atArgsVars.put(annType,vars);
}
Var[] vars = (Var[]) atArgsVars.get(annType);
if (i > (vars.length - 1) ) return null;
if (vars[i] == null) {
vars[i] = ReflectionVar.createArgsAnnotationVar(annType, i,this.annotationFinder);
}
return vars[i];
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getEnclosingCodeSignature()
*/
public Member getEnclosingCodeSignature() {
// XXX this code is copied from BcelShadow with one minor change...
if (getKind().isEnclosingKind()) {
return getSignature();
} else if (getKind() == Shadow.PreInitialization) {
// PreInit doesn't enclose code but its signature
// is correctly the signature of the ctor.
return getSignature();
} else if (enclosingShadow == null) {
return this.enclosingMember;
} else {
return enclosingShadow.getSignature();
}
}
/* (non-Javadoc)
* @see org.aspectj.weaver.Shadow#getSourceLocation()
*/
public ISourceLocation getSourceLocation() {
return null;
}
public MatchingContext getMatchingContext() {
return this.matchContext;
}
}