summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceDescription.java
blob: d1c546f9341e0eefe6789449d41ee22bdc224e6b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package org.openslx.libvirt.domain.device;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Representation of an USB device description.
 * 
 * @author Manuel Bentele
 * @version 1.0
 */
public class HostdevUsbDeviceDescription
{
	/**
	 * Regular expression to parse an USB device vendor and product identifier from a {@link String}.
	 * <p>
	 * The regular expression matches an USB device description if its textual USB device description
	 * is well-formed according to the following examples:
	 * 
	 * <pre>
	 *   1d6b:0002
	 *   0461:4d22
	 *   046d:c312
	 * </pre>
	 */
	private static final String DEVICE_DESCRIPTION_REGEX = "^([a-f0-9]{4}):([a-f0-9]{4})$";

	/**
	 * Minimum value of a valid identifier from an USB device description.
	 */
	private static final int DEVICE_DESCRIPTION_ID_MIN_VALUE = 0x0000;

	/**
	 * Maximum value of a valid identifier from an USB device description.
	 */
	private static final int DEVICE_DESCRIPTION_ID_MAX_VALUE = 0xffff;

	/**
	 * Vendor identifier of the USB device.
	 */
	final int vendorId;

	/**
	 * Product identifier of the USB device.
	 */
	final int productId;

	/**
	 * Creates a new USB device description consisting of a USB vendor and product identifier.
	 * 
	 * @param vendorId vendor identifier of the USB device.
	 * @param productId product identifier of the USB device.
	 * 
	 * @throws throws IllegalArgumentException failed to validate the USB device description
	 *            identifiers.
	 */
	public HostdevUsbDeviceDescription( int vendorId, int productId ) throws IllegalArgumentException
	{
		HostdevUsbDeviceDescription.validateUsbDeviceDescriptionId( "PCI vendor ID", vendorId );
		HostdevUsbDeviceDescription.validateUsbDeviceDescriptionId( "PCI device ID", productId );

		this.vendorId = vendorId;
		this.productId = productId;
	}

	/**
	 * Validates an USB device description ID (an USB vendor or product ID).
	 * 
	 * @param idName name of the USB device description identifier.
	 * @param id value of the USB device description identifier that should be validated.
	 * 
	 * @throws IllegalArgumentException failed to validate the USB device description identifier.
	 */
	private static void validateUsbDeviceDescriptionId( final String idName, final int id )
			throws IllegalArgumentException
	{
		if ( id < HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE ) {
			throw new IllegalArgumentException(
					"The " + idName + "must be larger or equal than "
							+ HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE );
		} else if ( id > HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE ) {
			throw new IllegalArgumentException(
					"The " + idName + "must be smaller or equal than "
							+ HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE );
		}
	}

	/**
	 * Returns the USB device vendor identifier.
	 * 
	 * @return USB device vendor identifier.
	 */
	public int getVendorId()
	{
		return this.vendorId;
	}

	/**
	 * Returns the USB vendor identifier as {@link String}.
	 * 
	 * @return USB vendor identifier as {@link String}.
	 */
	public String getVendorIdAsString()
	{
		return String.format( "%04x", HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getVendorId() );
	}

	/**
	 * Returns the USB device product identifier.
	 * 
	 * @return USB device product identifier.
	 */
	public int getProductId()
	{
		return this.productId;
	}

	/**
	 * Returns the USB device product identifier as {@link String}.
	 * 
	 * @return USB device product identifier as {@link String}.
	 */
	public String getProductIdAsString()
	{
		return String.format( "%04x", HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getProductId() );
	}

	/**
	 * Creates a new USB device description parsed from a {@link String}.
	 * <p>
	 * The USB device description consists of an USB vendor and product identifier parsed from the
	 * specified {@link String}.
	 * 
	 * @param vendorProductId textual information containing an USB device description as
	 *           {@link String}. The textual USB device description should be well-formed according
	 *           to the defined regular expression {@link #DEVICE_DESCRIPTION_REGEX}.
	 * 
	 * @return USB device description instance.
	 */
	public static HostdevUsbDeviceDescription valueOf( String vendorProductId )
	{
		HostdevUsbDeviceDescription usbDeviceDescription;

		if ( vendorProductId == null || vendorProductId.isEmpty() ) {
			usbDeviceDescription = null;
		} else {
			final Pattern usbDeviceDescPattern = Pattern.compile( HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_REGEX );
			final Matcher usbDeviceDescMatcher = usbDeviceDescPattern.matcher( vendorProductId.toLowerCase() );

			if ( usbDeviceDescMatcher.find() ) {
				final int vendorId = Integer.valueOf( usbDeviceDescMatcher.group( 1 ), 16 );
				final int productId = Integer.valueOf( usbDeviceDescMatcher.group( 2 ), 16 );

				try {
					usbDeviceDescription = new HostdevUsbDeviceDescription( vendorId, productId );
				} catch ( IllegalArgumentException e ) {
					usbDeviceDescription = null;
				}
			} else {
				usbDeviceDescription = null;
			}
		}

		return usbDeviceDescription;
	}

	@Override
	public boolean equals( Object obj )
	{
		if ( obj == null ) {
			return false;
		} else if ( this.getClass() != obj.getClass() ) {
			return false;
		} else {
			// check if vendor and product ID are equal
			final HostdevUsbDeviceDescription other = HostdevUsbDeviceDescription.class.cast( obj );
			if ( this.getVendorId() == other.getVendorId() && this.getProductId() == other.getProductId() ) {
				return true;
			} else {
				return false;
			}
		}
	}

	@Override
	public String toString()
	{
		return this.getVendorIdAsString() + ":" + this.getProductIdAsString();
	}
}