Better handling of fields that have `.` in their name when doing property based navigation, closes #1875.

This commit is contained in:
Shay Banon 2012-04-19 17:28:14 +03:00
parent 03c9eaf812
commit 98b1f368f5
2 changed files with 68 additions and 5 deletions

View File

@ -53,15 +53,24 @@ public class XContentMapValues {
if (index == pathElements.length) {
return;
}
String currentPath = pathElements[index];
Object currentValue = part.get(currentPath);
String key = pathElements[index];
Object currentValue = part.get(key);
int nextIndex = index + 1;
while (currentValue == null && nextIndex != pathElements.length) {
key += "." + pathElements[nextIndex];
currentValue = part.get(key);
nextIndex++;
}
if (currentValue == null) {
return;
}
if (currentValue instanceof Map) {
extractRawValues(values, (Map<String, Object>) currentValue, pathElements, index + 1);
extractRawValues(values, (Map<String, Object>) currentValue, pathElements, nextIndex);
} else if (currentValue instanceof List) {
extractRawValues(values, (List) currentValue, pathElements, index + 1);
extractRawValues(values, (List) currentValue, pathElements, nextIndex);
} else {
values.add(currentValue);
}
@ -101,7 +110,15 @@ public class XContentMapValues {
}
if (currentValue instanceof Map) {
Map map = (Map) currentValue;
return extractValue(pathElements, index + 1, map.get(pathElements[index]));
String key = pathElements[index];
Object mapValue = map.get(key);
int nextIndex = index + 1;
while (mapValue == null && nextIndex != pathElements.length) {
key += "." + pathElements[nextIndex];
mapValue = map.get(key);
nextIndex++;
}
return extractValue(pathElements, nextIndex, mapValue);
}
if (currentValue instanceof List) {
List valueList = (List) currentValue;

View File

@ -148,5 +148,51 @@ public class XContentMapValuesTests {
assertThat(extListValue.size(), equalTo(2));
assertThat(extListValue.get(0).toString(), equalTo("value1"));
assertThat(extListValue.get(1).toString(), equalTo("value2"));
// fields with . in them
builder = XContentFactory.jsonBuilder().startObject()
.field("xxx.yyy", "value")
.endObject();
map = XContentFactory.xContent(XContentType.JSON).createParser(builder.string()).mapAndClose();
assertThat(XContentMapValues.extractValue("xxx.yyy", map).toString(), equalTo("value"));
builder = XContentFactory.jsonBuilder().startObject()
.startObject("path1.xxx").startObject("path2.yyy").field("test", "value").endObject().endObject()
.endObject();
map = XContentFactory.xContent(XContentType.JSON).createParser(builder.string()).mapAndClose();
assertThat(XContentMapValues.extractValue("path1.xxx.path2.yyy.test", map).toString(), equalTo("value"));
}
@SuppressWarnings({"unchecked"})
@Test
public void testExtractRawValue() throws Exception {
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
.field("test", "value")
.endObject();
Map<String, Object> map = XContentFactory.xContent(XContentType.JSON).createParser(builder.string()).mapAndClose();
assertThat(XContentMapValues.extractRawValues("test", map).get(0).toString(), equalTo("value"));
builder = XContentFactory.jsonBuilder().startObject()
.field("test.me", "value")
.endObject();
map = XContentFactory.xContent(XContentType.JSON).createParser(builder.string()).mapAndClose();
assertThat(XContentMapValues.extractRawValues("test.me", map).get(0).toString(), equalTo("value"));
builder = XContentFactory.jsonBuilder().startObject()
.startObject("path1").startObject("path2").field("test", "value").endObject().endObject()
.endObject();
map = XContentFactory.xContent(XContentType.JSON).createParser(builder.string()).mapAndClose();
assertThat(XContentMapValues.extractRawValues("path1.path2.test", map).get(0).toString(), equalTo("value"));
builder = XContentFactory.jsonBuilder().startObject()
.startObject("path1.xxx").startObject("path2.yyy").field("test", "value").endObject().endObject()
.endObject();
map = XContentFactory.xContent(XContentType.JSON).createParser(builder.string()).mapAndClose();
assertThat(XContentMapValues.extractRawValues("path1.xxx.path2.yyy.test", map).get(0).toString(), equalTo("value"));
}
}