FELIX-1010 : Fix problems in getting annotation values by using qdox.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@776226 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/Util.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/Util.java
index 11f7b1e..ddef1f5 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/Util.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/defaulttag/Util.java
@@ -18,13 +18,13 @@
  */
 package org.apache.felix.scrplugin.tags.annotation.defaulttag;
 
-import java.util.Collection;
 import java.util.List;
 
 import org.apache.felix.scrplugin.tags.*;
 import org.apache.maven.plugin.MojoExecutionException;
 
 import com.thoughtworks.qdox.model.Annotation;
+import com.thoughtworks.qdox.model.annotation.*;
 
 /**
  * Helper class for getting values from annotations.
@@ -78,21 +78,8 @@
      */
     public static String[] getStringValues(Annotation annotation, JavaClassDescription desc, String name)
     {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null ) {
-            if (obj instanceof String)
-            {
-                return new String[] {stripQuotes(desc, obj.toString())};
-            }
-            final List<String> list = (List<String>)obj;
-            String[] values = new String[list.size()];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = stripQuotes(desc, list.get(i));
-            }
-            return values;
-        }
-        return null;
+        final String[] sValues = getAnnotationValues(annotation, name, desc);
+        return sValues;
     }
 
     /**
@@ -104,20 +91,16 @@
      */
     public static long[] getLongValues(Annotation annotation, JavaClassDescription desc, String name)
     {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null )
+        final String[] sValues = getAnnotationValues(annotation, name, desc);
+        if ( sValues != null && sValues.length > 0 )
         {
-            if ( !(obj instanceof Collection<?>))
-            {
-                return new long[] {Long.valueOf(stripQuotes(desc, obj.toString()))};
-            }
-            final List<Long> list = (List<Long>)obj;
-            long[] values = new long[list.size()];
+            final long[] values = new long[sValues.length];
             for (int i=0; i<values.length; i++)
             {
-                values[i] = list.get(i);
+                values[i] = Long.valueOf(sValues[i]);
             }
             return values;
+
         }
         return null;
     }
@@ -131,20 +114,16 @@
      */
     public static int[] getIntValues(Annotation annotation, JavaClassDescription desc, String name)
     {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null )
+        final String[] sValues = getAnnotationValues(annotation, name, desc);
+        if ( sValues != null && sValues.length > 0 )
         {
-            if ( !(obj instanceof Collection<?>))
-            {
-                return new int[] {Integer.valueOf(stripQuotes(desc, obj.toString()))};
-            }
-            final List<Integer> list = (List<Integer>)obj;
-            int[] values = new int[list.size()];
+            final int[] values = new int[sValues.length];
             for (int i=0; i<values.length; i++)
             {
-                values[i] = list.get(i);
+                values[i] = Integer.valueOf(sValues[i]);
             }
             return values;
+
         }
         return null;
     }
@@ -158,20 +137,16 @@
      */
     public static float[] getFloatValues(Annotation annotation, JavaClassDescription desc, String name)
     {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null )
+        final String[] sValues = getAnnotationValues(annotation, name, desc);
+        if ( sValues != null && sValues.length > 0 )
         {
-            if ( !(obj instanceof Collection<?>))
-            {
-                return new float[] {Float.valueOf(stripQuotes(desc, obj.toString()))};
-            }
-            final List<Float> list = (List<Float>)obj;
-            float[] values = new float[list.size()];
+            final float[] values = new float[sValues.length];
             for (int i=0; i<values.length; i++)
             {
-                values[i] = list.get(i);
+                values[i] = Float.valueOf(sValues[i]);
             }
             return values;
+
         }
         return null;
     }
@@ -185,20 +160,16 @@
      */
     public static double[] getDoubleValues(Annotation annotation, JavaClassDescription desc, String name)
     {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null )
