From 8e3a690b79fcef368beab749e0c13c1256f07c36 Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Tue, 18 Jan 2011 21:37:38 +0000 Subject: [PATCH] Fixed one little thing that bothered me: null enum values could safely be stored, but if rehydrated into a Set then an EnumSet would be created and that can't store nulls. So, check to see if the encoded String has any nulls in it and have the builder create a HashSet instead. --- .../com/samskivert/depot/Transformers.java | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/samskivert/depot/Transformers.java b/src/main/java/com/samskivert/depot/Transformers.java index 0306cd1..cb5ab52 100644 --- a/src/main/java/com/samskivert/depot/Transformers.java +++ b/src/main/java/com/samskivert/depot/Transformers.java @@ -164,20 +164,21 @@ public class Transformers { // create a Builder for our field type final Builder> ebuilder = createCollectionBuilder( - _ftype, _eclass, _immutable, _intern); + _ftype, hasNullElement(encoded) ? null : _eclass, _immutable, _intern); // wrap that builder in one that accepts String elements return new Builder>() { public void add (String s) { - if (s == null) { - ebuilder.add(null); - return; - } E value; - try { - value = Enum.valueOf(_eclass, s); - } catch (IllegalArgumentException iae) { - log.warning("Invalid enum cannot be unpersisted", "e", s, iae); - return; + if (s == null) { + value = null; + + } else { + try { + value = Enum.valueOf(_eclass, s); + } catch (IllegalArgumentException iae) { + log.warning("Invalid enum cannot be unpersisted", "e", s, iae); + return; + } } ebuilder.add(value); } @@ -187,6 +188,7 @@ public class Transformers }; } + /** The enum class. */ protected Class _eclass; } @@ -202,6 +204,8 @@ public class Transformers /** * Create a builder that populates a collection. + * + * @param elementType if non-null and an enum, will be used to possibly create an EnumSet. */ protected static Builder> createCollectionBuilder ( Type fieldType, Class elementType, boolean immutable, boolean intern) @@ -213,7 +217,9 @@ public class Transformers // TODO: fill out the collection types if (clazz == HashSet.class || clazz == Set.class || clazz == EnumSet.class) { Set set; - if (clazz == HashSet.class || !elementType.isEnum()) { + if (clazz == HashSet.class || (elementType == null) || !elementType.isEnum()) { + Preconditions.checkArgument(clazz != EnumSet.class, + "Cannot proceed: EnumSet field is to be populated with a null element."); set = Sets.newHashSet(); } else { @SuppressWarnings("unchecked") @@ -343,7 +349,7 @@ public class Transformers protected abstract Builder createBuilder (String encoded); /** - * Utility tount the number of elements in the encoded non-null string. + * Utility to count the number of elements in the encoded non-null string. */ protected static int countElements (String encoded) { @@ -352,6 +358,20 @@ public class Transformers return count; } + /** + * Utility to see if there are any nulls in the encoded string. + */ + protected static boolean hasNullElement (String encoded) + { + for (int pos = 0; -1 != (pos = encoded.indexOf("\\\n")); pos += 2) { + // make sure there isn't another slash before this token + if ((pos == 0) || ('\\' != encoded.charAt(pos - 1))) { + return true; + } + } + return false; + } + protected Type _ftype; /** Immutable hint. */