Fix FELIX-2705 Provide a way to extend the logger strategy
Define a new ErrorHandler service interface. The iPOJO logger invokes this services when a warning or an error is thrown.

Also generalize the usage of the logger

Add tests about FELIX-2705 and re-enable logger tests.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1037859 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/tests/core/logger/erroneous-component.xml b/ipojo/tests/core/logger/erroneous-component.xml
new file mode 100644
index 0000000..9ac7735
--- /dev/null
+++ b/ipojo/tests/core/logger/erroneous-component.xml
@@ -0,0 +1,5 @@
+<ipojo>
+<component immediate="true" classname="org.apache.felix.ipojo.tests.core.component.MyErroneousComponent">
+  <provides/>
+</component>
+</ipojo>
diff --git a/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/ErrorHandlerTest.java b/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/ErrorHandlerTest.java
new file mode 100644
index 0000000..1e0f7d6
--- /dev/null
+++ b/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/ErrorHandlerTest.java
@@ -0,0 +1,160 @@
+package org.apache.felix.ipojo.tests.core;
+
+import static org.ops4j.pax.exam.CoreOptions.felix;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.newBundle;
+import static org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOBuilder.withiPOJO;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ErrorHandler;
+import org.apache.felix.ipojo.tests.core.component.MyComponent;
+import org.apache.felix.ipojo.tests.core.component.MyErroneousComponent;
+import org.apache.felix.ipojo.tests.core.service.MyService;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.ow2.chameleon.testing.helpers.IPOJOHelper;
+import org.ow2.chameleon.testing.helpers.OSGiHelper;
+
+@RunWith( JUnit4TestRunner.class )
+public class ErrorHandlerTest {
+
+    @Inject
+    private BundleContext context;
+
+    private OSGiHelper osgi;
+
+    private IPOJOHelper ipojo;
+
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+
+    @Configuration
+    public static Option[] configure() {
+
+        File tmp = new File("target/tmp");
+        tmp.mkdirs();
+
+        Option[] opt =  options(
+                felix(),
+//                equinox(),
+                provision(
+                        // Runtime.
+                        mavenBundle().groupId( "org.apache.felix" ).artifactId( "org.apache.felix.log" ).version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.ow2.chameleon.testing").artifactId("osgi-helpers").versionAsInProject()
+                        ),
+                provision(
+                        newBundle()
+                            .add( MyService.class )
+                            .set(Constants.BUNDLE_SYMBOLICNAME,"ServiceInterface")
+                            .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.tests.core.service")
+                            .build()
+                    ),
+               provision(
+                       // Component
+                        newBundle()
+                            .add(MyComponent.class)
+                            .set(Constants.BUNDLE_SYMBOLICNAME,"MyComponent")
+                            .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.tests.core.service")
+                            .set("Ipojo-log-level", "info")
+                            .build( withiPOJO(new File(tmp, "provider-with-level-in-manifest.jar"), new File("component.xml")))
+                            ),
+                provision(
+                        // Component
+                         newBundle()
+                             .add(MyErroneousComponent.class)
+                             .set(Constants.BUNDLE_SYMBOLICNAME,"MyErroneousComponent")
+                             .set("Ipojo-log-level", "debug")
+                             .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.tests.core.service")
+                             .build( withiPOJO(new File(tmp, "erroneous-provider-with-level-in-manifest.jar"), new File("erroneous-component.xml")))
+                             )
+                );
+        return opt;
+    }
+
+    @Test
+    public void testErrorHandlerEmpty() throws InterruptedException, InvalidSyntaxException {
+    	MyErrorHandler handler = new MyErrorHandler();
+    	context.registerService(ErrorHandler.class.getName(), handler, null);
+
+        System.out.println(handler.m_errors);
+
+        Assert.assertTrue(handler.m_errors.isEmpty());
+    }
+
+    @Test
+    public void testErrorHandler() throws InterruptedException, InvalidSyntaxException {
+    	MyErrorHandler handler = new MyErrorHandler();
+    	context.registerService(ErrorHandler.class.getName(), handler, null);
+
+    	try {
+    		ipojo.createComponentInstance("org.apache.felix.ipojo.tests.core.component.MyErroneousComponent");
+    	} catch (Exception e ) {
+    		System.out.println(e);
+    	}
+
+
+        System.out.println(handler.m_errors);
+
+        Assert.assertFalse(handler.m_errors.isEmpty());
+        Assert.assertTrue(handler.m_errors.contains("org.apache.felix.ipojo.tests.core.component.MyErroneousComponent-0:[org.apache.felix.ipojo.tests.core.component.MyErroneousComponent-0] createInstance -> Cannot invoke the constructor method - the constructor throws an exception : bad:bad"));
+    }
+
+
+   private class MyErrorHandler implements ErrorHandler {
+
+	   private List<String> m_errors = new ArrayList<String>();
+
+	   public void onError(ComponentInstance instance, String message,
+				Throwable error) {
+		   System.out.println("on Error ! " + instance + " - " + message);
+			if (instance == null) {
+				if (error == null) {
+					m_errors.add("no-instance:" + message);
+				} else {
+					m_errors.add("no-instance:" + message + ":" + error.getMessage());
+				}
+			} else {
+				if (error == null) {
+					m_errors.add(instance.getInstanceName() + ":" + message);
+				} else {
+					m_errors.add(instance.getInstanceName() + ":" + message + ":" + error.getMessage());
+				}
+			}
+		}
+
+	   public void onWarning(ComponentInstance instance, String message,
+				Throwable error) {
+		   System.out.println("on warning ! " + instance + " - " + message);
+		}
+
+   }
+
+
+}
diff --git a/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/ManifestLoggerInfoTest.java b/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/ManifestLoggerInfoTest.java
index 7a9e9b7..5ca7c9d 100644
--- a/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/ManifestLoggerInfoTest.java
+++ b/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/ManifestLoggerInfoTest.java
@@ -1,5 +1,6 @@
 package org.apache.felix.ipojo.tests.core;
 
