Copy the online manipulator to the trunk

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@767425 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/online-manipulator/metadata.xml b/ipojo/online-manipulator/metadata.xml
new file mode 100644
index 0000000..352564c
--- /dev/null
+++ b/ipojo/online-manipulator/metadata.xml
@@ -0,0 +1,11 @@
+<ipojo>
+<component classname="org.apache.felix.org.apache.felix.ipojo.online.manipulator.IPOJOURLHandler" 
+	public="false"
+	immediate="true">
+	<provides>
+		<property name="url.handler.protocol" type="java.lang.String" value="ipojo"/>
+	</provides>
+	<callback transition="invalidate" method="stop"/>
+</component>
+<instance component="org.apache.felix.org.apache.felix.ipojo.online.manipulator.IPOJOURLHandler"/>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/online-manipulator/pom.xml b/ipojo/online-manipulator/pom.xml
new file mode 100644
index 0000000..68d7b62
--- /dev/null
+++ b/ipojo/online-manipulator/pom.xml
@@ -0,0 +1,82 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <groupId>org.apache.felix</groupId>
+  <artifactId>org.apache.felix.ipojo.online.manipulator</artifactId>
+  <version>1.3.0-SNAPSHOT</version>
+  <name>Apache Felix iPOJO URL Handler</name>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>1.4.3</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+            <Private-Package>org.apache.felix.org.apache.felix.ipojo.online.manipulator</Private-Package>
+            <Export-Package>
+            				org.apache.felix.ipojo.manipulator,
+            				org.apache.felix.ipojo.xml.parser,
+            				org.apache.felix.ipojo.manipulation,
+							org.apache.felix.ipojo.manipulation.annotations,
+							org.objectweb.asm.commons, org.objectweb.asm
+			</Export-Package>
+			<Import-Package>
+			!org.objectweb.asm.tree, !sun.io,
+							*
+						</Import-Package>
+						<Embed-Dependency>xercesImpl|xml-resolver</Embed-Dependency>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+	      <groupId>org.apache.felix</groupId>
+	      <artifactId>maven-ipojo-plugin</artifactId>
+	       <version>1.3.0-SNAPSHOT</version>
+		  <executions>
+          	<execution>
+            	<goals>
+	              <goal>ipojo-bundle</goal>
+               </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+  			<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
+			<version>1.3.0-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>asm</groupId>
+			<artifactId>asm-all</artifactId>
+			<version>3.0</version>
+			<exclusions>
+				<exclusion>
+					<groupId>asm</groupId>
+					<artifactId>asm-tree</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+  	<dependency>
+  		<groupId>org.apache.felix</groupId>
+  		<artifactId>org.osgi.core</artifactId>
+  		<version>1.2.0</version>
+  	</dependency>
+  	<dependency>
+  		<groupId>xerces</groupId>
+  		<artifactId>xercesImpl</artifactId>
+  		<version>2.9.1</version>
+  	</dependency>
+  	<dependency>
+  		<groupId>xml-resolver</groupId>
+  		<artifactId>xml-resolver</artifactId>
+  		<version>1.2</version>
+  	</dependency>
+  </dependencies>
+</project>
diff --git a/ipojo/online-manipulator/src/main/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/IPOJOURLHandler.java b/ipojo/online-manipulator/src/main/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/IPOJOURLHandler.java
new file mode 100644
index 0000000..27b0bc0
--- /dev/null
+++ b/ipojo/online-manipulator/src/main/java/org/apache/felix/org/apache/felix/ipojo/online/manipulator/IPOJOURLHandler.java
@@ -0,0 +1,155 @@
+package org.apache.felix.org.apache.felix.ipojo.online.manipulator;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.felix.ipojo.manipulator.Pojoization;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.url.URLStreamHandlerService;
+
+public class IPOJOURLHandler extends org.osgi.service.url.AbstractURLStreamHandlerService implements URLStreamHandlerService {
+    
+    private BundleContext m_context;
+    private File m_temp;
+    
+    public IPOJOURLHandler(BundleContext bc) {
+        m_context = bc;
+        m_temp = m_context.getDataFile("temp");
+        if (! m_temp.exists()) {
+            m_temp.mkdir();
+        }
+    }
+    
+    public void stop() {
+        File[] files = m_temp.listFiles();
+        for (int i = 0; i < files.length; i++) {
+            files[i].delete();
+        }
+        m_temp.delete();
+    }
+
+    public URLConnection openConnection(URL url) throws IOException {
+        System.out.println("Processing URL : " + url);
+
+       // Parse the url:
+        String full = url.toExternalForm();
+        // Remote ipojo://
+        if (full.startsWith("ipojo:")) {
+            full = full.substring(6);
+        }
+        // Remove '/' or '//'
+        while (full.startsWith("/")) {
+            full = full.substring(1);
+        }
+        
+        full = full.trim();
+        
+        // Now full is like : URL,URL or URL
+        String urls[] = full.split("!");
+        URL bundleURL = null;
+        URL metadataURL = null;
+        if (urls.length == 1) {
+            // URL form
+            System.out.println("Extracted URL : " + urls[0]);
+            bundleURL = new URL(urls[0]);
+        } else if (urls.length == 2){
+            // URL,URL form
+            bundleURL = new URL(urls[0]);
+            metadataURL = new URL(urls[1]);
+        } else {
+            throw new MalformedURLException("The iPOJO url is not formatted correctly, ipojo://bundle_url[!metadata_url] expected");
+        }
+        
+        File bundle = File.createTempFile("ipojo_", ".jar", m_temp);
+        save(bundleURL, bundle);
+        File metadata = null;
+        if (metadataURL != null) {
+            metadata = File.createTempFile("ipojo_", ".xml", m_temp);
+            save(metadataURL, metadata);   
+        } else {
+            // Check that the metadata are in the jar file
+            JarFile jar = new JarFile(bundle);
+            metadata = findMetadata(jar); 
+        }
+        
+        // Pojoization
+        Pojoization pojoizator = new Pojoization();
+        File out =  new File(m_temp, bundle.getName()+"-ipojo.jar");
+        System.out.println("Pojoization " + bundle.exists() + " - " + metadata.exists());
+        try {
+            pojoizator.pojoization(bundle, out, metadata);
+        } catch (Exception e) {
+            if (! pojoizator.getErrors().isEmpty()) {
+                throw new IOException("Errors occured during the manipulation : " + pojoizator.getErrors());
+            }
+            e.printStackTrace();
+            throw new RuntimeException(e.getMessage());
+        }
+        
+        if (! pojoizator.getErrors().isEmpty()) {
+            throw new IOException("Errors occured during the manipulation : " + pojoizator.getErrors());
+        }
+        if (! pojoizator.getWarnings().isEmpty()) {
+           System.err.println("Warnings occured during the manipulation : " + pojoizator.getWarnings());
+        }
+
+        System.out.println("Manipulation done : " + out.exists());
+        
+        // Cleanup
+        bundle.delete();
+        if (metadata != null) {
+            metadata.delete();
+        }
+        out.deleteOnExit();
+        // Returns the URL Connection
+        return out.toURL().openConnection();
+        
+        
+    }
+
+    private void save(URL url, File file) throws IOException {
+        InputStream is = url.openStream();
+        save(is, file);
+    }
+    
+    private void save(InputStream is, File file) throws IOException {
+        FileOutputStream writer = new FileOutputStream(file);
+        int cc = 0;
+        do {
+            int i = is.read();
+            if (i == -1)
+                break;
+            cc++;
+            writer.write(i);
+        } while (true);
+        System.out.println(cc + " bytes copied");
+        is.close();
+        writer.close();        
+    }
+    
+    private File findMetadata(JarFile jar) throws IOException {
+        JarEntry je = jar.getJarEntry("metadata.xml");
+        if (je == null) {
+            je = jar.getJarEntry("META-INF/metadata.xml");
+        }
+        
+        if (je == null) {
+            return null; // Not Found, use annotation only
+        } else {
+            System.out.println("Metadata file found: " + je.getName());
+            File metadata = File.createTempFile("ipojo_", ".xml", m_temp);
+            save(jar.getInputStream(je), metadata);
+            System.out.println("Metadata file saved to " + metadata.getAbsolutePath());
+            return metadata;
+        }
+        
+    }
+    
+}