Uploaded image for project: 'Commons Configuration'
  1. Commons Configuration
  2. CONFIGURATION-686

JSONConfiguration doesn't support array of objects

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.2
    • 2.3
    • None
    • None

    Description

      Hello,

      I have noticed that the array type is not properly handled by the JSONConfiguration (or AbstractYAMLBasedConfiguration)

      If we take the example from json.org

      {
        "menu": {
          "id": "file",
          "value": "File",
          "popup": {
            "menuitem": [
              {
                "value": "New",
                "onclick": "CreateNewDoc()"
              },
              {
                "value": "Open",
                "onclick": "OpenDoc()"
              },
              {
                "value": "Close",
                "onclick": "CloseDoc()"
              }
            ]
          }
        }
      }
      

      I would have expect the following call to return "New"

      configuration.getString("menu.popup.menuitem(0).value")
      

      The issue, I guess, is that only the Map type is handled by AbstractYAMLBasedConfiguration in a recursive way and not the list type.

      I had a custom JSONConfiguration implementation before supporting this use case, sorry for the code, it could be a bit messy and old, but it is maybe clearer to understand my issue

      @Override
          @SuppressWarnings("unchecked")
          public void read(Reader in) throws ConfigurationException {
              try {
                  Object jsonRoot = MAPPER.readValue(in, Object.class);
                  List<ImmutableNode.Builder> roots = createHierarchy(jsonRoot);
                  if (roots.size() != 1) {
                      throw new ConfigurationException("The configuration only support a single root");
                  }
                  getSubConfigurationParentModel().mergeRoot(roots.get(0).create(), null, null, null, null);
              } catch (IOException ex) {
                  throw new ConfigurationException("Invalid JsonConfiguration", ex);
              }
          }
       
          @SuppressWarnings("unchecked")
          private static List<ImmutableNode.Builder> createHierarchy(Object value) {
              if (value instanceof Map) {
                  ImmutableNode.Builder result = new ImmutableNode.Builder();
                  Map<String, ?> map = (Map<String, ?>) value;
                  for (Map.Entry<String, ?> entry : map.entrySet()) {
                      List<ImmutableNode.Builder> children = createHierarchy(entry.getValue());
                      for (ImmutableNode.Builder child : children) {
                          child.name(entry.getKey());
                          result.addChild(child.create());
                      }
                  }
                  return Collections.singletonList(result);
              } else if (value instanceof List) {
                  List list = (List) value;
                  List<ImmutableNode.Builder> result = new ArrayList<>(list.size());
                  for (Object item : list) {
                      List<ImmutableNode.Builder> children = createHierarchy(item);
                      for (ImmutableNode.Builder child : children) {
                          result.add(child);
                      }
                  }
                  return result;
              }
              ImmutableNode.Builder result = new ImmutableNode.Builder();
              result.value(value);
              return Collections.singletonList(result);
          }
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            vmaurin_glispa Vincent Maurin
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: