Package org.jnode.driver

Source Code of org.jnode.driver.DefaultDeviceManager

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.driver;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;
import javax.naming.NamingException;

import org.jnode.bootlog.BootLogInstance;
import org.jnode.naming.InitialNaming;
import org.jnode.plugin.ConfigurationElement;
import org.jnode.plugin.Extension;
import org.jnode.plugin.ExtensionPoint;
import org.jnode.plugin.ExtensionPointListener;
import org.jnode.plugin.PluginException;
import org.jnode.work.Work;
import org.jnode.work.WorkUtils;

/**
* Default device manager.
*
* @author epr
*/
public final class DefaultDeviceManager extends AbstractDeviceManager implements ExtensionPointListener {

    /**
     * finder extension-point
     */
    private final ExtensionPoint findersEP;

    /**
     * mappers extension-point
     */
    private final ExtensionPoint mappersEP;

    /**
     * Create a new instance
     *
     * @param findersEP
     * @param mappersEP
     */
    public DefaultDeviceManager(ExtensionPoint findersEP,
                                ExtensionPoint mappersEP) {
        super();
        if (findersEP == null) {
            throw new IllegalArgumentException("finders extension-point cannot be null");
        }
        if (mappersEP == null) {
            throw new IllegalArgumentException("mappers extension-point cannot be null");
        }
        this.findersEP = findersEP;
        this.mappersEP = mappersEP;
        findersEP.addListener(this);
        mappersEP.addListener(this);
    }

    /**
     * Start this manager
     *
     * @throws PluginException
     */
    public void start() throws PluginException {
        try {
            InitialNaming.bind(NAME, this);
            WorkUtils.add(new Work("Start device manager") {
                public void execute() {
                    loadExtensions();
                }
            });
        } catch (NamingException ex) {
            throw new PluginException(ex);
        }
    }

    /**
     * @param point
     * @param extension
     */
    public final void extensionAdded(ExtensionPoint point, Extension extension) {
        loadExtensions();
        findDeviceDrivers();
    }

    /**
     * @param point
     * @param extension
     */
    public final void extensionRemoved(ExtensionPoint point, Extension extension) {
        loadExtensions();
    }

    /**
     * Refresh the list of finders, based on the mappers extension-point.
     *
     * @param finders
     */
    protected final void refreshFinders(List<DeviceFinder> finders) {
        finders.clear();
        final Extension[] extensions = findersEP.getExtensions();
        BootLogInstance.get().debug("Found " + extensions.length + " device finders");

        for (int i = 0; i < extensions.length; i++) {
            final Extension ext = extensions[i];
            final ConfigurationElement[] elements = ext
                .getConfigurationElements();
            for (int j = 0; j < elements.length; j++) {
                configureFinder(finders, elements[j]);
            }
        }
    }

    /**
     * Refresh the list of mappers, based on the mappers extension-point.
     *
     * @param mappers
     */
    protected final void refreshMappers(List<DeviceToDriverMapper> mappers) {
        mappers.clear();
        final Extension[] extensions = mappersEP.getExtensions();
        BootLogInstance.get().debug("Found " + extensions.length + " mapper extensions");

        // First load all mappers
        for (int i = 0; i < extensions.length; i++) {
            final Extension ext = extensions[i];
            final ConfigurationElement[] elements = ext
                .getConfigurationElements();
            for (int j = 0; j < elements.length; j++) {
                configureMapper(mappers, elements[j]);
            }
        }

        // Now sort them
        Collections.sort(mappers, MapperComparator.INSTANCE);
    }

    /**
     * Configure a finder for a single finder configuration element and add the
     * new finder to the given list.
     *
     * @param finders
     * @param element
     */
    private void configureFinder(List<DeviceFinder> finders, ConfigurationElement element) {
        final String elementName = element.getName();
        if (!elementName.equals("finder")) {
            BootLogInstance.get().warn("Ignoring unrecognised descriptor element: " + elementName);
            return;
        }

        final String className = element.getAttribute("class");
        if (className != null) {
            try {
                BootLogInstance.get().debug("Configuring finder: " + className);
                final Class cls = Thread.currentThread().getContextClassLoader().loadClass(className);
                final DeviceFinder finder = (DeviceFinder) cls.newInstance();
                finders.add(finder);
            } catch (ClassNotFoundException ex) {
                BootLogInstance.get().error("Cannot find finder class " + className);
            } catch (IllegalAccessException ex) {
                BootLogInstance.get().error("Cannot access finder class " + className);
            } catch (InstantiationException ex) {
                BootLogInstance.get().error("Cannot instantiate finder class " + className);
            } catch (ClassCastException ex) {
                BootLogInstance.get()
                    .error("Finder class " + className + " does not implement the DeviceFinder interface");
            }
        }
    }

    /**
     * Configure a mapper for a single mapper configuration element and add the
     * new mapper to the given list.
     *
     * @param mappers
     * @param element
     */
    private void configureMapper(List<DeviceToDriverMapper> mappers, ConfigurationElement element) {
        final String elementName = element.getName();
        if (!elementName.equals("mapper")) {
            BootLogInstance.get().warn("Ignoring unrecognised descriptor element: " + elementName);
            return;
        }

        final String className = element.getAttribute("class");
        if (className != null) {
            try {
                BootLogInstance.get().debug("Configuring mapper: " + className);
                final Class cls = Thread.currentThread().getContextClassLoader().loadClass(className);
                final DeviceToDriverMapper mapper = newMapperInstance(cls, element);
                mappers.add(mapper);
            } catch (ClassNotFoundException ex) {
                BootLogInstance.get().error("Cannot find mapper class " + className, ex);
            } catch (IllegalAccessException ex) {
                BootLogInstance.get().error("Cannot access mapper class " + className, ex);
            } catch (InstantiationException ex) {
                BootLogInstance.get().error("Cannot instantiate mapper class " + className, ex);
            } catch (ClassCastException ex) {
                BootLogInstance.get()
                    .error("Mapper class " + className + " does not implement the DeviceToDriverMapper interface");
            }
        } else {
            BootLogInstance.get().error("class attribute required in mapper");
        }
    }

    /**
     * Instantiate the device to driver mapper.
     * First look for a constructor with a ConfigurationElement parameter,
     * if not found, use the default constructor.
     *
     * @param cls
     * @param element
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private DeviceToDriverMapper newMapperInstance(Class cls, ConfigurationElement element)
        throws InstantiationException, IllegalAccessException {
        try {
            final Constructor c = cls.getConstructor(new Class[]{ConfigurationElement.class});
            try {
                return (DeviceToDriverMapper) c.newInstance(new Object[]{element});
            } catch (InvocationTargetException ex1) {
                final InstantiationException ie = new InstantiationException();
                ie.initCause(ex1.getTargetException());
                throw ie;
            }
        } catch (NoSuchMethodException ex) {
            return (DeviceToDriverMapper) cls.newInstance();
        }
    }
}
TOP

Related Classes of org.jnode.driver.DefaultDeviceManager

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.