Reputation: 73
Using SnakeYAML's TypeDescription
, I can add type information about Lists and Maps using:
TypeDescription td = new TypeDescription(MyBean.class, "!mybean");
td.putMapPropertyType("mymap", String.class, MyOtherBean.class);
td.putListPropertyType("mylist", MyOtherBean.class);
This way, I can populate Collections with instances of MyOtherBean without having to rely on any other tags:
---
!mybean
mymap:
foobar: # will map to an instance of MyOtherBean
otherbeanprop1: foo
otherbeanprop2: bar
mylist: # will contain instances of MyOtherBean
- otherbeanprop1: foo
otherbeanprop2: bar
Is there any easy way to do something like this:
td.putPropertyType("myotherbean", MyOtherBean.class);
so that the property myotherbean
in MyBean
would be populated with a single instance of MyOtherBean
? Things I am trying to avoid:
!myotherbean
) in the yaml fileI have already played around with this and I think I need to create a custom constructor like this (adapted from the SnakeYAML Documentation):
class SelectiveConstructor extends Constructor {
public SelectiveConstructor() {
// define a custom way to create a mapping node
yamlClassConstructors.put(NodeId.mapping, new ConstructMapping() {
@Override
protected Object constructJavaBean2ndStep(MappingNode node, Object object) {
Class type = node.getType();
if (type.equals(MyBean.class)) {
// something
if (propertyname.equals("myotherbean")) {
// something
}
} else {
// redirect creation to Constructor
return super.constructJavaBean2ndStep(node, object);
}
}
}
}
The problem is that I don't really understand what exactly is going on there. Please let me know if there is an easier way. And if there isn't, I would appreciate it if you shared your experience with this.
Upvotes: 1
Views: 3236
Reputation: 4476
There is an elegant way to do this.
If you don't want to do some special tricks with the YAML content, you can use the following two methods of snakeYaml to dump and load yaml content:
public String dumpAsMap(Object data) // dump method
public <T> T loadAs(Reader io, Class<T> type) // load method
In your scenario,
dump :
MyBean bean = new MyBean();
// init bean...
String yamlContent = yaml.dumpAsMap(bean);
load :
FileReader reader = new FileReader(filename);
MyBean bean = yaml.loadAs(reader, MyBean.class);
Of course, you should implement the getter and setter of your classes. For details, you can take a look at the example here.
Upvotes: 2