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.
This commit is contained in:
Ray Greenwell
2011-01-18 21:37:38 +00:00
parent b32c6753c1
commit 8e3a690b79
@@ -164,20 +164,21 @@ public class Transformers
{ {
// create a Builder for our field type // create a Builder for our field type
final Builder<E, Iterable<E>> ebuilder = createCollectionBuilder( final Builder<E, Iterable<E>> ebuilder = createCollectionBuilder(
_ftype, _eclass, _immutable, _intern); _ftype, hasNullElement(encoded) ? null : _eclass, _immutable, _intern);
// wrap that builder in one that accepts String elements // wrap that builder in one that accepts String elements
return new Builder<String, Iterable<E>>() { return new Builder<String, Iterable<E>>() {
public void add (String s) { public void add (String s) {
if (s == null) {
ebuilder.add(null);
return;
}
E value; E value;
try { if (s == null) {
value = Enum.valueOf(_eclass, s); value = null;
} catch (IllegalArgumentException iae) {
log.warning("Invalid enum cannot be unpersisted", "e", s, iae); } else {
return; try {
value = Enum.valueOf(_eclass, s);
} catch (IllegalArgumentException iae) {
log.warning("Invalid enum cannot be unpersisted", "e", s, iae);
return;
}
} }
ebuilder.add(value); ebuilder.add(value);
} }
@@ -187,6 +188,7 @@ public class Transformers
}; };
} }
/** The enum class. */
protected Class<E> _eclass; protected Class<E> _eclass;
} }
@@ -202,6 +204,8 @@ public class Transformers
/** /**
* Create a builder that populates a collection. * 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 <E> Builder<E, Iterable<E>> createCollectionBuilder ( protected static <E> Builder<E, Iterable<E>> createCollectionBuilder (
Type fieldType, Class<E> elementType, boolean immutable, boolean intern) Type fieldType, Class<E> elementType, boolean immutable, boolean intern)
@@ -213,7 +217,9 @@ public class Transformers
// TODO: fill out the collection types // TODO: fill out the collection types
if (clazz == HashSet.class || clazz == Set.class || clazz == EnumSet.class) { if (clazz == HashSet.class || clazz == Set.class || clazz == EnumSet.class) {
Set<E> set; Set<E> 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(); set = Sets.newHashSet();
} else { } else {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -343,7 +349,7 @@ public class Transformers
protected abstract Builder<String, F> createBuilder (String encoded); protected abstract Builder<String, F> 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) protected static int countElements (String encoded)
{ {
@@ -352,6 +358,20 @@ public class Transformers
return count; 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; protected Type _ftype;
/** Immutable hint. */ /** Immutable hint. */