samedi 9 mai 2015

Additional logic with JAXB during unmarshalling XML

I'm trying to use JAXB for parsing an XML file, like this:

<customers>
        ...
        <customer>
            <id>123456</id>
            <name>Mike</name>
            <orders>
                ...
                <order>
                    <id>233658</id>
                    <positions>
                        ...
                        <position>
                            <id>12345</id>
                            <price>10.0</price>
                            <count>5</count>
                        </position>
                        ...
                    </positions>
                </order>
                ...
            </orders>
        </customer>
<customers>

I've generated model classes, having XSD schema. Here, for example, Orders and Positions classes:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "order"
})
@XmlRootElement(name = "orders")
public class Orders {

    @XmlElement(required = true)
    protected List<Order> order;

    public List<Order> getOrder() {
        if (order == null) {
            order = new ArrayList<Order>();
        }
        return this.order;
    }
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "id",
    "positions"
})
@XmlRootElement(name = "order")
public class Order {

    @XmlElement(required = true)
    protected BigInteger id;

    @XmlElement(required = true)
    protected Positions positions;

    public BigInteger getId() {
        return id;
    }

    public void setId(BigInteger value) {
        this.id = value;
    }

    public Positions getPositions() {
        return positions;
    }

    public void setPositions(Positions value) {
        this.positions = value;
    }
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "position"
})
@XmlRootElement(name = "positions")
public class Positions {

    @XmlElement(required = true)
    protected List<Position> position;

    public List<Position> getPosition() {
        if (position == null) {
            position = new ArrayList<Position>();
        }
        return this.position;
    }
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "id",
    "price",
    "count"
})
@XmlRootElement(name = "position")
public class Position {

    @XmlElement(required = true)
    protected BigInteger id;
    @XmlElement(required = true)
    protected BigDecimal price;
    @XmlElement(required = true)
    protected BigInteger count;

    public BigInteger getId() {
        return id;
    }

    public void setId(BigInteger value) {
        this.id = value;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal value) {
        this.price = value;
    }

    public BigInteger getCount() {
        return count;
    }

    public void setCount(BigInteger value) {
        this.count = value;
    }

}

Everything works fine, but i have to iterate through this objects with 3-level foreach loop.

My question is, can i add totalPositionsAmount field in Postions class to automatically fill the value during marshalling?

There is no setPosition() method there, as you can see, and obviously some mysterious magic adds List position in the object.

I mean, if there was setPosition() method, i would do something like this:

public class Positions {

    @XmlElement(required = true)
    protected List<Position> position;

    protected BigDecimal totalPositionsAmount = new BigDecimal(0);

    public List<Position> getPosition() {
        if (position == null) {
            position = new ArrayList<Position>();
        }
        return this.position;
    }

    public void setPosition(Position newPosition) {
        this.position.add(newPosition);
        this.totalPositionsAmount = this.totalPositionsAmount.add(newPosition.getPrice());
    }
}

Aucun commentaire:

Enregistrer un commentaire