Initial support for property value definition through arrays.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@618233 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/PropertyHandler.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/PropertyHandler.java
index 80d11fe..88b92a1 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/PropertyHandler.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/PropertyHandler.java
@@ -24,7 +24,8 @@
 import org.apache.felix.scrplugin.om.Property;
 import org.apache.felix.scrplugin.om.metatype.AttributeDefinition;
 import org.apache.felix.scrplugin.om.metatype.OCD;
-import org.apache.felix.scrplugin.tags.*;
+import org.apache.felix.scrplugin.tags.JavaField;
+import org.apache.felix.scrplugin.tags.JavaTag;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.codehaus.plexus.util.StringUtils;
 import org.osgi.service.cm.ConfigurationAdmin;
@@ -40,7 +41,7 @@
      * @param component
      * @param ocd
      */
-    public void doProperty(JavaTag property, String name, Component component, OCD ocd)
+    public void doProperty(JavaTag property, String name, Component component, OCD ocd, JavaField javaField)
     throws MojoExecutionException {
         final Property prop = new Property(property);
         prop.setName(name);
@@ -53,7 +54,7 @@
             // now we check for a value ref attribute
             final String valueRef = property.getNamedParameter(Constants.PROPERTY_VALUE_REF);
             if ( valueRef != null ) {
-                prop.setValue(this.getPropertyValueRef(property.getJavaClassDescription(), prop, valueRef));
+                this.setPropertyValueRef(property, prop, valueRef);
             } else {
                 // check for multivalue - these can either be values or value refs
                 final List values = new ArrayList();
@@ -64,11 +65,22 @@
                     if (key.startsWith(Constants.PROPERTY_MULTIVALUE_PREFIX) ) {
                         values.add(entry.getValue());
                     } else if ( key.startsWith(Constants.PROPERTY_MULTIVALUE_REF_PREFIX) ) {
-                        values.add(this.getPropertyValueRef(property.getJavaClassDescription(), prop, (String)entry.getValue()));
+                        final String[] stringValues = this.getPropertyValueRef(property, prop, (String)entry.getValue());
+                        if ( stringValues != null ) {
+                            for(int i=0; i<stringValues.length; i++) {
+                                values.add(stringValues[i]);
+                            }
+                        }
                     }
                 }
                 if ( values.size() > 0 ) {
                     prop.setMultiValue((String[])values.toArray(new String[values.size()]));
+                } else {
+                    // we have no value, valueRef or values so let's try to
+                    // get the value of the field if a name attribute is specified
+                    if ( property.getNamedParameter(Constants.PROPERTY_NAME) != null && javaField != null ) {
+                        this.setPropertyValueRef(property, prop, javaField.getName());
+                    }
                 }
             }
         }
@@ -159,14 +171,25 @@
         return defaultName;
     }
 
-    public String getPropertyValueRef(JavaClassDescription desc, Property prop, String valueRef)
+    public void setPropertyValueRef(final JavaTag tag, Property property, String valueRef)
+    throws MojoExecutionException {
+        final String[] values = this.getPropertyValueRef(tag, property, valueRef);
+        if ( values != null && values.length == 1 ) {
+            property.setValue(values[0]);
+        } else if ( values != null && values.length > 1 ) {
+            property.setMultiValue(values);
+        }
+    }
+
+    public String[] getPropertyValueRef(final JavaTag tag, Property prop, String valueRef)
     throws MojoExecutionException {
         int classSep = valueRef.lastIndexOf('.');
         if ( classSep == -1 ) {
             // local variable
-            final JavaField field = desc.getFieldByName(valueRef);
+            // TODO - This could be a static import!
+            final JavaField field = tag.getJavaClassDescription().getFieldByName(valueRef);
             if ( field == null ) {
-                throw new MojoExecutionException("Property references unknown field " + valueRef + " in class " + desc.getName());
+                throw new MojoExecutionException("Property references unknown field " + valueRef + " in class " + tag.getJavaClassDescription().getName());
             }
             // determine type (if not set explicitly)
             if ( prop.getType() == null ) {
@@ -197,7 +220,7 @@
         throw new MojoExecutionException("Referencing values from foreign classes not supported yet.");
     }
 
-    public void testProperty(Map properties, JavaTag property, String defaultName, boolean isInspectedClass)
+    public void testProperty(Map properties, JavaTag property, String defaultName, JavaField field, boolean isInspectedClass)
     throws MojoExecutionException {
         final String propName = this.getPropertyName(property, defaultName);
 
@@ -209,7 +232,7 @@
                     throw new MojoExecutionException("Duplicate definition for property " + propName + " in class " + property.getJavaClassDescription().getName());
                 }
             } else {
-                properties.put(propName, property);
+                properties.put(propName, new Object[] {property, field});
             }
         }
     }
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorMojo.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorMojo.java
index 0f1022c..ad39889 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorMojo.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorMojo.java
@@ -233,7 +233,7 @@
             // properties
             final JavaTag[] props = currentDescription.getTagsByName(Constants.PROPERTY, false);
             for (int i=0; i < props.length; i++) {
-                this.propertyHandler.testProperty(properties, props[i], null, description == currentDescription);
+                this.propertyHandler.testProperty(properties, props[i], null, null, description == currentDescription);
             }
 
             // references
@@ -254,9 +254,12 @@
                 if (tag != null) {
                     String defaultName = null;
                     if ( "java.lang.String".equals(fields[i].getType()) ) {
-                        defaultName = fields[i].getInitializationExpression();
+                        final String[] initValues = fields[i].getInitializationExpression();
+                        if ( initValues != null && initValues.length == 1 ) {
+                            defaultName = initValues[0];
+                        }
                     }
-                    this.propertyHandler.testProperty(properties, tag, defaultName, description == currentDescription);
+                    this.propertyHandler.testProperty(properties, tag, defaultName, fields[i], description == currentDescription);
                 }
             }
 
