2015-04-22 12 views
5

Per un convertitore locale, quando si esegue il marshalling in XML, esiste un modo per accedere all'oggetto padre?XStream ottiene oggetto principale nel convertitore

Devo eseguire il marshalling di una raccolta con elementi da un'origine di terze parti, utilizzando un ID archiviato nell'oggetto padre.

Purtroppo non sembra esserci modo di interrogare il percorso dell'oggetto che porta all'oggetto corrente. O c'è?

+0

Ho un problema simile. Hai trovato una soluzione? TIA – t777

+0

L'ho accettato, perché è passato tanto tempo. :-) –

risposta

0

ho trovato una soluzione con po 'reflaction:

import java.io.InputStream; 
import java.lang.reflect.Field; 
import java.util.List; 
import java.util.Map; 

import org.junit.Test; 
import org.springframework.util.ReflectionUtils; 

import com.thoughtworks.xstream.XStream; 
import com.thoughtworks.xstream.annotations.XStreamAlias; 
import com.thoughtworks.xstream.annotations.XStreamAsAttribute; 
import com.thoughtworks.xstream.converters.Converter; 
import com.thoughtworks.xstream.converters.MarshallingContext; 
import com.thoughtworks.xstream.converters.UnmarshallingContext; 
import com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller; 
import com.thoughtworks.xstream.io.HierarchicalStreamReader; 
import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 
import com.thoughtworks.xstream.io.path.Path; 

import lombok.Data; 

public class XStreamGetInfoFromParentTest { 

    @Test 
    public void smokeTest() { 
     InputStream file = XStreamGetInfoFromParentTest.class.getResourceAsStream("XStreamGetInfoFromParentTest.xml"); 

     XStream xStream = new XStream() { 
      @Override 
      public void registerConverter(Converter converter, int priority) { 
       Converter myConverter = new MyConverterWrapper(converter); 
       super.registerConverter(myConverter, priority); 
      } 
     }; 
     xStream.processAnnotations(Papa.class); 
     xStream.processAnnotations(Baby.class); 

     Papa papa = (Papa) xStream.fromXML(file); 

     System.out.println(papa); 
    } 

    public class MyConverterWrapper implements Converter { 

     private Converter converter; 
     private boolean isBabyClass; 

     public MyConverterWrapper(Converter converter) { 
      this.converter = converter; 
     } 

     @Override 
     public boolean canConvert(Class type) { 
      this.isBabyClass = type.equals(Baby.class); 
      return converter.canConvert(type); 
     } 

     @Override 
     public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { 
      this.converter.marshal(source, writer, context); 
     } 

     @SuppressWarnings({ "unchecked", "rawtypes" }) 
     @Override 
     public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { 
      if (isBabyClass) { 
       AbstractReferenceUnmarshaller runm = (AbstractReferenceUnmarshaller) context; 

       Field field = ReflectionUtils.findField(AbstractReferenceUnmarshaller.class, "values"); 
       field.setAccessible(true); 
       Map values = (Map) ReflectionUtils.getField(field, runm); 

       values.forEach((key, value) -> { 
        System.out.println(key + " : " + value); 
       }); 

       Papa papa = (Papa) values.get(new Path("/papa")); 
       System.out.println(papa.firstname); 
      } 

      return converter.unmarshal(reader, context); 
     } 

    } 

    @XStreamAlias("papa") 
    @Data 
    public class Papa { 

     @XStreamAsAttribute 
     private String firstname; 

     private int age; 

     private List<Baby> babies; 

    } 

    @XStreamAlias("baby") 
    @Data 
    public class Baby { 
     private String firstname; 
    } 

} 

xml:

<?xml version="1.0" encoding="UTF-8"?> 
<papa firstname="Adam"> 
     <age>33</age> 
     <babies> 
      <baby> 
       <firstname>Eva</firstname> 
      </baby> 
     </babies> 
</papa> 
Problemi correlati