All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cucumber.java.runtime.osgi.OsgiClassFinder Maven / Gradle / Ivy

There is a newer version: 3.0.2
Show newest version
package cucumber.java.runtime.osgi;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cucumber.runtime.ClassFinder;

public class OsgiClassFinder implements ClassFinder {

    private static final Logger LOGGER = LoggerFactory.getLogger(OsgiClassFinder.class);

    private final BundleContext bundleContext;

    public OsgiClassFinder(BundleContext bundleContext) {
        this.bundleContext = bundleContext;
    }

    @Override
    public  Collection> getDescendants(Class parentType, String packageName) {
        if (LOGGER.isDebugEnabled())
            LOGGER.debug("Looking for sub classes of " + parentType.getName() + " in '" + packageName + "' package");

        final String searchPath = packageName.replace('.', '/');

        final ArrayList> result = new ArrayList>();;
        for (Bundle bundle : bundleContext.getBundles()) {
            try {
                result.addAll(findClassesInBundle(bundle, searchPath, parentType));
            } catch (Exception e) {
                LOGGER.error("Failed to inspect bundle " + bundle.getSymbolicName() + ": " + e.getMessage(), e);
            }
        }
        result.trimToSize();
        return result;
    }

    @Override
    public  Class loadClass(String className) throws ClassNotFoundException {
        for (Bundle bundle : bundleContext.getBundles()) {
            return (Class) bundle.loadClass(className);
        }
        throw new ClassNotFoundException("Couldn't load class from bundles: " + className);
    }

    private  Collection> findClassesInBundle(Bundle bundle, String searchPath, Class parentType) {
        final Collection> result = new ArrayList>();
        final Enumeration resources = bundle.findEntries(searchPath, "*.class", true);
        if (resources == null)
            return Collections.emptyList();
        for (URL url : Collections.list(resources)) {
            final String className = pathToClassName(url.getPath());
            try {
                final Class castClass = loadClassFromBundle(parentType, bundle, className);
                if (castClass != null)
                    result.add(castClass);
            } catch (Exception e) {
                LOGGER.error("Failed to load class " + className, e);
            }
        }
        return result;
    }

    private  Class loadClassFromBundle(Class parentType, Bundle bundle, String className) throws ClassNotFoundException {
        final Class clazz = bundle.loadClass(className);
        if (clazz != null && !parentType.equals(clazz) && parentType.isAssignableFrom(clazz)) {
            return clazz.asSubclass(parentType);
        }
        return null;
    }

    private static String pathToClassName(final String path) {
        return path.substring(1, path.length() - 6).replace('/', '.');
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy