Index: src/test/com/thoughtworks/acceptance/BooleanFieldsTest.java
===================================================================
--- src/test/com/thoughtworks/acceptance/BooleanFieldsTest.java (revision 0)
+++ src/test/com/thoughtworks/acceptance/BooleanFieldsTest.java (revision 0)
@@ -0,0 +1,123 @@
+package com.thoughtworks.acceptance;
+
+import com.thoughtworks.xstream.converters.basic.BooleanConverter;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author David Blevins
+ */
+public class BooleanFieldsTest extends AbstractAcceptanceTest {
+
+ public static class Musican {
+ public String name;
+ public String genre;
+ public boolean alive;
+
+ public Musican(String name, String genre, boolean alive) {
+ this.name = name;
+ this.genre = genre;
+ this.alive = alive;
+ }
+ }
+
+ public void testTrueFalseValues() {
+ List jazzIcons = new ArrayList();
+ jazzIcons.add(new Musican("Miles Davis", "jazz", false));
+ jazzIcons.add(new Musican("Wynton Marsalis", "jazz", true));
+
+ xstream.alias("musician", Musican.class);
+
+ String expectedXml =
+ "\n" +
+ " \n" +
+ " Miles Davis\n" +
+ " jazz\n" +
+ " false\n" +
+ " \n" +
+ " \n" +
+ " Wynton Marsalis\n" +
+ " jazz\n" +
+ " true\n" +
+ " \n" +
+ "
";
+
+ assertBothWays(jazzIcons, expectedXml);
+ }
+
+ public void testYesNoValues() {
+ List jazzIcons = new ArrayList();
+ jazzIcons.add(new Musican("Miles Davis", "jazz", false));
+ jazzIcons.add(new Musican("Wynton Marsalis", "jazz", true));
+
+ xstream.alias("musician", Musican.class);
+ xstream.registerConverter(BooleanConverter.YES_NO);
+
+ String expectedXml =
+ "\n" +
+ " \n" +
+ " Miles Davis\n" +
+ " jazz\n" +
+ " no\n" +
+ " \n" +
+ " \n" +
+ " Wynton Marsalis\n" +
+ " jazz\n" +
+ " yes\n" +
+ " \n" +
+ "
";
+
+ assertBothWays(jazzIcons, expectedXml);
+ }
+
+ public void testBinaryValues() {
+ List jazzIcons = new ArrayList();
+ jazzIcons.add(new Musican("Miles Davis", "jazz", false));
+ jazzIcons.add(new Musican("Wynton Marsalis", "jazz", true));
+
+ xstream.alias("musician", Musican.class);
+ xstream.registerConverter(BooleanConverter.BINARY);
+
+ String expectedXml =
+ "\n" +
+ " \n" +
+ " Miles Davis\n" +
+ " jazz\n" +
+ " 0\n" +
+ " \n" +
+ " \n" +
+ " Wynton Marsalis\n" +
+ " jazz\n" +
+ " 1\n" +
+ " \n" +
+ "
";
+
+ assertBothWays(jazzIcons, expectedXml);
+ }
+
+ public void testEmptyElementImplied() {
+ List jazzIcons = new ArrayList();
+ jazzIcons.add(new Musican("Miles Davis", "jazz", false));
+ jazzIcons.add(new Musican("Wynton Marsalis", "jazz", true));
+ xstream.registerConverter(BooleanConverter.EMPTY_ELEMENT);
+
+ xstream.alias("musician", Musican.class);
+
+ String expectedXml =
+ "\n" +
+ " \n" +
+ " Miles Davis\n" +
+ " jazz\n" +
+ " \n" +
+ " \n" +
+ " Wynton Marsalis\n" +
+ " jazz\n" +
+ " \n" +
+ " \n" +
+ "
";
+
+ assertBothWays(jazzIcons, expectedXml);
+ }
+
+}
Index: src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java
===================================================================
--- src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java (revision 847)
+++ src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java (working copy)
@@ -1,19 +1,73 @@
package com.thoughtworks.xstream.converters.basic;
+import com.thoughtworks.xstream.converters.ConditionalConverter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
/**
* Converts a boolean primitive or java.lang.Boolean wrapper to
* a String.
*
* @author Joe Walnes
+ * @author David Blevins
*/
-public class BooleanConverter extends AbstractSingleValueConverter {
+public class BooleanConverter implements Converter, ConditionalConverter {
+ public static final BooleanConverter TRUE_FALSE = new BooleanConverter("true", "false", false);
+
+ public static final BooleanConverter YES_NO = new BooleanConverter("yes", "no", false);
+
+ public static final BooleanConverter BINARY = new BooleanConverter("1", "0", true);
+
+ public static final BooleanConverter EMPTY_ELEMENT = new BooleanConverter() {
+ public boolean shouldConvert(Class type, Object obj) {
+ Boolean value = (Boolean) obj;
+ return value.booleanValue();
+ }
+
+ public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+ }
+
+ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+ return Boolean.TRUE;
+ }
+ };
+
+ private final String positive;
+ private final String negative;
+ private final boolean caseSensitive;
+
+ public BooleanConverter(String positive, String negative, boolean caseSensitive) {
+ this.positive = positive;
+ this.negative = negative;
+ this.caseSensitive = caseSensitive;
+ }
+
+ public BooleanConverter() {
+ this("true", "false", false);
+ }
+
+ public boolean shouldConvert(Class type, Object value) {
+ return true;
+ }
+
public boolean canConvert(Class type) {
return type.equals(boolean.class) || type.equals(Boolean.class);
}
- public Object fromString(String str) {
- return str.equals("true") ? Boolean.TRUE : Boolean.FALSE;
+ public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+ Boolean value = (Boolean) source;
+ writer.setValue(value.booleanValue() ? positive : negative);
}
+ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+ if (caseSensitive) {
+ return positive.equals(reader.getValue()) ? Boolean.TRUE : Boolean.FALSE;
+ } else {
+ return positive.equalsIgnoreCase(reader.getValue()) ? Boolean.TRUE : Boolean.FALSE;
+ }
+ }
}