org.aspectj.weaver.patterns.BindingAnnotationFieldTypePattern Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjweaver Show documentation
Show all versions of aspectjweaver Show documentation
The AspectJ weaver introduces advices to java classes
/* *******************************************************************
* Copyright (c) 2008 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://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andy Clement initial implementation
* ******************************************************************/
package org.aspectj.weaver.patterns;
import java.io.IOException;
import java.util.Map;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.AnnotatedElement;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.CompressingDataOutputStream;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.IntMap;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.VersionedDataInputStream;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
/**
* Represents an attempt to bind the field of an annotation within a pointcut. For example:
*
* before(Level lev): execution(* *(..)) && @annotation(TraceAnnotation(lev))
*
* This binding annotation type pattern will be for 'lev'.
*/
public class BindingAnnotationFieldTypePattern extends ExactAnnotationTypePattern implements BindingPattern {
protected int formalIndex;
UnresolvedType formalType; // In this construct the formal type differs from the annotation type
public BindingAnnotationFieldTypePattern(UnresolvedType formalType, int formalIndex, UnresolvedType theAnnotationType) {
super(theAnnotationType, null);
this.formalIndex = formalIndex;
this.formalType = formalType;
}
public void resolveBinding(World world) {
if (resolved) {
return;
}
resolved = true;
formalType = world.resolve(formalType);
annotationType = world.resolve(annotationType);
ResolvedType annoType = (ResolvedType) annotationType;
if (!annoType.isAnnotation()) {
IMessage m = MessageUtil
.error(WeaverMessages.format(WeaverMessages.REFERENCE_TO_NON_ANNOTATION_TYPE, annoType.getName()),
getSourceLocation());
world.getMessageHandler().handleMessage(m);
resolved = false;
}
}
@Override
public AnnotationTypePattern parameterizeWith(Map typeVariableMap, World w) {
throw new BCException("Parameterization not implemented for annotation field binding construct (compiler limitation)");
// UnresolvedType newAnnotationType = annotationType;
// if (annotationType.isTypeVariableReference()) {
// TypeVariableReference t = (TypeVariableReference) annotationType;
// String key = t.getTypeVariable().getName();
// if (typeVariableMap.containsKey(key)) {
// newAnnotationType = (UnresolvedType) typeVariableMap.get(key);
// }
// } else if (annotationType.isParameterizedType()) {
// newAnnotationType = annotationType.parameterize(typeVariableMap);
// }
// BindingAnnotationTypePattern ret = new BindingAnnotationTypePattern(newAnnotationType, this.formalIndex);
// if (newAnnotationType instanceof ResolvedType) {
// ResolvedType rat = (ResolvedType) newAnnotationType;
// verifyRuntimeRetention(rat.getWorld(), rat);
// }
// ret.copyLocationFrom(this);
// return ret;
}
@Override
public int getFormalIndex() {
return formalIndex;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof BindingAnnotationFieldTypePattern)) {
return false;
}
BindingAnnotationFieldTypePattern btp = (BindingAnnotationFieldTypePattern) obj;
return (btp.formalIndex == formalIndex) && (annotationType.equals(btp.annotationType))
&& (formalType.equals(btp.formalType));
}
@Override
public int hashCode() {
return (annotationType.hashCode() * 37 + formalIndex * 37) + formalType.hashCode();
}
@Override
public AnnotationTypePattern remapAdviceFormals(IntMap bindings) {
if (!bindings.hasKey(formalIndex)) {
throw new BCException("Annotation field binding reference must be bound (compiler limitation)");
// must be something like returning the unbound form: return new ExactAnnotationTypePattern(annotationType,
// null);
} else {
int newFormalIndex = bindings.get(formalIndex);
BindingAnnotationFieldTypePattern baftp = new BindingAnnotationFieldTypePattern(formalType, newFormalIndex,
annotationType);
baftp.formalName = formalName;
return baftp;
}
}
@Override
public void write(CompressingDataOutputStream s) throws IOException {
s.writeByte(AnnotationTypePattern.BINDINGFIELD2);
formalType.write(s); // the type of the field within the annotation
s.writeShort((short) formalIndex);
annotationType.write(s); // the annotation type
s.writeUTF(formalName);
writeLocation(s);
}
public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
AnnotationTypePattern ret = new BindingAnnotationFieldTypePattern(UnresolvedType.read(s), s.readShort(),
UnresolvedType.read(s));
ret.readLocation(context, s);
return ret;
}
public static AnnotationTypePattern read2(VersionedDataInputStream s, ISourceContext context) throws IOException {
BindingAnnotationFieldTypePattern ret = new BindingAnnotationFieldTypePattern(UnresolvedType.read(s), s.readShort(),
UnresolvedType.read(s));
ret.formalName = s.readUTF();
ret.readLocation(context, s);
return ret;
}
@Override
public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations) {
// Inheritance irrelevant because @annotation(Anno(x)) only supported at method execution join points (compiler limitation)
// boolean checkSupers = false;
// if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
// if (annotated instanceof ResolvedType) {
// checkSupers = true;
// }
// }
//
if (annotated.hasAnnotation(annotationType)) {
if (annotationType instanceof ReferenceType) {
ReferenceType rt = (ReferenceType) annotationType;
if (rt.getRetentionPolicy() != null && rt.getRetentionPolicy().equals("SOURCE")) {
rt.getWorld()
.getMessageHandler()
.handleMessage(
MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,
annotationType, annotated), getSourceLocation()));
return FuzzyBoolean.NO;
}
ResolvedMember[] methods = rt.getDeclaredMethods();
boolean found = false;
for (int i = 0; i < methods.length && !found; i++) {
if (methods[i].getReturnType().equals(formalType)) {
found = true;
}
}
return (found ? FuzzyBoolean.YES : FuzzyBoolean.NO);
}
}
// else if (checkSupers) {
// ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass();
// while (toMatchAgainst != null) {
// if (toMatchAgainst.hasAnnotation(annotationType)) {
// return FuzzyBoolean.YES;
// }
// toMatchAgainst = toMatchAgainst.getSuperclass();
// }
// }
//
return FuzzyBoolean.NO;
}
public UnresolvedType getFormalType() {
return formalType;
}
}