Applied patch (FELIX-254) to add support for property values in
<property> element body.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@519016 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java b/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
index e67021b..66e4f44 100644
--- a/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/PropertyMetadata.java
@@ -18,6 +18,10 @@
*/
package org.apache.felix.scr;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
import org.osgi.service.component.ComponentException;
/**
@@ -75,40 +79,91 @@
return;
}
- // 112.4.5 Parsing of the value is done by the valueOf(String) method (P. 291)
- // Should the type accept lowercase too?
- if(m_type.equals("String")) {
- m_value = String.valueOf(value);
- }
- else if(m_type.equals("Long")) {
- m_value = Long.valueOf(value);
- }
- else if(m_type.equals("Double")) {
- m_value = Double.valueOf(value);
- }
- else if(m_type.equals("Float")) {
- m_value = Float.valueOf(value);
- }
- else if(m_type.equals("Integer")) {
- m_value = Integer.valueOf(value);
- }
- else if(m_type.equals("Byte")) {
- m_value = Byte.valueOf(value);
- }
- else if(m_type.equals("Char")) {
- //TODO: verify if this is adequate for Characters
- m_value = Byte.valueOf(value);
- }
- else if(m_type.equals("Boolean")) {
- m_value = Boolean.valueOf(value);
- }
- else if(m_type.equals("Short")) {
- m_value = Short.valueOf(value);
- }
- else {
- throw new IllegalArgumentException("Undefined property type '"+m_type+"'");
- }
+ m_value = toType( value );
}
+
+ /**
+ * Set multiple values as an array, where the values are contained in
+ * the string as one value per line.
+ *
+ * @param values
+ */
+ public void setValues(String values) {
+ // splite the values and convert to boxed objects
+ List valueList = new ArrayList();
+ StringTokenizer tokener = new StringTokenizer(values, "\r\n");
+ while (tokener.hasMoreTokens()) {
+ String value = tokener.nextToken().trim();
+ if (value.length() > 0) {
+ valueList.add(toType( value ));
+ }
+ }
+
+ // 112.4.5 Except for String objects, the result will be translated to an array of primitive types.
+ if(m_type.equals("String")) {
+ m_value = valueList.toArray( new String[valueList.size()] );
+ }
+ else if(m_type.equals("Long")) {
+ long[] array = new long[valueList.size()];
+ for (int i=0; i < array.length; i++) {
+ array[i] = ((Long) valueList.get(i)).longValue();
+ }
+ m_value = array;
+ }
+ else if(m_type.equals("Double")) {
+ double[] array = new double[valueList.size()];
+ for (int i=0; i < array.length; i++) {
+ array[i] = ((Double) valueList.get(i)).doubleValue();
+ }
+ m_value = array;
+ }
+ else if(m_type.equals("Float")) {
+ float[] array = new float[valueList.size()];
+ for (int i=0; i < array.length; i++) {
+ array[i] = ((Float) valueList.get(i)).floatValue();
+ }
+ m_value = array;
+ }
+ else if(m_type.equals("Integer")) {
+ int[] array = new int[valueList.size()];
+ for (int i=0; i < array.length; i++) {
+ array[i] = ((Integer) valueList.get(i)).intValue();
+ }
+ m_value = array;
+ }
+ else if(m_type.equals("Byte")) {
+ byte[] array = new byte[valueList.size()];
+ for (int i=0; i < array.length; i++) {
+ array[i] = ((Byte) valueList.get(i)).byteValue();
+ }
+ m_value = array;
+ }
+ else if(m_type.equals("Char")) {
+ //TODO: verify if this is adequate for Characters
+ char[] array = new char[valueList.size()];
+ for (int i=0; i < array.length; i++) {
+ array[i] = ((Character) valueList.get(i)).charValue();
+ }
+ m_value = array;
+ }
+ else if(m_type.equals("Boolean")) {
+ boolean[] array = new boolean[valueList.size()];
+ for (int i=0; i < array.length; i++) {
+ array[i] = ((Boolean) valueList.get(i)).booleanValue();
+ }
+ m_value = array;
+ }
+ else if(m_type.equals("Short")) {
+ short[] array = new short[valueList.size()];
+ for (int i=0; i < array.length; i++) {
+ array[i] = ((Short) valueList.get(i)).shortValue();
+ }
+ m_value = array;
+ }
+ else {
+ throw new IllegalArgumentException("Undefined property type '"+m_type+"'");
+ }
+ }
/**
* Get the name of the property
@@ -146,4 +201,40 @@
throw new ComponentException("Property name attribute is mandatory");
}
}
+
+ private Object toType(String value) {
+ // 112.4.5 Parsing of the value is done by the valueOf(String) method (P. 291)
+ // Should the type accept lowercase too?
+ if(m_type.equals("String")) {
+ return String.valueOf(value);
+ }
+ else if(m_type.equals("Long")) {
+ return Long.valueOf(value);
+ }
+ else if(m_type.equals("Double")) {
+ return Double.valueOf(value);
+ }
+ else if(m_type.equals("Float")) {
+ return Float.valueOf(value);
+ }
+ else if(m_type.equals("Integer")) {
+ return Integer.valueOf(value);
+ }
+ else if(m_type.equals("Byte")) {
+ return Byte.valueOf(value);
+ }
+ else if(m_type.equals("Char")) {
+ char c = ( value.length() > 0 ) ? value.charAt( 0 ) : 0;
+ return new Character( c );
+ }
+ else if(m_type.equals("Boolean")) {
+ return Boolean.valueOf(value);
+ }
+ else if(m_type.equals("Short")) {
+ return Short.valueOf(value);
+ }
+ else {
+ throw new IllegalArgumentException("Undefined property type '"+m_type+"'");
+ }
+ }
}
diff --git a/scr/src/main/java/org/apache/felix/scr/XmlHandler.java b/scr/src/main/java/org/apache/felix/scr/XmlHandler.java
index b2e674a..a9b43e7 100644
--- a/scr/src/main/java/org/apache/felix/scr/XmlHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/XmlHandler.java
@@ -40,6 +40,9 @@
// A list of component descriptors contained in the file
private List m_components = new ArrayList();
+ // PropertyMetaData whose value attribute is missing, hence has element data
+ private PropertyMetadata m_pendingProperty;
+
/**
* Method called when a tag opens
*
@@ -89,26 +92,24 @@
}
// 112.4.5 Properties and Property Elements
else if (qName.equals("property")) {
- // 112.4.5: If the value attribute is specified, the body of the element is ignored.
+ PropertyMetadata prop = new PropertyMetadata();
+
+ // name attribute is mandatory
+ prop.setName(attrib.getProperty("name"));
+
+ // type attribute is optional
+ if(attrib.getProperty("type") != null) {
+ prop.setType(attrib.getProperty("type"));
+ }
+
+ // 112.4.5: If the value attribute is specified, the body of the element is ignored.
if( attrib.getProperty("value") != null) {
- PropertyMetadata prop = new PropertyMetadata();
-
- // name attribute is mandatory
- prop.setName(attrib.getProperty("name"));
-
- // type attribute is optional
- if(attrib.getProperty("type") != null) {
- prop.setType(attrib.getProperty("type"));
- }
-
- // value attribute is optional
- if(attrib.getProperty("value") != null) {
- prop.setValue(attrib.getProperty("value"));
- }
+ prop.setValue(attrib.getProperty("value"));
m_currentComponent.addProperty(prop);
}
else {
- // TODO: treat the case where property value is not specified (p. 291)
+ // hold the metadata pending
+ m_pendingProperty = prop;
}
// TODO: treat the case where a properties file name is provided (p. 292)
}
@@ -175,6 +176,11 @@
// When the closing tag for a component is found, the component is validated to check if
// the implementation class has been set
m_currentComponent.validate();
+ } else if (qName.equals("property") && m_pendingProperty != null) {
+ // 112.4.5 body expected to contain property value
+ // if so, the m_pendingProperty field would be null
+ // currently, we just ignore this situation
+ m_pendingProperty = null;
}
}
@@ -188,10 +194,16 @@
return m_components;
}
- public void characters(char[] ch, int offset, int length) throws Exception {
- // Not used
-
- }
+ public void characters( char[] ch, int offset, int length ) throws Exception
+ {
+ // 112.4.5 If the value attribute is not specified, the body must contain one or more values
+ if ( m_pendingProperty != null )
+ {
+ m_pendingProperty.setValues( new String( ch, offset, length ) );
+ m_currentComponent.addProperty( m_pendingProperty );
+ m_pendingProperty = null;
+ }
+ }
public void processingInstruction(String target, String data) throws Exception {
// Not used