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

JSONConfiguration doesn't support array of objects

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.2
    • Fix Version/s: 2.3
    • Component/s: None
    • Labels:
      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

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

              Dates

              • Created:
                Updated:
                Resolved: