Update junit4osgi to use Felix 2.0
Apply the patch from Felix-1646 (just change some cosmetic stuff)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@819461 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java b/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java
new file mode 100644
index 0000000..e2461ad
--- /dev/null
+++ b/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares a handler.
+ * This annotation is mandatory to declares an iPOJO handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Handler {
+
+    /**
+     * Name of the handler (required).
+     */
+    String name();
+
+    /**
+     * Namespace of the handler (required).
+     */
+    String namespace();
+
+    /**
+     * Start-level of the handler.
+     * Default: 1.
+     */
+    int level() default 1;
+
+    /**
+     * Enable / Disable the architecture exposition.
+     * Default : false
+     */
+    boolean architecture() default false;
+}
diff --git a/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java b/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java
new file mode 100644
index 0000000..242e928
--- /dev/null
+++ b/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation is used to configure a handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface HandlerDeclaration {
+
+    /**
+     * The content of this attribute represents the XML 
+     * that would be used in the metadata.xml.
+     */
+    String value();
+}
diff --git a/ipojo/junit4osgi/maven-junit4osgi-plugin/pom.xml b/ipojo/junit4osgi/maven-junit4osgi-plugin/pom.xml
index 1909460..6555f44 100644
--- a/ipojo/junit4osgi/maven-junit4osgi-plugin/pom.xml
+++ b/ipojo/junit4osgi/maven-junit4osgi-plugin/pom.xml
@@ -41,7 +41,8 @@
     <dependency>
       <groupId>org.apache.felix</groupId>
       <artifactId>org.apache.felix.framework</artifactId>
-      <version>1.8.1</version>
+      <!--  <version>1.8.1</version> -->
+      <version>2.0.0</version>
     </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
diff --git a/ipojo/junit4osgi/maven-junit4osgi-plugin/src/main/java/org/apache/felix/ipojo/junit4osgi/plugin/Junit4osgiPlugin.java b/ipojo/junit4osgi/maven-junit4osgi-plugin/src/main/java/org/apache/felix/ipojo/junit4osgi/plugin/Junit4osgiPlugin.java
index c32af8c..953926b 100644
--- a/ipojo/junit4osgi/maven-junit4osgi-plugin/src/main/java/org/apache/felix/ipojo/junit4osgi/plugin/Junit4osgiPlugin.java
+++ b/ipojo/junit4osgi/maven-junit4osgi-plugin/src/main/java/org/apache/felix/ipojo/junit4osgi/plugin/Junit4osgiPlugin.java
@@ -47,6 +47,7 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -211,27 +212,29 @@
         felixConf.put("org.osgi.framework.storage.clean", "onFirstInit");
         felixConf.put("ipojo.log.level", "WARNING");
         // Use a boot delagation to share classes between the host and the embedded Felix.
-        // The junit.framework package is boot delegated to execute tests
-        // The log service package is also boot delegated as the host publish a log service
         // The cobertura package is used during code coverage collection
-        felixConf.put("org.osgi.framework.bootdelegation", "junit.framework, org.osgi.service.log, net.sourceforge.cobertura.coveragedata"); 
+        //felixConf.put("org.osgi.framework.bootdelegation", "net.sourceforge.cobertura.coveragedata"); 
+        felixConf.put("org.osgi.framework.system.packages.extra", "org.osgi.service.log;version=1.3, junit.framework;version=1.3");
+
+        //felixConf.put("org.osgi.framework.system.packages.extra", "org.osgi.service.log, junit.framework");
         
         felixConf.put("org.osgi.framework.storage", m_targetDir.getAbsolutePath() + "/felix-cache"); 
         
