]> source.dussan.org Git - aspectj.git/commitdiff
Declare annotation: new infrastructure. AnnotationX is a holder for a real annotatio...
authoraclement <aclement>
Thu, 10 Mar 2005 17:21:06 +0000 (17:21 +0000)
committeraclement <aclement>
Thu, 10 Mar 2005 17:21:06 +0000 (17:21 +0000)
weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/AnnotationX.java [new file with mode: 0644]

diff --git a/weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java b/weaver/src/org/aspectj/weaver/AnnotationOnTypeMunger.java
new file mode 100644 (file)
index 0000000..f12e98d
--- /dev/null
@@ -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 (file)
index 0000000..e2e67e2
--- /dev/null
@@ -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