Atihska
Atihska

Reputation: 5126

How to simplify my yaml structure for better readability in java

If I have the following yaml structure, how can I read it in java efficiently? Currently, I an reading as

xmas-fifth-day:
   calling-birds: 
     value: four
   partridges:
     count: 1
     value: "a pear tree"
   turtle-doves: 
     value: two


Yaml yaml = new Yaml();
InputStream inputStream = new FileInputStream(new File("src/main/resources/customer.yaml"));
Map<String, Object> data = yaml.load(inputStream);

LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, String>>> lhm = (LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<String, String>>>) data.get("xmas-fifth-day");

Since I am using 3 levels of hashmap, just for the readability purpose, I was wondering if there's a simplified version of this yaml structure to read in less nesting LHM way in java?

EDIT: I don't want to add a POJO here since the config is meant to be dynamic in my use case, where any one can add any config and the code should work without editing the java classes.

Upvotes: 1

Views: 320

Answers (2)

Radu Toader
Radu Toader

Reputation: 1561

As I see it you have better options with Jackson:

        Yaml yaml = new Yaml();
        InputStream inputStream = new FileInputStream(new File("test.yml"));
        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
        final JsonNode jsonNode = mapper.readValue(inputStream, JsonNode.class);
        System.out.println(jsonNode.toPrettyString());

and the output will be :

{
  "xmas-fifth-day" : {
    "calling-birds" : {
      "value" : "four"
    },
    "partridges" : {
      "count" : 1,
      "value" : "a pear tree"
    },
    "turtle-doves" : {
      "value" : "two"
    }
  }
}
System.out.println(jsonNode.get("xmas-fifth-day"));
{"calling-birds":{"value":"four"},"partridges":{"count":1,"value":"a pear tree"},"turtle-doves":{"value":"two"}}

Also you could have a map of String and JsonNode, using TyperReference

inputStream = new FileInputStream(new File("test.yml"));
        final Map<String,JsonNode>  map = mapper.readValue(inputStream, new TypeReference<Map<String, JsonNode>>() {});
        System.out.println(map.get("xmas-fifth-day"));

and the output is :

{"calling-birds":{"value":"four"},"partridges":{"count":1,"value":"a pear tree"},"turtle-doves":{"value":"two"}}

Upvotes: 1

Karol Dowbecki
Karol Dowbecki

Reputation: 44942

It looks like you are using SnakeYAML so you could define custom types:

public class XmasFifthDay {
  private CallingBirds callingBirds;
  private Partridges partridges;
  private TurtleDoves turtle-doves;
  // getters and setters
}

public class CallingBirds {
  private String value;
  // getters and setters
}

// other classes: Partridges, TurtleDoves

and then load it with:

XmasFifthDay data = yaml.load(inputStream);

Perhaps CallingBirds, Partridges, TurtleDoves could be a single class with count and value fields but the example you have provided is not very clear.

Upvotes: 1

Related Questions