/* * $Id$ * * Copyright (C) 2003-2015 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 org.jnode.bootlog.BootLogInstance; import org.jnode.plugin.PluginClassLoader; import org.jnode.plugin.PluginDescriptor; import org.jnode.plugin.PluginDescriptorListener; import java.security.AccessController; import java.security.PrivilegedAction; /** * Abstract driver of a Device. * <p/> * Every device driver must extend this class directly or indirectly. * <p/> * A suitable driver for a specific Device is found by a DeviceToDriverMapper. * * @author Ewout Prangsma (epr@users.sourceforge.net) * @see org.jnode.driver.Device * @see org.jnode.driver.DeviceToDriverMapper */ public abstract class Driver { /** * The device this driver it to control */ private Device device; /** * Default constructor */ public Driver() { final ClassLoader loader = AccessController.doPrivileged( new PrivilegedAction<ClassLoader>() { public ClassLoader run() { return getClass().getClassLoader(); } }); if (loader instanceof PluginClassLoader) { final PluginDescriptor descr = ((PluginClassLoader) loader).getDeclaringPluginDescriptor(); descr.addListener(new PluginListener()); } } /** * Sets the device this driver is to control. * * @param device The device to control, never null * from the device. * @throws DriverException */ protected final void connect(Device device) throws DriverException { if (this.device != null) { throw new DriverException("This driver is already connected to a device"); } verifyConnect(device); this.device = device; afterConnect(device); } /** * Gets the device this driver is to control. * * @return The device I'm driving */ public final Device getDevice() { return device; } /** * This method is called just before a new device is set to this driver. * If we should refuse the given device, throw a DriverException. * * @param device * @throws DriverException */ protected void verifyConnect(Device device) throws DriverException { /* do nothing for now */ } /** * This method is called after a new device is set to this driver. * You can initialize the driver and/or the device here. * Note not to start the device yet. * * @param device */ protected void afterConnect(Device device) { /* do nothing for now */ } /** * Start the device. * * @throws DriverException */ protected abstract void startDevice() throws DriverException; /** * Stop the device. * * @throws DriverException */ protected abstract void stopDevice() throws DriverException; final class PluginListener implements PluginDescriptorListener { /** * @see org.jnode.plugin.PluginDescriptorListener#pluginStarted(org.jnode.plugin.PluginDescriptor) */ public void pluginStarted(PluginDescriptor descriptor) { // Ignore } /** * @see org.jnode.plugin.PluginDescriptorListener#pluginStop(org.jnode.plugin.PluginDescriptor) */ public void pluginStop(PluginDescriptor descriptor) { final Device dev = Driver.this.device; if (dev != null) { try { BootLogInstance.get().debug("Stopping device " + dev.getId() + " due to plugin stop"); dev.stop(true); } catch (DriverException ex) { BootLogInstance.get().error("Cannot stop device " + dev.getId(), ex); } } descriptor.removeListener(this); } } }