@@ -268,8 +271,9 @@
         while ( propIter.hasNext() ) {
             final Map.Entry entry = (Map.Entry)propIter.next();
             final String propName = entry.getKey().toString();
-            final JavaTag tag = (JavaTag)entry.getValue();
-            this.propertyHandler.doProperty(tag, propName, component, ocd);
+            final Object[] values = (Object[])entry.getValue();
+            final JavaTag tag = (JavaTag)values[0];
+            this.propertyHandler.doProperty(tag, propName, component, ocd, (JavaField)values[1]);
         }
 
         // process references
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/ClassUtil.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/ClassUtil.java
new file mode 100644
index 0000000..496c00f
--- /dev/null
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/ClassUtil.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scrplugin.tags;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+
+/**
+ * Utility class.
+ */
+public class ClassUtil {
+
+    /**
+     * Try to get the initial value of a static field
+     * @param clazz     The class.
+     * @param fieldName The name of the field.
+     * @return The initial value or null.
+     */
+    public static String[] getInitializationExpression(Class clazz, String fieldName) {
+        try {
+            final Field field = clazz.getDeclaredField(fieldName);
+            field.setAccessible(true);
+            final Object value = field.get(null);
+            if ( value != null ) {
+                if ( value.getClass().isArray() ) {
+                    final String[] values = new String[Array.getLength(value)];
+                    for(int i=0; i<values.length; i++) {
+                        values[i] = Array.get(value, i).toString();
+                    }
+                    return values;
+                }
+                return new String[] {value.toString()};
+            }
+            return null;
+        } catch (NoClassDefFoundError e) {
+            // ignore and just return null
+        } catch (Exception e) {
+            // ignore and just return null
+        }
+        return null;
+    }
+}
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/JavaField.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/JavaField.java
index 2fc9769..cbadb04 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/JavaField.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/JavaField.java
@@ -24,11 +24,25 @@
  */
 public interface JavaField {
 
+    /** The name of the field. */
     String getName();
 
+    /** The type of the field. */
     String getType();
 
+    /**
+     * Return the given tag.
+     * @param name The tag name.
+     * @return The tag or null.
+     */
     JavaTag getTagByName(String name);
 
-    String getInitializationExpression();
+    /**
+     * Return the initial value if this is a static constant.
+     * If this field is not an array, an array of length 1 is
+     * returned with the value. If this field is an array,
+     * the array of values is returned.
+     * @return The initial value of the field.
+     */
+    String[] getInitializationExpression();
 }
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaField.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaField.java
index afebf4c..37ab90b 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaField.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/cl/ClassLoaderJavaField.java
@@ -40,18 +40,8 @@
     /**
      * @see org.apache.felix.scrplugin.tags.JavaField#getInitializationExpression()
      */
-    public String getInitializationExpression() {
-        try {
-            this.field.setAccessible(true);
-            final Object value = this.field.get(null);
-            if ( value != null ) {
-                return value.toString();
-            }
-            return null;
-        } catch (Exception e) {
-            // ignore and return null
-            return null;
-        }
+    public String[] getInitializationExpression() {
+        return ClassUtil.getInitializationExpression(this.field.getDeclaringClass(), this.field.getName());
     }
 
     /**
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaField.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaField.java
index 17b9a59..5719e73 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaField.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/qdox/QDoxJavaField.java
@@ -18,10 +18,7 @@
  */
 package org.apache.felix.scrplugin.tags.qdox;
 
-import java.lang.reflect.Field;
-
-import org.apache.felix.scrplugin.tags.JavaField;
-import org.apache.felix.scrplugin.tags.JavaTag;
+import org.apache.felix.scrplugin.tags.*;
 
 import com.thoughtworks.qdox.model.DocletTag;
 
@@ -43,35 +40,26 @@
     /**
      * @see org.apache.felix.scrplugin.tags.JavaField#getInitializationExpression()
      */
-    public String getInitializationExpression() {
-        final Class c = this.description.getCompiledClass();
-        try {
-            final Field field = c.getDeclaredField(this.getName());
-            field.setAccessible(true);
-            final Object value = field.get(null);
+    public String[] getInitializationExpression() {
+        String[] values = ClassUtil.getInitializationExpression(this.description.getCompiledClass(), this.getName());
+        if ( values == null ) {
+            // try qdox
+            String value = this.field.getInitializationExpression();
             if ( value != null ) {
-                return value.toString();
-            }
-            return null;
-        } catch (NoClassDefFoundError e) {
-            // ignore and try qdox
-        } catch (Exception e) {
-            // ignore and try qdox
-        }
-        String value = this.field.getInitializationExpression();
-        if ( value != null ) {
-            int pos = value.indexOf("\"");
-            if ( pos != -1 ) {
-                try {
-                    value = value.substring(pos + 1);
-                    value = value.substring(0, value.lastIndexOf("\""));
-                } catch (ArrayIndexOutOfBoundsException aioobe) {
-                    // ignore this as this is a qdox problem
-                    value = this.field.getInitializationExpression();
+                int pos = value.indexOf("\"");
+                if ( pos != -1 ) {
+                    try {
+                        value = value.substring(pos + 1);
+                        value = value.substring(0, value.lastIndexOf("\""));
+                    } catch (ArrayIndexOutOfBoundsException aioobe) {
+                        // ignore this as this is a qdox problem
+                        value = this.field.getInitializationExpression();
+                    }
                 }
+                values = new String[] {value};
             }
         }
-        return value;
+        return values;
     }
 
     /**