Package org.apache.geronimo.hook.equinox

Source Code of org.apache.geronimo.hook.equinox.GeronimoClassLoader

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

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;

import org.eclipse.osgi.baseadaptor.BaseData;
import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
import org.eclipse.osgi.framework.adaptor.BundleData;
import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
import org.eclipse.osgi.framework.internal.core.AbstractBundle;
import org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader;
import org.eclipse.osgi.service.urlconversion.URLConverter;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

public class GeronimoClassLoader extends URLClassLoader implements BaseClassLoader {

    private static final String PREFIX = "org.apache.xbean.osgi.bundle.util.BundleResourceHelper";
    private static final String SEARCH_WIRED_BUNDLES = PREFIX + ".searchWiredBundles";
    private static final String CONVERT_RESOURCE_URLS = PREFIX + ".convertResourceUrls";

    private final static String META_INF_1 = "META-INF/";
    private final static String META_INF_2 = "/META-INF/";

    private final ClassLoaderHook hook;
    private final ClassLoaderDelegate delegate;
    private final ProtectionDomain domain;
    private final AbstractBundle bundle;
    private final ClasspathManager manager;

    private LinkedHashSet<Bundle> wiredBundles = null;
    private boolean searchWiredBundles = getSearchWiredBundles(true);
    private boolean convertResourceUrls = getConvertResourceUrls(true);

    private URLConverter converter;

    public GeronimoClassLoader(ClassLoaderHook hook,
                               ClassLoader parent,
                               ClassLoaderDelegate delegate,
                               ProtectionDomain domain,
                               BaseData bundledata,
                               String[] classpath,
                               AbstractBundle bundle) {
        super(new URL[] {}, parent);
        this.hook = hook;
        this.delegate = delegate;
        this.domain = domain;
        this.bundle = bundle;

        this.manager = new ClasspathManager(bundledata, classpath, this);
    }

    @Override
    protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
        Class clazz = delegate.findClass(name);
        if (resolve) {
            resolveClass(clazz);
        }
        return clazz;
    }

    @Override
    public URL getResource(String name) {
        URL resource = delegate.findResource(name);
        if (resource == null && isMetaInfResource(name)) {
            LinkedHashSet<Bundle> wiredBundles = getWiredBundles();
            Iterator<Bundle> iterator = wiredBundles.iterator();
            while (iterator.hasNext() && resource == null) {
                resource = iterator.next().getResource(name);
            }
        }
        if (resource != null && converter != null) {
            return convert(resource);
        } else {
            return resource;
        }
    }

    @Override
    public Enumeration<URL> findResources(String name) throws IOException {
        Enumeration<URL> e = delegate.findResources(name);
        if (isMetaInfResource(name)) {
            List<URL> allResources = getList();
            addToList(allResources, e);
            LinkedHashSet<Bundle> wiredBundles = getWiredBundles();
            for (Bundle wiredBundle : wiredBundles) {
                Enumeration<URL> resources = wiredBundle.getResources(name);
                addToList(allResources, resources);
            }
            return Collections.enumeration(allResources);
        } else if (e == null) {
            return Collections.enumeration(Collections.<URL>emptyList());
        } else {
            List<URL> allResources = getList();
            addToList(allResources, e);
            return Collections.enumeration(allResources);
        }
    }

    public void setSearchWiredBundles(boolean search) {
        searchWiredBundles = search;
    }

    public boolean getSearchWiredBundles() {
        return searchWiredBundles;
    }

    private synchronized LinkedHashSet<Bundle> getWiredBundles() {
        if (wiredBundles == null) {
            wiredBundles = BundleUtils.getWiredBundles(bundle);
        }
        return wiredBundles;
    }

    private boolean isMetaInfResource(String name) {
        return searchWiredBundles && name != null && (name.startsWith(META_INF_1) || name.startsWith(META_INF_2));
    }

    private List<URL> getList() {
        if (converter == null) {
            return new ArrayList<URL>();
        } else {
            return new ArrayList<URL>() {
                public boolean add(URL u) {
                    return super.add(convert(u));
                }
            };
        }
    }

    private void addToList(List<URL> list, Enumeration<URL> enumeration) {
        if (enumeration != null) {
            while (enumeration.hasMoreElements()) {
                list.add(enumeration.nextElement());
            }
        }
    }

    private URL convert(URL url) {
        try {
            URL convertedURL = converter.resolve(url);
            return convertedURL;
        } catch (IOException e) {
            e.printStackTrace();
            return url;
        }
    }

    public void initialize() {
        manager.initialize();
        if (convertResourceUrls) {
            BundleContext context = bundle.getBundleContext();
            if (context != null) {
                ServiceReference urlReference = context.getServiceReference(URLConverter.class.getName());
                if (urlReference != null) {
                    converter = (URLConverter) context.getService(urlReference);
                }
            }
        }
    }

    public void close() {
        manager.close();
    }

    // other BaseClassLoader methods

    public ProtectionDomain getDomain() {
        return domain;
    }

    @Override
    protected String findLibrary(String libname) {
        // let the manager find the library for us
        return manager.findLibrary(libname);
    }

    public ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain cpDomain) {
        return new ClasspathEntry(bundlefile, DefaultClassLoader.createProtectionDomain(bundlefile, cpDomain));
    }

    public Class defineClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry) {
        return defineClass(name, classbytes, 0, classbytes.length, classpathEntry.getDomain());
    }

    public Class publicFindLoaded(String classname) {
        return findLoadedClass(classname);
    }

    public Object publicGetPackage(String pkgname) {
        return getPackage(pkgname);
    }

    public Object publicDefinePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) {
        return definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
    }

    public URL findLocalResource(String resource) {
        return manager.findLocalResource(resource);
    }

    public Enumeration findLocalResources(String resource) {
        return manager.findLocalResources(resource);
    }

    public Class findLocalClass(String classname) throws ClassNotFoundException {
        return manager.findLocalClass(classname);
    }

    public void attachFragment(BundleData sourcedata, ProtectionDomain sourcedomain, String[] sourceclasspath) {
        manager.attachFragment(sourcedata, sourcedomain, sourceclasspath);
    }

    public ClassLoaderDelegate getDelegate() {
        return delegate;
    }

    public List<URL> findEntries(String path, String filePattern, int options) {
        return manager.findEntries(path, filePattern, options);
    }

    public Collection<String> listResources(String path, String filePattern, int options) {
        return delegate.listResources(path, filePattern, options);
    }

    public Collection<String> listLocalResources(String path, String filePattern, int options) {
        return manager.listLocalResources(path, filePattern, options);
    }

    public ClasspathManager getClasspathManager() {
        return manager;
    }

    public Bundle getBundle() {
        return manager.getBaseData().getBundle();
    }

    private static boolean getSearchWiredBundles(boolean defaultValue) {
        String value = System.getProperty(SEARCH_WIRED_BUNDLES);
        return (value == null) ? defaultValue : Boolean.parseBoolean(value);
    }

    private static boolean getConvertResourceUrls(boolean defaultValue) {
        String value = System.getProperty(CONVERT_RESOURCE_URLS);
        return (value == null) ? defaultValue : Boolean.parseBoolean(value);
    }
   
    public String toString() {
        return "GeronimoClassLoader[" + bundle + "]";
    }
   
}
TOP

Related Classes of org.apache.geronimo.hook.equinox.GeronimoClassLoader

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.