final AtomicBoolean dirtyFlag = new AtomicBoolean(); final AtomicBoolean facetFlag = new AtomicBoolean(); indexingRule.getAggregate().collectAggregates(state, new Aggregate.ResultCollector() { @Override public void onResult(Aggregate.NodeIncludeResult result) {
public void collectAggregates(NodeState root, ResultCollector collector) { if (matchingType(nodeTypeName, root)) { List<Matcher> matchers = createMatchers(); collectAggregates(root, matchers, collector); } }
private static void matchChildren(List<Matcher> matchers, ResultCollector collector, Iterable<? extends ChildNodeEntry> children) { for (ChildNodeEntry cne : children) { List<Matcher> nextSet = newArrayListWithCapacity(matchers.size()); for (Matcher m : matchers) { Matcher result = m.match(cne.getName(), cne.getNodeState()); if (result.getStatus() == Matcher.Status.MATCH_FOUND){ result.collectResults(collector); } if (result.getStatus() != Matcher.Status.FAIL){ nextSet.addAll(result.nextSet()); } } if (!nextSet.isEmpty()) { collectAggregates(cne.getNodeState(), nextSet, collector); } } }
@Test public void noOfChildNodeRead() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("a"))); NodeBuilder nb = newNode("nt:base"); nb.child("a"); for (int i = 0; i < 10; i++) { nb.child("a"+i); } NodeState state = nb.getNodeState(); final AtomicInteger counter = new AtomicInteger(); Iterable<? extends ChildNodeEntry> countingIterator = Iterables.transform(state.getChildNodeEntries(), new Function<ChildNodeEntry, ChildNodeEntry>() { @Override public ChildNodeEntry apply(ChildNodeEntry input) { counter.incrementAndGet(); return input; } }); NodeState mocked = spy(state); doReturn(countingIterator).when(mocked).getChildNodeEntries(); ag.collectAggregates(mocked, col); //Here at max a single call should happen for reading child nodes assertThat(counter.get(), is(lessThanOrEqualTo(1))); }
@Test public void oneLevelTypedMixin() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("mix:title","*", false))); NodeBuilder nb = newNode("nt:base"); nb.child("a").setProperty(JcrConstants.JCR_MIXINTYPES, Collections.singleton("mix:title"), Type.NAMES); nb.child("b"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(1, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a")); }
@Test public void testRelativeNodeInclude() throws Exception{ //Enable relative include for all child nodes of nt:folder //So indexing would create fulltext field for each relative nodes Aggregate agContent = new Aggregate("app:Page", of(ni(null, "jcr:content", true))); mapper.add("app:Page", agContent); NodeBuilder nb = newNode("app:Page"); nb.child("jcr:content").setProperty("foo", "bar"); agContent.collectAggregates(nb.getNodeState(), col); assertEquals(1, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("jcr:content")); assertEquals(2, col.nodeResults.get("jcr:content").size()); //Check that a result is provided for relative node 'b'. Actual node provided //is b/jcr:content assertEquals(1, col.getRelativeNodeResults("jcr:content", "jcr:content").size()); }
@Test public void recursionEnabledWithLimitCheck() throws Exception{ int limit = 5; Aggregate agFile = new Aggregate("nt:file", of(ni("*")), limit); mapper.add("nt:file", agFile); List<String> expectedPaths = Lists.newArrayList(); NodeBuilder nb = newNode("nt:file"); nb.child("a").child("c"); String path = ""; NodeBuilder fb = nb; for (int i = 0; i < limit + 2; i++){ String name = "f "+ i; path = PathUtils.concat(path, name); fb = fb.child(name); fb.setProperty(JCR_PRIMARYTYPE, "nt:file"); if (i < limit) { expectedPaths.add(path); } } expectedPaths.add("a"); agFile.collectAggregates(nb.getNodeState(), col); assertEquals(expectedPaths.size(), col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems(toArray(expectedPaths, String.class))); }
@Test public void oneLevelNamed() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("a"))); NodeBuilder nb = newNode("nt:base"); nb.child("a"); nb.child("b"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(1, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a")); }
@Test public void oneLevelTyped() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("nt:resource","*", false))); NodeBuilder nb = newNode("nt:base"); nb.child("a").setProperty(JCR_PRIMARYTYPE,"nt:resource"); nb.child("b"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(1, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a")); }
@Test public void oneLevelAll() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("*"))); NodeBuilder nb = newNode("nt:base"); nb.child("a").child("c"); nb.child("b"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(2, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a", "b")); }
@Test public void testReaggregate() throws Exception{ //Enable relative include for all child nodes of nt:folder //So indexing would create fulltext field for each relative nodes Aggregate agFolder = new Aggregate("nt:folder", of(ni("nt:file", "*", true))); Aggregate agFile = new Aggregate("nt:file", of(ni(null, "jcr:content", true))); mapper.add("nt:file", agFile); mapper.add("nt:folder", agFolder); NodeBuilder nb = newNode("nt:folder"); nb.child("a").child("c"); createFile(nb, "b", "hello world"); createFile(nb, "c", "hello world"); agFolder.collectAggregates(nb.getNodeState(), col); assertEquals(4, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("b", "c", "b/jcr:content", "c/jcr:content")); assertEquals(2, col.nodeResults.get("b/jcr:content").size()); //Check that a result is provided for relative node 'b'. Actual node provided //is b/jcr:content assertEquals(1, col.getRelativeNodeResults("b/jcr:content", "b").size()); }
@Test public void testReaggregateMixin() throws Exception{ //A variant of testReaggregation but using mixin //instead of normal nodetype. It abuses mix:title //and treat it like nt:file. Test check if reaggregation //works for mixins also //Enable relative include for all child nodes of nt:folder //So indexing would create fulltext field for each relative nodes Aggregate agFolder = new Aggregate("nt:folder", of(ni("mix:title", "*", true))); Aggregate agFile = new Aggregate("mix:title", of(ni(null, "jcr:content", true))); mapper.add("mix:title", agFile); mapper.add("nt:folder", agFolder); NodeBuilder nb = newNode("nt:folder"); nb.child("a").child("c"); createFileMixin(nb, "b", "hello world"); createFileMixin(nb, "c", "hello world"); agFolder.collectAggregates(nb.getNodeState(), col); assertEquals(4, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("b", "c", "b/jcr:content", "c/jcr:content")); assertEquals(2, col.nodeResults.get("b/jcr:content").size()); //Check that a result is provided for relative node 'b'. Actual node provided //is b/jcr:content assertEquals(1, col.getRelativeNodeResults("b/jcr:content", "b").size()); }
@Test public void multiLevelNamed() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("a"), ni("d/e"))); NodeBuilder nb = newNode("nt:base"); nb.child("a").child("c"); nb.child("b"); nb.child("d").child("e").child("f"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(2, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a", "d/e")); }
@Test public void multiLevelAll() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("*"), ni("*/*"))); NodeBuilder nb = newNode("nt:base"); nb.child("a").child("c"); nb.child("b"); nb.child("d").child("e").child("f"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(5, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a", "b", "d", "a/c", "d/e")); }
@Test public void multiAggregateMapping() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("*"))); Aggregate agFile = new Aggregate("nt:file", of(ni("*"), ni("*/*"))); mapper.add("nt:file", agFile); NodeBuilder nb = newNode("nt:base"); nb.child("a").child("c"); nb.child("b").setProperty(JCR_PRIMARYTYPE, "nt:file"); nb.child("b").child("b1").child("b2"); nb.child("c"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(5, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a", "b", "c", "b/b1", "b/b1/b2")); }
@Test public void recursionEnabled() throws Exception{ Aggregate agFile = new Aggregate("nt:file", of(ni("*")), 5); mapper.add("nt:file", agFile); NodeBuilder nb = newNode("nt:file"); nb.child("a").child("c"); nb.child("b").setProperty(JCR_PRIMARYTYPE, "nt:file"); nb.child("b").child("b1").child("b2"); nb.child("c"); agFile.collectAggregates(nb.getNodeState(), col); assertEquals(4, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a", "b", "c", "b/b1")); }
@Test public void multiLevelNamedSubAll() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("a"), ni("d/*/*"))); NodeBuilder nb = newNode("nt:base"); nb.child("a").child("c"); nb.child("b"); nb.child("d").child("e").child("f"); nb.child("d").child("e").child("f2"); nb.child("d").child("e2").child("f3"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(4, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a", "d/e/f", "d/e/f2", "d/e2/f3")); }
@Test public void multiLevelTyped() throws Exception{ Aggregate ag = new Aggregate("nt:base", of(ni("a"), ni("nt:resource", "d/*/*", false))); NodeBuilder nb = newNode("nt:base"); nb.child("a").child("c"); nb.child("b"); nb.child("d").child("e").child("f").setProperty(JCR_PRIMARYTYPE,"nt:resource"); nb.child("d").child("e").child("f2"); nb.child("d").child("e2").child("f3").setProperty(JCR_PRIMARYTYPE, "nt:resource"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(3, col.getNodePaths().size()); assertThat(col.getNodePaths(), hasItems("a", "d/e/f", "d/e2/f3")); }
@Test public void propOneLevelNamed() throws Exception{ NodeBuilder rules = builder.child(INDEX_RULES); rules.child("nt:folder"); child(rules, "nt:folder/properties/p1") .setProperty(FulltextIndexConstants.PROP_NAME, "a/p1"); IndexDefinition defn = new IndexDefinition(root, builder.getNodeState(), "/foo"); Aggregate ag = defn.getApplicableIndexingRule("nt:folder").getAggregate(); NodeBuilder nb = newNode("nt:folder"); nb.child("a").setProperty("p1", "foo"); nb.child("a").setProperty("p2", "foo"); nb.child("b").setProperty("p2", "foo"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(1, col.getPropPaths().size()); assertThat(col.getPropPaths(), hasItems("a/p1")); }
@Test public void propOneLevelRegex() throws Exception{ NodeBuilder rules = builder.child(INDEX_RULES); rules.child("nt:folder"); child(rules, "nt:folder/properties/p1") .setProperty(FulltextIndexConstants.PROP_NAME, "a/foo.*") .setProperty(FulltextIndexConstants.PROP_IS_REGEX, true); IndexDefinition defn = new IndexDefinition(root, builder.getNodeState(), "/foo"); Aggregate ag = defn.getApplicableIndexingRule("nt:folder").getAggregate(); NodeBuilder nb = newNode("nt:folder"); nb.child("a").setProperty("foo1", "foo"); nb.child("a").setProperty("foo2", "foo"); nb.child("a").setProperty("bar1", "foo"); nb.child("b").setProperty("p2", "foo"); ag.collectAggregates(nb.getNodeState(), col); assertEquals(2, col.getPropPaths().size()); assertThat(col.getPropPaths(), hasItems("a/foo1", "a/foo2")); }