Package org.apache.felix.ipojo.online.manipulator

Source Code of org.apache.felix.ipojo.online.manipulator.IPOJOURLHandler

/*
* 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.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;

/**
* iPOJO URL Handler allowing installation time manipulation.
* When a bundle is installed with the <code>ipojo:</code> URL
* prefix, the bundle is downloaded and manipulated by this
* handler.
* The metadata.xml file can either be provided inside the bundle (root,
* or in META-INF) or given in the URL:
* ipojo:URL_BUNDLE!URL_METADATA.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class IPOJOURLHandler extends org.osgi.service.url.AbstractURLStreamHandlerService implements URLStreamHandlerService {
   
    /**
     * The bundle context.
     */
    private BundleContext m_context;
   
    /**
     * The directory storing bundles.
     */
    private File m_temp;
   
    /**
     * Creates a IPOJOURLHandler.
     * Gets the bundle context and create the working
     * directory.
     * @param bc the bundle context
     */
    public IPOJOURLHandler(BundleContext bc) {
        m_context = bc;
        m_temp = m_context.getDataFile("temp");
        if (! m_temp.exists()) {
            m_temp.mkdir();
        }
    }
   
    /**
     * Stops the URL handler:
     * Deletes the working directory. 
     */
    public void stop() {
        File[] files = m_temp.listFiles();
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                files[i].delete();
            }
        }
        m_temp.delete();
    }

    /**
     * Opens a connection using the ipojo url handler.
     * This methods parses the URL and manipulate the given bundle.
     * @param url the url.
     * @return the URL connection on the manipulated bundle
     * @throws IOException  occurs when the bundle cannot be either downloaded, or manipulated or
     * installed correctly.
     * @see org.osgi.service.url.AbstractURLStreamHandlerService#openConnection(java.net.URL)
     */
    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.toURI().toURL().openConnection();
       
       
    }

    /**
     * Downloads the content pointed by the given url to
     * the given file.
     * @param url   the url
     * @param file  the file
     * @throws IOException occurs if the content cannot be read
     * and save inside the file
     */
    private void save(URL url, File file) throws IOException {
        InputStream is = url.openStream();
        save(is, file);
    }
   
    /**
     * Saves the content of the input stream to the given file.
     * @param is    the input stream to read
     * @param file  the file
     * @throws IOException  occurs if the content cannot be read
     * and save inside the 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();       
    }
   
    /**
     * Looks for the metadata.xml file in the jar file.
     * Two locations are checked:
     * <ol>
     * <li>the root of the jar file</li>
     * <li>the META-INF directory</li>
     * </ol>
     * @param jar   the jar file
     * @return  the founded file or <code>null</code> if not found.
     * @throws IOException  occurs when the Jar file cannot be read.
     */
    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) {
            System.out.println("Metadata file not found, use annotations only.");
            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;
        }
       
    }
   
}
TOP

Related Classes of org.apache.felix.ipojo.online.manipulator.IPOJOURLHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.