[jboss-cvs] container/src/main/org/jboss/annotation/factory/javassist ...

Kabir Khan kkhan at jboss.com
Tue Jul 18 07:23:50 EDT 2006


  User: kkhan   
  Date: 06/07/18 07:23:50

  Added:       src/main/org/jboss/annotation/factory/javassist    
                        AnnotationProxy.java ProxyMapCreator.java
                        MemberValueGetter.java
                        DefaultValueAnnotationValidator.java
  Log:
  Move annotation creator into container from aop module
  
  Use jboss retro to create a JDK 1.4 dist and test under JDK 1,4.
  
  Revision  Changes    Path
  1.1      date: 2006/07/18 11:23:50;  author: kkhan;  state: Exp;container/src/main/org/jboss/annotation/factory/javassist/AnnotationProxy.java
  
  Index: AnnotationProxy.java
  ===================================================================
  /*
    * JBoss, Home of Professional Open Source
    * Copyright 2005, JBoss Inc., and individual contributors as indicated
    * by the @authors tag. See the copyright.txt in the distribution for a
    * full listing of individual contributors.
    *
    * This is free software; you can redistribute it and/or modify it
    * under the terms of the GNU Lesser General Public License as
    * published by the Free Software Foundation; either version 2.1 of
    * the License, or (at your option) any later version.
    *
    * This software is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    * Lesser General Public License for more details.
    *
    * You should have received a copy of the GNU Lesser General Public
    * License along with this software; if not, write to the Free
    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
    */
  package org.jboss.annotation.factory.javassist;
  
  import java.lang.reflect.InvocationHandler;
  import java.util.Map;
  
  /**
   * Comment
   *
   * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
   * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
   * @version $Revision: 1.1 $
   */
  public class AnnotationProxy extends org.jboss.annotation.factory.AnnotationProxy implements InvocationHandler
  {
     public AnnotationProxy(Class annotationType, Map valueMap)
     {
        super(annotationType, valueMap);
     }
  
     public static Object createProxy(javassist.bytecode.annotation.Annotation info) throws Exception
     {
        Class annotation = Thread.currentThread().getContextClassLoader().loadClass(info.getTypeName());
        return createProxy(info, annotation);
     }
  
     public static Object createProxy(javassist.bytecode.annotation.Annotation info, Class annotation) throws Exception
     {
        Map map = ProxyMapCreator.createProxyMap(annotation, info);
        DefaultValueAnnotationValidator reader = new DefaultValueAnnotationValidator();
        reader.validate(map, annotation);
        AnnotationProxy proxyHandler = new AnnotationProxy(annotation, map);
        return java.lang.reflect.Proxy.newProxyInstance(annotation.getClassLoader(), new Class[]{annotation}, proxyHandler);
     }
     
  }
  
  
  
  1.1      date: 2006/07/18 11:23:50;  author: kkhan;  state: Exp;container/src/main/org/jboss/annotation/factory/javassist/ProxyMapCreator.java
  
  Index: ProxyMapCreator.java
  ===================================================================
  /*
    * JBoss, Home of Professional Open Source
    * Copyright 2005, JBoss Inc., and individual contributors as indicated
    * by the @authors tag. See the copyright.txt in the distribution for a
    * full listing of individual contributors.
    *
    * This is free software; you can redistribute it and/or modify it
    * under the terms of the GNU Lesser General Public License as
    * published by the Free Software Foundation; either version 2.1 of
    * the License, or (at your option) any later version.
    *
    * This software is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    * Lesser General Public License for more details.
    *
    * You should have received a copy of the GNU Lesser General Public
    * License along with this software; if not, write to the Free
    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
    */
  package org.jboss.annotation.factory.javassist;
  
  import javassist.bytecode.annotation.AnnotationMemberValue;
  import javassist.bytecode.annotation.ArrayMemberValue;
  import javassist.bytecode.annotation.BooleanMemberValue;
  import javassist.bytecode.annotation.ByteMemberValue;
  import javassist.bytecode.annotation.CharMemberValue;
  import javassist.bytecode.annotation.ClassMemberValue;
  import javassist.bytecode.annotation.DoubleMemberValue;
  import javassist.bytecode.annotation.EnumMemberValue;
  import javassist.bytecode.annotation.FloatMemberValue;
  import javassist.bytecode.annotation.IntegerMemberValue;
  import javassist.bytecode.annotation.LongMemberValue;
  import javassist.bytecode.annotation.MemberValue;
  import javassist.bytecode.annotation.MemberValueVisitor;
  import javassist.bytecode.annotation.ShortMemberValue;
  import javassist.bytecode.annotation.StringMemberValue;
  
  import java.lang.reflect.Array;
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  
  /**
   * Comment
   *
   * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
   * @version $Revision: 1.1 $
   */
  public class ProxyMapCreator implements MemberValueVisitor
  {
     public Object value;
     private Class type;
  
  
     public ProxyMapCreator(Class type)
     {
        this.type = type;
     }
  
     public void visitAnnotationMemberValue(AnnotationMemberValue annotationMemberValue)
     {
        try
        {
           value = AnnotationProxy.createProxy(annotationMemberValue.getValue());
        }
        catch (Exception e)
        {
           throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
        }
     }
  
     public void visitArrayMemberValue(ArrayMemberValue arrayMemberValue)
     {
        Class baseType = type.getComponentType();
        int size = 0;
        if (arrayMemberValue.getValue() == null || arrayMemberValue.getValue().length == 0)
        {
           size = 0;
        }
        else
        {
           size = arrayMemberValue.getValue().length;
        }
        value = Array.newInstance(baseType, size);
        MemberValue[] elements = arrayMemberValue.getValue();
        for (int i = 0; i < size; i++)
        {
           ProxyMapCreator creator = new ProxyMapCreator(baseType);
           elements[i].accept(creator);
           Array.set(value, i, creator.value);
        }
     }
  
     public void visitBooleanMemberValue(BooleanMemberValue booleanMemberValue)
     {
        value = new Boolean(booleanMemberValue.getValue());
     }
  
     public void visitByteMemberValue(ByteMemberValue byteMemberValue)
     {
        value = new Byte(byteMemberValue.getValue());
     }
  
     public void visitCharMemberValue(CharMemberValue charMemberValue)
     {
        value = new Character(charMemberValue.getValue());
     }
  
     public void visitDoubleMemberValue(DoubleMemberValue doubleMemberValue)
     {
        value = new Double(doubleMemberValue.getValue());
     }
  
     public void visitEnumMemberValue(EnumMemberValue enumMemberValue)
     {
        try
        {
           Field enumVal = type.getField(enumMemberValue.getValue());
           value = enumVal.get(null);
        }
        catch (NoSuchFieldException e)
        {
           throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
        }
        catch (SecurityException e)
        {
           throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
        }
        catch (IllegalArgumentException e)
        {
           throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
        }
        catch (IllegalAccessException e)
        {
           throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
        }
     }
  
     public void visitFloatMemberValue(FloatMemberValue floatMemberValue)
     {
        value = new Float(floatMemberValue.getValue());
     }
  
     public void visitIntegerMemberValue(IntegerMemberValue integerMemberValue)
     {
        value = new Integer(integerMemberValue.getValue());
     }
  
     public void visitLongMemberValue(LongMemberValue longMemberValue)
     {
        value = new Long(longMemberValue.getValue());
     }
  
     public void visitShortMemberValue(ShortMemberValue shortMemberValue)
     {
        value = new Short(shortMemberValue.getValue());
     }
  
     public void visitStringMemberValue(StringMemberValue stringMemberValue)
     {
        value = stringMemberValue.getValue();
     }
  
     public void visitClassMemberValue(ClassMemberValue classMemberValue)
     {
        try
        {
           String classname = classMemberValue.getValue();
           if (classname.equals("void"))
           {
              value = void.class;
           }
           else if (classname.equals("int"))
           {
              value = int.class;
           }
           else if (classname.equals("byte"))
           {
              value = byte.class;
           }
           else if (classname.equals("long"))
           {
              value = long.class;
           }
           else if (classname.equals("double"))
           {
              value = double.class;
           }
           else if (classname.equals("float"))
           {
              value = float.class;
           }
           else if (classname.equals("char"))
           {
              value = char.class;
           }
           else if (classname.equals("short"))
           {
              value = short.class;
           }
           else if (classname.equals("boolean"))
           {
              value = boolean.class;
           }
           else
           {
              value = Thread.currentThread().getContextClassLoader().loadClass(classMemberValue.getValue());
           }
        }
        catch (ClassNotFoundException e)
        {
           throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
        }
  
     }
  
     public static Class getMemberType(Class annotation, String member)
     {
        Method[] methods = annotation.getMethods();
        for (int i = 0; i < methods.length; i++)
        {
           if (methods[i].getName().equals(member))
           {
              return methods[i].getReturnType();
           }
        }
        throw new RuntimeException("unable to determine member type for annotation: " + annotation.getName() + "." + member);
     }
  
     public static Map createProxyMap(Class annotation, javassist.bytecode.annotation.Annotation info)
     {
        //TODO: Need to handle default values for annotations in jdk 1.5
        Map map = new HashMap();
  
        if (info.getMemberNames() == null) return map;
        Set members = info.getMemberNames();
        Iterator it = members.iterator();
        while (it.hasNext())
        {
           String name = (String) it.next();
           MemberValue mv = info.getMemberValue(name);
           ProxyMapCreator creator = new ProxyMapCreator(getMemberType(annotation, name));
           mv.accept(creator);
           map.put(name, creator.value);
        }
        return map;
     }
  }
  
  
  
  1.1      date: 2006/07/18 11:23:50;  author: kkhan;  state: Exp;container/src/main/org/jboss/annotation/factory/javassist/MemberValueGetter.java
  
  Index: MemberValueGetter.java
  ===================================================================
  /*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, JBoss Inc., and individual contributors as indicated
  * by the @authors tag. See the copyright.txt in the distribution for a
  * full listing of individual contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */ 
  package org.jboss.annotation.factory.javassist;
  
  import java.lang.reflect.Array;
  import java.lang.reflect.Method;
  
  import org.jboss.reflect.plugins.introspection.IntrospectionTypeInfoFactoryImpl;
  
  import javassist.bytecode.annotation.Annotation;
  import javassist.bytecode.annotation.AnnotationMemberValue;
  import javassist.bytecode.annotation.ArrayMemberValue;
  import javassist.bytecode.annotation.BooleanMemberValue;
  import javassist.bytecode.annotation.ByteMemberValue;
  import javassist.bytecode.annotation.CharMemberValue;
  import javassist.bytecode.annotation.ClassMemberValue;
  import javassist.bytecode.annotation.DoubleMemberValue;
  import javassist.bytecode.annotation.EnumMemberValue;
  import javassist.bytecode.annotation.FloatMemberValue;
  import javassist.bytecode.annotation.IntegerMemberValue;
  import javassist.bytecode.annotation.LongMemberValue;
  import javassist.bytecode.annotation.MemberValue;
  import javassist.bytecode.annotation.MemberValueVisitor;
  import javassist.bytecode.annotation.ShortMemberValue;
  import javassist.bytecode.annotation.StringMemberValue;
  
  /**
   * 
   * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
   * @version $Revision: 1.1 $
   */
  public class MemberValueGetter implements MemberValueVisitor
  {
     Object value;
     Method method;
     static IntrospectionTypeInfoFactoryImpl typeFactory = new IntrospectionTypeInfoFactoryImpl();
  
     public MemberValueGetter(Method method)
     {
        this.method = method;
     }
     
     public Object getValue()
     {
        return value;
     }
     
     public void visitAnnotationMemberValue(AnnotationMemberValue node)
     {
        try
        {
           Annotation ann = node.getValue();
           value = AnnotationProxy.createProxy(ann);
        }
        catch (Exception e)
        {
           throw new RuntimeException(e);
        }
     }
  
     public void visitArrayMemberValue(ArrayMemberValue node)
     {
        MemberValue[] values = node.getValue();
        value = node.getValue();
        Object vals = Array.newInstance(getAttributeType(), values.length);
        
        for (int i = 0 ; i < values.length ; i++)
        {
           values[i].accept(this);
           Array.set(vals, i, value);
        }
  
        value = vals;
     }
  
     public void visitBooleanMemberValue(BooleanMemberValue node)
     {
        value = new Boolean(node.getValue());
     }
  
     public void visitByteMemberValue(ByteMemberValue node)
     {
        value = new Byte(node.getValue());
     }
  
     public void visitCharMemberValue(CharMemberValue node)
     {
        value = new Character(node.getValue());
     }
  
     public void visitDoubleMemberValue(DoubleMemberValue node)
     {
        value = new Double(node.getValue());
     }
  
     public void visitEnumMemberValue(EnumMemberValue node)
     {
        value = Enum.valueOf(getAttributeType(), node.getValue());
     }
  
     public void visitFloatMemberValue(FloatMemberValue node)
     {
        value = new Float(node.getValue());
     }
  
     public void visitIntegerMemberValue(IntegerMemberValue node)
     {
        value = new Integer(node.getValue());
     }
  
     public void visitLongMemberValue(LongMemberValue node)
     {
        value = new Long(node.getValue());
     }
  
     public void visitShortMemberValue(ShortMemberValue node)
     {
        value = new Short(node.getValue());
     }
  
     public void visitStringMemberValue(StringMemberValue node)
     {
        value = node.getValue();
     }
  
     public void visitClassMemberValue(ClassMemberValue node)
     {
        try
        {
           value = Class.forName(node.getValue());
        }
        catch (ClassNotFoundException e)
        {
           throw new RuntimeException(e);
        }
     }
  
     private Class getAttributeType()
     {
        Class rtn = method.getReturnType();
        
        while (rtn.isArray())
        {
           rtn = rtn.getComponentType();         
        }
        
        return rtn;
     }
     
  }
  
  
  
  1.1      date: 2006/07/18 11:23:50;  author: kkhan;  state: Exp;container/src/main/org/jboss/annotation/factory/javassist/DefaultValueAnnotationValidator.java
  
  Index: DefaultValueAnnotationValidator.java
  ===================================================================
  /*
  * JBoss, Home of Professional Open Source
  * Copyright 2005, JBoss Inc., and individual contributors as indicated
  * by the @authors tag. See the copyright.txt in the distribution for a
  * full listing of individual contributors.
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as
  * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */ 
  package org.jboss.annotation.factory.javassist;
  
  import java.lang.reflect.Method;
  import java.security.AccessController;
  import java.security.PrivilegedAction;
  import java.util.ArrayList;
  import java.util.Map;
  
  import org.jboss.annotation.factory.AnnotationValidationException;
  import org.jboss.annotation.factory.AnnotationValidator;
  
  import javassist.ClassPool;
  import javassist.CtClass;
  import javassist.CtMethod;
  import javassist.NotFoundException;
  import javassist.bytecode.AnnotationDefaultAttribute;
  import javassist.bytecode.MethodInfo;
  import javassist.bytecode.annotation.MemberValue;
  import javassist.scopedpool.ScopedClassPoolRepository;
  import javassist.scopedpool.ScopedClassPoolRepositoryImpl;
  
  /**
   * Validates if all attributes have been filled in for an annotation. 
   * Attempts to read default values where they exist
   *
   * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
   * @version $Revision: 1.1 $
   */
  public class DefaultValueAnnotationValidator implements AnnotationValidator
  {
     ScopedClassPoolRepository repository = ScopedClassPoolRepositoryImpl.getInstance();
     
     public void validate(Map map, Class annotation)
     {
        ArrayList notAssignedAttributes = null;
        CtClass ctClass = null;
        
        Method[] methods = getDeclaredMethods(annotation);
        for (int i = 0 ; i < methods.length ; i++)
        {
           if (map.get(methods[i].getName()) == null)
           {
              if (ctClass == null)
              {
                 ctClass = getCtClass(annotation);
              }
              
              CtMethod method;
              try
              {
                 method = ctClass.getDeclaredMethod(methods[i].getName());
              }
              catch (NotFoundException e)
              {
                 throw new RuntimeException("Unable to find method " + methods[i].getName() + " for " + annotation.getName());
              }
              Object defaultValue = null;
              MethodInfo minfo = method.getMethodInfo2();
              AnnotationDefaultAttribute defAttr = (AnnotationDefaultAttribute)minfo.getAttribute(AnnotationDefaultAttribute.tag);
              
              if (defAttr != null)
              {
                 MemberValue value = defAttr.getDefaultValue();    // default value of age
                 MemberValueGetter getter = new MemberValueGetter(methods[i]);
                 value.accept(getter);
                 defaultValue = getter.getValue();
              }
              
              if (defaultValue != null)
              {
                 map.put(methods[i].getName(), defaultValue);
              }
              else
              {
                 if (notAssignedAttributes == null)
                 {
                    notAssignedAttributes = new ArrayList();
                 }
                 notAssignedAttributes.add(methods[i].getName());
              }
  
           }
        }
  
        if (notAssignedAttributes != null)
        {
           throw new AnnotationValidationException("Unable to fill in default attributes for " + annotation + " " + notAssignedAttributes);
        }
     }
     
     
     CtClass getCtClass(Class clazz)
     {
        try
        {
           ClassPool pool = repository.findClassPool(clazz.getClassLoader());
           return pool.get(clazz.getName());
        }
        catch (NotFoundException e)
        {
           throw new RuntimeException("Unable to load CtClass for " + clazz, e);
        }
     }
  
     private Method[] getDeclaredMethods(final Class clazz)
     {
        return (Method[])AccessController.doPrivileged(new PrivilegedAction() {
           public Object run() 
           {
              return clazz.getDeclaredMethods();
           };  
        });
     }
  }
  
  
  
  



More information about the jboss-cvs-commits mailing list