diff options
author | aclement <aclement> | 2005-03-10 17:21:06 +0000 |
---|---|---|
committer | aclement <aclement> | 2005-03-10 17:21:06 +0000 |
commit | ca004fd36e4280bfb78b58c37fcb1b6dfcbdb223 (patch) | |
tree | 1340b6b1922b424d0bfe76e4dcd584effda4d34b /weaver | |
parent | 61d90580a82596c0a6f00ecd5d8b52af411ab18d (diff) | |
download | aspectj-ca004fd36e4280bfb78b58c37fcb1b6dfcbdb223.tar.gz aspectj-ca004fd36e4280bfb78b58c37fcb1b6dfcbdb223.zip |
Declare annotation: new infrastructure. AnnotationX is a holder for a real annotation (which is currently always a BCEL annotation) - annotationX's can flow outside of the bcel subpackages in the weaver.
Diffstat (limited to 'weaver')
-rw-r--r-- | weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java | 38 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/AnnotationX.java | 161 |
2 files changed, 199 insertions, 0 deletions
diff --git a/weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java b/weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java new file mode 100644 index 000000000..f12e98d63 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java @@ -0,0 +1,38 @@ +/* ******************************************************************* + * Copyright (c) 2005 IBM + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Represents adding an annotation to a type + */ +public class AnnotationOnTypeMunger extends ResolvedTypeMunger { + AnnotationX newAnnotation; + + public AnnotationOnTypeMunger(AnnotationX anno) { + super(AnnotationOnType,null); + newAnnotation = anno; + } + + public void write(DataOutputStream s) throws IOException { + throw new RuntimeException("unimplemented"); + } + + + public AnnotationX getNewAnnotation() { + return newAnnotation; + } +} diff --git a/weaver/src/org/aspectj/weaver/AnnotationX.java b/weaver/src/org/aspectj/weaver/AnnotationX.java new file mode 100644 index 000000000..e2e67e203 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/AnnotationX.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Andy Clement initial API and implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.aspectj.apache.bcel.classfile.annotation.Annotation; +import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; +import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; +import org.aspectj.apache.bcel.classfile.annotation.ElementValue; +import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue; + +/** + * An AnnotationX is the 'holder' for a BCEL annotation - we have this holder + * so that types about the bcel weaver package can work with something not + * BCEL specific. + */ +public class AnnotationX { + + private Annotation theRealAnnotation; + private ResolvedTypeX signature = null; + + // @target meta-annotation related stuff, built lazily + private boolean lookedForAtTargetAnnotation = false; + private AnnotationX atTargetAnnotation = null; + private Set supportedTargets = null; + + public AnnotationX(Annotation a,World world) { + theRealAnnotation = a; + signature = TypeX.forSignature(theRealAnnotation.getTypeSignature()).resolve(world); + } + + public Annotation getBcelAnnotation() { + return theRealAnnotation; + } + + public TypeX getSignature() { + return signature; + } + + public String toString() { + return theRealAnnotation.toString(); + } + + + public String getTypeName() { + return theRealAnnotation.getTypeName(); + } + + public String getTypeSignature() { + return theRealAnnotation.getTypeSignature(); + } + + + // @target related helpers + /** + * return true if this annotation can target an annotation type + */ + public boolean allowedOnAnnotationType() { + ensureAtTargetInitialized(); + if (atTargetAnnotation == null) return true; // if no target specified, then return true + return supportedTargets.contains("ANNOTATION_TYPE"); + } + + /** + * return true if this annotation is marked with @target() + */ + public boolean specifiesTarget() { + ensureAtTargetInitialized(); + return atTargetAnnotation!=null; + } + + /** + * return true if this annotation can target a 'regular' type. + * A 'regular' type is enum/class/interface - it is *not* annotation. + */ + public boolean allowedOnRegularType() { + ensureAtTargetInitialized(); + if (atTargetAnnotation == null) return true; // if no target specified, then return true + return supportedTargets.contains("TYPE"); + } + + /** + * Use in messages about this annotation + */ + public String stringify() { + return signature.getName(); + } + + public String getValidTargets() { + StringBuffer sb = new StringBuffer(); + sb.append("{"); + for (Iterator iter = supportedTargets.iterator(); iter.hasNext();) { + String evalue = (String) iter.next(); + sb.append(evalue); + if (iter.hasNext()) sb.append(","); + } + sb.append("}"); + return sb.toString(); + } + + + + // privates + + /** + * Helper method to retrieve an annotation on an annotation e.g. + * retrieveAnnotationOnAnnotation(TypeX.AT_TARGET) + */ + private AnnotationX retrieveAnnotationOnAnnotation(TypeX requiredAnnotationSignature) { + AnnotationX[] annos = signature.getAnnotations(); + for (int i = 0; i < annos.length; i++) { + AnnotationX annotationX = annos[i]; + if (annotationX.getSignature().equals(requiredAnnotationSignature)) return annos[i]; + } + return null; + } + + /** + * Makes sure we have looked for the @target() annotation on this annotation. + * Calling this method initializes (and caches) the information for later use. + */ + private void ensureAtTargetInitialized() { + if (!lookedForAtTargetAnnotation) { + lookedForAtTargetAnnotation = true; + atTargetAnnotation = retrieveAnnotationOnAnnotation(TypeX.AT_TARGET); + if (atTargetAnnotation != null) { + supportedTargets = new HashSet(); + List values = atTargetAnnotation.getBcelAnnotation().getValues(); + ElementNameValuePair envp = (ElementNameValuePair)values.get(0); + ArrayElementValue aev = (ArrayElementValue)envp.getValue(); + ElementValue[] evs = aev.getElementValuesArray(); + for (int i = 0; i < evs.length; i++) { + EnumElementValue ev = (EnumElementValue)evs[i]; + supportedTargets.add(ev.getEnumValueString()); + } + } + } + } + + /** + * @return true if this annotation can be put on a field + */ + public boolean allowedOnField() { + ensureAtTargetInitialized(); + if (atTargetAnnotation == null) return true; // if no target specified, then return true + return supportedTargets.contains("FIELD"); + } + +}
\ No newline at end of file |