added support for a prefix wild card (*.field) in includes

This commit is contained in:
Boaz Leskes 2013-07-05 12:51:07 +02:00
parent 1645e4230f
commit 491d2b721c
2 changed files with 63 additions and 9 deletions

View File

@ -164,29 +164,41 @@ public class XContentMapValues {
sb.setLength(mark);
continue;
}
boolean exactIncludeMatch = false;
if (includes.length > 0) {
boolean atLeastOnOneIncludeMatched = false;
boolean exactIncludeMatch;
if (includes.length == 0) {
// implied match anything
exactIncludeMatch = true;
} else {
exactIncludeMatch = false;
boolean pathIsPrefixOfAnInclude = false;
for (String include : includes) {
// check for prefix as well to see if we need to zero in, something like: obj1.arr1.*
// check for prefix matches as well to see if we need to zero in, something like: obj1.arr1.* or *.field
// note, this does not work well with middle matches, like obj1.*.obj3
if (include.charAt(0) == '*') {
if (Regex.simpleMatch(include, path)) {
exactIncludeMatch = true;
break;
}
pathIsPrefixOfAnInclude = true;
break;
}
if (include.startsWith(path)) {
if (include.length() == path.length()) {
atLeastOnOneIncludeMatched = true;
exactIncludeMatch = true;
break;
} else if (include.length() > path.length() && include.charAt(path.length()) == '.') {
// include might may match deeper paths. Dive deeper.
atLeastOnOneIncludeMatched = true;
pathIsPrefixOfAnInclude = true;
break;
}
}
if (Regex.simpleMatch(include, path)) {
atLeastOnOneIncludeMatched = true;
exactIncludeMatch = true;
break;
}
}
if (!atLeastOnOneIncludeMatched) {
if (!pathIsPrefixOfAnInclude && !exactIncludeMatch) {
// skip subkeys, not interesting.
sb.setLength(mark);
continue;
}
@ -206,7 +218,7 @@ public class XContentMapValues {
// if we had an exact match, we want give deeper excludes their chance
filter(list, innerInto, exactIncludeMatch ? Strings.EMPTY_ARRAY : includes, excludes, sb);
into.put(entry.getKey(), innerInto);
} else {
} else if (exactIncludeMatch) {
into.put(entry.getKey(), entry.getValue());
}
sb.setLength(mark);

View File

@ -317,6 +317,48 @@ public class XContentMapValuesTests {
assertThat(((Map<String, Object>) ((List) filteredMap.get("array")).get(1)).get("field").toString(), equalTo("value"));
}
@Test
public void filterIncludesUsingStarPrefix() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("field", "value");
map.put("obj",
new HashMap<String, Object>() {{
put("field", "value");
put("field2", "value2");
}});
map.put("n_obj",
new HashMap<String, Object>() {{
put("n_field", "value");
put("n_field2", "value2");
}});
Map<String, Object> filteredMap = XContentMapValues.filter(map, new String[]{"*.field2"}, Strings.EMPTY_ARRAY);
assertThat(filteredMap.size(), equalTo(1));
assertThat(filteredMap, hasKey("obj"));
assertThat(((Map) filteredMap.get("obj")).size(), equalTo(1));
assertThat(((Map) filteredMap.get("obj")), hasKey("field2"));
// only objects
filteredMap = XContentMapValues.filter(map, new String[]{"*.*"}, Strings.EMPTY_ARRAY);
assertThat(filteredMap.size(), equalTo(2));
assertThat(filteredMap, hasKey("obj"));
assertThat(((Map) filteredMap.get("obj")).size(), equalTo(2));
assertThat(filteredMap, hasKey("n_obj"));
assertThat(((Map) filteredMap.get("n_obj")).size(), equalTo(2));
filteredMap = XContentMapValues.filter(map, new String[]{"*"}, new String[]{"*.*2"});
assertThat(filteredMap.size(), equalTo(3));
assertThat(filteredMap, hasKey("field"));
assertThat(filteredMap, hasKey("obj"));
assertThat(((Map) filteredMap.get("obj")).size(), equalTo(1));
assertThat(((Map) filteredMap.get("obj")), hasKey("field"));
assertThat(filteredMap, hasKey("n_obj"));
assertThat(((Map) filteredMap.get("n_obj")).size(), equalTo(1));
assertThat(((Map) filteredMap.get("n_obj")), hasKey("n_field"));
}
@Test
public void filterWithEmptyIncludesExcludes() {
Map<String, Object> map = new HashMap<String, Object>();