blob: bf83188fa4c57ec40a5883dc0200f32f7eae9302 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.jackrabbit.oak.plugins.index.lucene.property;
import java.util.List;
import com.google.common.collect.ImmutableList;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.index.lucene.util.IndexDefinitionBuilder;
import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
import org.apache.jackrabbit.oak.plugins.index.search.PropertyDefinition;
import org.apache.jackrabbit.oak.query.NodeStateNodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.QueryEngineSettings;
import org.apache.jackrabbit.oak.query.ast.NodeTypeInfo;
import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.ast.Operator;
import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
import org.apache.jackrabbit.oak.query.index.FilterImpl;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.junit.Test;
import static org.apache.jackrabbit.oak.InitialContentHelper.INITIAL_CONTENT;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
import static org.apache.jackrabbit.oak.plugins.memory.PropertyValues.newString;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertThat;
public class HybridPropertyIndexLookupTest {
private NodeState root = INITIAL_CONTENT;
private NodeBuilder builder = EMPTY_NODE.builder();
private IndexDefinitionBuilder defnb = new IndexDefinitionBuilder();
private String indexPath = "/oak:index/foo";
private PropertyIndexUpdateCallback callback = new PropertyIndexUpdateCallback(indexPath, builder, root);
@Test
public void simplePropertyRestriction() throws Exception{
defnb.indexRule("nt:base").property("foo").sync();
propertyUpdated("/a", "foo", "bar");
FilterImpl f = createFilter();
f.restrictProperty("foo", Operator.EQUAL, newString("bar"));
assertThat(query(f, "foo"), containsInAnyOrder("/a"));
}
@Test
public void valuePattern() throws Exception{
defnb.indexRule("nt:base").property("foo").sync().valuePattern("(a.*|b)");
propertyUpdated("/a", "foo", "a");
propertyUpdated("/a1", "foo", "a1");
propertyUpdated("/b", "foo", "b");
propertyUpdated("/c", "foo", "c");
assertThat(query("foo", "a"), containsInAnyOrder("/a"));
assertThat(query("foo", "a1"), containsInAnyOrder("/a1"));
assertThat(query("foo", "b"), containsInAnyOrder("/b"));
// c should not be found as its excluded
assertThat(query("foo", "c"), empty());
}
@Test
public void relativeProperty() throws Exception{
defnb.indexRule("nt:base").property("foo").sync();
propertyUpdated("/a", "foo", "bar");
FilterImpl f = createFilter();
f.restrictProperty("jcr:content/foo", Operator.EQUAL, newString("bar"));
assertThat(query(f, "foo", "jcr:content/foo"), containsInAnyOrder("/a"));
}
@Test
public void pathResultAbsolutePath() throws Exception{
defnb.indexRule("nt:base").property("foo").sync();
propertyUpdated("/a", "foo", "bar");
String propertyName = "foo";
FilterImpl filter = createFilter();
filter.restrictProperty("foo", Operator.EQUAL, newString("bar"));
HybridPropertyIndexLookup lookup = new HybridPropertyIndexLookup(indexPath, builder.getNodeState());
Iterable<String> paths = lookup.query(filter, propertyName,
filter.getPropertyRestriction(propertyName));
assertThat(ImmutableList.copyOf(paths), containsInAnyOrder("/a"));
}
@Test
public void nonRootIndex() throws Exception{
defnb.indexRule("nt:base").property("foo").sync();
indexPath = "/content/oak:index/fooIndex";
propertyUpdated("/a", "foo", "bar");
String propertyName = "foo";
FilterImpl filter = createFilter();
filter.restrictProperty("foo", Operator.EQUAL, newString("bar"));
filter.restrictPath("/content", Filter.PathRestriction.ALL_CHILDREN);
HybridPropertyIndexLookup lookup = new HybridPropertyIndexLookup(indexPath, builder.getNodeState(),
"/content", false);
Iterable<String> paths = lookup.query(filter, propertyName,
filter.getPropertyRestriction(propertyName));
assertThat(ImmutableList.copyOf(paths), containsInAnyOrder("/a"));
lookup = new HybridPropertyIndexLookup(indexPath, builder.getNodeState(),
"/content", true);
paths = lookup.query(filter, propertyName,
filter.getPropertyRestriction(propertyName));
assertThat(ImmutableList.copyOf(paths), containsInAnyOrder("/content/a"));
}
private void propertyUpdated(String nodePath, String propertyRelativeName, String value){
callback.propertyUpdated(nodePath, propertyRelativeName, pd(propertyRelativeName),
null, createProperty(PathUtils.getName(propertyRelativeName), value));
}
private List<String> query(String propertyName, String value) {
FilterImpl f = createFilter();
f.restrictProperty(propertyName, Operator.EQUAL, newString(value));
return query(f, propertyName);
}
private List<String> query(Filter filter, String propertyName) {
return query(filter, propertyName, propertyName);
}
private List<String> query(Filter filter, String propertyName, String propertyRestrictionName) {
HybridPropertyIndexLookup lookup = new HybridPropertyIndexLookup(indexPath, builder.getNodeState());
Iterable<String> paths = lookup.query(filter, propertyName,
filter.getPropertyRestriction(propertyRestrictionName));
return ImmutableList.copyOf(paths);
}
private PropertyDefinition pd(String propName){
IndexDefinition defn = new IndexDefinition(root, defnb.build(), indexPath);
return defn.getApplicableIndexingRule("nt:base").getConfig(propName);
}
private FilterImpl createFilter() {
return createFilter(root, "nt:base");
}
private FilterImpl createFilter(NodeState root, String nodeTypeName) {
NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(root);
NodeTypeInfo type = nodeTypes.getNodeTypeInfo(nodeTypeName);
SelectorImpl selector = new SelectorImpl(type, nodeTypeName);
return new FilterImpl(selector, "SELECT * FROM [" + nodeTypeName + "]", new QueryEngineSettings());
}
}