org.ebayopensource.turmeric.eclipse.utils.classloader.SOAPluginClassLoader.java Source code

Java tutorial

Introduction

Here is the source code for org.ebayopensource.turmeric.eclipse.utils.classloader.SOAPluginClassLoader.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
 * Licensed 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
 *******************************************************************************/
package org.ebayopensource.turmeric.eclipse.utils.classloader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.io.FileUtils;
import org.osgi.framework.Bundle;

/**
 * The Class SOAPluginClassLoader.
 *
 * @author smathew
 */
public class SOAPluginClassLoader extends URLClassLoader {
    private static final URL[] EMPTY_URLS = new URL[0];
    private static final Comparator<URL> URL_COMPARATOR = new Comparator<URL>() {

        @Override
        public int compare(URL o1, URL o2) {
            return (o1 != null && o2 != null) ? o1.toString().compareTo(o2.toString()) : 0;
        }
    };
    private Set<URL> m_jarURLs = new TreeSet<URL>(URL_COMPARATOR);
    private Set<URL> m_dirURLs = new TreeSet<URL>(URL_COMPARATOR);
    private Set<URL> m_classPathURLs = new TreeSet<URL>(URL_COMPARATOR);
    private List<Bundle> pluginBundles = new ArrayList<Bundle>();
    private static final Logger logger = Logger.getLogger(SOAPluginClassLoader.class.getName());

    /**
     * Instantiates a new sOA plugin class loader.
     *
     * @param name the name
     * @param urls the urls
     */
    public SOAPluginClassLoader(String name, URL[] urls) {
        super(EMPTY_URLS);

        for (int i = 0; i < urls.length; i++) {
            File file = FileUtils.toFile(urls[i]);
            if (file.isDirectory()) {
                m_dirURLs.add(urls[i]);
            } else if (file.isFile()) {
                m_jarURLs.add(urls[i]);
            }
        }
        for (URL dirURL : m_dirURLs) {
            addURL(dirURL);
        }
        m_classPathURLs.addAll(m_jarURLs);
        m_classPathURLs.addAll(m_dirURLs);
        if (logger.isLoggable(Level.FINE)) {
            logger.fine("Inside soa plugin loader setM_classPathURLs: " + m_classPathURLs);
        }
    }

    /* (non-Javadoc)
     * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
     */
    @Override
    protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        try {
            Class<?> _class = doLoadClass(name);
            if (_class != null)
                return _class;
        } catch (Exception e) {
            //oops, got some problems just ignore it.
        }
        return super.loadClass(name, resolve);
    }

    private Class<?> doLoadClass(String className) throws ClassNotFoundException {
        Class<?> clazz = null;
        try {
            for (Bundle pluginBundle : pluginBundles) {
                clazz = pluginBundle.loadClass(className);
                if (clazz != null) {
                    //logger.info("loaded using bundle class loader->"
                    //      + className);
                    return clazz;
                }
            }

        } catch (ClassNotFoundException classNotFoundException) {
        }
        return clazz;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        Class<?> loadedClass = findLoadedClass(name);
        if (loadedClass != null) {
            return loadedClass;
        }

        StringBuilder sb = new StringBuilder(name.length() + 6);
        sb.append(name.replace('.', '/')).append(".class");

        InputStream is = getResourceAsStream(sb.toString());

        if (is == null)
            throw new ClassNotFoundException("Class not found " + sb);
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int len;
            while ((len = is.read(buf)) >= 0)
                baos.write(buf, 0, len);

            buf = baos.toByteArray();

            // define package if not defined yet
            int i = name.lastIndexOf('.');
            if (i != -1) {
                String pkgname = name.substring(0, i);
                Package pkg = getPackage(pkgname);
                if (pkg == null)
                    definePackage(pkgname, null, null, null, null, null, null, null);
            }
            baos.close();
            is.close();
            return defineClass(name, buf, 0, buf.length);
        } catch (IOException e) {
            throw new ClassNotFoundException(name, e);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public URL findResource(String resourceName) {
        //logger.info("resource name in findresource is " + resourceName);
        try {
            URL retUrl = null;
            for (Bundle pluginBundle : pluginBundles) {
                retUrl = pluginBundle.getResource(resourceName);
                if (retUrl != null) {
                    if (logger.isLoggable(Level.FINE)) {
                        logger.fine("found resource using bundle " + resourceName);
                    }
                    return retUrl;
                }
            }

        } catch (Exception exception) {
        }

        for (URL url : m_jarURLs) {

            try {
                File file = FileUtils.toFile(url);
                JarFile jarFile;
                jarFile = new JarFile(file);
                JarEntry jarEntry = jarFile.getJarEntry(resourceName);
                if (jarEntry != null) {
                    SOAToolFileUrlHandler handler = new SOAToolFileUrlHandler(jarFile, jarEntry);
                    URL retUrl = new URL("jar", "", -1,
                            new File(jarFile.getName()).toURI().toURL() + "!/" + jarEntry.getName(), handler);
                    handler.setExpectedUrl(retUrl);
                    return retUrl;

                }
            } catch (IOException e) {
                e.printStackTrace(); // KEEPME
            }

        }

        return super.findResource(resourceName);
    }

    /**
     * Gets the plugin bundles.
     *
     * @return the plugin bundles
     */
    public List<Bundle> getPluginBundles() {
        return pluginBundles;
    }

    /**
     * Sets the plugin bundles.
     *
     * @param pluginBundles the new plugin bundles
     */
    public void setPluginBundles(List<Bundle> pluginBundles) {
        this.pluginBundles = pluginBundles;
    }

    /* (non-Javadoc)
     * @see java.net.URLClassLoader#getURLs()
     */
    @Override
    public URL[] getURLs() {
        return m_classPathURLs.toArray(new URL[0]);
    }

    /**
     * Gets the m_class path ur ls.
     *
     * @return the m_class path ur ls
     */
    public Set<URL> getM_classPathURLs() {
        return m_classPathURLs;
    }

    /**
     * Sets the m_class path ur ls.
     *
     * @param pathURLs the new m_class path ur ls
     */
    public void setM_classPathURLs(Set<URL> pathURLs) {
        if (logger.isLoggable(Level.FINE)) {
            logger.fine("Inside soa plugin loader setM_classPathURLs: " + pathURLs);
        }
        m_classPathURLs = pathURLs;
    }

}