Custom XStream converter creates unexpeted output for referenced objects












0















For ObjectProperty I have created a custom converter for XStream:



public class ObjectPropertyConverter extends AbstractPropertyConverter<Object> implements Converter {

public ObjectPropertyConverter(Mapper mapper) {
super(ObjectProperty.class, mapper);
}

@Override
protected WritableValue<Object> createProperty() {
return new SimpleObjectProperty();
}

@Override
protected Class readType(HierarchicalStreamReader reader) {
return mapper.realClass(reader.getAttribute("propertyClass"));
}

@Override
protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, Object value) {
final Class clazz = value.getClass();
final String propertyClass = mapper.serializedClass(clazz);
writer.addAttribute("propertyClass", propertyClass);
context.convertAnother(value);
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<Object> property = createProperty();
if (reader.getAttribute("propertyClass") != null) {
final Object value = context.convertAnother(null, readType(reader));
property.setValue(value);
}
return property;
}
}
public abstract class AbstractPropertyConverter<T> implements Converter {

private final Class clazz;
protected final Mapper mapper;


public AbstractPropertyConverter(Class clazz, Mapper mapper) {
this.clazz = clazz;
this.mapper = mapper;
}

public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
if (source != null) {
T value = ((ObservableValue<T>) source).getValue();
if (value != null) {
writeValue(writer, context, value);
}
}
}

protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, T value) {
context.convertAnother(value);
}

public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
WritableValue<T> property = createProperty();
final T value = (T) context.convertAnother(null, readType(reader));
property.setValue(value);
return property;
}

protected abstract WritableValue<T> createProperty();

protected abstract Class<? extends T> readType(HierarchicalStreamReader reader);

public boolean canConvert(Class type) {
return clazz.isAssignableFrom(type);
}

}


In most cases this does the job just fine. However I have run into an issue when there is a list of items, that link to each other through an ObjectProperty. As long as the linked item is in the list before it is linked to it works and a reference is used. However the other way around it does not work.
Here is the sample application to create said situation:



public class ObjectPropertyReferenceSerializer {

public static void main(String args) {
Item item1 = new Item("item1");
Item item2 = new Item("item2");
Item item3 = new Item("item3");
item2.setParent(item1);
item1.setParent(item3);
List<Item> list = asList(item1, item2, item3);
XStream xStream = getXstreamObject();

// Save to file
String filename = "xStreamCrayersWithReference.xml";
try {
xStream.toXML(list, Files.newOutputStream(Paths.get(filename), StandardOpenOption.CREATE));
} catch (IOException e) {
e.printStackTrace();
}
}

private static XStream getXstreamObject() {
XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
xstream.setMode(XStream.ID_REFERENCES);
xstream.autodetectAnnotations(true);
xstream.registerConverter(new ObjectPropertyConverter(xstream.getMapper()));
return xstream;
}
}


And this output is created:



<java.util.Arrays_-ArrayList id="1">
<a class="ch.sahits.game.openpatrician.app.model.Item-array" id="2">
<ch.sahits.game.openpatrician.app.model.Item id="3">
<uuid>3e0d8b93-b283-4244-997f-d78e7f6e1954</uuid>
<name>item1</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="4" propertyClass="ch.sahits.game.openpatrician.app.model.Item">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="6"/>
</parent>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="7">
<uuid>524e325c-188a-47d5-914d-53581461e6c9</uuid>
<name>item2</name>
<parent class="javafx.beans.property.SimpleObjectProperty" id="8" propertyClass="ch.sahits.game.openpatrician.app.model.Item" reference="3"/>
</ch.sahits.game.openpatrician.app.model.Item>
<ch.sahits.game.openpatrician.app.model.Item id="9">
<uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
<name>item3</name>
<parent class="javafx.beans.property.SimpleObjectProperty" reference="6"/>
</ch.sahits.game.openpatrician.app.model.Item>
</a>
</java.util.Arrays_-ArrayList>


The items with ids 4 and 9 are the same. Only when it is added as the value of an ObjectProperty it is inlined, meaning the outer most element () is missing.



How can I get the converter to produce output, that can be properly referenced?










share|improve this question





























    0















    For ObjectProperty I have created a custom converter for XStream:



    public class ObjectPropertyConverter extends AbstractPropertyConverter<Object> implements Converter {

    public ObjectPropertyConverter(Mapper mapper) {
    super(ObjectProperty.class, mapper);
    }

    @Override
    protected WritableValue<Object> createProperty() {
    return new SimpleObjectProperty();
    }

    @Override
    protected Class readType(HierarchicalStreamReader reader) {
    return mapper.realClass(reader.getAttribute("propertyClass"));
    }

    @Override
    protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, Object value) {
    final Class clazz = value.getClass();
    final String propertyClass = mapper.serializedClass(clazz);
    writer.addAttribute("propertyClass", propertyClass);
    context.convertAnother(value);
    }
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    WritableValue<Object> property = createProperty();
    if (reader.getAttribute("propertyClass") != null) {
    final Object value = context.convertAnother(null, readType(reader));
    property.setValue(value);
    }
    return property;
    }
    }
    public abstract class AbstractPropertyConverter<T> implements Converter {

    private final Class clazz;
    protected final Mapper mapper;


    public AbstractPropertyConverter(Class clazz, Mapper mapper) {
    this.clazz = clazz;
    this.mapper = mapper;
    }

    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
    if (source != null) {
    T value = ((ObservableValue<T>) source).getValue();
    if (value != null) {
    writeValue(writer, context, value);
    }
    }
    }

    protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, T value) {
    context.convertAnother(value);
    }

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    WritableValue<T> property = createProperty();
    final T value = (T) context.convertAnother(null, readType(reader));
    property.setValue(value);
    return property;
    }

    protected abstract WritableValue<T> createProperty();

    protected abstract Class<? extends T> readType(HierarchicalStreamReader reader);

    public boolean canConvert(Class type) {
    return clazz.isAssignableFrom(type);
    }

    }


    In most cases this does the job just fine. However I have run into an issue when there is a list of items, that link to each other through an ObjectProperty. As long as the linked item is in the list before it is linked to it works and a reference is used. However the other way around it does not work.
    Here is the sample application to create said situation:



    public class ObjectPropertyReferenceSerializer {

    public static void main(String args) {
    Item item1 = new Item("item1");
    Item item2 = new Item("item2");
    Item item3 = new Item("item3");
    item2.setParent(item1);
    item1.setParent(item3);
    List<Item> list = asList(item1, item2, item3);
    XStream xStream = getXstreamObject();

    // Save to file
    String filename = "xStreamCrayersWithReference.xml";
    try {
    xStream.toXML(list, Files.newOutputStream(Paths.get(filename), StandardOpenOption.CREATE));
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    private static XStream getXstreamObject() {
    XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
    xstream.setMode(XStream.ID_REFERENCES);
    xstream.autodetectAnnotations(true);
    xstream.registerConverter(new ObjectPropertyConverter(xstream.getMapper()));
    return xstream;
    }
    }


    And this output is created:



    <java.util.Arrays_-ArrayList id="1">
    <a class="ch.sahits.game.openpatrician.app.model.Item-array" id="2">
    <ch.sahits.game.openpatrician.app.model.Item id="3">
    <uuid>3e0d8b93-b283-4244-997f-d78e7f6e1954</uuid>
    <name>item1</name>
    <parent class="javafx.beans.property.SimpleObjectProperty" id="4" propertyClass="ch.sahits.game.openpatrician.app.model.Item">
    <uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
    <name>item3</name>
    <parent class="javafx.beans.property.SimpleObjectProperty" id="6"/>
    </parent>
    </ch.sahits.game.openpatrician.app.model.Item>
    <ch.sahits.game.openpatrician.app.model.Item id="7">
    <uuid>524e325c-188a-47d5-914d-53581461e6c9</uuid>
    <name>item2</name>
    <parent class="javafx.beans.property.SimpleObjectProperty" id="8" propertyClass="ch.sahits.game.openpatrician.app.model.Item" reference="3"/>
    </ch.sahits.game.openpatrician.app.model.Item>
    <ch.sahits.game.openpatrician.app.model.Item id="9">
    <uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
    <name>item3</name>
    <parent class="javafx.beans.property.SimpleObjectProperty" reference="6"/>
    </ch.sahits.game.openpatrician.app.model.Item>
    </a>
    </java.util.Arrays_-ArrayList>


    The items with ids 4 and 9 are the same. Only when it is added as the value of an ObjectProperty it is inlined, meaning the outer most element () is missing.



    How can I get the converter to produce output, that can be properly referenced?










    share|improve this question



























      0












      0








      0








      For ObjectProperty I have created a custom converter for XStream:



      public class ObjectPropertyConverter extends AbstractPropertyConverter<Object> implements Converter {

      public ObjectPropertyConverter(Mapper mapper) {
      super(ObjectProperty.class, mapper);
      }

      @Override
      protected WritableValue<Object> createProperty() {
      return new SimpleObjectProperty();
      }

      @Override
      protected Class readType(HierarchicalStreamReader reader) {
      return mapper.realClass(reader.getAttribute("propertyClass"));
      }

      @Override
      protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, Object value) {
      final Class clazz = value.getClass();
      final String propertyClass = mapper.serializedClass(clazz);
      writer.addAttribute("propertyClass", propertyClass);
      context.convertAnother(value);
      }
      public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
      WritableValue<Object> property = createProperty();
      if (reader.getAttribute("propertyClass") != null) {
      final Object value = context.convertAnother(null, readType(reader));
      property.setValue(value);
      }
      return property;
      }
      }
      public abstract class AbstractPropertyConverter<T> implements Converter {

      private final Class clazz;
      protected final Mapper mapper;


      public AbstractPropertyConverter(Class clazz, Mapper mapper) {
      this.clazz = clazz;
      this.mapper = mapper;
      }

      public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
      if (source != null) {
      T value = ((ObservableValue<T>) source).getValue();
      if (value != null) {
      writeValue(writer, context, value);
      }
      }
      }

      protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, T value) {
      context.convertAnother(value);
      }

      public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
      WritableValue<T> property = createProperty();
      final T value = (T) context.convertAnother(null, readType(reader));
      property.setValue(value);
      return property;
      }

      protected abstract WritableValue<T> createProperty();

      protected abstract Class<? extends T> readType(HierarchicalStreamReader reader);

      public boolean canConvert(Class type) {
      return clazz.isAssignableFrom(type);
      }

      }


      In most cases this does the job just fine. However I have run into an issue when there is a list of items, that link to each other through an ObjectProperty. As long as the linked item is in the list before it is linked to it works and a reference is used. However the other way around it does not work.
      Here is the sample application to create said situation:



      public class ObjectPropertyReferenceSerializer {

      public static void main(String args) {
      Item item1 = new Item("item1");
      Item item2 = new Item("item2");
      Item item3 = new Item("item3");
      item2.setParent(item1);
      item1.setParent(item3);
      List<Item> list = asList(item1, item2, item3);
      XStream xStream = getXstreamObject();

      // Save to file
      String filename = "xStreamCrayersWithReference.xml";
      try {
      xStream.toXML(list, Files.newOutputStream(Paths.get(filename), StandardOpenOption.CREATE));
      } catch (IOException e) {
      e.printStackTrace();
      }
      }

      private static XStream getXstreamObject() {
      XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
      xstream.setMode(XStream.ID_REFERENCES);
      xstream.autodetectAnnotations(true);
      xstream.registerConverter(new ObjectPropertyConverter(xstream.getMapper()));
      return xstream;
      }
      }


      And this output is created:



      <java.util.Arrays_-ArrayList id="1">
      <a class="ch.sahits.game.openpatrician.app.model.Item-array" id="2">
      <ch.sahits.game.openpatrician.app.model.Item id="3">
      <uuid>3e0d8b93-b283-4244-997f-d78e7f6e1954</uuid>
      <name>item1</name>
      <parent class="javafx.beans.property.SimpleObjectProperty" id="4" propertyClass="ch.sahits.game.openpatrician.app.model.Item">
      <uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
      <name>item3</name>
      <parent class="javafx.beans.property.SimpleObjectProperty" id="6"/>
      </parent>
      </ch.sahits.game.openpatrician.app.model.Item>
      <ch.sahits.game.openpatrician.app.model.Item id="7">
      <uuid>524e325c-188a-47d5-914d-53581461e6c9</uuid>
      <name>item2</name>
      <parent class="javafx.beans.property.SimpleObjectProperty" id="8" propertyClass="ch.sahits.game.openpatrician.app.model.Item" reference="3"/>
      </ch.sahits.game.openpatrician.app.model.Item>
      <ch.sahits.game.openpatrician.app.model.Item id="9">
      <uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
      <name>item3</name>
      <parent class="javafx.beans.property.SimpleObjectProperty" reference="6"/>
      </ch.sahits.game.openpatrician.app.model.Item>
      </a>
      </java.util.Arrays_-ArrayList>


      The items with ids 4 and 9 are the same. Only when it is added as the value of an ObjectProperty it is inlined, meaning the outer most element () is missing.



      How can I get the converter to produce output, that can be properly referenced?










      share|improve this question
















      For ObjectProperty I have created a custom converter for XStream:



      public class ObjectPropertyConverter extends AbstractPropertyConverter<Object> implements Converter {

      public ObjectPropertyConverter(Mapper mapper) {
      super(ObjectProperty.class, mapper);
      }

      @Override
      protected WritableValue<Object> createProperty() {
      return new SimpleObjectProperty();
      }

      @Override
      protected Class readType(HierarchicalStreamReader reader) {
      return mapper.realClass(reader.getAttribute("propertyClass"));
      }

      @Override
      protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, Object value) {
      final Class clazz = value.getClass();
      final String propertyClass = mapper.serializedClass(clazz);
      writer.addAttribute("propertyClass", propertyClass);
      context.convertAnother(value);
      }
      public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
      WritableValue<Object> property = createProperty();
      if (reader.getAttribute("propertyClass") != null) {
      final Object value = context.convertAnother(null, readType(reader));
      property.setValue(value);
      }
      return property;
      }
      }
      public abstract class AbstractPropertyConverter<T> implements Converter {

      private final Class clazz;
      protected final Mapper mapper;


      public AbstractPropertyConverter(Class clazz, Mapper mapper) {
      this.clazz = clazz;
      this.mapper = mapper;
      }

      public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
      if (source != null) {
      T value = ((ObservableValue<T>) source).getValue();
      if (value != null) {
      writeValue(writer, context, value);
      }
      }
      }

      protected void writeValue(HierarchicalStreamWriter writer, MarshallingContext context, T value) {
      context.convertAnother(value);
      }

      public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
      WritableValue<T> property = createProperty();
      final T value = (T) context.convertAnother(null, readType(reader));
      property.setValue(value);
      return property;
      }

      protected abstract WritableValue<T> createProperty();

      protected abstract Class<? extends T> readType(HierarchicalStreamReader reader);

      public boolean canConvert(Class type) {
      return clazz.isAssignableFrom(type);
      }

      }


      In most cases this does the job just fine. However I have run into an issue when there is a list of items, that link to each other through an ObjectProperty. As long as the linked item is in the list before it is linked to it works and a reference is used. However the other way around it does not work.
      Here is the sample application to create said situation:



      public class ObjectPropertyReferenceSerializer {

      public static void main(String args) {
      Item item1 = new Item("item1");
      Item item2 = new Item("item2");
      Item item3 = new Item("item3");
      item2.setParent(item1);
      item1.setParent(item3);
      List<Item> list = asList(item1, item2, item3);
      XStream xStream = getXstreamObject();

      // Save to file
      String filename = "xStreamCrayersWithReference.xml";
      try {
      xStream.toXML(list, Files.newOutputStream(Paths.get(filename), StandardOpenOption.CREATE));
      } catch (IOException e) {
      e.printStackTrace();
      }
      }

      private static XStream getXstreamObject() {
      XStream xstream = new XStream(); // DomDriver and StaxDriver instances also can be used with constructor
      xstream.setMode(XStream.ID_REFERENCES);
      xstream.autodetectAnnotations(true);
      xstream.registerConverter(new ObjectPropertyConverter(xstream.getMapper()));
      return xstream;
      }
      }


      And this output is created:



      <java.util.Arrays_-ArrayList id="1">
      <a class="ch.sahits.game.openpatrician.app.model.Item-array" id="2">
      <ch.sahits.game.openpatrician.app.model.Item id="3">
      <uuid>3e0d8b93-b283-4244-997f-d78e7f6e1954</uuid>
      <name>item1</name>
      <parent class="javafx.beans.property.SimpleObjectProperty" id="4" propertyClass="ch.sahits.game.openpatrician.app.model.Item">
      <uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
      <name>item3</name>
      <parent class="javafx.beans.property.SimpleObjectProperty" id="6"/>
      </parent>
      </ch.sahits.game.openpatrician.app.model.Item>
      <ch.sahits.game.openpatrician.app.model.Item id="7">
      <uuid>524e325c-188a-47d5-914d-53581461e6c9</uuid>
      <name>item2</name>
      <parent class="javafx.beans.property.SimpleObjectProperty" id="8" propertyClass="ch.sahits.game.openpatrician.app.model.Item" reference="3"/>
      </ch.sahits.game.openpatrician.app.model.Item>
      <ch.sahits.game.openpatrician.app.model.Item id="9">
      <uuid>fb2ca551-8a0d-450c-966f-4261fdde1d7d</uuid>
      <name>item3</name>
      <parent class="javafx.beans.property.SimpleObjectProperty" reference="6"/>
      </ch.sahits.game.openpatrician.app.model.Item>
      </a>
      </java.util.Arrays_-ArrayList>


      The items with ids 4 and 9 are the same. Only when it is added as the value of an ObjectProperty it is inlined, meaning the outer most element () is missing.



      How can I get the converter to produce output, that can be properly referenced?







      java xstream converters






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 1 at 12:31







      hotzst

















      asked Jan 1 at 12:05









      hotzsthotzst

      4,46931643




      4,46931643
























          1 Answer
          1






          active

          oldest

          votes


















          0














          Replacing the converter with a more straight forward approach seems to work:



          public class ObjectPropertyConverterV2 implements Converter {

          private Mapper mapper;

          public ObjectPropertyConverterV2(Mapper mapper) {
          this.mapper = mapper;
          }

          @Override
          public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
          ObjectProperty objProperty = (ObjectProperty) o;
          if (objProperty.get() != null) {
          hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
          marshallingContext.convertAnother(objProperty.get());
          hierarchicalStreamWriter.endNode();
          }
          }

          @Override
          public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
          String type = hierarchicalStreamReader.getAttribute("class");
          ObjectProperty objProperty;
          try {
          objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
          } catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
          log.warn("Failed to create instance of type " + type, e);
          objProperty = new SimpleObjectProperty();
          }

          if (hierarchicalStreamReader.hasMoreChildren()) {
          hierarchicalStreamReader.moveDown();
          Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
          hierarchicalStreamReader.moveUp();
          objProperty.setValue(value);
          }
          return objProperty;
          }

          @Override
          public boolean canConvert(Class aClass) {
          return ObjectProperty.class.isAssignableFrom(aClass);
          }
          }





          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995286%2fcustom-xstream-converter-creates-unexpeted-output-for-referenced-objects%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            Replacing the converter with a more straight forward approach seems to work:



            public class ObjectPropertyConverterV2 implements Converter {

            private Mapper mapper;

            public ObjectPropertyConverterV2(Mapper mapper) {
            this.mapper = mapper;
            }

            @Override
            public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
            ObjectProperty objProperty = (ObjectProperty) o;
            if (objProperty.get() != null) {
            hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
            marshallingContext.convertAnother(objProperty.get());
            hierarchicalStreamWriter.endNode();
            }
            }

            @Override
            public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
            String type = hierarchicalStreamReader.getAttribute("class");
            ObjectProperty objProperty;
            try {
            objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
            } catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
            log.warn("Failed to create instance of type " + type, e);
            objProperty = new SimpleObjectProperty();
            }

            if (hierarchicalStreamReader.hasMoreChildren()) {
            hierarchicalStreamReader.moveDown();
            Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
            hierarchicalStreamReader.moveUp();
            objProperty.setValue(value);
            }
            return objProperty;
            }

            @Override
            public boolean canConvert(Class aClass) {
            return ObjectProperty.class.isAssignableFrom(aClass);
            }
            }





            share|improve this answer




























              0














              Replacing the converter with a more straight forward approach seems to work:



              public class ObjectPropertyConverterV2 implements Converter {

              private Mapper mapper;

              public ObjectPropertyConverterV2(Mapper mapper) {
              this.mapper = mapper;
              }

              @Override
              public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
              ObjectProperty objProperty = (ObjectProperty) o;
              if (objProperty.get() != null) {
              hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
              marshallingContext.convertAnother(objProperty.get());
              hierarchicalStreamWriter.endNode();
              }
              }

              @Override
              public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
              String type = hierarchicalStreamReader.getAttribute("class");
              ObjectProperty objProperty;
              try {
              objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
              } catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
              log.warn("Failed to create instance of type " + type, e);
              objProperty = new SimpleObjectProperty();
              }

              if (hierarchicalStreamReader.hasMoreChildren()) {
              hierarchicalStreamReader.moveDown();
              Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
              hierarchicalStreamReader.moveUp();
              objProperty.setValue(value);
              }
              return objProperty;
              }

              @Override
              public boolean canConvert(Class aClass) {
              return ObjectProperty.class.isAssignableFrom(aClass);
              }
              }





              share|improve this answer


























                0












                0








                0







                Replacing the converter with a more straight forward approach seems to work:



                public class ObjectPropertyConverterV2 implements Converter {

                private Mapper mapper;

                public ObjectPropertyConverterV2(Mapper mapper) {
                this.mapper = mapper;
                }

                @Override
                public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
                ObjectProperty objProperty = (ObjectProperty) o;
                if (objProperty.get() != null) {
                hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
                marshallingContext.convertAnother(objProperty.get());
                hierarchicalStreamWriter.endNode();
                }
                }

                @Override
                public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
                String type = hierarchicalStreamReader.getAttribute("class");
                ObjectProperty objProperty;
                try {
                objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
                } catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
                log.warn("Failed to create instance of type " + type, e);
                objProperty = new SimpleObjectProperty();
                }

                if (hierarchicalStreamReader.hasMoreChildren()) {
                hierarchicalStreamReader.moveDown();
                Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
                hierarchicalStreamReader.moveUp();
                objProperty.setValue(value);
                }
                return objProperty;
                }

                @Override
                public boolean canConvert(Class aClass) {
                return ObjectProperty.class.isAssignableFrom(aClass);
                }
                }





                share|improve this answer













                Replacing the converter with a more straight forward approach seems to work:



                public class ObjectPropertyConverterV2 implements Converter {

                private Mapper mapper;

                public ObjectPropertyConverterV2(Mapper mapper) {
                this.mapper = mapper;
                }

                @Override
                public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
                ObjectProperty objProperty = (ObjectProperty) o;
                if (objProperty.get() != null) {
                hierarchicalStreamWriter.startNode(mapper.serializedClass(objProperty.get().getClass()));
                marshallingContext.convertAnother(objProperty.get());
                hierarchicalStreamWriter.endNode();
                }
                }

                @Override
                public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
                String type = hierarchicalStreamReader.getAttribute("class");
                ObjectProperty objProperty;
                try {
                objProperty = (ObjectProperty) getClass().getClassLoader().loadClass(type).newInstance();
                } catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
                log.warn("Failed to create instance of type " + type, e);
                objProperty = new SimpleObjectProperty();
                }

                if (hierarchicalStreamReader.hasMoreChildren()) {
                hierarchicalStreamReader.moveDown();
                Object value = unmarshallingContext.convertAnother(null, mapper.realClass(hierarchicalStreamReader.getNodeName()));
                hierarchicalStreamReader.moveUp();
                objProperty.setValue(value);
                }
                return objProperty;
                }

                @Override
                public boolean canConvert(Class aClass) {
                return ObjectProperty.class.isAssignableFrom(aClass);
                }
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 1 at 13:21









                hotzsthotzst

                4,46931643




                4,46931643
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995286%2fcustom-xstream-converter-creates-unexpeted-output-for-referenced-objects%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    MongoDB - Not Authorized To Execute Command

                    in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

                    Npm cannot find a required file even through it is in the searched directory