-        
+        felixConf.put(Constants.FRAMEWORK_BUNDLE_PARENT, Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK);
+
         if (configuration != null) {
             felixConf.putAll(configuration);
             // Check boot delegation
-            String bd = (String) felixConf.get("org.osgi.framework.bootdelegation");
-            if (bd.indexOf("junit.framework") == -1) {
-                bd.concat(", junit.framework");
-            }
-            if (bd.indexOf("org.osgi.service.log") == -1) {
-                bd.concat(", org.osgi.service.log");
-            }
-            if (bd.indexOf("net.sourceforge.cobertura.coveragedata") == -1) {
-                bd.concat(", net.sourceforge.cobertura.coveragedata");
-            }
+//            String bd = (String) felixConf.get("org.osgi.framework.bootdelegation");
+////            if (bd.indexOf("junit.framework") == -1) {
+////                bd.concat(", junit.framework");
+////            }
+////            if (bd.indexOf("org.osgi.service.log") == -1) {
+////                bd.concat(", org.osgi.service.log");
+////            }
+//            if (bd.indexOf("net.sourceforge.cobertura.coveragedata") == -1) {
+//                bd.concat(", net.sourceforge.cobertura.coveragedata");
+//            }
         }
         
         System.out.println("");
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
index 6ecda0d..d989f70 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -18,11 +18,17 @@
  */
 package org.apache.felix.ipojo.manipulation.annotations;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
 import org.apache.felix.ipojo.metadata.Attribute;
 import org.apache.felix.ipojo.metadata.Element;
 import org.objectweb.asm.AnnotationVisitor;
@@ -31,6 +37,10 @@
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 import org.objectweb.asm.commons.EmptyVisitor;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.NodeList;
 
 /**
  * Collect metadata from classes by parsing annotation.
@@ -47,7 +57,7 @@
     /**
      * Root element of computed metadata.
      */
-    private Element m_elem = new Element("component", "");
+    private Element m_elem = null;
 
     /**
      * True if the visited class is a component type declaration (i.e. contains the @component annotation).
@@ -67,6 +77,11 @@
      */
     private Map m_elements = new HashMap();
 
+    /**
+     * XML document parser.
+     */
+    private DocumentBuilder m_builder;
+
     public Element getElem() {
         return m_elem;
     }
@@ -106,16 +121,31 @@
         // @Component
         if (desc.equals("Lorg/apache/felix/ipojo/annotations/Component;")) {
             // It is a component
+            m_elem =  new Element("component", "");
             m_containsAnnotation = true;
             m_elem.addAttribute(new Attribute("className", m_className.replace('/', '.')));
             return new ComponentVisitor();
         }
 
+        // @Handler
+        if (desc.equals("Lorg/apache/felix/ipojo/annotations/Handler;")) {
+            // It is a handler, change the root element
+            m_elem = new Element("handler", "");
+            m_containsAnnotation = true;
+            m_elem.addAttribute(new Attribute("classname", m_className.replace('/', '.')));
+            return new HandlerVisitor();
+        }
+
         // @Provides
         if (desc.equals("Lorg/apache/felix/ipojo/annotations/Provides;")) {
             return new ProvidesVisitor();
         }
 
+        // @HandlerDeclaration
+        if (desc.equals("Lorg/apache/felix/ipojo/annotations/HandlerDeclaration;")) {
+            return new HandlerDeclarationVisitor();
+        }
+
         if (CustomAnnotationVisitor.isCustomAnnotation(desc)) {
             Element elem = CustomAnnotationVisitor.buildElement(desc);
             return new CustomAnnotationVisitor(elem, this, true, true);
@@ -191,6 +221,32 @@
     }
 
     /**
+     * Creates a 'fresh' document builder.
+     * @return a new document builder is not already created, else reset
+     * the created one, and return it.
+     */
+    protected DocumentBuilder getFreshDocumentBuilder() {
+        if (m_builder == null) {
+
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            try {
+                m_builder = factory.newDocumentBuilder();
+            } catch (ParserConfigurationException e) {
+                // TODO GSA is this acceptable to throw a RuntimeException here ?
+                e.printStackTrace();
+            }
+
+            return m_builder;
+        }
+
+        // The builder has to be reseted
+        m_builder.reset();
+
+        return m_builder;
+    }
+
+    /**
      * Parse the @provides annotation.
      */
     private class ProvidesVisitor extends EmptyVisitor implements AnnotationVisitor {
@@ -407,4 +463,115 @@
             }
         }
     }
