diff --git a/src/main/java/de/ailis/usb4java/AbstractDevice.java b/src/main/java/de/ailis/usb4java/AbstractDevice.java index 5914bc3..f85c3db 100644 --- a/src/main/java/de/ailis/usb4java/AbstractDevice.java +++ b/src/main/java/de/ailis/usb4java/AbstractDevice.java @@ -21,7 +21,6 @@ import javax.usb.UsbDevice; import javax.usb.UsbDeviceDescriptor; import javax.usb.UsbDisconnectedException; import javax.usb.UsbException; -import javax.usb.UsbHostManager; import javax.usb.UsbPort; import javax.usb.UsbStringDescriptor; import javax.usb.event.UsbDeviceEvent; @@ -264,17 +263,7 @@ abstract class AbstractDevice implements UsbDevice this.port = port; - final Services services; - try - { - services = (Services) UsbHostManager.getUsbServices(); - } - catch (final UsbException e) - { - // Can't happen. When we got here then USB services are already - // loaded - throw new Usb4JavaRuntimeException(e.toString(), e); - } + final Services services = Services.getInstance(); if (port == null) { diff --git a/src/main/java/de/ailis/usb4java/AbstractIrpQueue.java b/src/main/java/de/ailis/usb4java/AbstractIrpQueue.java index 23bf431..b2f3479 100644 --- a/src/main/java/de/ailis/usb4java/AbstractIrpQueue.java +++ b/src/main/java/de/ailis/usb4java/AbstractIrpQueue.java @@ -9,7 +9,6 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import javax.usb.UsbException; -import javax.usb.UsbHostManager; import javax.usb.UsbIrp; @@ -171,16 +170,7 @@ abstract class AbstractIrpQueue */ protected final Config getConfig() { - try - { - return ((Services) UsbHostManager.getUsbServices()).getConfig(); - } - catch (final UsbException e) - { - // Can't happen because we can't get to this point when USB - // services are not available. - throw new Usb4JavaRuntimeException(e.toString(), e); - } + return Services.getInstance().getConfig(); } /** diff --git a/src/main/java/de/ailis/usb4java/DeviceManager.java b/src/main/java/de/ailis/usb4java/DeviceManager.java index 8d55de8..a70529a 100644 --- a/src/main/java/de/ailis/usb4java/DeviceManager.java +++ b/src/main/java/de/ailis/usb4java/DeviceManager.java @@ -110,49 +110,44 @@ final class DeviceManager * Returns all currently connected devices. * * @return The connected devices. + * @throws LibUsbException + * When libusb reports an error while enumerating the devices. */ - private Set getConnectedDevices() + private Set getConnectedDevices() throws LibUsbException { final DeviceList devices = new DeviceList(); final int result = LibUSB.getDeviceList(this.context, devices); if (result < 0) - throw new Usb4JavaRuntimeException("Unable to get USB device list", + throw new LibUsbException("Unable to get USB device list", result); final Set found = new HashSet(); try { - try + for (Device libUsbDevice: devices) { - for (Device libUsbDevice: devices) - { - final DeviceId id = createId(libUsbDevice); - if (id == null) continue; + final DeviceId id = createId(libUsbDevice); + if (id == null) continue; - AbstractDevice device = this.devices.get(id); - if (device == null) + AbstractDevice device = this.devices.get(id); + if (device == null) + { + final Device parent = LibUSB.getParent(libUsbDevice); + final DeviceId parentId = createId(parent); + final int speed = LibUSB.getDeviceSpeed(libUsbDevice); + final boolean isHub = id.getDeviceDescriptor() + .bDeviceClass() == LibUSB.CLASS_HUB; + if (isHub) { - final Device parent = LibUSB.getParent(libUsbDevice); - final DeviceId parentId = createId(parent); - final int speed = LibUSB.getDeviceSpeed(libUsbDevice); - final boolean isHub = id.getDeviceDescriptor() - .bDeviceClass() == LibUSB.CLASS_HUB; - if (isHub) - { - device = new Hub(this, id, parentId, - speed, libUsbDevice); - } - else - { - device = new NonHub(this, id, - parentId, speed, libUsbDevice); - } + device = new Hub(this, id, parentId, + speed, libUsbDevice); + } + else + { + device = new NonHub(this, id, + parentId, speed, libUsbDevice); } - found.add(device); } - } - catch (UsbException e) - { - throw new Usb4JavaRuntimeException(e.toString(), e); + found.add(device); } } finally @@ -224,9 +219,16 @@ final class DeviceManager */ public void scan() { - final Set found = getConnectedDevices(); - processRemovedDevices(found); - processNewDevices(found); + try + { + final Set found = getConnectedDevices(); + processRemovedDevices(found); + processNewDevices(found); + } + catch (LibUsbException e) + { + throw new ScanException("Unable to scan USB devices: " + e, e); + } } /** @@ -236,19 +238,19 @@ final class DeviceManager * @param id * The id of the device to return. Must not be null. * @return device The libusb device. Never null. - * @throws Usb4JavaRuntimeException - * When an error occurred while searching for the device. * @throws DeviceNotFoundException * When the device was not found. + * @throws LibUsbException + * When libusb reported an error while enumerating USB devices. */ - public Device getLibUsbDevice(final DeviceId id) + public Device getLibUsbDevice(final DeviceId id) throws LibUsbException { if (id == null) throw new IllegalArgumentException("id must be set"); final DeviceList devices = new DeviceList(); final int result = LibUSB.getDeviceList(this.context, devices); if (result < 0) - throw new Usb4JavaRuntimeException("Unable to get USB device list", + throw new LibUsbException("Unable to get USB device list", result); try { @@ -265,7 +267,8 @@ final class DeviceManager { LibUSB.freeDeviceList(devices, true); } - return null; + + throw new DeviceNotFoundException(id); } /** diff --git a/src/main/java/de/ailis/usb4java/Usb4JavaRuntimeException.java b/src/main/java/de/ailis/usb4java/DeviceManagerException.java similarity index 84% rename from src/main/java/de/ailis/usb4java/Usb4JavaRuntimeException.java rename to src/main/java/de/ailis/usb4java/DeviceManagerException.java index 4c446ed..80d35f1 100644 --- a/src/main/java/de/ailis/usb4java/Usb4JavaRuntimeException.java +++ b/src/main/java/de/ailis/usb4java/DeviceManagerException.java @@ -12,7 +12,7 @@ import de.ailis.usb4java.libusb.LibUSB; * * @author Klaus Reimer (k@ailis.de) */ -final class Usb4JavaRuntimeException extends RuntimeException +final class DeviceManagerException extends RuntimeException { /** Serial version UID. */ private static final long serialVersionUID = 1L; @@ -28,7 +28,7 @@ final class Usb4JavaRuntimeException extends RuntimeException * @param errorCode * The error code. */ - Usb4JavaRuntimeException(final String message, final int errorCode) + DeviceManagerException(final String message, final int errorCode) { super(String.format("USB error %d: %s: %s", -errorCode, message, LibUSB.errorName(errorCode))); @@ -43,7 +43,7 @@ final class Usb4JavaRuntimeException extends RuntimeException * @param cause * The root cause. */ - Usb4JavaRuntimeException(final String message, final Throwable cause) + DeviceManagerException(final String message, final Throwable cause) { super("USB error: " + message, cause); this.errorCode = 0; diff --git a/src/main/java/de/ailis/usb4java/ScanException.java b/src/main/java/de/ailis/usb4java/ScanException.java new file mode 100644 index 0000000..76611fc --- /dev/null +++ b/src/main/java/de/ailis/usb4java/ScanException.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +/** + * Thrown when USB device scan fails. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class ScanException extends RuntimeException +{ + /** Serial version UID. */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + * @param message + * The error message. + * @param cause + * The root cause. + */ + ScanException(final String message, final Throwable cause) + { + super(message, cause); + } +} diff --git a/src/main/java/de/ailis/usb4java/Services.java b/src/main/java/de/ailis/usb4java/Services.java index f4bfc2f..b53ab1a 100644 --- a/src/main/java/de/ailis/usb4java/Services.java +++ b/src/main/java/de/ailis/usb4java/Services.java @@ -18,7 +18,7 @@ import de.ailis.usb4java.libusb.LoaderException; /** * usb4java implementation of JSR-80 UsbServices. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class Services implements UsbServices @@ -47,7 +47,7 @@ public final class Services implements UsbServices /** * Constructor. - * + * * @throws UsbException * When properties could not be loaded. * @throws LoaderException @@ -101,7 +101,7 @@ public final class Services implements UsbServices /** * Informs listeners about a new attached device. - * + * * @param device * The new attached device. */ @@ -112,7 +112,7 @@ public final class Services implements UsbServices /** * Informs listeners about a detached device. - * + * * @param device * The detached device. */ @@ -123,11 +123,34 @@ public final class Services implements UsbServices /** * Returns the configuration. - * + * * @return The configuration. */ Config getConfig() { return this.config; } + + /** + * Returns the usb4java services. + * + * @return The usb4java services. + */ + static Services getInstance() + { + try + { + UsbServices services = UsbHostManager.getUsbServices(); + return (Services) services; + } + catch (final ClassCastException e) + { + throw new ServicesException("Looks like usb4java is not the " + + "configured USB services implementation: " + e, e); + } + catch (final UsbException e) + { + throw new Error("Unable to create USB services: " + e, e); + } + } } diff --git a/src/main/java/de/ailis/usb4java/ServicesException.java b/src/main/java/de/ailis/usb4java/ServicesException.java new file mode 100644 index 0000000..39c4b0f --- /dev/null +++ b/src/main/java/de/ailis/usb4java/ServicesException.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +/** + * Thrown when usb4java services could not be created. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class ServicesException extends RuntimeException +{ + /** Serial version UID. */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + * @param message + * The error message. + * @param cause + * The root cause. + */ + ServicesException(final String message, final Throwable cause) + { + super(message, cause); + } +}