+import static org.ops4j.pax.exam.CoreOptions.equinox;
 import static org.ops4j.pax.exam.CoreOptions.felix;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
 import static org.ops4j.pax.exam.CoreOptions.options;
@@ -9,6 +10,7 @@
 import static org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOBuilder.withiPOJO;
 
 import java.io.File;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
@@ -20,13 +22,14 @@
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Customizer;
 import org.ops4j.pax.exam.Inject;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.Configuration;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.swissbox.tinybundles.core.TinyBundles;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -78,7 +81,7 @@
 
         Option[] opt =  options(
                 felix(),
-//                equinox(),
+                equinox(),
                 provision(
                         // Runtime.
                         mavenBundle().groupId( "org.apache.felix" ).artifactId( "org.apache.felix.log" ).version(asInProject()),
@@ -98,15 +101,22 @@
                             .add(MyComponent.class)
                             .set(Constants.BUNDLE_SYMBOLICNAME,"MyComponent")
                             .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.tests.core.service")
-                            .set("ipojo-log-level", "info")
+                            .set("Ipojo-log-level", "info")
                             .build( withiPOJO(new File(tmp, "provider-with-level-in-manifest.jar"), new File("component.xml")))
-                            )
-                );
+                            ),
+                new Customizer() {
+                    @Override
+                    public InputStream customizeTestProbe( InputStream testProbe )
+                    {
+                       return TinyBundles.modifyBundle(testProbe)
+                           .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.tests.core.service")
+                           .build();
+                    }
+                });
         return opt;
     }
 
     @Test
-    @Ignore //TODO Why we have a classloading issue here ?
     public void testMessages() throws InterruptedException, InvalidSyntaxException {
         Bundle bundle = osgi.getBundle("MyComponent");
         Assert.assertNotNull(bundle);
@@ -123,9 +133,9 @@
 
 
 
-   //     Assert.assertNotNull(osgi.getServiceObject(MyService.class.getName(), null));
+        Assert.assertNotNull(osgi.getServiceObject(MyService.class.getName(), null));
 
-//        osgi.waitForService("org.apache.felix.ipojo.tests.core.service.MyService", null, 5000);
+        osgi.waitForService("org.apache.felix.ipojo.tests.core.service.MyService", null, 5000);
         List<String> messages = getMessages(log.getLog());
         System.out.println(messages);
         Assert.assertTrue(messages.contains("Ready"));
diff --git a/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/component/MyErroneousComponent.java b/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/component/MyErroneousComponent.java
new file mode 100644
index 0000000..feca648
--- /dev/null
+++ b/ipojo/tests/core/logger/src/test/java/org/apache/felix/ipojo/tests/core/component/MyErroneousComponent.java
@@ -0,0 +1,15 @@
+package org.apache.felix.ipojo.tests.core.component;
+
+import org.apache.felix.ipojo.tests.core.service.MyService;
+
+public class MyErroneousComponent implements MyService {
+
+	public MyErroneousComponent() {
+		throw new NullPointerException("bad");
+	}
+
+    public void foo() {
+        // Nothing to do.
+    }
+
+}