+        final String[] sValues = getAnnotationValues(annotation, name, desc);
+        if ( sValues != null && sValues.length > 0 )
         {
-            if ( !(obj instanceof Collection<?>))
-            {
-                return new double[] {Double.valueOf(stripQuotes(desc, obj.toString()))};
-            }
-            final List<Double> list = (List<Double>)obj;
-            double[] values = new double[list.size()];
+            final double[] values = new double[sValues.length];
             for (int i=0; i<values.length; i++)
             {
-                values[i] = list.get(i);
+                values[i] = Double.valueOf(sValues[i]);
             }
             return values;
+
         }
         return null;
     }
@@ -211,20 +182,16 @@
      * @return The array of char values or null.
      */
     public static char[] getCharValues(Annotation annotation, JavaClassDescription desc, String name) {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null )
+        final String[] sValues = getAnnotationValues(annotation, name, desc);
+        if ( sValues != null && sValues.length > 0 )
         {
-            if ( !(obj instanceof Collection<?>))
-            {
-                return new char[] {Character.valueOf(stripQuotes(desc, obj.toString()).charAt(0))};
-            }
-            final List<Character> list = (List<Character>)obj;
-            char[] values = new char[list.size()];
+            final char[] values = new char[sValues.length];
             for (int i=0; i<values.length; i++)
             {
-                values[i] = list.get(i);
+                values[i] = sValues[i].charAt(0);
             }
             return values;
+
         }
         return null;
     }
@@ -238,22 +205,18 @@
      */
    public static short[] getShortValues(Annotation annotation, JavaClassDescription desc, String name)
    {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null )
-        {
-            if ( !(obj instanceof Collection<?>))
-            {
-                return new short[] {Short.valueOf(stripQuotes(desc, obj.toString()))};
-            }
-            final List<Short> list = (List<Short>)obj;
-            short[] values = new short[list.size()];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = list.get(i);
-            }
-            return values;
-        }
-        return null;
+       final String[] sValues = getAnnotationValues(annotation, name, desc);
+       if ( sValues != null && sValues.length > 0 )
+       {
+           final short[] values = new short[sValues.length];
+           for (int i=0; i<values.length; i++)
+           {
+               values[i] = Short.valueOf(sValues[i]);
+           }
+           return values;
+
+       }
+       return null;
     }
 
     /**
@@ -265,22 +228,18 @@
      */
    public static byte[] getByteValues(Annotation annotation, JavaClassDescription desc, String name)
    {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null )
-        {
-            if ( !(obj instanceof Collection<?>))
-            {
-                return new byte[] {Byte.valueOf(stripQuotes(desc, obj.toString()))};
-            }
-            final List<Byte> list = (List<Byte>)obj;
-            byte[] values = new byte[list.size()];
-            for (int i=0; i<values.length; i++)
-            {
-                values[i] = list.get(i);
-            }
-            return values;
-        }
-        return null;
+       final String[] sValues = getAnnotationValues(annotation, name, desc);
+       if ( sValues != null && sValues.length > 0 )
+       {
+           final byte[] values = new byte[sValues.length];
+           for (int i=0; i<values.length; i++)
+           {
+               values[i] = Byte.valueOf(sValues[i]);
+           }
+           return values;
+
+       }
+       return null;
     }
 
     /**
@@ -292,32 +251,34 @@
      */
     public static boolean[] getBooleanValues(Annotation annotation, JavaClassDescription desc, String name)
     {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null )
+        final String[] sValues = getAnnotationValues(annotation, name, desc);
+        if ( sValues != null && sValues.length > 0 )
         {
-            if ( !(obj instanceof Collection<?>))
-            {
-                return new boolean[] {Boolean.valueOf(stripQuotes(desc, obj.toString()))};
-            }
-            final List<Boolean> list = (List<Boolean>)obj;
-            boolean[] values = new boolean[list.size()];
+            final boolean[] values = new boolean[sValues.length];
             for (int i=0; i<values.length; i++)
             {
-                values[i] = list.get(i);
+                values[i] = Boolean.valueOf(sValues[i]);
             }
             return values;
+
         }
         return null;
     }
 
