1 7 package org.jboss.aop.annotation; 8 9 import org.jboss.aop.annotation.ast.ASTAnnotation; 10 import org.jboss.aop.annotation.ast.ASTChar; 11 import org.jboss.aop.annotation.ast.ASTIdentifier; 12 import org.jboss.aop.annotation.ast.ASTMemberValueArrayInitializer; 13 import org.jboss.aop.annotation.ast.ASTMemberValuePair; 14 import org.jboss.aop.annotation.ast.ASTMemberValuePairs; 15 import org.jboss.aop.annotation.ast.ASTSingleMemberValue; 16 import org.jboss.aop.annotation.ast.ASTStart; 17 import org.jboss.aop.annotation.ast.ASTString; 18 import org.jboss.aop.annotation.ast.AnnotationParser; 19 import org.jboss.aop.annotation.ast.AnnotationParserVisitor; 20 import org.jboss.aop.annotation.ast.Node; 21 import org.jboss.aop.annotation.ast.SimpleNode; 22 23 import java.io.StringReader ; 24 import java.lang.reflect.Array ; 25 import java.lang.reflect.Field ; 26 import java.lang.reflect.InvocationTargetException ; 27 import java.lang.reflect.Method ; 28 import java.util.HashMap ; 29 30 36 public class AnnotationCreator implements AnnotationParserVisitor 37 { 38 private Class annotation; 39 private Class type; 40 public Object typeValue; 41 42 public AnnotationCreator(Class annotation, Class type) 43 { 44 this.type = type; 45 this.annotation = annotation; 46 } 47 48 49 public Object visit(ASTMemberValuePairs node, Object data) 50 { 51 node.childrenAccept(this, data); 52 return null; 53 } 54 55 public Object visit(ASTMemberValuePair node, Object data) 56 { 57 String name = node.getIdentifier().getValue(); 58 node.getValue().jjtAccept(this, name); 59 return data; 60 } 61 62 public Object visit(ASTSingleMemberValue node, Object data) 63 { 64 node.getValue().jjtAccept(this, "value"); 65 return data; 66 } 67 68 public Object visit(ASTIdentifier node, Object data) 69 { 70 try 71 { 72 if (type.equals(Class .class)) 73 { 74 String classname = node.getValue(); 75 if (classname.endsWith(".class")) 76 { 77 classname = classname.substring(0, classname.indexOf(".class")); 78 } 79 if (classname.equals("void")) 80 { 81 typeValue = void.class; 82 } 83 else if (classname.equals("int")) 84 { 85 typeValue = int.class; 86 } 87 else if (classname.equals("byte")) 88 { 89 typeValue = byte.class; 90 } 91 else if (classname.equals("long")) 92 { 93 typeValue = long.class; 94 } 95 else if (classname.equals("double")) 96 { 97 typeValue = double.class; 98 } 99 else if (classname.equals("float")) 100 { 101 typeValue = float.class; 102 } 103 else if (classname.equals("char")) 104 { 105 typeValue = char.class; 106 } 107 else if (classname.equals("short")) 108 { 109 typeValue = short.class; 110 } 111 else if (classname.equals("boolean")) 112 { 113 typeValue = boolean.class; 114 } 115 else 116 { 117 typeValue = Thread.currentThread().getContextClassLoader().loadClass(classname); 118 } 119 } 120 else if (type.isPrimitive()) 121 { 122 if (type.equals(boolean.class)) 123 { 124 typeValue = new Boolean (node.getValue()); 125 } 126 else if (type.equals(short.class)) 127 { 128 typeValue = Short.valueOf(node.getValue()); 129 } 130 else if (type.equals(float.class)) 131 { 132 typeValue = Float.valueOf(node.getValue()); 133 } 134 else if (type.equals(double.class)) 135 { 136 typeValue = Double.valueOf(node.getValue()); 137 } 138 else if (type.equals(long.class)) 139 { 140 typeValue = Long.valueOf(node.getValue()); 141 } 142 else if (type.equals(byte.class)) 143 { 144 typeValue = new Byte (node.getValue()); 145 } 146 else if (type.equals(int.class)) 147 { 148 typeValue = new Integer (node.getValue()); 149 } 150 } 151 else { 153 int index = node.getValue().lastIndexOf('.'); 154 if (index == -1) throw new RuntimeException ("Enum must be fully qualified: " + node.getValue()); 155 String className = node.getValue().substring(0, index); 156 String en = node.getValue().substring(index + 1); 157 Class enumClass = Thread.currentThread().getContextClassLoader().loadClass(className); 158 159 if (enumClass.getSuperclass().getName().equals("java.lang.Enum")) 160 { 161 Method valueOf = null; 162 Method [] methods = enumClass.getSuperclass().getMethods(); 163 for (int i = 0; i < methods.length; i++) 164 { 165 if (methods[i].getName().equals("valueOf")) 166 { 167 valueOf = methods[i]; 168 break; 169 } 170 } 171 Object [] args = {enumClass, en}; 172 typeValue = valueOf.invoke(null, args); 173 } 174 else 175 { 176 Field field = enumClass.getField(en); 177 typeValue = field.get(null); 178 } 179 } 180 } 181 catch (ClassNotFoundException e) 182 { 183 throw new RuntimeException (e); 184 } 185 catch (IllegalAccessException e) 186 { 187 throw new RuntimeException (e); 188 } 189 catch (InvocationTargetException e) 190 { 191 throw new RuntimeException (e); 192 } 193 catch (NoSuchFieldException e) 194 { 195 throw new RuntimeException (e); 196 } 197 return null; 198 } 199 200 public Object visit(ASTString node, Object data) 201 { 202 if (!type.equals(String .class)) throw new RuntimeException (annotation.getName() + "." + data + " is not an String"); 203 typeValue = node.getValue(); 204 return null; 205 } 206 207 public Object visit(ASTChar node, Object data) 208 { 209 if (!type.equals(char.class)) throw new RuntimeException (annotation.getName() + "." + data + " is not an char"); 210 typeValue = new Character (node.getValue()); 211 return null; 212 } 213 214 215 public Object visit(ASTMemberValueArrayInitializer node, Object data) 216 { 217 if (!type.isArray()) throw new RuntimeException (annotation.getName() + "." + data + " is not an array"); 218 Class baseType = type.getComponentType(); 219 int size = node.jjtGetNumChildren(); 220 typeValue = Array.newInstance(baseType, size); 221 222 for (int i = 0; i < size; i++) 223 { 224 AnnotationCreator creator = new AnnotationCreator(annotation, baseType); 225 node.jjtGetChild(i).jjtAccept(creator, null); 226 Array.set(typeValue, i, creator.typeValue); 227 } 228 return null; 229 } 230 231 public Object visit(ASTAnnotation node, Object data) 232 { 233 try 234 { 235 Class subAnnotation = Thread.currentThread().getContextClassLoader().loadClass(node.getIdentifier()); 236 typeValue = createAnnotation(node, subAnnotation); 237 } 238 catch (Exception e) 239 { 240 throw new RuntimeException (e); 241 } 242 return null; 243 } 244 245 247 public Object visit(SimpleNode node, Object data) 248 { 249 return null; 250 } 251 252 public Object visit(ASTStart node, Object data) 253 { 254 return null; 255 } 256 257 public static Object createAnnotation(ASTAnnotation node, Class annotation) throws Exception 258 { 259 HashMap map = new HashMap (); 260 Node contained = node.jjtGetChild(0); 261 if (contained instanceof ASTSingleMemberValue) 262 { 263 Class type = ProxyMapCreator.getMemberType(annotation, "value"); 264 AnnotationCreator creator = new AnnotationCreator(annotation, type); 265 contained.jjtAccept(creator, "value"); 266 map.put("value", creator.typeValue); 267 } 268 else 269 { 270 ASTMemberValuePairs pairs = (ASTMemberValuePairs) contained; 271 for (int i = 0; i < pairs.jjtGetNumChildren(); i++) 272 { 273 ASTMemberValuePair member = (ASTMemberValuePair) pairs.jjtGetChild(i); 274 Class type = ProxyMapCreator.getMemberType(annotation, member.getIdentifier().getValue()); 275 AnnotationCreator creator = new AnnotationCreator(annotation, type); 276 member.jjtAccept(creator, null); 277 map.put(member.getIdentifier().getValue(), creator.typeValue); 278 } 279 } 280 return AnnotationProxy.createProxy(map, annotation); 281 } 282 283 public static Object createAnnotation(String annotationExpr, Class annotation) throws Exception 284 { 285 AnnotationParser parser = new AnnotationParser(new StringReader (annotationExpr)); 286 org.jboss.aop.annotation.ast.ASTStart start = parser.Start(); 287 ASTAnnotation node = (ASTAnnotation) start.jjtGetChild(0); 288 return createAnnotation(node, annotation); 289 } 290 291 } 292 | Popular Tags |