I have a YAML config which I construct with this builder. The builder takes an InputStream which allows me to test it with test config files. It works great as SnakeYAML can figure out how to build my object.
public static MyConfig buildFromYaml(InputStream is) {
MyConfig config = null;
Yaml yaml = new Yaml();
try{
config = yaml.loadAs(is, MyConfig.class);
} catch (Exception e) {
e.printStackTrace();
}
return config;
}
But in my application, which happens to be a Cucumber Runner, this config needs to be constructor injected into the object that uses it, which happens to be done by PicoContainer.
public MyStepDefinition(MyConfig myConfig, OtherAppStuff otherAppStuff) {
otherAppStuff.doStuffWith(myConfig);
}
So now I need a constructor for MyConfig so that MyConfig can be constructed by PicoContainer and then injected into MyStepDefinition.
What I came up with is this, which is not right.
public class MyConfig {
public List<ConfigItem> configItemList;
public MyConfig() {
InputStream is = getClass().getResourceAsStream("/myconfigdefinition.yaml");
MyConfig myConfig = buildFromYaml(is);
this.configItemList = myConfig.configItemList;
}
public static MyConfig buildFromYaml(InputStream is) {
...
}
}
The problem is the infinite loop where the constructor calls buildFromYaml which calls the constructor again and thus loops.
So to sum it up, my question is, how do I write a constructor that uses a builder that builds the class being constructed?
In other words, how do I use yaml.loadAs(is, MyConfig.class)
in the constructor of MyConfig?