Marshalling/Unmarshalling Java superclass and subclasses using JAXB

I’ve been experimenting with JAXB tutorials and have managed to get code working that generates an XML file from a Java object and then is able to use the XML to generate a Java object. At the moment it reads multiple instances of the same class to create an XML file similar to the one below

<Car>
    <regplate>TR54</regplate>
    <colour>red</colour>
    <energyrating>5</energyrating>
</Car>
<Car>
    <regplate>BN04 THY</regplate>
    <colour>yellow</colour>
    <energyrating>3</energyrating>
</Car>
<Car>
    <regplate>BN05 THY</regplate>
    <colour>yellow</colour>
    <energyrating>5</energyrating>
</Car>

I would like to be able to use the JAXB technology to work with subclasses. For example: Say I have a Car, Van and Bicycle objects that are subclasses of Vehicle. Is it possible for me to manipulate my JAXB class to write an XML file that would produce something similar to this? I have provided the code I am working with below.

<Vehicle>
    <Car>
        <regplate>TR54</regplate>
        <colour>red</colour>
        <energyrating>5</energyrating>
    </Car>
    <Van>
        <regplate>MN05 RFD</regplate>
        <colour>red</colour>
        <energyrating>5</energyrating>
    </Van>
    <Car>
        <regplate>ZX54 UJK</regplate>
        <colour>red</colour>
        <energyrating>1</energyrating>
    </Car>
</Vehicle>

Main Class

package basictransport2;

public class Main
{
    public static void main(String[] args)
    {
        JAXB parser = new JAXB();
        parser.marshall();
        //parser.unmarshallList();
    }
}

Vehicle Class

package basictransport2;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

//@XmlRootElement(name = "Vehicle")
public class Vehicle
{
    private int ownerId;

    public Vehicle(int ownerId)
    {
        this.setOwnerId(ownerId);
    }

    //@XmlElement (name = "Owner ID")
    public int getOwnerId()
    {
        return ownerId;
    }

    public void setOwnerId(int ownerId)
    {
        this.ownerId = ownerId;
    }


    public int getEnergyRating()
    {
        return (Integer) null;
    }


    public String getColour()
    {
        return null;
    }

    public String getRegPlate()
    {
        return null;
    }
}

Car Class

package basictransport2;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

//@XmlRootElement(name = "Car")
public class Car extends Vehicle
{
    private String regPlate;
    private int energyRating;
    private String colour;

    public Car(String regPlate, int energyRating, String colour, int ownerId)
    {
        super(ownerId);
        this.regPlate = regPlate;
        this.energyRating = energyRating;
        this.colour = colour;
    } 

    public Car(int ownerId)
    {
        super(ownerId);
    }

    //@XmlElement (name = "Registration")
    public String getRegPlate()
    {
        return regPlate;
    }

    public void setRegPlate(String regPlate)
    {
        if(this.regPlate == null)
        {
            this.regPlate = regPlate;
        }
    }

    //@XmlElement (name = "Energy Rating")
    public int getEnergyRating()
    {
        return energyRating;
    }

    public void setEnergyRating(int energyRating)
    {
        this.energyRating = energyRating;
    }

    //@XmlElement (name = "Colour")
    public String getColour()
    {
        return colour;
    }

    public void setColour(String colour)
    {
        this.colour = colour;
    }
}

JAXB Class

package basictransport2;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class JAXB
{   
    public void marshall()
    {
        try
        {
            List<Vehicle> vehicleList = new ArrayList<Vehicle>();

            vehicleList.add(new Car("SG09 TYH", 4, "Yellow", 1));
            vehicleList.add(new Car("XX09 VVV", 3, "Red", 2));
            vehicleList.add(new Car("BL09 TYZ", 4, "Blue", 3));

            Garage listOfVehicles = new Garage();
            listOfVehicles.setListOfVehicles(vehicleList);

            JAXBContext context = JAXBContext.newInstance(Garage.class);
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(listOfVehicles, System.out);
            marshaller.marshal(listOfVehicles, new File("src\\data\\listcar.xml"));
        }

        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }

    public void unmarshall()
    {
        try
        {
            JAXBContext context = JAXBContext.newInstance(Garage.class);
            Unmarshaller unmarhsaller = context.createUnmarshaller();
            Garage listOfVehicles = (Garage)unmarhsaller.unmarshal(new File("src\\data\\listcar.xml"));
            System.out.println("List Car information");

            for(Vehicle vehicle : listOfVehicles.getListOfVehicles())
            {
                System.out.println("Reg Plate: " + vehicle.getRegPlate());
                System.out.println("Energy Rating: " + vehicle.getEnergyRating());
                System.out.println("Colour: " + vehicle.getColour());
                System.out.println("================");
            }    
        }

        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}

List class

package basictransport2;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="Vehicle")
public class Garage
{
    @XmlElements
    ({
        @XmlElement(name = "Car", type = Car.class, required = false)
    })    

    private List<Vehicle> vehicleCollection = new ArrayList<Vehicle>();

    public List<Vehicle> getListOfVehicles()
    {
        return vehicleCollection;
    }

    public void setListOfVehicles(List<Vehicle> listOfVehicles)
    {
        this.vehicleCollection = listOfVehicles;
    }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s