Vincent Maurin created CONFIGURATION-686:
--------------------------------------------
Summary: JSONConfiguration doesn't support array of objects
Key: CONFIGURATION-686
URL: https://issues.apache.org/jira/browse/CONFIGURATION-686
Project: Commons Configuration
Issue Type: Bug
Affects Versions: 2.2
Reporter: Vincent Maurin
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
{noformat}
{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{
"value": "New",
"onclick": "CreateNewDoc()"
},
{
"value": "Open",
"onclick": "OpenDoc()"
},
{
"value": "Close",
"onclick": "CloseDoc()"
}
]
}
}
}
{noformat}
I would have expect the following call to return "New"
{code:java}
configuration.getString("menu.popup.menuitem(0).value")
{code}
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
{code:java}
@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);
}
{code}
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)