Applied patch (FELIX-91) to add support for arrays in component metadata.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@420896 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
index b78a6d1..281ee73 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
@@ -28,7 +28,11 @@
import org.apache.felix.ipojo.handlers.dependency.Dependency;
import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
import org.apache.felix.ipojo.handlers.dependency.DependencyMetadata;
-import org.apache.felix.ipojo.handlers.providedservice.*;
+import org.apache.felix.ipojo.handlers.providedservice.Property;
+import org.apache.felix.ipojo.handlers.providedservice.PropertyMetadata;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedService;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceMetadata;
import org.apache.felix.ipojo.metadata.Element;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
index 53de8c0..e179ec7 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurableProperty.java
@@ -16,6 +16,7 @@
*/
package org.apache.felix.ipojo.handlers.configuration;
+import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
@@ -24,7 +25,7 @@
import org.apache.felix.ipojo.metadata.Element;
/**
- * Configurable Property
+ * Configurable Property.
* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
*/
public class ConfigurableProperty {
@@ -95,6 +96,14 @@
if (type.equals("long")) { value = new Long(strValue); }
if (type.equals("float")) { value = new Float(strValue); }
if (type.equals("double")) { value = new Double(strValue); }
+ // 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);
+ return;
+ }
if (value == null) {
// Else it is a neither a primitive type neither a String -> create the object by calling a constructor with a string in argument.
@@ -134,6 +143,81 @@
}
+ private void setArrayValue(String internalType, String[] values) {
+ 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]).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]).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]).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]).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]).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]).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]).doubleValue(); }
+ m_value = dl;
+ return; }
+
+ // Else it is a neither a primitive type neither a String -> create the object by calling a constructor with a string in argument.
+ try {
+ Class c = m_handler.getComponentManager().getContext().getBundle().loadClass(internalType);
+ 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]});
+ }
+ m_value = ob;
+ return;
+ } catch (ClassNotFoundException e) {
+ System.err.println("Class not found exception in setValue on " + internalType);
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ } catch (NoSuchMethodException e) {
+ System.err.println("Constructor not found exeption in setValue on " + internalType);
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ System.err.println("Argument problem to call the constructor of the type " + internalType);
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ System.err.println("Instantiation problem " + internalType);
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ System.err.println("Invocation problem " + internalType);
+ e.printStackTrace();
+ }
+ }
+
/**
* @return the name of the property.
*/
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
index e9683b1..eb8c332 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -24,6 +24,7 @@
import org.apache.felix.ipojo.ComponentManager;
import org.apache.felix.ipojo.Handler;
import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
import org.apache.felix.ipojo.metadata.Element;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
@@ -48,6 +49,17 @@
private ConfigurableProperty[] m_configurableProperties = new ConfigurableProperty[0];
/**
+ * ProvidedServiceHandler of the component.
+ * It is useful to priopagate properties to service registrations.
+ */
+ private ProvidedServiceHandler m_providedServiceHandler;
+
+ /**
+ * Properties porpagated at the last "updated".
+ */
+ private Dictionary m_propagated = new Properties();
+
+ /**
* PID of the component.
*/
private String m_pid;
@@ -92,6 +104,7 @@
// Get the PID :
if (metadata.containsAttribute("name")) { m_pid = metadata.getAttribute("name"); }
else { m_pid = metadata.getAttribute("className"); }
+ m_providedServiceHandler = (ProvidedServiceHandler) m_manager.getHandler(ProvidedServiceHandler.class.getName());
}
/**
@@ -168,7 +181,7 @@
* @see org.osgi.service.cm.ManagedService#updated(java.util.Dictionary)
*/
public void updated(Dictionary np) throws ConfigurationException {
-
+ Properties toPropagate = new Properties();
if (np != null) {
Enumeration keysEnumeration = np.keys();
while (keysEnumeration.hasMoreElements()) {
@@ -188,12 +201,22 @@
}
}
if (!find) {
- Activator.getLogger().log(Level.WARNING, "[" + m_manager.getComponentMetatada().getClassName() + "] The configuration is not valid, the property " + name + " is not a configurable property");
+ //The property is not a configurable property
+ Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] The property " + name + " will be propagated to service registrations");
+ toPropagate.put(name, value);
}
}
}
else { Activator.getLogger().log(Level.WARNING, "[" + m_manager.getComponentMetatada().getClassName() + "] The pushed configuration is null for " + m_pid); }
+ // Propagation of the properties to service registrations :
+ if (m_providedServiceHandler != null && !toPropagate.isEmpty()) {
+ Activator.getLogger().log(Level.INFO, "[" + m_manager.getComponentMetatada().getClassName() + "] Properties will be propagated");
+ m_providedServiceHandler.removeProperties(m_propagated);
+ m_providedServiceHandler.addProperties(toPropagate);
+ m_propagated = toPropagate;
+ }
+
}
/**
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
index d94ef94..da99dff 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java
@@ -16,6 +16,7 @@
*/
package org.apache.felix.ipojo.handlers.providedservice;
+import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
@@ -70,7 +71,6 @@
break;
}
}
-
pm.setType(type);
}
@@ -78,6 +78,19 @@
}
/**
+ * Property constructor.
+ * This constructor is used only for non-field property (property not attached to a field).
+ * @param ps : the provided service
+ * @param name : the name of the property
+ * @param value : the value of the property
+ */
+ public Property(ProvidedService ps, String name, Object value) {
+ m_providedService = ps;
+ m_metadata = new PropertyMetadata(name, null, value.getClass().getName(), null);
+ m_value = value;
+ }
+
+ /**
* @return the Object value of the property
*/
protected Object get() {
@@ -130,6 +143,16 @@
private void setValue(String value) {
String type = m_metadata.getType();
+ // Array :
+ if (type.endsWith("[]")) {
+ String internalType = type.substring(0, type.length() - 2);
+ value = value.substring(1, value.length() - 1);
+ String[] values = value.split(",");
+ setArrayValue(internalType, values);
+ return;
+ }
+
+ // Simple :
Activator.getLogger().log(Level.INFO, "[" + m_providedService.getComponentManager().getComponentMetatada().getClassName() + "] Set the value of the property " + m_metadata.getName() + " [" + m_metadata.getType() + "] " + " with the value : " + value);
if (type.equals("string") || type.equals("String")) { m_value = new String(value); return; }
@@ -169,7 +192,82 @@
}
}
- /**
+ private void setArrayValue(String internalType, String[] values) {
+ 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]).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]).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]).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]).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]).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]).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]).doubleValue(); }
+ m_value = dl;
+ return; }
+
+ // Else it is a neither a primitive type neither a String -> create the object by calling a constructor with a string in argument.
+ try {
+ Class c = m_providedService.getComponentManager().getContext().getBundle().loadClass(internalType);
+ 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]});
+ }
+ m_value = ob;
+ return;
+ } catch (ClassNotFoundException e) {
+ System.err.println("Class not found exception in setValue on " + internalType);
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ } catch (NoSuchMethodException e) {
+ System.err.println("Constructor not found exeption in setValue on " + internalType);
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ System.err.println("Argument problem to call the constructor of the type " + internalType);
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ System.err.println("Instantiation problem " + internalType);
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ System.err.println("Invocation problem " + internalType);
+ e.printStackTrace();
+ }
+ }
+
+ /**
* @return the value of the property.
*/
public Object getValue() { return m_value; }
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
index 8c9f0bb..82ce8fb 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
@@ -16,6 +16,8 @@
*/
package org.apache.felix.ipojo.handlers.providedservice;
+import java.util.Dictionary;
+import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.Level;
@@ -106,7 +108,7 @@
* Add the given property to the property list.
* @param p : the element to add
*/
- private void addProperty(Property p) {
+ private synchronized void addProperty(Property p) {
for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
if (m_properties[i] == p) { return; }
}
@@ -120,6 +122,24 @@
else { m_properties = new Property[] {p}; }
}
+ private synchronized void removeProperty(String name) {
+ int idx = -1;
+ for (int i = 0; i < m_properties.length; i++) {
+ if (m_properties[i].getMetadata().getName() == name) { idx = i; break; }
+ }
+
+ if (idx >= 0) {
+ if ((m_properties.length - 1) == 0) { m_properties = new Property[0]; }
+ else {
+ Property[] newPropertiesList = new Property[m_properties.length - 1];
+ System.arraycopy(m_properties, 0, newPropertiesList, 0, idx);
+ if (idx < newPropertiesList.length) {
+ System.arraycopy(m_properties, idx + 1, newPropertiesList, idx, newPropertiesList.length - idx); }
+ m_properties = newPropertiesList;
+ }
+ }
+ }
+
/**
* @return the service reference of the provided service (null if the service is not published).
*/
@@ -263,7 +283,7 @@
* Update refresh the service properties.
* The new list of properties is sended to the service registry.
*/
- protected void update() {
+ public void update() {
// Update the service properties
// Contruct the service properties list
@@ -284,4 +304,32 @@
return m_metadata;
}
+ /**
+ * Add properties to the list.
+ * @param props : properties to add
+ */
+ protected void addProperties(Dictionary props) {
+ Enumeration keys = props.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ Object value = props.get(key);
+ Property prop = new Property(this, key, value);
+ addProperty(prop);
+ }
+ update();
+ }
+
+ /**
+ * Remove properties from the list.
+ * @param props : properties to remove
+ */
+ protected void deleteProperties(Dictionary props) {
+ Enumeration keys = props.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String) keys.nextElement();
+ removeProperty(key);
+ }
+ update();
+ }
+
}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
index 2351dcf..1546a3d 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -16,6 +16,7 @@
*/
package org.apache.felix.ipojo.handlers.providedservice;
+import java.util.Dictionary;
import java.util.logging.Level;
import org.apache.felix.ipojo.ComponentManager;
@@ -302,4 +303,24 @@
}
+ /**
+ * Add properties to all provided services.
+ * @param dict : dictionary fo properties to add
+ */
+ public void addProperties(Dictionary dict) {
+ for (int i = 0; i < m_providedServices.length; i++) {
+ m_providedServices[i].addProperties(dict);
+ }
+ }
+
+ /**
+ * Remove properties form all provided services.
+ * @param dict : dictionary of properties to delete.
+ */
+ public void removeProperties(Dictionary dict) {
+ for (int i = 0; i < m_providedServices.length; i++) {
+ m_providedServices[i].deleteProperties(dict);
+ }
+ }
+
}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
index da85147..04a271e 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
@@ -137,7 +137,7 @@
c = string[i];
}
i++; // skip "
- c=string[i];
+ c = string[i];
Attribute att = new Attribute(attName, attNs , attValue);
m_elements[m_elements.length - 1].addAttribute(att);