defaultdevicemanager.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 622 行 · 第 1/2 页

JAVA
622
字号
/*
 * $Id: DefaultDeviceManager.java,v 1.4 2004/02/26 10:33:47 epr Exp $
 */
package org.jnode.driver;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.naming.NamingException;

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.system.BootLog;
import org.jnode.util.TimeoutException;

/**
 * Default device manager.
 * 
 * @author epr
 */
public class DefaultDeviceManager implements DeviceManager,
        ExtensionPointListener {

    /** All registered devices */
    private final Map devices = new HashMap();

    /** All registered device to driver mappers */
    private final List mappers = new ArrayList();

    /** All registered device finders */
    private final List finders = new ArrayList();

    /** All listeners to my events */
    private final List listeners = new LinkedList();

    /** All listeners to device events */
    private final List deviceListeners = new LinkedList();

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

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

    /** The system bus */
    private final Bus systemBus;

    /** The JNode command line */
    private final String cmdLine;

    private long defaultStartTimeout = 10000;

    /**
     * Create a new instance
     * 
     * @param findersEP
     * @param mappersEP
     */
    public DefaultDeviceManager(ExtensionPoint findersEP,
            ExtensionPoint mappersEP) {
        if (findersEP == null) { throw new IllegalArgumentException(
                "finders extension-point cannot be null"); }
        if (mappersEP == null) { throw new IllegalArgumentException(
                "mappers extension-point cannot be null"); }
        cmdLine = System.getProperty("jnode.cmdline", "");
        this.systemBus = new SystemBus();
        this.findersEP = findersEP;
        this.mappersEP = mappersEP;
        findersEP.addListener(this);
        mappersEP.addListener(this);
        refreshFinders();
        refreshMappers();
    }

    /**
     * Returns a collection of all known devices. The collection is not
     * modifiable, but the underlying collection can change, so be aware of
     * exceptions in iterators.
     * 
     * @return All known devices.
     */
    public Collection getDevices() {
        return Collections.unmodifiableCollection(devices.values());
    }

    /**
     * Returns a collection of all known devices that implement the given api..
     * The collection is not modifiable, but the underlying collection can
     * change, so be aware of exceptions in iterators.
     * 
     * @param apiClass
     * @return All known devices the implement the given api.
     */
    public Collection getDevicesByAPI(Class apiClass) {
        final Vector result = new Vector();
        for (Iterator i = devices.values().iterator(); i.hasNext();) {
            final Device dev = (Device) i.next();
            if (dev.implementsAPI(apiClass)) {
                result.add(dev);
            }
        }
        return result;
    }

    /**
     * Gets the device with the given ID.
     * 
     * @param id
     * @return The device with the given id
     * @throws DeviceNotFoundException
     *             No device with the given id was found.
     */
    public Device getDevice(String id) throws DeviceNotFoundException {
        Device device;
        device = (Device) devices.get(id);
        if (device == null) { throw new DeviceNotFoundException(id); }
        return device;
    }

    /**
     * Register a new device. This involves the following steps:
     * <ul>
     * <li>Search for a suitable driver for the device. If not found the
     * driver startup is delayed.
     * <li>Connect the driver to the device, if a driver is found
     * <li>Attempt to start the device. If this fails an exception is printed
     * in the log. You can test if the device was started succesfully, by read
     * the <code>isStarted</code> status.
     * </ul>
     * Note that if the device already has a driver connected to it, the first
     * two steps are ignored.
     * 
     * @param device
     * @throws DeviceAlreadyRegisteredException
     * @throws DriverException
     */
    public synchronized void register(Device device)
            throws DeviceAlreadyRegisteredException, DriverException {
        final String devID = device.getId();
        if (devices.containsKey(devID)) { throw new DeviceAlreadyRegisteredException(
                devID); }
        // Set a link to me
        device.setManager(this);
        // Find a driver if needed
        boolean shouldStart = true;
        if (device.getDriver() == null) {
            final Driver drv = findDriver(device);
            if (drv == null) {
                shouldStart = false;
            } else {
                // Connect the device to the driver
                device.setDriver(drv);
            }
        }
        // Test for no<id> on the command line
        if (cmdLine.indexOf("no" + device.getId()) >= 0) {
            BootLog.info("Blocking the start of " + device.getId());
            shouldStart = false;
        }
        // Add the device to my list
        devices.put(device.getId(), device);
        // Notify my listeners
        fireRegisteredEvent(device);
        if (shouldStart) {
            // Try to start the device
            try {
                BootLog.debug("Starting " + device.getId());
                device.start();
                BootLog.debug("Started " + device.getId());
            } catch (DriverException ex) {
                BootLog.error("Cannot start " + device.getId(), ex);
            }
        }
    }

    /**
     * Unregister a device. The device will be stopped and removed from the
     * namespace.
     * 
     * @param device
     * @throws DriverException
     */
    public synchronized void unregister(Device device) throws DriverException {
        // First stop the device if it is running
        if (device.isStarted()) {
            device.stop();
        }
        // Notify my listeners
        fireUnregisterEvent(device);
        // Actually remove it
        devices.remove(device.getId());
    }

    /**
     * Rename a registered device, optionally using an autonumber postfix
     * 
     * @param device
     * @param name
     * @param autonumber
     * @throws DeviceAlreadyRegisteredException
     */
    public synchronized void rename(Device device, String name,
            boolean autonumber) throws DeviceAlreadyRegisteredException {
        if (!device.getId().startsWith(name)) {
            String newId;
            if (autonumber) {
                int cnt = 0;
                newId = name + cnt;
                while (devices.containsKey(newId)) {
                    cnt++;
                    newId = name + cnt;
                }
            } else {
                newId = name;
            }

            if (devices.containsKey(newId)) { throw new DeviceAlreadyRegisteredException(
                    newId); }
            // Remove the old id
            devices.remove(device.getId());
            // Add the new id
            devices.put(newId, device);
            // Change the device id
            device.setId(newId);
        }
    }

    /**
     * Add a listener
     * 
     * @param listener
     */
    public void addListener(DeviceManagerListener listener) {
        synchronized (listeners) {
            listeners.add(listener);
        }
    }

    /**
     * Add a listener
     * 
     * @param listener
     */
    public void removeListener(DeviceManagerListener listener) {
        synchronized (listeners) {
            listeners.remove(listener);
        }
    }

    /**
     * Add a device listener
     * 
     * @param listener
     */
    public void addListener(DeviceListener listener) {
        synchronized (deviceListeners) {
            deviceListeners.add(listener);
        }
    }

    /**
     * Add a device listener
     * 
     * @param listener
     */
    public void removeListener(DeviceListener listener) {
        synchronized (deviceListeners) {
            deviceListeners.remove(listener);
        }
    }

    /**
     * Stop all devices
     */
    public void stopDevices() {
        while (!devices.isEmpty()) {
            final Device dev = (Device) devices.values().iterator().next();
            try {
                BootLog.debug("Stopping device " + dev.getId());
                unregister(dev);
            } catch (DriverException ex) {
                BootLog.error("Failed to stop device " + dev.getId(), ex);
            }
        }

    }

    /**
     * Gets the system bus. The system bus is the root of all hardware busses
     * and devices connected to these busses.
     * 
     * @return The system bus
     */
    public Bus getSystemBus() {
        return systemBus;
    }

    /**
     * Find a driver from each device that has not yet has a driver connected

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?