Search code examples
javaapixstream

XStream - Make a class in custom converter (unmarshal)


I'm programming a Java application and using XStream, I need to make the entire Unmarshal on my own, I could make the code to get the XML propertie but there is a problem: I can't take the other class (Agent).

I've tried "reader.getValue()" and then take the XML into the Device tag, but it does't work.

XML:

<Device dev_id="99999">
    <Agent>
        <Name>PPPOOOLLL</Name>
        <Enable>1</Enable>
        <MAC>FF:FF:FF:FF:FF:FF</MAC>
        <IMEI/>
        <Addr>222.222.1.117</Addr>
        <LocalAddr>222.222.1.117</LocalAddr>
        <Port>80</Port>
        <LocalPort>80</LocalPort>
        <Username/>
        <Passwd/>
        <Mask>444.444.444.0</Mask>
        <GW>555.555.1.1</GW>
        <Model devtype_id="88">TTTYYYUUU2 3268</Model>
        <Incon incon_id="8">HWg PUSH via HTML</Incon>
        <LogPer>60</LogPer>
        <DatalogPer>3600</DatalogPer>
        <Push push_id="1">Default</Push>
        <Status>2</Status>
        <Alias>XXXYYYVVV</Alias>
        <Description/>
    </Agent>
</Device>

Now, my code is like this, and I don't know how I could get the Agent tag and transform it into a java class.

public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        DevicePai devicePai = new DevicePai();
        devicePai.setDev_id(reader.getAttribute("dev_id"));
        devicePai.setAgent( ??? );
        return devicePai;
    }

I can't change the way I'm programming this nor the API I'm using, I need to make the unmarshal. Every other aspect of my code is ok, I tested, but if you have something in mind I may have forgot, please tell me and I'll check asap. :)


Solution

  • Source: http://x-stream.github.io/converter-tutorial.html#ComplexConverter
    I could take every attribute of my class by doing moveDown() and moveUp(). I've learned that when you use moveDown(), the object moves the cursor to the next non-read child, so what I had to do was make a loop to moveDown and moveUp as many as the tag agent allows. my code is now:

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    
        DevicePai devicePai = new DevicePai();
        devicePai.setDev_id(reader.getAttribute("dev_id"));
    
        reader.moveDown();
        Agent agent = new Agent();
        while (reader.hasMoreChildren()) {
            reader.moveDown();
            agentFieldContructor(agent, reader.getNodeName(), reader.getValue());
            reader.moveUp();
        }
    
        devicePai.setAgent(agent);
        reader.moveUp();
    


    agentFieldConstructor() is a metod that add to agent the specified field pass through parameter, it's just a switch-case block.

    Update 12/14/2017:
    A second and better answer. I can tell to XStream automatcly convert the Agent tag, so I'm taking "dev_id" and after, all I need to do is call "context":
    Agent newAgent = (Agent) context.convertAnother(devicePai, Agent.class);
    And now I need to set the device attribute:
    devicePai.setAgent(newAgent);
    Nothing was done manualy, and my unmarshal method endup like this:

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    
        DevicePai devicePai = new DevicePai();
        devicePai.setDev_id(reader.getAttribute("dev_id");
    
        reader.moveDown();
        Agent newAgent = (Agent) context.convertAnother(devicePai, Agent.class));
        devicePai.setAgent(newAgent);
        reader.moveUp();
    
        return devicePai;
    
    }