XStream
  1. XStream
  2. XSTR-308

Conditional Conversion support

    Details

    • Type: New Feature New Feature
    • Status: Open Open
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      So i've rethought my need to not serialize things like empty collections and as well have seen other requests on the list from people who don't want to serialize int's that are zero, empty strings, etc.

      This patch allows the converter to make the call on weather the data (and enclosing tag) is written or not. I added this functionality as an additional and optional interface, ConditionalConverter, rather than adding it directly to Converter and SingleValueConverter as I don't want to break any custom Converter implementations people have out there in the wild. If it's more desirable to add the method right to those interfaces, that's fine too.

      For the sake of ease of review, here is a chuck of an attached test case:

          public static class SkipEmptyCollectionConverter extends CollectionConverter implements ConditionalConverter {
              public SkipEmptyCollectionConverter(Mapper mapper) {
                  super(mapper);
              }
      
              public boolean shouldConvert(Class type, Object value) {
                  return (value != null && ((Collection) value).size() != 0);
              }
          }
      
          public static class SkipEmptyMapConverter extends MapConverter implements ConditionalConverter {
              public SkipEmptyMapConverter(Mapper mapper) {
                  super(mapper);
              }
      
              public boolean shouldConvert(Class type, Object value) {
                  return (value != null && ((Map) value).size() != 0);
              }
          }
      
          public static class SkipEmptyStringConverter extends StringConverter {
              public boolean shouldConvert(Class type, Object value) {
                  return (value != null && ((String)value).length() != 0);
              }
          }
      
          public static class Contact extends StandardObject {
              public String name;
              public String company;
              public List emailAddresses = new ArrayList();
              public Map addresses = new HashMap();
              public Map telephone = new HashMap();
              public String notes;
      
              public Contact(String name) {
                  this.name = name;
              }
          }
      
          public void testSkipNonSimpleTypes() {
              List addressBook = new ArrayList();
              Contact wallace = new Contact("Wallace");
              wallace.company = "Window Washing Inventors, Inc.";
              wallace.addresses.put("home", "62 West Wallaby Street");
              addressBook.add(wallace);
      
              Contact gromit = new Contact("Gromit");
              gromit.emailAddresses.add("gromit@genious-k9s.net");
              addressBook.add(gromit);
      
              Contact jenny = new Contact("Jenny");
              jenny.telephone.put("home", "867-5309");
              jenny.notes = "Found this number on the bathroom wall.";
              addressBook.add(jenny);
      
              xstream.alias("contact", Contact.class);
              xstream.registerConverter(new SkipEmptyCollectionConverter(xstream.getMapper()));
              xstream.registerConverter(new SkipEmptyMapConverter(xstream.getMapper()));
              xstream.registerConverter(new SkipEmptyStringConverter());
      
              String expectedXml = ""+
                      "<list>\n" +
                      "  <contact>\n" +
                      "    <name>Wallace</name>\n" +
                      "    <company>Window Washing Inventors, Inc.</company>\n" +
                      "    <addresses>\n" +
                      "      <entry>\n" +
                      "        <string>home</string>\n" +
                      "        <string>62 West Wallaby Street</string>\n" +
                      "      </entry>\n" +
                      "    </addresses>\n" +
                      "  </contact>\n" +
                      "  <contact>\n" +
                      "    <name>Gromit</name>\n" +
                      "    <emailAddresses>\n" +
                      "      <string>gromit@genious-k9s.net</string>\n" +
                      "    </emailAddresses>\n" +
                      "  </contact>\n" +
                      "  <contact>\n" +
                      "    <name>Jenny</name>\n" +
                      "    <telephone>\n" +
                      "      <entry>\n" +
                      "        <string>home</string>\n" +
                      "        <string>867-5309</string>\n" +
                      "      </entry>\n" +
                      "    </telephone>\n" +
                      "    <notes>Found this number on the bathroom wall.</notes>\n" +
                      "  </contact>\n" +
                      "</list>";
      
              assertBothWays(addressBook, expectedXml);
          }
      
      1. ConditionalConversion.patch
        24 kB
        David Blevins
      2. FieldAliasingMapper-shouldSerializeMember.patch
        0.6 kB
        David Blevins
      3. FieldAliasingMapper-shouldSerializeMember2.patch
        0.8 kB
        David Blevins
      4. OmitFieldsTest-shouldSerializeMember.patch
        0.6 kB
        David Blevins

        People

        • Assignee:
          Unassigned
          Reporter:
          David Blevins
        • Votes:
          1 Vote for this issue
          Watchers:
          1 Start watching this issue

          Dates

          • Created:
            Updated: