I want to read a YAML document to a map of custom objects (instead of maps, which snakeYaml does by default). So this:
19:
typeID: 2
limit: 300
20:
typeID: 8
limit: 100
Would be loaded to a map which looks like this:
Map<Integer, Item>
where Item is:
class Item {
private Integer typeId;
private Integer limit;
}
I could not find a way to do this with snakeYaml, and I couldn't find a better library for the task either.
The documentation only has examples with maps/collections nested inside other objects, so that you can do the following:
TypeDescription typeDescription = new TypeDescription(ClassContainingAMap.class);
typeDescription.putMapPropertyType("propertyNameOfNestedMap", Integer.class, Item.class);
Constructor constructor = new Constructor(typeDescription);
Yaml yaml = new Yaml(constructor);
/* creating an input stream (is) */
ClassContainingAMap obj = (ClassContainingAMap) yaml.load(is);
But how do I go about defining the Map format when it is at the root of the document?
Here is what I did for a very similar situation. I just tabbed my whole yml file over one tab and added a map: tag to the top. So for your case it would be.
map:
19:
typeID: 2
limit: 300
20:
typeID: 8
limit: 100
And then create a static class in your class that reads this file like follows.
static class Items {
public Map<Integer, Item> map;
}
And then to read your map just use.
Yaml yaml = new Yaml(new Constructor(Items));
Items items = (Items) yaml.load(<file>);
Map<Integer, Item> itemMap = items.map;
UPDATE:
If you don't want to or cannot edit your yml file you could just do the above transform in code while reading the file with something like this.
try (BufferedReader br = new BufferedReader(new FileReader(new File("example.yml")))) {
StringBuilder builder = new StringBuilder("map:\n");
String line;
while ((line = br.readLine()) != null) {
builder.append(" ").append(line).append("\n");
}
Yaml yaml = new Yaml(new Constructor(Items));
Items items = (Items) yaml.load(builder.toString());
Map<Integer, Item> itemMap = items.map;
}