At Wed, 01 Aug 2012 16:57:33 -0600,
Eric Blake wrote:
On 08/01/2012 08:11 AM, Claudio Bley wrote:
> At Mon, 23 Jul 2012 14:56:55 -0600,
>> the old version crashed, and your version leaves code as null (which is
>> a strict improvement, but might cause its own NullPointer issue later
>> on). Having an else branch that sticks in a placeholder would be nicer
>> to end clients to at least recognize that they are talking to a newer
>> server, without crashing.
>
> Please have look at the following patch.
>
> -- >8 --
> Subject: [PATCH] Fix IndexOutOfBoundsException for unknown error
> number/domain/level codes.
>
> Remove default constructor because it does not init the object properly.
>
> Add a special *_UNKNOWN enum value to each enum which is used when the
> given enum code is out of bounds.
> + /**
> + * Map an integer to an enum value.
> + *
> + * @return when {@code n < values.length} return n-th item of
> + * {@code values}, otherwise the last item of array
> + * {@code values}.
> + */
> + private static final <T extends Enum<T>> T wrapToEnum(final int n,
final T[] values) {
Wow, Java has changed since I last programmed in it (I haven't
programmed Java since 1.4 when 'assert' was added, although I was at
least following the development of Java 1.5 at the time enough to
understand this syntax - I guess that would be 8 or so years ago?).
Indeed, they try to shoehorn every kind of feature into the language,
nowadays. ;)
But, as I'm looking at the code now, I notice that it is unnecessarily
complex (originally I was trying to make it more succinct, but Java
wouldn't let me).
I simplified the code, renaming the method / fixing the documentation
and made v3 of the patch.
> @@ -71,7 +90,13 @@ public class Error implements Serializable {
> /**
> * An error
> */
> - VIR_ERR_ERROR
> + VIR_ERR_ERROR,
> +
> + VIR_ERR_UNKNOWN; /* must be the last entry! */
Is this...
> +
> + protected static final ErrorLevel wrap(int value) {
> + return wrapToEnum(value, values());
> + }
> }
>
> public static enum ErrorNumber {
> @@ -161,6 +186,11 @@ public class Error implements Serializable {
> VIR_ERR_MIGRATE_UNSAFE, /* Migration is not safe */
> VIR_ERR_OVERFLOW, /* integer overflow */
> VIR_ERR_BLOCK_COPY_ACTIVE, /* action prevented by block copy job */
> + VIR_ERR_UNKNOWN; /* unknown error (must be the last entry!) */
...and this common use of a name among two different enums going to bite
us?
No, not at all. Enums are type-safe in Java and enums have their own
namespace; one always has to specify the enum name when referring to
an enum constant. (except in case statements where the compiler can
infer the type of the enum constant)
Rather, I would /very/ much like these superfluous prefixes of all enum
constants to be removed from the libvirt-java interface. They're of no
use really, despite adding to the code bloat.
When using 'git send-email', it helps to use
'--subject-prefix="libvirt-java PATCHv2" ' for the repost to make it
obvious that it is a revision of an earlier post.
OK, thanks for the tip.
-- >8 --
Subject: [libvirt-java PATCHv3] Fix IndexOutOfBoundsException for
unknown error number/domain/level
codes.
Remove default constructor because it does not init the object properly.
Add a special *_UNKNOWN enum value to each enum which is used when the
given enum code is out of bounds.
---
src/main/java/org/libvirt/Error.java | 43 +++++++++++++++++++++++++++++-------
1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/src/main/java/org/libvirt/Error.java b/src/main/java/org/libvirt/Error.java
index f185ce0..e3c3246 100644
--- a/src/main/java/org/libvirt/Error.java
+++ b/src/main/java/org/libvirt/Error.java
@@ -12,6 +12,21 @@ import org.libvirt.jna.virError;
*/
public class Error implements Serializable {
+ /**
+ * Returns the element of the given array at the specified index,
+ * or the last element of the array if the index is not less than
+ * {@code values.length}.
+ *
+ * @return n-th item of {@code values} when {@code n <
+ * values.length}, otherwise the last item of {@code values}.
+ */
+ private static final <T> T safeElementAt(final int n, final T[] values) {
+ assert(n >= 0 && values.length > 0);
+
+ int idx = Math.min(n, values.length - 1);
+ return values[idx];
+ }
+
public static enum ErrorDomain {
VIR_FROM_NONE, VIR_FROM_XEN, /* Error at Xen hypervisor layer */
VIR_FROM_XEND, /* Error at connection with xend daemon */
@@ -60,6 +75,11 @@ public class Error implements Serializable {
VIR_FROM_URI, /* Error from URI handling */
VIR_FROM_AUTH, /* Error from auth handling */
VIR_FROM_DBUS, /* Error from DBus */
+ VIR_FROM_UNKNOWN; /* unknown error domain (must be the last entry!) */
+
+ protected static final ErrorDomain wrap(int value) {
+ return safeElementAt(value, values());
+ }
}
public static enum ErrorLevel {
@@ -71,7 +91,13 @@ public class Error implements Serializable {
/**
* An error
*/
- VIR_ERR_ERROR
+ VIR_ERR_ERROR,
+
+ VIR_ERR_UNKNOWN; /* must be the last entry! */
+
+ protected static final ErrorLevel wrap(int value) {
+ return safeElementAt(value, values());
+ }
}
public static enum ErrorNumber {
@@ -161,6 +187,11 @@ public class Error implements Serializable {
VIR_ERR_MIGRATE_UNSAFE, /* Migration is not safe */
VIR_ERR_OVERFLOW, /* integer overflow */
VIR_ERR_BLOCK_COPY_ACTIVE, /* action prevented by block copy job */
+ VIR_ERR_UNKNOWN; /* unknown error (must be the last entry!) */
+
+ protected static final ErrorNumber wrap(int value) {
+ return safeElementAt(value, values());
+ }
}
/**
@@ -181,14 +212,10 @@ public class Error implements Serializable {
int int2;
NetworkPointer VNP; /* Deprecated */
- public Error() {
-
- }
-
public Error(virError vError) {
- code = ErrorNumber.values()[vError.code];
- domain = ErrorDomain.values()[vError.domain];
- level = ErrorLevel.values()[vError.level];
+ code = code.wrap(vError.code);
+ domain = domain.wrap(vError.domain);
+ level = level.wrap(vError.level);
message = vError.message;
str1 = vError.str1;
str2 = vError.str2;
--
1.7.11.msysgit.0
--
AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany
Phone: +49 341 265 310 19
Web:<http://www.av-test.org>
Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076)
Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern