XStream
  1. XStream
  2. XSTR-607

@XStreamImplicit annotation seems to be ingored under certain cirumstances

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Not A Bug
    • Affects Version/s: 1.3.1
    • Fix Version/s: None
    • Component/s: Annotations
    • Labels:
      None
    • JDK version and platform:
      Sun jdk1.6.0_13 for Windows

      Description

      This is what I want to achieve:

      <message success="true">
        <data>
          <record>
      
          </record>
      
          <record>
          </record>
          <record>
      
          </record>
        </data>
      </message>
      

      where top level container - message - has one boolean attribute - success. Under the message there is one container - data - which contains data records, which might contain whatever.

      So I have a message class:

      MessageDto .java
      @XStreamAlias("message")
      public class MessageDto {
      
        public MessageDto () {
          this.setSuccess(true);
        }
      
        public MessageDto (Boolean success) {
          this.setSuccess(success);
        }
      
        private Boolean success;
        private RecordDto record;
      
        public void setRecord(RecordDto record) {
          this.record = record;
        }
        public void setSuccess(Boolean success) {
          this.success = success;
        }
      
        public RecordDto getRecord() {
          return this.record;
        }
        public Boolean getSuccess() {
          return success;
        }
      
      }
      

      persons class:

      PersonsDto.java
      public class PersonsDto implements RecordDto {
      
        public String getRecordName() {
          return "data";
        }
      
        @XStreamImplicit(itemFieldName="person")
        private List <PersonDto> persons = new LinkedList <PersonDto> ();
      
        public void addPerson (PersonDto person) {
          persons.add(person);
        }
      
      }
      

      as seen, a list which contains persons is annotated whith @XStreamImplicit(itemFieldName="person") annotation.

      A single person is:

      PersonDto.java
      @SuppressWarnings("unused")
      public class PersonDto {
      
        public PersonDto () {
        }
      
        public PersonDto (String firstName, String lastName) {
          this.firstName = firstName;
          this.lastName = lastName;
        }
      
        private String firstName;
        private String lastName;
      
        public void setFirstName(String firstName) {
          this.firstName = firstName;
        }
        public void setLastName(String lastName) {
          this.lastName = lastName;
        }
      
      }
      

      Now, finally, converter:

      MessageConverter.java
      public class MessageConverter implements Converter {
      
        @SuppressWarnings("unchecked")
        public boolean canConvert(Class type) {
          return (MessageDto.class == type);
        }
      
        public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
          MessageDto message = (MessageDto) source;
          writer.addAttribute("success", message.getSuccess().toString());
          writer.startNode(message.getRecord().getRecordName());
          context.convertAnother(message.getRecord());
          writer.endNode();
        }
      
        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
          return null;
        }
      
      }
      

      now the test:

      ConverterTest.java
      public class ConverterTest {
      
        public static void main(String[] args) throws IOException {
      
          XStream xStream = new XStream();
          xStream.registerConverter(new MessageConverter());
          xStream.autodetectAnnotations(true);
      
          PersonsDto persons = new PersonsDto ();
          persons.addPerson(new PersonDto("Charles", "Barkley"));
          persons.addPerson(new PersonDto("Michael", "Jordan"));
          persons.addPerson(new PersonDto("Kobe", "Bryant"));
      
          MessageDto  message = new MessageDto () ;
          message.setRecord(persons);
      
          System.out.println(xStream.toXML(message));
      
          System.out.println(xStream.toXML(message));
        }
      
      }
      

      now first call to xStream.toXML method gives me this:

      <message success="true">
        <data>
          <persons class="linked-list">
            <com.xstr.dto.PersonDto>
              <firstName>Charles</firstName>
              <lastName>Barkley</lastName>
            </com.xstr.dto.PersonDto>
            <com.xstr.dto.PersonDto>
              <firstName>Michael</firstName>
              <lastName>Jordan</lastName>
            </com.xstr.dto.PersonDto>
            <com.xstr.dto.PersonDto>
              <firstName>Kobe</firstName>
              <lastName>Bryant</lastName>
            </com.xstr.dto.PersonDto>
          </persons>
        </data>
      </message>
      

      as seen, the @XStreamImplicit annotation seems to be completely ingored. What is more surprising, the second call, just below the first one, gives correct result:

      <message success="true">
        <data>
          <person>
            <firstName>Charles</firstName>
            <lastName>Barkley</lastName>
          </person>
          <person>
            <firstName>Michael</firstName>
            <lastName>Jordan</lastName>
          </person>
          <person>
            <firstName>Kobe</firstName>
            <lastName>Bryant</lastName>
          </person>
        </data>
      </message>
      

      A workaround for this is to register an implicit collection with an XStream instance programatically

          XStream xStream = new XStream(new DomDriver());
          xStream.registerConverter(new MessageConverter());
          xStream.autodetectAnnotations(true);
      
          xStream.addImplicitCollection(PersonsDto.class, "persons", "person", PersonDto.class);
      
      

      with this change, the xml is correct from the first time. However, in my case, it is not that simple as it seems, since I am using Spring oxm support and have to configure it wihthin an applicationContext.xml file, but it is doable.

      1. test.rar
        9 kB
        Wiktor Misiek

        People

        • Assignee:
          Jörg Schaible
          Reporter:
          Wiktor Misiek
        • Votes:
          0 Vote for this issue
          Watchers:
          0 Start watching this issue

          Dates

          • Created:
            Updated:
            Resolved: