Factored shared code into a base class. Restructured to avoid double checking

for null.
This commit is contained in:
Michael Bayne
2010-07-06 18:22:09 +00:00
parent 0b84e08917
commit 5ec15839d3
+25 -34
View File
@@ -44,7 +44,7 @@ import com.google.common.collect.Sets;
* specify it via a {@link Column} annotation. For example: * specify it via a {@link Column} annotation. For example:
* <pre> * <pre>
* public class MyRecord extends PersistentRecord { * public class MyRecord extends PersistentRecord {
* @Transform(Transformers.CommaSeparatedString.class) * @Transform(Transformers.StringArray.class)
* public String[] cities; * public String[] cities;
* } * }
* </pre> * </pre>
@@ -52,53 +52,48 @@ import com.google.common.collect.Sets;
public class Transformers public class Transformers
{ {
/** /**
* Combines the contents of a String[] column into a single String, terminating * Combines the contents of a String[] column into a single String, terminating each String
* each String element with a newline. * element with a newline. A backslash ('\') in Strings will be prefixed by another backslash,
* A backslash ('\') in Strings will be prefixed by another backslash,
* newlines will be encoded as "\n", and null elements will be encoded as "\0" (but not * newlines will be encoded as "\n", and null elements will be encoded as "\0" (but not
* terminated by a newline). * terminated by a newline).
*/ */
public static class StringArray implements Transformer<String[], String> public static class StringArray extends StringBase<String[]>
{ {
public String toPersistent (String[] value) public String toPersistent (String[] value)
{ {
if (value == null) { return (value == null) ? null : encode(Arrays.asList(value));
return null;
}
return StringIterable.toPersistent0(Arrays.asList(value));
} }
public String[] fromPersistent (Type ftype, String encoded) public String[] fromPersistent (Type ftype, String encoded)
{ {
if (encoded == null) { return (encoded == null) ? null : Iterables.toArray(decode(encoded), String.class);
return null;
}
return Iterables.toArray(StringIterable.fromPersistent0(encoded), String.class);
} }
} }
/** /**
* Combines the contents of an Iterable<String> column into a single String, terminating * Combines the contents of an Iterable<String> column into a single String, terminating each
* each String element with a newline. * String element with a newline. A backslash ('\') in Strings will be prefixed by another
* A backslash ('\') in Strings will be prefixed by another backslash, * backslash, newlines will be encoded as "\n", and null elements will be encoded as "\0" (but
* newlines will be encoded as "\n", and null elements will be encoded as "\0" (but not * not terminated by a newline).
* terminated by a newline).
*/ */
public static class StringIterable implements Transformer<Iterable<String>, String> public static class StringIterable extends StringBase<Iterable<String>>
{ {
public String toPersistent (Iterable<String> value) public String toPersistent (Iterable<String> value)
{ {
return toPersistent0(value); return (value == null) ? null : encode(value);
} }
public Iterable<String> fromPersistent (Type ftype, String encoded) public Iterable<String> fromPersistent (Type ftype, String encoded)
{ {
ArrayList<String> value = fromPersistent0(encoded); if (encoded == null) {
return null;
}
ArrayList<String> value = decode(encoded);
Type fclass = (ftype instanceof ParameterizedType) ? Type fclass = (ftype instanceof ParameterizedType) ?
((ParameterizedType)ftype).getRawType() : ftype; ((ParameterizedType)ftype).getRawType() : ftype;
if (value == null || if (fclass == ArrayList.class || fclass == List.class ||
fclass == ArrayList.class || fclass == List.class || fclass == Collection.class || fclass == Iterable.class) {
fclass == Collection.class || fclass == Iterable.class) {
return value; return value;
} }
if (fclass == LinkedList.class) { if (fclass == LinkedList.class) {
@@ -111,12 +106,12 @@ public class Transformers
// and return? Something? // and return? Something?
return value; return value;
} }
}
protected static String toPersistent0 (Iterable<String> value) protected abstract static class StringBase<F> implements Transformer<F, String>
{
protected static String encode (Iterable<String> value)
{ {
if (value == null) {
return null;
}
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
for (String s : value) { for (String s : value) {
if (s == null) { if (s == null) {
@@ -130,11 +125,8 @@ public class Transformers
return buf.toString(); return buf.toString();
} }
protected static ArrayList<String> fromPersistent0 (String encoded) protected static ArrayList<String> decode (String encoded)
{ {
if (encoded == null) {
return null;
}
ArrayList<String> value = Lists.newArrayList(); ArrayList<String> value = Lists.newArrayList();
StringBuilder buf = new StringBuilder(encoded.length()); StringBuilder buf = new StringBuilder(encoded.length());
for (int ii = 0, nn = encoded.length(); ii < nn; ii++) { for (int ii = 0, nn = encoded.length(); ii < nn; ii++) {
@@ -153,11 +145,9 @@ public class Transformers
Preconditions.checkArgument(buf.length() == 0, "Invalid encoded string"); Preconditions.checkArgument(buf.length() == 0, "Invalid encoded string");
value.add(null); value.add(null);
break; break;
case 'n': // turn \n back into a newline case 'n': // turn \n back into a newline
buf.append('\n'); buf.append('\n');
break; break;
default: // this should only be a slash... default: // this should only be a slash...
buf.append(slashed); buf.append(slashed);
break; break;
@@ -169,6 +159,7 @@ public class Transformers
break; break;
} }
} }
// make sure the last element was terminated // make sure the last element was terminated
Preconditions.checkArgument(buf.length() == 0, "Invalid encoded string"); Preconditions.checkArgument(buf.length() == 0, "Invalid encoded string");
return value; return value;