View Javadoc
Minimize
Table

1   /*
2    * Copyright 2003-2007 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.codehaus.groovy.ast;
17  
18  import java.util.HashMap;
19  import java.util.Map;
20  
21  import org.codehaus.groovy.ast.expr.Expression;
22  import org.codehaus.groovy.GroovyBugError;
23  
24  
25  /**
26   * Represents an annotation which can be attached to interfaces, classes, methods and fields.
27   * 
28   * @author <a href="mailto:jstrachan@protique.com">James Strachan</a>
29   * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
30   * @version $Revision: 16963 $
31   */
32  public class AnnotationNode extends ASTNode {
33      public static final int TYPE_TARGET = 1;
34      public static final int CONSTRUCTOR_TARGET = 1 << 1;
35      public static final int METHOD_TARGET = 1 << 2;
36      public static final int FIELD_TARGET = 1 << 3;
37      public static final int PARAMETER_TARGET =  1 << 4;
38      public static final int LOCAL_VARIABLE_TARGET = 1 << 5;
39      public static final int ANNOTATION_TARGET = 1 << 6;
40      public static final int PACKAGE_TARGET = 1 << 7;
41      private static final int ALL_TARGETS = TYPE_TARGET | CONSTRUCTOR_TARGET | METHOD_TARGET
42          | FIELD_TARGET | PARAMETER_TARGET | LOCAL_VARIABLE_TARGET | ANNOTATION_TARGET | PACKAGE_TARGET;
43      
44      private final ClassNode classNode;
45      private Map<String, Expression> members = new HashMap<String, Expression>();
46      private boolean runtimeRetention= false, sourceRetention= false, classRetention = false;
47      private int allowedTargets = ALL_TARGETS;
48  
49      public AnnotationNode(ClassNode classNode) {
50          this.classNode = classNode;
51      }
52  
53      public ClassNode getClassNode() {
54          return classNode;
55      }
56  
57      public Map<String, Expression> getMembers() {
58          return members;
59      }
60      
61      public Expression getMember(String name) {
62          return members.get(name);
63      }
64  
65      public void addMember(String name, Expression value) {
66          Expression oldValue = members.get(name);
67          if (oldValue == null) {
68              members.put(name, value);
69          }
70          else {
71              throw new GroovyBugError(String.format("Annotation member %s has already been added", name));
72          }
73      }
74  
75      public void setMember(String name, Expression value) {
76          members.put(name, value);
77      }
78      
79      public boolean isBuiltIn(){
80          return false;
81      }
82  
83      /**
84       * Flag corresponding to <code>RetentionPolicy</code>.
85       * @return <tt>true</tt> if the annotation should be visible at runtime, 
86       *      <tt>false</tt> otherwise
87       */
88      public boolean hasRuntimeRetention() {
89          return this.runtimeRetention;
90      }
91  
92      /**
93       * Sets the internal flag of this annotation runtime retention policy.
94       * If the current annotation has 
95       * <code>RetentionPolicy.RUNTIME</code> or if <tt>false</tt>
96       * if the <code>RetentionPolicy.CLASS</code>.
97       * @param flag if <tt>true</tt> then current annotation is marked as having
98       *     <code>RetentionPolicy.RUNTIME</code>. If <tt>false</tt> then
99       *     the annotation has <code>RetentionPolicy.CLASS</code>.
100      */
101     public void setRuntimeRetention(boolean flag) {
102         this.runtimeRetention = flag;
103     }
104     
105     /**
106      * Flag corresponding to <code>RetentionPolicy.SOURCE</code>.
107      * @return <tt>true</tt> if the annotation is only allowed in sources 
108      *      <tt>false</tt> otherwise
109      */
110     public boolean hasSourceRetention() {
111         if (!runtimeRetention && !classRetention) return true;
112         return this.sourceRetention;
113     }
114 
115     /** Sets the internal flag if the current annotation has 
116      * <code>RetentionPolicy.SOURCE</code>.
117      */ 
118     public void setSourceRetention(boolean flag) {
119         this.sourceRetention = flag;
120     }
121 
122     /**
123      * Flag corresponding to <code>RetentionPolicy.CLASS</code>.
124      * @return <tt>true</tt> if the annotation is recorded by the compiler,
125      *                       but not visible at runtime     *
126       *        <tt>false</tt> otherwise
127      */
128     public boolean hasClassRetention() {
129         return this.classRetention;
130     }
131 
132     /** Sets the internal flag if the current annotation has
133      * <code>RetentionPolicy.CLASS</code>.
134      */
135     public void setClassRetention(boolean flag) {
136         this.classRetention = flag;
137     }
138 
139     public void setAllowedTargets(int bitmap) {
140         this.allowedTargets = bitmap;
141     }
142     
143     public boolean isTargetAllowed(int target) {
144         return (this.allowedTargets & target) == target;
145     }
146     
147     public static String targetToName(int target) {
148         switch(target) {
149             case TYPE_TARGET:
150                 return "TYPE";
151             case CONSTRUCTOR_TARGET:
152                 return "CONSTRUCTOR";
153             case METHOD_TARGET:
154                 return "METHOD";
155             case FIELD_TARGET:
156                 return "FIELD";
157             case PARAMETER_TARGET:
158                 return "PARAMETER";
159             case LOCAL_VARIABLE_TARGET:
160                 return "LOCAL_VARIABLE";
161             case ANNOTATION_TARGET:
162                 return "ANNOTATION";
163             case PACKAGE_TARGET:
164                 return "PACKAGE";
165             default:
166                 return "unknown target";
167         }
168     }
169 }