How to load a yaml directly into a Map<String, Car> with SnakeYAML?

ktulinho picture ktulinho · Feb 5, 2015 · Viewed 17.1k times · Source

I would like to load this file (test.yml):

Car1:
    countriesSold: [Spain, France, Italy]
    model: Seat
    specs: {color: black, height: 29, with: 29}
Car2:
    countriesSold: [Germany, France]
    model: BMW
    specs: {color: white, height: 11, with: 33}

To a Map<String, Car>.

All examples I see in the SnaleYAML are always putting the Map object inside another object.

When I try to load my file like this

Map<String, Car> load = 
(Map<String, Car>) yaml.load(new ClassPathResource("test.yml").getInputStream());

it gets loaded to Map of a Map and everything inside are either Strings of Maps.

I think I need to provide the Constructor object and TypeDescription objects of my inner types the Yaml, but I'm not sure how to do it. Something like this, but I'm not sure what to put for the root element, which is the Map:

TypeDescription mapDesc = new TypeDescription(Map.class);
mapDesc.putMapPropertyType("???", String.class, Car.class);
Constructor constructor = new Constructor(mapDesc);

The Car class looks like this:

public class Car {

    private String model;
    private Specs specs;
    private List<String> countriesSold = new ArrayList<>();

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public Specs getSpecs() {
        return specs;
    }

    public void setSpecs(Specs specs) {
        this.specs = specs;
    }

    public List<String> getCountriesSold() {
        return countriesSold;
    }

    public void setCountriesSold(List<String> countriesSold) {
        this.countriesSold = countriesSold;
    }
}

And the Specs class looks like this:

public class Specs {

    private int height;
    private int with;

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWith() {
        return with;
    }

    public void setWith(int with) {
        this.with = with;
    }
}

Answer