/* */ package org.jboss.annotation.factory;
/* */
/* */ import java.io.StringReader;
/* */ import java.lang.reflect.Array;
/* */ import java.lang.reflect.Field;
/* */ import java.lang.reflect.InvocationTargetException;
/* */ import java.lang.reflect.Method;
/* */ import java.security.AccessController;
/* */ import java.security.PrivilegedActionException;
/* */ import java.security.PrivilegedExceptionAction;
/* */ import java.util.HashMap;
/* */ import org.jboss.annotation.factory.ast.ASTAnnotation;
/* */ import org.jboss.annotation.factory.ast.ASTChar;
/* */ import org.jboss.annotation.factory.ast.ASTIdentifier;
/* */ import org.jboss.annotation.factory.ast.ASTMemberValue;
/* */ import org.jboss.annotation.factory.ast.ASTMemberValueArrayInitializer;
/* */ import org.jboss.annotation.factory.ast.ASTMemberValuePair;
/* */ import org.jboss.annotation.factory.ast.ASTMemberValuePairs;
/* */ import org.jboss.annotation.factory.ast.ASTSingleMemberValue;
/* */ import org.jboss.annotation.factory.ast.ASTStart;
/* */ import org.jboss.annotation.factory.ast.ASTString;
/* */ import org.jboss.annotation.factory.ast.AnnotationParser;
/* */ import org.jboss.annotation.factory.ast.AnnotationParserVisitor;
/* */ import org.jboss.annotation.factory.ast.Node;
/* */ import org.jboss.annotation.factory.ast.ParseException;
/* */ import org.jboss.annotation.factory.ast.SimpleNode;
/* */ import org.jboss.annotation.factory.javassist.DefaultValueAnnotationValidator;
/* */
/* */ public class AnnotationCreator
/* */ implements AnnotationParserVisitor
/* */ {
/* */ private Class annotation;
/* */ private Class type;
/* */ public Object typeValue;
/* */ static final AnnotationValidator defaultAnnotationReader;
/* */
/* */ public AnnotationCreator(Class annotation, Class type)
/* */ {
/* 88 */ this.type = type;
/* 89 */ this.annotation = annotation;
/* */ }
/* */
/* */ public Object visit(ASTMemberValuePairs node, Object data)
/* */ {
/* 95 */ node.childrenAccept(this, data);
/* 96 */ return null;
/* */ }
/* */
/* */ public Object visit(ASTMemberValuePair node, Object data)
/* */ {
/* 101 */ String name = node.getIdentifier().getValue();
/* 102 */ node.getValue().jjtAccept(this, name);
/* 103 */ return data;
/* */ }
/* */
/* */ public Object visit(ASTSingleMemberValue node, Object data)
/* */ {
/* 108 */ node.getValue().jjtAccept(this, "value");
/* 109 */ return data;
/* */ }
/* */
/* */ public Object visit(ASTIdentifier node, Object data)
/* */ {
/* */ try
/* */ {
/* 116 */ if (this.type.equals(Class.class))
/* */ {
/* 118 */ String classname = node.getValue();
/* 119 */ if (classname.endsWith(".class"))
/* */ {
/* 121 */ classname = classname.substring(0, classname.indexOf(".class"));
/* */ }
/* 123 */ if (classname.equals("void"))
/* */ {
/* 125 */ this.typeValue = Void.TYPE;
/* */ }
/* 127 */ else if (classname.equals("int"))
/* */ {
/* 129 */ this.typeValue = Integer.TYPE;
/* */ }
/* 131 */ else if (classname.equals("byte"))
/* */ {
/* 133 */ this.typeValue = Byte.TYPE;
/* */ }
/* 135 */ else if (classname.equals("long"))
/* */ {
/* 137 */ this.typeValue = Long.TYPE;
/* */ }
/* 139 */ else if (classname.equals("double"))
/* */ {
/* 141 */ this.typeValue = Double.TYPE;
/* */ }
/* 143 */ else if (classname.equals("float"))
/* */ {
/* 145 */ this.typeValue = Float.TYPE;
/* */ }
/* 147 */ else if (classname.equals("char"))
/* */ {
/* 149 */ this.typeValue = Character.TYPE;
/* */ }
/* 151 */ else if (classname.equals("short"))
/* */ {
/* 153 */ this.typeValue = Short.TYPE;
/* */ }
/* 155 */ else if (classname.equals("boolean"))
/* */ {
/* 157 */ this.typeValue = Boolean.TYPE;
/* */ }
/* */ else
/* */ {
/* 161 */ this.typeValue = Thread.currentThread().getContextClassLoader().loadClass(classname);
/* */ }
/* */ }
/* 164 */ else if (this.type.isPrimitive())
/* */ {
/* 166 */ if (this.type.equals(Boolean.TYPE))
/* */ {
/* 168 */ this.typeValue = new Boolean(node.getValue());
/* */ }
/* 170 */ else if (this.type.equals(Short.TYPE))
/* */ {
/* 172 */ this.typeValue = Short.valueOf(node.getValue());
/* */ }
/* 174 */ else if (this.type.equals(Float.TYPE))
/* */ {
/* 176 */ this.typeValue = Float.valueOf(node.getValue());
/* */ }
/* 178 */ else if (this.type.equals(Double.TYPE))
/* */ {
/* 180 */ this.typeValue = Double.valueOf(node.getValue());
/* */ }
/* 182 */ else if (this.type.equals(Long.TYPE))
/* */ {
/* 184 */ this.typeValue = Long.valueOf(node.getValue());
/* */ }
/* 186 */ else if (this.type.equals(Byte.TYPE))
/* */ {
/* 188 */ this.typeValue = new Byte(node.getValue());
/* */ }
/* 190 */ else if (this.type.equals(Integer.TYPE))
/* */ {
/* 192 */ this.typeValue = new Integer(node.getValue());
/* */ }
/* */ }
/* */ else
/* */ {
/* 197 */ int index = node.getValue().lastIndexOf('.');
/* 198 */ if (index == -1) throw new RuntimeException("Enum must be fully qualified: " + node.getValue());
/* 199 */ String className = node.getValue().substring(0, index);
/* 200 */ String en = node.getValue().substring(index + 1);
/* 201 */ Class enumClass = Thread.currentThread().getContextClassLoader().loadClass(className);
/* */
/* 203 */ if (enumClass.getSuperclass().getName().equals("java.lang.Enum"))
/* */ {
/* 205 */ Method valueOf = null;
/* 206 */ Method[] methods = enumClass.getSuperclass().getMethods();
/* 207 */ for (int i = 0; i < methods.length; i++)
/* */ {
/* 209 */ if (!methods[i].getName().equals("valueOf"))
/* */ continue;
/* 211 */ valueOf = methods[i];
/* 212 */ break;
/* */ }
/* */
/* 215 */ Object[] args = { enumClass, en };
/* 216 */ this.typeValue = valueOf.invoke(null, args);
/* */ }
/* */ else
/* */ {
/* 220 */ Field field = enumClass.getField(en);
/* 221 */ this.typeValue = field.get(null);
/* */ }
/* */ }
/* */ }
/* */ catch (ClassNotFoundException e)
/* */ {
/* 227 */ throw new RuntimeException(e);
/* */ }
/* */ catch (IllegalAccessException e)
/* */ {
/* 231 */ throw new RuntimeException(e);
/* */ }
/* */ catch (InvocationTargetException e)
/* */ {
/* 235 */ throw new RuntimeException(e);
/* */ }
/* */ catch (NoSuchFieldException e)
/* */ {
/* 239 */ throw new RuntimeException(e);
/* */ }
/* 241 */ return null;
/* */ }
/* */
/* */ public Object visit(ASTString node, Object data)
/* */ {
/* 246 */ if (!this.type.equals(String.class)) throw new RuntimeException(this.annotation.getName() + "." + data + " is not an String");
/* 247 */ this.typeValue = node.getValue();
/* 248 */ return null;
/* */ }
/* */
/* */ public Object visit(ASTChar node, Object data)
/* */ {
/* 253 */ if (!this.type.equals(Character.TYPE)) throw new RuntimeException(this.annotation.getName() + "." + data + " is not an char");
/* 254 */ this.typeValue = new Character(node.getValue());
/* 255 */ return null;
/* */ }
/* */
/* */ public Object visit(ASTMemberValueArrayInitializer node, Object data)
/* */ {
/* 261 */ if (!this.type.isArray()) throw new RuntimeException(this.annotation.getName() + "." + data + " is not an array");
/* 262 */ Class baseType = this.type.getComponentType();
/* 263 */ int size = node.jjtGetNumChildren();
/* 264 */ this.typeValue = Array.newInstance(baseType, size);
/* */
/* 266 */ for (int i = 0; i < size; i++)
/* */ {
/* 268 */ AnnotationCreator creator = new AnnotationCreator(this.annotation, baseType);
/* 269 */ node.jjtGetChild(i).jjtAccept(creator, null);
/* 270 */ Array.set(this.typeValue, i, creator.typeValue);
/* */ }
/* 272 */ return null;
/* */ }
/* */
/* */ public Object visit(ASTAnnotation node, Object data)
/* */ {
/* */ try
/* */ {
/* 279 */ Class subAnnotation = Thread.currentThread().getContextClassLoader().loadClass(node.getIdentifier());
/* 280 */ this.typeValue = createAnnotation(node, subAnnotation);
/* */ }
/* */ catch (Exception e)
/* */ {
/* 284 */ throw new RuntimeException(e);
/* */ }
/* 286 */ return null;
/* */ }
/* */
/* */ public Object visit(SimpleNode node, Object data)
/* */ {
/* 293 */ return null;
/* */ }
/* */
/* */ public Object visit(ASTStart node, Object data)
/* */ {
/* 298 */ return null;
/* */ }
/* */
/* */ private static Class getMemberType(Class annotation, String member)
/* */ {
/* 303 */ Method[] methods = annotation.getMethods();
/* 304 */ for (int i = 0; i < methods.length; i++)
/* */ {
/* 306 */ if (methods[i].getName().equals(member))
/* */ {
/* 308 */ return methods[i].getReturnType();
/* */ }
/* */ }
/* 311 */ throw new RuntimeException("unable to determine member type for annotation: " + annotation.getName() + "." + member);
/* */ }
/* */
/* */ private static ASTAnnotation getRootExpr(String annotationExpr)
/* */ throws Exception
/* */ {
/* */ try
/* */ {
/* 319 */ return (ASTAnnotation)AccessController.doPrivileged(new PrivilegedExceptionAction(annotationExpr)
/* */ {
/* */ public ASTAnnotation run() throws Exception
/* */ {
/* 323 */ AnnotationParser parser = new AnnotationParser(new StringReader(this.val$annotationExpr));
/* 324 */ ASTStart start = parser.Start();
/* 325 */ return (ASTAnnotation)start.jjtGetChild(0);
/* */ } } );
/* */ }
/* */ catch (PrivilegedActionException e) {
/* */ }
/* 331 */ throw new RuntimeException("Error getting root expression", e.getException());
/* */ }
/* */
/* */ public static Object createAnnotation(ASTAnnotation node, Class annotation, ClassLoader cl)
/* */ throws Exception
/* */ {
/* 338 */ HashMap map = new HashMap();
/* 339 */ if (annotation == null)
/* */ {
/* 341 */ ClassLoader loader = cl != null ? cl : Thread.currentThread().getContextClassLoader();
/* 342 */ annotation = loader.loadClass(node.getIdentifier());
/* */ }
/* */
/* 345 */ if (node.jjtGetNumChildren() > 0)
/* */ {
/* 347 */ Node contained = node.jjtGetChild(0);
/* 348 */ if ((contained instanceof ASTSingleMemberValue))
/* */ {
/* 350 */ Class type = getMemberType(annotation, "value");
/* 351 */ AnnotationCreator creator = new AnnotationCreator(annotation, type);
/* 352 */ contained.jjtAccept(creator, "value");
/* 353 */ map.put("value", creator.typeValue);
/* */ }
/* */ else
/* */ {
/* 357 */ ASTMemberValuePairs pairs = (ASTMemberValuePairs)contained;
/* 358 */ for (int i = 0; i < pairs.jjtGetNumChildren(); i++)
/* */ {
/* 360 */ ASTMemberValuePair member = (ASTMemberValuePair)pairs.jjtGetChild(i);
/* 361 */ Class type = getMemberType(annotation, member.getIdentifier().getValue());
/* 362 */ AnnotationCreator creator = new AnnotationCreator(annotation, type);
/* 363 */ member.jjtAccept(creator, null);
/* 364 */ map.put(member.getIdentifier().getValue(), creator.typeValue);
/* */ }
/* */ }
/* */ }
/* */
/* 369 */ defaultAnnotationReader.validate(map, annotation);
/* 370 */ return AnnotationProxy.createProxy(map, annotation);
/* */ }
/* */
/* */ public static Object createAnnotation(ASTAnnotation node, Class annotation) throws Exception
/* */ {
/* 375 */ return createAnnotation(node, annotation, null);
/* */ }
/* */
/* */ public static Object createAnnotation(String annotationExpr, Class annotation) throws Exception
/* */ {
/* 380 */ return createAnnotation(getRootExpr(annotationExpr), annotation, null);
/* */ }
/* */
/* */ public static Object createAnnotation(String annotationExpr, ClassLoader cl) throws Exception
/* */ {
/* 385 */ return createAnnotation(getRootExpr(annotationExpr), null, cl);
/* */ }
/* */
/* */ static
/* */ {
/* 65 */ boolean haveJavassist = false;
/* */ try
/* */ {
/* 68 */ Class.forName("javassist.CtClass");
/* 69 */ haveJavassist = true;
/* */ }
/* */ catch (ClassNotFoundException ignore)
/* */ {
/* */ }
/* */
/* 75 */ if (haveJavassist)
/* */ {
/* 77 */ defaultAnnotationReader = new DefaultValueAnnotationValidator();
/* */ }
/* */ else
/* */ {
/* 81 */ defaultAnnotationReader = new SimpleAnnotationValidator();
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.annotation.factory.AnnotationCreator
* JD-Core Version: 0.6.0
*/