+    /**
+     * Get a single annotation value
+     * @param annotation The annotation
+     * @param desc The class description
+     * @param name The name of the annotation
+     * @param clazz The class of the annotation
+     * @return The value
+     */
     public static String getStringValue(Annotation annotation, JavaClassDescription desc, String name, final Class<?> clazz) {
-        final Object obj = annotation.getNamedParameter(name);
-        if ( obj != null ) {
-            if ( obj instanceof String ) {
-                return stripQuotes(desc, (String)obj);
-            }
-            return obj.toString();
+        final String values[] = getAnnotationValues(annotation, name, desc);
+        if ( values != null && values.length > 0 ) {
+            return values[0];
         }
+        // try to get the default value
         try {
             return (String) clazz.getMethod(name).getDefaultValue();
         } catch( NoSuchMethodException mnfe) {
@@ -326,41 +287,6 @@
         }
     }
 
-    /**
-     * QDox annotations seem to return annotation values always with quotes - remove them.
-     * If the string value does not contain a string, it's a reference to a field!
-     * @param s String with our without quotes
-     * @return String without quotes
-     */
-    private static String stripQuotes(final JavaClassDescription desc, String s)
-    throws IllegalArgumentException {
-        try {
-            s = s.trim();
-            if (s.startsWith("\"") && s.endsWith("\"")) {
-                return s.substring(1, s.length() - 1);
-            }
-            int classSep = s.lastIndexOf('.');
-            JavaField field = null;
-            if ( classSep == -1 ) {
-                // local variable
-                field = desc.getFieldByName(s);
-            }
-            if ( field == null ) {
-                field = desc.getExternalFieldByName(s);
-            }
-            if ( field == null ) {
-                throw new IllegalArgumentException("Property references unknown field " + s + " in class " + desc.getName());
-            }
-            String[] values = field.getInitializationExpression();
-            if ( values != null && values.length == 1 ) {
-                return values[0];
-            }
-            throw new IllegalArgumentException("Something is wrong.");
-        } catch (MojoExecutionException mee) {
-            throw new IllegalArgumentException(mee);
-        }
-    }
-
     public static Class<?> getClassValue(Annotation annotation, String name, final Class<?> clazz) {
         final Object obj = annotation.getNamedParameter(name);
         if ( obj != null ) {
@@ -403,4 +329,62 @@
         return null;
     }
 
+    private static String getAnnotationValue(final AnnotationValue av, final JavaClassDescription desc)
+    throws IllegalArgumentException
+    {
+        if ( av instanceof AnnotationFieldRef )
+        {
+            // getField throws AIOOBE
+            // return ((AnnotationFieldRef)av).getField().getInitializationExpression();
+            final String s = av.getParameterValue().toString().trim();
+            try
+            {
+                int classSep = s.lastIndexOf('.');
+                JavaField field = null;
+                if ( classSep == -1 ) {
+                    // local variable
+                    field = desc.getFieldByName(s);
+                }
+                if ( field == null ) {
+                    field = desc.getExternalFieldByName(s);
+                }
+                if ( field == null ) {
+                    throw new IllegalArgumentException("Property references unknown field " + s + " in class " + desc.getName());
+                }
+                String[] values = field.getInitializationExpression();
+                if ( values != null && values.length == 1 ) {
+                    return values[0];
+                }
+                throw new IllegalArgumentException("Something is wrong.");
+            }
+            catch (MojoExecutionException mee)
+            {
+                throw new IllegalArgumentException(mee);
+            }
+        }
+        return ((AnnotationConstant)av).getValue().toString();
+    }
+
+    private static String[] getAnnotationValues(final Annotation annotation, final String name, final JavaClassDescription desc)
+    throws IllegalArgumentException
+    {
+        final AnnotationValue av = annotation.getProperty(name);
+        if ( av != null )
+        {
+            if ( av instanceof AnnotationValueList )
+            {
+                final AnnotationValueList avl = (AnnotationValueList)av;
+                @SuppressWarnings("unchecked")
+                final List<AnnotationValue> list = avl.getValueList();
+                final String[] values = new String[list.size()];
+                for(int i=0; i < values.length; i++)
+                {
+                    values[i] = getAnnotationValue(list.get(i), desc);
+                }
+                return values;
+            }
+            return new String[] {getAnnotationValue(av, desc)};
+        }
+        return null;
+    }
 }