Applied patch (FELIX-196) to throw an exception when a configuration is 
refused by a component factory.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@499395 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/Activator.java b/ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
index b1c4950..ea63748 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
@@ -111,7 +111,7 @@
             ComponentFactory factory = m_factories[i];
             factory.stop();
         }
-        m_creator.stop();
+        if(m_creator != null) { m_creator.stop(); }
         m_factories = new ComponentFactory[0]; // Release all factories
     }
 
@@ -150,7 +150,12 @@
     			String componentClass = m_factories[j].getComponentClassName();
     			String factoryName = m_factories[j].getFactoryName();
     			if(conf.get("component") != null && (conf.get("component").equals(componentClass) || conf.get("component").equals(factoryName))) {
-    				if(m_factories[j].isAcceptable(conf)) { m_factories[j].createComponentInstance(conf); created = true;}
+    				try {
+						m_factories[j].createComponentInstance(conf);
+	    				created = true;
+					} catch (UnacceptableConfiguration e) {
+						System.err.println("Cannot create the instance " + conf.get("name") +" : " + e.getMessage());
+					} 
     			}
     		}
     		if(!created && conf.get("component") != null) {
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
index 519994b..513a67b 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -296,10 +296,12 @@
     /**
      * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
      */
-    public ComponentInstance createComponentInstance(Dictionary configuration) {
-    	if(!isAcceptable(configuration)) {
-    		m_logger.log(Logger.ERROR, "The configuration is not acceptable");
-    		return null; 
+    public ComponentInstance createComponentInstance(Dictionary configuration)  throws UnacceptableConfiguration {
+    	try {
+    		_isAcceptable(configuration);
+    	} catch(UnacceptableConfiguration e) {
+    		m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+    		throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage() );
     	}
     	
         IPojoContext context = new IPojoContext(m_context);
@@ -319,11 +321,12 @@
     /**
      * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
      */
-    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) {
-    	if(!isAcceptable(configuration)) {
-    		//TODO : extend the message with infomation about the non acceptability
-    		m_logger.log(Logger.ERROR, "The configuration is not acceptable");
-    		return null; 
+    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration {
+    	try {
+    		_isAcceptable(configuration);
+    	} catch(UnacceptableConfiguration e) {
+    		m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+    		throw new UnacceptableConfiguration("The configuration " + configuration + " is not acceptable for " + m_factoryName + ": " + e.getMessage() );
     	}
     	
     	IPojoContext context = new IPojoContext(m_context, serviceContext);
@@ -361,9 +364,24 @@
      */
     public void updated(String pid, Dictionary properties) throws ConfigurationException {
         InstanceManager cm = (InstanceManager) m_componentInstances.get(pid);
-        if (cm == null) { createComponentInstance(properties); } // Create the component
+        if (cm == null) { 
+        	try {
+        		createComponentInstance(properties);
+        	} catch (UnacceptableConfiguration e) {
+        		m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+        		throw new ConfigurationException(properties.toString(), e.getMessage());
+        	} 
+        }
         else {
             cm.stop(); // Stop the component
+            
+            try {
+				_isAcceptable(properties); // Test if the configuration is acceptable
+			} catch (UnacceptableConfiguration e) {
+				m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+        		throw new ConfigurationException(properties.toString(), e.getMessage());
+			}
+			
             cm.configure(m_componentMetadata, properties); // re-configure the component
             cm.start(); // restart it
         }
@@ -393,5 +411,17 @@
     	}
     	return true;
     }
+    
+    private void _isAcceptable(Dictionary conf) throws UnacceptableConfiguration {
+    	if(conf == null || conf.get("name") == null) { throw new UnacceptableConfiguration("The configuration does not contains the \"name\" property"); }
+    	PropertyDescription[] props = m_componentDesc.getProperties();
+    	for(int i = 0; i < props.length; i++) {
+    		PropertyDescription pd = props[i];
+    		// Failed if the props has no default value and the configuration does not push a value 
+    		if(pd.getValue() == null && conf.get(pd.getName()) == null) {
+    			throw new UnacceptableConfiguration("The configuration does not contains the \"" + pd.getName() + "\" property");
+    		}
+    	}
+    }
 
 }
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/Factory.java b/ipojo/src/main/java/org/apache/felix/ipojo/Factory.java
index 66606ca..86d006c 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/Factory.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/Factory.java
@@ -34,7 +34,7 @@
      * @param configuration : the configuration properties for this component.
      * @return the created instance manager.
      */
-    ComponentInstance createComponentInstance(Dictionary configuration);
+    ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration;
     
     /**
      * Create an instance manager (i.e. component type instance).
@@ -43,7 +43,7 @@
      * @param serviceContext : the service context of the component.
      * @return the created instance manager.
      */
-    ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext);
+    ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration;
 
     /**
      * Get the component type information containing provided service, configuration properties ...
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/InstanceCreator.java b/ipojo/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
index a9708a7..d6c0c7d 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
@@ -20,6 +20,7 @@
 
 import java.util.Dictionary;
 
+import org.apache.felix.ipojo.util.Logger;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceEvent;
@@ -35,6 +36,7 @@
 	
 	private BundleContext m_context;
 	
+	private Logger m_logger;
 	
 	/**
 	 * This structure aims to manage a configuration.
@@ -54,17 +56,15 @@
 	 */
 	private ManagedConfiguration[] m_configurations;
 	
-	
-	
 	public InstanceCreator(BundleContext context, Dictionary[] configurations) {
 		m_context = context;
+		m_logger = new Logger(context, "InstanceCreator"+context.getBundle().getBundleId(), Logger.WARNING);
 		m_configurations = new ManagedConfiguration[configurations.length];
 		for(int i = 0; i < configurations.length; i++) {
 			ManagedConfiguration conf = new ManagedConfiguration(configurations[i]);
 			m_configurations[i] = conf;
 			
 			// Get the component type name :
-			System.out.println("component = " + conf.configuration.get("component"));
 			String componentType = (String) conf.configuration.get("component");
 			Factory fact = null;
 			
@@ -76,26 +76,24 @@
 					createInstance(fact, conf);					
 				}
 				else {
-					System.err.println("No factory available for the type : " + componentType);
+					m_logger.log(Logger.WARNING, "No factory available for the type : " + componentType);
 				}
-			} catch (InvalidSyntaxException e) { e.printStackTrace(); }
-
+			} catch (InvalidSyntaxException e) { m_logger.log(Logger.ERROR, "Invalid syntax filter for the type : " + componentType, e); }
 		}
 		
 		// Register a service listenner on Factory Service
 		try {
 			m_context.addServiceListener(this, "(objectClass="+Factory.class.getName() + ")");
-		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+		} catch (InvalidSyntaxException e) { m_logger.log(Logger.ERROR, "Invalid syntax filter when registering a listener on Factory Service", e); }
 	}
 	
 	private void createInstance(Factory fact, ManagedConfiguration config) {
 		Dictionary conf = config.configuration;
-		if(fact.isAcceptable(conf)) {
-			config.instance = fact.createComponentInstance(conf);
-			config.factoryName = fact.getName();
-		}
-		else {
-			System.err.println("A factory is available for the configuration but the configuration is not acceptable");
+		try {
+				config.instance = fact.createComponentInstance(conf);
+				config.factoryName = fact.getName();
+		} catch (UnacceptableConfiguration e) {
+			m_logger.log(Logger.ERROR, "A factory is available for the configuration but the configuration is not acceptable", e);
 		}
 	}
 
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/UnacceptableConfiguration.java b/ipojo/src/main/java/org/apache/felix/ipojo/UnacceptableConfiguration.java
new file mode 100644
index 0000000..bcda55b
--- /dev/null
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/UnacceptableConfiguration.java
@@ -0,0 +1,9 @@
+package org.apache.felix.ipojo;
+
+public class UnacceptableConfiguration extends Exception {
+
+	private static final long serialVersionUID = 2998931848886223965L;
+	
+	public UnacceptableConfiguration(String message) { super(message); }
+
+}
diff --git a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
index 7136732..60cda50 100644
--- a/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
+++ b/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
@@ -281,6 +281,10 @@
 
         // Contruct the service properties list
         Properties serviceProperties = getServiceProperties();
+        
+        if(serviceProperties == null) {
+        	m_handler.getInstanceManager().getFactory().getLogger().log(Logger.ERROR, "Cannot get the properties of the provided service");
+        }
 
         // Update the service registration
         if (m_state == REGISTERED) {
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 17451fd..1684578 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
@@ -58,13 +58,18 @@
         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", "");
-                d.put(propsName, propsValue);
+                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;
         }