Applied patch (FELIX-200) to add support for XML property configuration 
to iPOJO.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@503673 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
index e49068c..51e92e2 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
@@ -38,8 +38,6 @@
      * Default value of the property.
      */
     private String m_value = null;
-    
-    private boolean m_needed;
 
     /**
      * Constructor.
@@ -59,11 +57,6 @@
     public String getName() { return m_name; }
     
     /**
-     * @return true is the property need to be configured.
-     */
-    public boolean isNeeded() { return m_needed; }
-
-    /**
      * @return the property type.
      */
     public String getType() { return m_type; }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
index 8430b88..bdcc3c5 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
@@ -22,6 +22,8 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 
+import org.apache.felix.ipojo.parser.ParseUtils;
+
 /**
  * Configurable Property.
  * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
@@ -83,9 +85,7 @@
         // Array :
         if (type.endsWith("[]")) {
             String internalType = type.substring(0, type.length() - 2);
-            strValue = strValue.substring(1, strValue.length() - 1);
-            String[] values = strValue.split(",");
-            setArrayValue(internalType, values);
+            setArrayValue(internalType, ParseUtils.parseArrays(strValue));
             return;
         }
 
@@ -135,48 +135,48 @@
     private void setArrayValue(String internalType, String[] values) {
         if (internalType.equals("string") || internalType.equals("String")) { 
         	String[] str = new String[values.length];
-        	for (int i = 0; i < values.length; i++) { str[i] = new String(values[i].trim()); }
+        	for (int i = 0; i < values.length; i++) { str[i] = new String(values[i]); }
         	m_value = str;
         	return;
         }
         if (internalType.equals("boolean")) {
             boolean[] bool = new boolean[values.length];
-            for (int i = 0; i < values.length; i++) { bool[i] = new Boolean(values[i].trim()).booleanValue(); }
+            for (int i = 0; i < values.length; i++) { bool[i] = new Boolean(values[i]).booleanValue(); }
             m_value = bool;
             return;
         }
         if (internalType.equals("byte")) {
             byte[] byt = new byte[values.length];
-            for (int i = 0; i < values.length; i++) { byt[i] = new Byte(values[i].trim()).byteValue(); }
+            for (int i = 0; i < values.length; i++) { byt[i] = new Byte(values[i]).byteValue(); }
             m_value = byt;
             return;
         }
         if (internalType.equals("short")) {
             short[] shor = new short[values.length];
-            for (int i = 0; i < values.length; i++) { shor[i] = new Short(values[i].trim()).shortValue(); }
+            for (int i = 0; i < values.length; i++) { shor[i] = new Short(values[i]).shortValue(); }
             m_value = shor;
             return;
         }
         if (internalType.equals("int")) {
             int[] in = new int[values.length];
-            for (int i = 0; i < values.length; i++) { in[i] = new Integer(values[i].trim()).intValue(); }
+            for (int i = 0; i < values.length; i++) { in[i] = new Integer(values[i]).intValue(); }
             m_value = in;
             return;
         }
         if (internalType.equals("long")) {
             long[] ll = new long[values.length];
-            for (int i = 0; i < values.length; i++) { ll[i] = new Long(values[i].trim()).longValue(); }
+            for (int i = 0; i < values.length; i++) { ll[i] = new Long(values[i]).longValue(); }
             m_value = ll;
             return;
         }
         if (internalType.equals("float")) {
             float[] fl = new float[values.length];
-            for (int i = 0; i < values.length; i++) { fl[i] = new Float(values[i].trim()).floatValue(); }
+            for (int i = 0; i < values.length; i++) { fl[i] = new Float(values[i]).floatValue(); }
             m_value = fl;
             return; }
         if (internalType.equals("double")) {
             double[] dl = new double[values.length];
-            for (int i = 0; i < values.length; i++) { dl[i] = new Double(values[i].trim()).doubleValue(); }
+            for (int i = 0; i < values.length; i++) { dl[i] = new Double(values[i]).doubleValue(); }
             m_value = dl;
             return; }
 
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index 388ec72..cdec550 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -149,10 +149,6 @@
                 else { if (fieldName != null &&  configuration.get(fieldName) != null && !(configuration.get(fieldName) instanceof String)) { m_configurableProperties[k].setValue(configuration.get(fieldName)); } }
             }
             m_manager.register(this, fields);
-
-
-
-
         }
         else { return; }
     }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
index 89b06e6..a47e82e 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
@@ -23,8 +23,11 @@
 import java.lang.reflect.InvocationTargetException;
 
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseUtils;
 import org.apache.felix.ipojo.util.Logger;
 
+import sun.net.www.ParseUtil;
+
 /**
  * Represent a property i.e. a set : [name, type, value].
  * A property can be attached to a field.
@@ -154,9 +157,7 @@
         // Array :
         if (m_type.endsWith("[]")) {
             String internalType = m_type.substring(0, m_type.length() - 2);
-            value = value.substring(1, value.length() - 1);
-            String[] values = value.split(",");
-            setArrayValue(internalType, values);
+            setArrayValue(internalType, ParseUtils.parseArrays(value));
             return;
         }
 
@@ -207,42 +208,42 @@
         if (internalType.equals("string") || internalType.equals("String")) { m_value = values; return; }
         if (internalType.equals("boolean")) {
             boolean[] bool = new boolean[values.length];
-            for (int i = 0; i < values.length; i++) { bool[i] = new Boolean(values[i].trim()).booleanValue(); }
+            for (int i = 0; i < values.length; i++) { bool[i] = new Boolean(values[i]).booleanValue(); }
             m_value = bool;
             return;
         }
         if (internalType.equals("byte")) {
             byte[] byt = new byte[values.length];
-            for (int i = 0; i < values.length; i++) { byt[i] = new Byte(values[i].trim()).byteValue(); }
+            for (int i = 0; i < values.length; i++) { byt[i] = new Byte(values[i]).byteValue(); }
             m_value = byt;
             return;
         }
         if (internalType.equals("short")) {
             short[] shor = new short[values.length];
-            for (int i = 0; i < values.length; i++) { shor[i] = new Short(values[i].trim()).shortValue(); }
+            for (int i = 0; i < values.length; i++) { shor[i] = new Short(values[i]).shortValue(); }
             m_value = shor;
             return;
         }
         if (internalType.equals("int")) {
             int[] in = new int[values.length];
-            for (int i = 0; i < values.length; i++) { in[i] = new Integer(values[i].trim()).intValue(); }
+            for (int i = 0; i < values.length; i++) { in[i] = new Integer(values[i]).intValue(); }
             m_value = in;
             return;
         }
         if (internalType.equals("long")) {
             long[] ll = new long[values.length];
-            for (int i = 0; i < values.length; i++) { ll[i] = new Long(values[i].trim()).longValue(); }
+            for (int i = 0; i < values.length; i++) { ll[i] = new Long(values[i]).longValue(); }
             m_value = ll;
             return;
         }
         if (internalType.equals("float")) {
             float[] fl = new float[values.length];
-            for (int i = 0; i < values.length; i++) { fl[i] = new Float(values[i].trim()).floatValue(); }
+            for (int i = 0; i < values.length; i++) { fl[i] = new Float(values[i]).floatValue(); }
             m_value = fl;
             return; }
         if (internalType.equals("double")) {
             double[] dl = new double[values.length];
-            for (int i = 0; i < values.length; i++) { dl[i] = new Double(values[i].trim()).doubleValue(); }
+            for (int i = 0; i < values.length; i++) { dl[i] = new Double(values[i]).doubleValue(); }
             m_value = dl;
             return; }
 
@@ -252,7 +253,7 @@
             Constructor cst = c.getConstructor(new Class[] {String.class});
             Object[] ob = (Object[]) Array.newInstance(c, values.length);
             for (int i = 0; i < values.length; i++) {
-                ob[i] = cst.newInstance(new Object[] {values[i].trim()});
+                ob[i] = cst.newInstance(new Object[] {values[i]});
             }
             m_value = ob;
             return;
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
index 57b584f..0ae43ec 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -25,6 +25,7 @@
 import org.apache.felix.ipojo.architecture.ComponentDescription;
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseUtils;
 import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.Constants;
 
@@ -94,9 +95,7 @@
             if (providedServices[i].containsAttribute("interface")) {
                 String serviceSpecificationStr = providedServices[i].getAttribute("interface");
                 //Get serviceSpecification if exist in the metadata
-                String[] spec = serviceSpecificationStr.split(",");
-                serviceSpecification = new String[spec.length];
-                for (int j = 0; j < spec.length; j++) { serviceSpecification[j] = spec[j].trim(); }
+                serviceSpecification = ParseUtils.parseArrays(serviceSpecificationStr);
             } else {
                 serviceSpecification = new String[manipulation.getElements("Interface").length];
                 for (int j = 0; j < manipulation.getElements("Interface").length; j++) {
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java b/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
index 1684578..c6bfcc3 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
@@ -57,34 +57,48 @@
         Element[] configs = m_elements[0].getElements("Instance");
         Dictionary[] dicts = new Dictionary[configs.length];
         for (int i = 0; i < configs.length; i++) {
-            String comp = configs[i].getAttribute("component"); // get the component targeted by the configuration
-            if(comp == null) { throw new ParseException("An instance connaot be parsed : no component attribute"); }
-            Dictionary d = new Properties();
-            d.put("component", comp);
-            if (configs[i].getAttribute("name") != null) { d.put("name", configs[i].getAttribute("name")); }
-            for (int j = 0; j < configs[i].getElements("property", "").length; j++) {
-                String propsName = configs[i].getElements("property", "")[j].getAttribute("name", "");
-                String propsValue = configs[i].getElements("property", "")[j].getAttribute("value", "");
-                if(propsName == null || propsValue == null) { 
-                	System.err.println("A property cannot be parsed : " + propsName + " = " + propsValue);
-                	throw new ParseException("A property cannot be parsed : " + propsName + " = " + propsValue);
-                } 
-                else { d.put(propsName, propsValue); }
-            }
-            dicts[i] = d;
+            dicts[i] = parseInstance(configs[i]);
         }
         return dicts;
     }
+    
+    private Dictionary parseInstance(Element instance) throws ParseException {
+    	Dictionary dict = new Properties();
+    	if(!instance.containsAttribute("name")) { throw new ParseException("An instance does not have the 'name' attribute"); }
+    	if(!instance.containsAttribute("component")) { throw new ParseException("An instance does not have the 'component' attribute"); }
+    	dict.put("name", instance.getAttribute("name"));
+    	dict.put("component", instance.getAttribute("component"));
+    	
+    	for(int i=0; i < instance.getElements("property").length; i++) {
+    		parseProperty(instance.getElements("property")[i], dict);
+    	}
+    	
+    	return dict;
+    }
+    
+    private void parseProperty(Element prop, Dictionary dict) throws ParseException {
+    	// Check that the property has a name 
+    	if(!prop.containsAttribute("name")) { throw new ParseException("A property does not have the 'name' attribute"); }
+    	// Final case : the property element has a 'value' attribute
+    	if(prop.containsAttribute("value")) { dict.put(prop.getAttribute("name"), prop.getAttribute("value")); }
+    	else {
+    		// Recursive case
+    		// Check if there is 'property' element
+    		Element[] subProps = prop.getElements("property");
+    		if(subProps.length == 0) { throw new ParseException("A complex property must have at least one 'property' sub-element"); }
+    		Dictionary dict2 = new Properties();
+    		for(int i = 0; i < subProps.length; i++) {
+    			parseProperty(subProps[i], dict2);
+    			dict.put(prop.getAttribute("name"), dict2);
+    		}
+    	}
+    }
 
     /**
      * Add an element to the list.
      * @param elem : the element to add
      */
     private void addElement(Element elem) {
-        for (int i = 0; (m_elements != null) && (i < m_elements.length); i++) {
-            if (m_elements[i] == elem) { return; }
-        }
-
         if (m_elements != null) {
             Element[] newElementsList = new Element[m_elements.length + 1];
             System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java b/ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
new file mode 100644
index 0000000..823337b
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
@@ -0,0 +1,24 @@
+package org.apache.felix.ipojo.parser;
+
+public class ParseUtils {
+	
+	/**
+	 * Parse the string form of an array as {a, b, c}
+	 * @param str : the string form
+	 * @return the resulting string array
+	 */
+	public static String[] parseArrays(String str) {
+		// Remove { and }
+		if(str.startsWith("{") && str.endsWith("}")) {
+			String m = str.substring(1, str.length() - 1);
+			String[] values = m.split(",");
+			for(int i = 0; i < values.length; i++) {
+				values[i] = values[i].trim();
+			}
+			return values;
+		} else {
+			return new String[] {str};
+		}
+	}
+
+}