diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/filtering/FilterPath.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/filtering/FilterPath.java index cddb5f4890b65..9bb289bfccd47 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/filtering/FilterPath.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/filtering/FilterPath.java @@ -11,63 +11,166 @@ import org.elasticsearch.core.Glob; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; public class FilterPath { - - public static final FilterPath EMPTY = new FilterPath(); - - private final String filter; - private final String segment; - private final FilterPath next; - private final boolean simpleWildcard; - private final boolean doubleWildcard; - - protected FilterPath(String filter, String segment, FilterPath next) { - this.filter = filter; - this.segment = segment; - this.next = next; - this.simpleWildcard = (segment != null) && (segment.length() == 1) && (segment.charAt(0) == '*'); - this.doubleWildcard = (segment != null) && (segment.length() == 2) && (segment.charAt(0) == '*') && (segment.charAt(1) == '*'); + private static final String WILDCARD = "*"; + private static final String DOUBLE_WILDCARD = "**"; + + private final Map termsChildren; + private final FilterPath[] wildcardChildren; + private final String pattern; + private final boolean isDoubleWildcard; + private final boolean isFinalNode; + + private FilterPath(String pattern, boolean isFinalNode, Map termsChildren, FilterPath[] wildcardChildren) { + this.pattern = pattern; + this.isFinalNode = isFinalNode; + this.termsChildren = Collections.unmodifiableMap(termsChildren); + this.wildcardChildren = wildcardChildren; + this.isDoubleWildcard = pattern.equals(DOUBLE_WILDCARD); } - private FilterPath() { - this("", "", null); - } - - public FilterPath matchProperty(String name) { - if ((next != null) && (simpleWildcard || doubleWildcard || Glob.globMatch(segment, name))) { - return next; + public boolean hasDoubleWildcard() { + if (isDoubleWildcard || pattern.contains(DOUBLE_WILDCARD)) { + return true; } - return null; + for (FilterPath filterPath : wildcardChildren) { + if (filterPath.hasDoubleWildcard()) { + return true; + } + } + for (FilterPath filterPath : termsChildren.values()) { + if (filterPath.hasDoubleWildcard()) { + return true; + } + } + return false; } - public boolean matches() { - return next == null; + private String getPattern() { + return pattern; } - public boolean isDoubleWildcard() { - return doubleWildcard; + private boolean isFinalNode() { + return isFinalNode; } - public boolean hasDoubleWildcard() { - if (filter == null) { + /** + * check if the name matches filter nodes + * if the name equals the filter node name, the node will add to nextFilters. + * if the filter node is a final node, it means the name matches the pattern, and return true + * if the name don't equal a final node, then return false, continue to check the inner filter node + * if current node is a double wildcard node, the node will also add to nextFilters. + * @param name the xcontent property name + * @param nextFilters nextFilters is a List, used to check the inner property of name + * @return true if the name equal a final node, otherwise return false + */ + boolean matches(String name, List nextFilters) { + if (nextFilters == null) { return false; } - return filter.indexOf("**") >= 0; - } - public boolean isSimpleWildcard() { - return simpleWildcard; - } + FilterPath termNode = termsChildren.get(name); + if (termNode != null) { + if (termNode.isFinalNode()) { + return true; + } else { + nextFilters.add(termNode); + } + } + + for (FilterPath wildcardNode : wildcardChildren) { + String wildcardPattern = wildcardNode.getPattern(); + if (Glob.globMatch(wildcardPattern, name)) { + if (wildcardNode.isFinalNode()) { + return true; + } else { + nextFilters.add(wildcardNode); + } + } + } - public String getSegment() { - return segment; + if (isDoubleWildcard) { + nextFilters.add(this); + } + + return false; } - public FilterPath getNext() { - return next; + private static class FilterPathBuilder { + private class BuildNode { + private final Map children; + private final boolean isFinalNode; + + BuildNode(boolean isFinalNode) { + children = new HashMap<>(); + this.isFinalNode = isFinalNode; + } + } + + private BuildNode root = new BuildNode(false); + + void insert(String filter) { + insertNode(filter, root); + } + + FilterPath build() { + return buildPath("", root); + } + + void insertNode(String filter, BuildNode node) { + int end = filter.length(); + int splitPosition = -1; + boolean findEscapes = false; + for (int i = 0; i < end; i++) { + char c = filter.charAt(i); + if (c == '.') { + splitPosition = i; + break; + } else if ((c == '\\') && (i + 1 < end) && (filter.charAt(i + 1) == '.')) { + ++i; + findEscapes = true; + } + } + + if (splitPosition > 0) { + String field = findEscapes + ? filter.substring(0, splitPosition).replaceAll("\\\\.", ".") + : filter.substring(0, splitPosition); + BuildNode child = node.children.get(field); + if (child == null) { + child = new BuildNode(false); + node.children.put(field, child); + } + if (false == child.isFinalNode) { + insertNode(filter.substring(splitPosition + 1), child); + } + } else { + String field = findEscapes ? filter.replaceAll("\\\\.", ".") : filter; + node.children.put(field, new BuildNode(true)); + } + } + + FilterPath buildPath(String segment, BuildNode node) { + Map termsChildren = new HashMap<>(); + List wildcardChildren = new ArrayList<>(); + for (Map.Entry entry : node.children.entrySet()) { + String childName = entry.getKey(); + BuildNode childNode = entry.getValue(); + FilterPath childFilterPath = buildPath(childName, childNode); + if (childName.contains(WILDCARD)) { + wildcardChildren.add(childFilterPath); + } else { + termsChildren.put(childName, childFilterPath); + } + } + return new FilterPath(segment, node.isFinalNode, termsChildren, wildcardChildren.toArray(new FilterPath[0])); + } } public static FilterPath[] compile(Set filters) { @@ -75,38 +178,16 @@ public static FilterPath[] compile(Set filters) { return null; } - List paths = new ArrayList<>(); + FilterPathBuilder builder = new FilterPathBuilder(); for (String filter : filters) { if (filter != null) { filter = filter.trim(); if (filter.length() > 0) { - paths.add(parse(filter, filter)); + builder.insert(filter); } } } - return paths.toArray(new FilterPath[paths.size()]); - } - - private static FilterPath parse(final String filter, final String segment) { - int end = segment.length(); - - for (int i = 0; i < end;) { - char c = segment.charAt(i); - - if (c == '.') { - String current = segment.substring(0, i).replaceAll("\\\\.", "."); - return new FilterPath(filter, current, parse(filter, segment.substring(i + 1))); - } - ++i; - if ((c == '\\') && (i < end) && (segment.charAt(i) == '.')) { - ++i; - } - } - return new FilterPath(filter, segment.replaceAll("\\\\.", "."), EMPTY); - } - - @Override - public String toString() { - return "FilterPath [filter=" + filter + ", segment=" + segment + "]"; + FilterPath filterPath = builder.build(); + return Collections.singletonList(filterPath).toArray(new FilterPath[0]); } } diff --git a/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/filtering/FilterPathBasedFilter.java b/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/filtering/FilterPathBasedFilter.java index 451d897ac870a..dc0ca01cc3f3c 100644 --- a/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/filtering/FilterPathBasedFilter.java +++ b/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/filtering/FilterPathBasedFilter.java @@ -59,26 +59,15 @@ public FilterPathBasedFilter(Set filters, boolean inclusive) { */ private TokenFilter evaluate(String name, FilterPath[] filterPaths) { if (filterPaths != null) { - List nextFilters = null; - + List nextFilters = new ArrayList<>(); for (FilterPath filter : filterPaths) { - FilterPath next = filter.matchProperty(name); - if (next != null) { - if (next.matches()) { - return MATCHING; - } else { - if (nextFilters == null) { - nextFilters = new ArrayList<>(); - } - if (filter.isDoubleWildcard()) { - nextFilters.add(filter); - } - nextFilters.add(next); - } + boolean matches = filter.matches(name, nextFilters); + if (matches) { + return MATCHING; } } - if ((nextFilters != null) && (nextFilters.isEmpty() == false)) { + if (nextFilters.isEmpty() == false) { return new FilterPathBasedFilter(nextFilters.toArray(new FilterPath[nextFilters.size()]), inclusive); } } diff --git a/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/FilterPathGeneratorFilteringTests.java b/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/FilterPathGeneratorFilteringTests.java index a3cff5ad7e226..d7c6eba6d0c97 100644 --- a/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/FilterPathGeneratorFilteringTests.java +++ b/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/FilterPathGeneratorFilteringTests.java @@ -15,7 +15,8 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.test.ESTestCase; -import java.util.Collections; +import java.util.Arrays; +import java.util.stream.Collectors; import static org.hamcrest.Matchers.equalTo; @@ -67,6 +68,11 @@ public void testInclusiveFilters() throws Exception { assertResult(SAMPLE, "**.l", true, "{'h':{'i':{'j':{'k':{'l':'l_value'}}}}}"); assertResult(SAMPLE, "**.*2", true, "{'e':[{'f2':'f2_value'},{'g2':'g2_value'}]}"); + + assertResult(SAMPLE, "h.i.j.k.l,h.i.j.k.l.m", true, "{'h':{'i':{'j':{'k':{'l':'l_value'}}}}}"); + assertResult(SAMPLE, "a,b,c,d,e.f1,e.f2,e.g1,e.g2,h.i.j.k.l", true, SAMPLE); + assertResult(SAMPLE, "", true, ""); + assertResult(SAMPLE, "h.", true, ""); } public void testExclusiveFilters() throws Exception { @@ -278,6 +284,16 @@ public void testExclusiveFilters() throws Exception { + "{'g1':'g1_value'}],'h':{'i':{'j':{'k':{'l':'l_value'}}}}}" ); + assertResult( + SAMPLE, + "h.i.j.k.l,h.i.j.k.l.m", + false, + "{'a':0,'b':true,'c':'c_value','d':[0,1,2],'e':[{'f1':'f1_value','f2':'f2_value'}," + "{'g1':'g1_value','g2':'g2_value'}]}" + ); + + assertResult(SAMPLE, "a,b,c,d,e.f1,e.f2,e.g1,e.g2,h.i.j.k.l", false, ""); + assertResult(SAMPLE, "", false, SAMPLE); + assertResult(SAMPLE, "h.", false, SAMPLE); } public void testInclusiveFiltersWithDots() throws Exception { @@ -295,7 +311,7 @@ private void assertResult(String input, String filter, boolean inclusive, String try ( FilteringGeneratorDelegate generator = new FilteringGeneratorDelegate( JSON_FACTORY.createGenerator(os), - new FilterPathBasedFilter(Collections.singleton(filter), inclusive), + new FilterPathBasedFilter(Arrays.asList(filter.split(",")).stream().collect(Collectors.toSet()), inclusive), true, true ) diff --git a/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/FilterPathTests.java b/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/FilterPathTests.java index a3a29481ff5ee..8545a497fdb68 100644 --- a/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/FilterPathTests.java +++ b/libs/x-content/src/test/java/org/elasticsearch/xcontent/support/filtering/FilterPathTests.java @@ -10,20 +10,19 @@ import org.elasticsearch.test.ESTestCase; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import static java.util.Collections.singleton; import static org.hamcrest.Matchers.arrayWithSize; -import static org.hamcrest.Matchers.emptyString; -import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; public class FilterPathTests extends ESTestCase { - public void testSimpleFilterPath() { final String input = "test"; @@ -31,16 +30,10 @@ public void testSimpleFilterPath() { assertNotNull(filterPaths); assertThat(filterPaths, arrayWithSize(1)); + List nextFilters = new ArrayList<>(); FilterPath filterPath = filterPaths[0]; - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("test")); - - FilterPath next = filterPath.getNext(); - assertNotNull(next); - assertThat(next.matches(), is(true)); - assertThat(next.getSegment(), is(emptyString())); - assertSame(next, FilterPath.EMPTY); + assertThat(filterPath.matches("test", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); } public void testFilterPathWithSubField() { @@ -50,21 +43,16 @@ public void testFilterPathWithSubField() { assertNotNull(filterPaths); assertThat(filterPaths, arrayWithSize(1)); + List nextFilters = new ArrayList<>(); FilterPath filterPath = filterPaths[0]; assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("foo")); + assertThat(filterPath.matches("foo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("bar")); - - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + assertThat(filterPath.matches("bar", nextFilters), is(true)); + assertEquals(nextFilters.size(), 1); } public void testFilterPathWithSubFields() { @@ -74,38 +62,34 @@ public void testFilterPathWithSubFields() { assertNotNull(filterPaths); assertThat(filterPaths, arrayWithSize(1)); + List nextFilters = new ArrayList<>(); FilterPath filterPath = filterPaths[0]; assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("foo")); - - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("bar")); + assertThat(filterPath.matches("foo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("quz")); + assertThat(filterPath.matches("bar", nextFilters), is(false)); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + assertThat(filterPath.matches("quz", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); } public void testEmptyFilterPath() { FilterPath[] filterPaths = FilterPath.compile(singleton("")); assertNotNull(filterPaths); - assertThat(filterPaths, arrayWithSize(0)); + assertThat(filterPaths, arrayWithSize(1)); } public void testNullFilterPath() { FilterPath[] filterPaths = FilterPath.compile(singleton(null)); assertNotNull(filterPaths); - assertThat(filterPaths, arrayWithSize(0)); + assertThat(filterPaths, arrayWithSize(1)); } public void testFilterPathWithEscapedDots() { @@ -115,31 +99,29 @@ public void testFilterPathWithEscapedDots() { assertNotNull(filterPaths); assertThat(filterPaths, arrayWithSize(1)); + List nextFilters = new ArrayList<>(); FilterPath filterPath = filterPaths[0]; assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("w")); - - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("0")); + assertThat(filterPath.matches("w", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("0")); + assertThat(filterPath.matches("0", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("t")); + assertThat(filterPath.matches("0", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + assertThat(filterPath.matches("t", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); input = "w\\.0\\.0\\.t"; @@ -147,16 +129,10 @@ public void testFilterPathWithEscapedDots() { assertNotNull(filterPaths); assertThat(filterPaths, arrayWithSize(1)); + nextFilters = new ArrayList<>(); filterPath = filterPaths[0]; - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("w.0.0.t")); - - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + assertTrue(filterPath.matches("w.0.0.t", nextFilters)); + assertEquals(nextFilters.size(), 0); input = "w\\.0.0\\.t"; @@ -165,19 +141,16 @@ public void testFilterPathWithEscapedDots() { assertThat(filterPaths, arrayWithSize(1)); filterPath = filterPaths[0]; - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("w.0")); - - filterPath = filterPath.getNext(); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("0.t")); + assertThat(filterPath.matches("w.0", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + assertThat(filterPath.matches("0.t", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); } public void testSimpleWildcardFilterPath() { @@ -186,14 +159,10 @@ public void testSimpleWildcardFilterPath() { assertThat(filterPaths, arrayWithSize(1)); FilterPath filterPath = filterPaths[0]; + List nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.isSimpleWildcard(), is(true)); - assertThat(filterPath.getSegment(), equalTo("*")); - - FilterPath next = filterPath.matchProperty(randomAlphaOfLength(2)); - assertNotNull(next); - assertSame(next, FilterPath.EMPTY); + assertThat(filterPath.matches("foo", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); } public void testWildcardInNameFilterPath() { @@ -204,24 +173,22 @@ public void testWildcardInNameFilterPath() { assertThat(filterPaths, arrayWithSize(1)); FilterPath filterPath = filterPaths[0]; - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("f*o")); - assertThat(filterPath.matchProperty("foo"), notNullValue()); - assertThat(filterPath.matchProperty("flo"), notNullValue()); - assertThat(filterPath.matchProperty("foooo"), notNullValue()); - assertThat(filterPath.matchProperty("boo"), nullValue()); - - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("bar")); - - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + List nextFilters = new ArrayList<>(); + assertNotNull(filterPath); + assertThat(filterPath.matches("foo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); + assertThat(filterPath.matches("flo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 2); + assertThat(filterPath.matches("foooo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 3); + assertThat(filterPath.matches("boo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 3); + + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); + assertNotNull(filterPath); + assertThat(filterPath.matches("bar", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); } public void testDoubleWildcardFilterPath() { @@ -230,14 +197,11 @@ public void testDoubleWildcardFilterPath() { assertThat(filterPaths, arrayWithSize(1)); FilterPath filterPath = filterPaths[0]; + List nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.isDoubleWildcard(), is(true)); - assertThat(filterPath.getSegment(), equalTo("**")); - - FilterPath next = filterPath.matchProperty(randomAlphaOfLength(2)); - assertNotNull(next); - assertSame(next, FilterPath.EMPTY); + assertThat(filterPath.matches("foo", nextFilters), is(true)); + assertThat(filterPath.hasDoubleWildcard(), is(true)); + assertEquals(nextFilters.size(), 0); } public void testStartsWithDoubleWildcardFilterPath() { @@ -248,20 +212,16 @@ public void testStartsWithDoubleWildcardFilterPath() { assertThat(filterPaths, arrayWithSize(1)); FilterPath filterPath = filterPaths[0]; + List nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("**")); - - FilterPath next = filterPath.matchProperty(randomAlphaOfLength(2)); - assertNotNull(next); - assertThat(next.matches(), is(false)); - assertThat(next.getSegment(), equalTo("bar")); - - next = next.getNext(); - assertNotNull(next); - assertThat(next.matches(), is(true)); - assertThat(next.getSegment(), is(emptyString())); - assertSame(next, FilterPath.EMPTY); + assertThat(filterPath.matches("foo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); + + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); + assertNotNull(filterPath); + assertThat(filterPath.matches("bar", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); } public void testContainsDoubleWildcardFilterPath() { @@ -272,26 +232,22 @@ public void testContainsDoubleWildcardFilterPath() { assertThat(filterPaths, arrayWithSize(1)); FilterPath filterPath = filterPaths[0]; + List nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("foo")); + assertThat(filterPath.matches("foo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.isDoubleWildcard(), equalTo(true)); - assertThat(filterPath.getSegment(), equalTo("**")); + assertThat(filterPath.matches("test", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("bar")); - - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + assertThat(filterPath.matches("bar", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); } public void testMultipleFilterPaths() { @@ -299,51 +255,87 @@ public void testMultipleFilterPaths() { FilterPath[] filterPaths = FilterPath.compile(inputs); assertNotNull(filterPaths); - assertThat(filterPaths, arrayWithSize(2)); + assertThat(filterPaths, arrayWithSize(1)); // foo.**.bar.* FilterPath filterPath = filterPaths[0]; + List nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("foo")); + assertThat(filterPath.matches("foo", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.isDoubleWildcard(), equalTo(true)); - assertThat(filterPath.getSegment(), equalTo("**")); + assertThat(filterPath.matches("test", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("bar")); + assertThat(filterPath.matches("bar", nextFilters), is(false)); + assertEquals(nextFilters.size(), 2); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.isSimpleWildcard(), equalTo(true)); - assertThat(filterPath.getSegment(), equalTo("*")); - - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + assertThat(filterPath.matches("test2", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); // test.dot\.ted - filterPath = filterPaths[1]; + filterPath = filterPaths[0]; + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("test")); + assertThat(filterPath.matches("test", nextFilters), is(false)); + assertEquals(nextFilters.size(), 1); - filterPath = filterPath.getNext(); + filterPath = nextFilters.get(0); + nextFilters = new ArrayList<>(); assertNotNull(filterPath); - assertThat(filterPath.matches(), is(false)); - assertThat(filterPath.getSegment(), equalTo("dot.ted")); + assertThat(filterPath.matches("dot.ted", nextFilters), is(true)); + assertEquals(nextFilters.size(), 0); + } - filterPath = filterPath.getNext(); - assertNotNull(filterPath); - assertThat(filterPath.matches(), is(true)); - assertThat(filterPath.getSegment(), is(emptyString())); - assertSame(filterPath, FilterPath.EMPTY); + public void testHasNoDoubleWildcard() { + Set filters = new HashSet<>(); + for (int i = 0; i < randomIntBetween(5, 10); i++) { + String item = randomList(1, 5, () -> randomAlphaOfLength(5)).stream().collect(Collectors.joining(".")); + filters.add(item); + } + + FilterPath[] filterPaths = FilterPath.compile(filters); + assertEquals(filterPaths.length, 1); + assertFalse(filterPaths[0].hasDoubleWildcard()); + } + + public void testHasDoubleWildcard() { + Set filters = new HashSet<>(); + for (int i = 0; i < randomIntBetween(5, 10); i++) { + String item = randomList(1, 5, () -> randomAlphaOfLength(5)).stream().collect(Collectors.joining(".")); + filters.add(item); + } + + String item = randomList(1, 5, () -> randomAlphaOfLength(5)).stream().collect(Collectors.joining(".")); + filters.add(item + ".test**doubleWildcard"); + + FilterPath[] filterPaths = FilterPath.compile(filters); + assertEquals(filterPaths.length, 1); + assertTrue(filterPaths[0].hasDoubleWildcard()); + } + + public void testNoMatchesFilter() { + Set filters = new HashSet<>(); + for (int i = 0; i < randomIntBetween(5, 10); i++) { + String item = randomList(1, 5, () -> randomAlphaOfLength(5)).stream().collect(Collectors.joining(".")); + filters.add(item); + } + + FilterPath[] filterPaths = FilterPath.compile(filters); + assertEquals(filterPaths.length, 1); + + List nextFilters = new ArrayList<>(); + FilterPath filterPath = filterPaths[0]; + assertFalse(filterPath.matches(randomAlphaOfLength(10), nextFilters)); + assertEquals(nextFilters.size(), 0); } }