+
+    /**
+     * Parses the @Handler annotation.
+     */
+    private class HandlerVisitor extends EmptyVisitor implements AnnotationVisitor {
+
+        /**
+         * Visit @handler annotation attributes.
+         * @param arg0 : annotation attribute name
+         * @param arg1 : annotation attribute value
+         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
+         */
+        public void visit(String arg0, Object arg1) {
+            if (arg0.equals("name")) {
+                m_elem.addAttribute(new Attribute("name", arg1.toString()));
+                return;
+            }
+            if (arg0.equals("namespace")) {
+                m_elem.addAttribute(new Attribute("namespace", arg1.toString()));
+                return;
+            }
+            if (arg0.equals("level")) {
+                m_elem.addAttribute(new Attribute("level", arg1.toString()));
+                return;
+            }
+            if (arg0.equals("architecture")) {
+                m_elem.addAttribute(new Attribute("architecture", arg1.toString()));
+                return;
+            }
+        }
+    }
+
+    /**
+     * Parse the @HandlerDeclaration annotation.
+     */
+    private class HandlerDeclarationVisitor extends EmptyVisitor implements AnnotationVisitor {
+
+        /**
+         * XML accepted by the handler.
+         */
+        private String m_value;
+
+        /**
+         * Parses the value attribute.
+         * @param arg0 'value'
+         * @param arg1 the value
+         * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
+         */
+        public void visit(String arg0, Object arg1) {
+            // there is only a 'value' attribute
+            this.m_value = (String) arg1;
+        }
+
+        /**
+         * End of the visit.
+         * Builds the XML document.
+         * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
+         */
+        public void visitEnd() {
+            // The value is an XML document
+            DocumentBuilder builder = getFreshDocumentBuilder();
+            InputStream is = new ByteArrayInputStream(m_value.getBytes());
+            Document document = null;
+            try {
+                document = builder.parse(is);
+                convertDOMElements(m_elem, document.getDocumentElement());
+            } catch (Exception e) {
+                // TODO GSA change this to a logger ?
+                System.err.println("[warning] Cannot convert " + m_value + " to iPOJO Elements.");
+            }
+        }
+
+        /**
+         * Converts recursively the given XML Element into an iPOJO Element.
+         * @param root iPOJO root Element
+         * @param xmlElement DOM Element to be converted
+         */
+        private void convertDOMElements(final Element root,
+                                        final org.w3c.dom.Element xmlElement) {
+
+            // Create an equivalent iPOJO element
+            Element converted = new Element(xmlElement.getLocalName(), xmlElement.getNamespaceURI());
+
+            // Convert attributes if any
+            if (xmlElement.hasAttributes()) {
+                NamedNodeMap attributes = xmlElement.getAttributes();
+                for (int i = 0; i < attributes.getLength(); i++) {
+                    Attr attr = (Attr) attributes.item(i);
+                    converted.addAttribute(new Attribute(attr.getName(),
+                                                         attr.getNamespaceURI(),
+                                                         attr.getValue()));
+                }
+            }
+
+            // Convert child elements if any
+            if (xmlElement.hasChildNodes()) {
+                NodeList childs = xmlElement.getChildNodes();
+                for (int i = 0; i < childs.getLength(); i++) {
+
+                    // Recursive call
+                    convertDOMElements(converted, (org.w3c.dom.Element) childs.item(i));
+                }
+            }
+
+            // Add converted element as a root's child
+            root.addElement(converted);
+        }
+
+
+    }
 }
+
diff --git a/ipojo/tests/integration-tests/pom.xml b/ipojo/tests/integration-tests/pom.xml
index cc564e3..38a79f1 100644
--- a/ipojo/tests/integration-tests/pom.xml
+++ b/ipojo/tests/integration-tests/pom.xml
@@ -24,6 +24,7 @@
             </goals>
             <configuration>
               <hideOutputs>true</hideOutputs>
+              <logService>false</logService>
               <configuration>
               <org.osgi.http.port>8083</org.osgi.http.port>
               </configuration>
@@ -239,12 +240,7 @@
       <scope>test</scope>
     </dependency>
   <!--  Utility bundles -->
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.configadmin</artifactId>
-      <version>1.2.2</version>
-      <scope>test</scope>
-    </dependency>
+   
     <dependency>
       <groupId>org.apache.felix</groupId>
       <artifactId>org.apache.felix.ipojo.handler.whiteboard</artifactId>
@@ -287,6 +283,12 @@
       <version>${ipojo.version}</version>
       <scope>test</scope>
     </dependency>
+     <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.configadmin</artifactId>
+      <version>1.2.4</version>
+      <scope>test</scope>
+    </dependency>
     </dependencies>
     </profile>
   </profiles>