Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphic collections in SnakeYaml

My intention is to have polymorphic collections like the ones in JSON using jackson, maybe with the help of tags.

I can't seem to able to configure it properly tho.

My yaml file is:

!person
age: 27
job: dev
name: me
skills:
- !devSkill {
  description: 'software development',
  name: android,
  language: java, c++
  years: 7
}
- !softSkill {
  description: 'good person',
  name: <3,
  reason: lots of NGO work
}
- !sportsSkill {
  description: 'racing legend',
  name: vrooom,
  championships: - San Marino 2012
                 - San Marino 2015
}

Which in code would map to a hierarchy with an (abstract?) BaseSkill with description and name, and 3 children: dev, soft and sports.

My problem is, I don't understand SnakeYAML's documentation enough to allow this. My current options are:

Constructor constructor = new Constructor(Person.class);
TypeDescription carDescription = new TypeDescription(Person.class);
                carDescription.putListPropertyType("skills", SportsSkill.class);
                carDescription.putListPropertyType("skills", SoftSkill.class);
                carDescription.putListPropertyType("skills", DevSkill.class);
                // Apparently the last is the winner here because it overrides
                constructor.addTypeDescription(carDescription);

Representer representer = new Representer();
                representer.addClassTag(Person.class, new Tag("!person"));
                representer.addClassTag(SoftSkill.class, new Tag("!Softkill"));
                representer.addClassTag(DevSkill.class, new Tag("!devSkill"));
                representer.addClassTag(SportsSkill.class, new Tag("!portsSkill"));

DumperOptions options = new DumperOptions();
                options.setPrettyFlow(true);
Yaml yaml = new Yaml(constructor, representer, options);

The error is in the lines of

E/YAML﹕ Can't construct a java object for tag:yaml.org,2002:app.yamlmodel.Person; exception=Cannot create property=skills for JavaBean=Person(name=me, job=dev, age=27, skills=null); null; Can't construct a java object for !sportSkill; exception=Invalid tag: !sportSkill
    in "<reader>", line 1, column 1:
    name: me
    ^
like image 539
MLProgrammer-CiM Avatar asked Jan 27 '15 17:01

MLProgrammer-CiM


1 Answers

This thread is quit old but I found a solution for it, hope its still help someone. your mistake is that you should add the tags and type descriptor to the constructor and let SnakeYaml figure out the object structure. In you case:

Constructor constructor = new Constructor(Person.class);
constructor.addTypeDescription(new TypeDescription(SoftSkill.class, new Tag("!softkill"));
constructor.addTypeDescription(new TypeDescription(DevSkill.class, new Tag("!devkill"));
constructor.addTypeDescription(new TypeDescription(SportsSkill.class, new Tag("!sportskill"));

you didnt mention the SnakeYaml version you use but I am using 1.16

like image 110
Noam Shaish Avatar answered Nov 18 '22 17:11

Noam Shaish