You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2015/08/12 11:21:42 UTC
svn commit: r1695457 - in /jackrabbit/oak/trunk/oak-lucene/src:
main/java/org/apache/jackrabbit/oak/plugins/index/lucene/
test/java/org/apache/jackrabbit/oak/plugins/index/lucene/
Author: tommaso
Date: Wed Aug 12 09:21:42 2015
New Revision: 1695457
URL: http://svn.apache.org/r1695457
Log:
OAK-3157 - suggestions ACLs should be checked against :SUGGEST field
Added:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java?rev=1695457&r1=1695456&r2=1695457&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java Wed Aug 12 09:21:42 2015
@@ -377,9 +377,9 @@ public class LuceneIndex implements Adva
// ACL filter spellchecks
Collection<String> suggestedWords = new ArrayList<String>(suggestWords.length);
- QueryParser qp = new QueryParser(Version.LUCENE_47, FieldNames.FULLTEXT, indexNode.getDefinition().getAnalyzer());
+ QueryParser qp = new QueryParser(Version.LUCENE_47, FieldNames.SUGGEST, indexNode.getDefinition().getAnalyzer());
for (SuggestWord suggestion : suggestWords) {
- Query query = qp.createPhraseQuery(FieldNames.FULLTEXT, suggestion.string);
+ Query query = qp.createPhraseQuery(FieldNames.SUGGEST, suggestion.string);
TopDocs topDocs = searcher.search(query, 100);
if (topDocs.totalHits > 0) {
for (ScoreDoc doc : topDocs.scoreDocs) {
Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1695457&r1=1695456&r2=1695457&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java Wed Aug 12 09:21:42 2015
@@ -410,9 +410,9 @@ public class LucenePropertyIndex impleme
// ACL filter suggestions
Collection<String> suggestedWords = new ArrayList<String>(lookupResults.size());
- QueryParser qp = new QueryParser(Version.LUCENE_47, FieldNames.FULLTEXT, indexNode.getDefinition().getAnalyzer());
+ QueryParser qp = new QueryParser(Version.LUCENE_47, FieldNames.SUGGEST, indexNode.getDefinition().getAnalyzer());
for (Lookup.LookupResult suggestion : lookupResults) {
- Query query = qp.createPhraseQuery(FieldNames.FULLTEXT, suggestion.key.toString());
+ Query query = qp.createPhraseQuery(FieldNames.SUGGEST, suggestion.key.toString());
TopDocs topDocs = searcher.search(query, 100);
if (topDocs.totalHits > 0) {
for (ScoreDoc doc : topDocs.scoreDocs) {
Added: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java?rev=1695457&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexSuggestionTest.java Wed Aug 12 09:21:42 2015
@@ -0,0 +1,210 @@
+/*
+ * 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;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.*;
+import org.apache.jackrabbit.oak.plugins.index.nodetype.NodeTypeIndexProvider;
+import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.query.AbstractQueryTest;
+import org.apache.jackrabbit.oak.spi.commit.Observer;
+import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.Iterator;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+@SuppressWarnings("ConstantConditions")
+public class LuceneIndexSuggestionTest extends AbstractQueryTest {
+
+ private ExecutorService executorService = Executors.newFixedThreadPool(2);
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private LuceneIndexEditorProvider editorProvider;
+
+ @Override
+ protected void createTestIndexNode() throws Exception {
+ setTraversalEnabled(false);
+ }
+
+ @Override
+ protected ContentRepository createRepository() {
+ editorProvider = new LuceneIndexEditorProvider(createIndexCopier());
+ LuceneIndexProvider provider = new LuceneIndexProvider();
+ return new Oak()
+ .with(new InitialContent())
+ .with(new OpenSecurityProvider())
+ .with((QueryIndexProvider) provider)
+ .with((Observer) provider)
+ .with(editorProvider)
+ .with(new PropertyIndexEditorProvider())
+ .with(new NodeTypeIndexProvider())
+ .createContentRepository();
+ }
+
+ private IndexCopier createIndexCopier() {
+ try {
+ return new IndexCopier(executorService, temporaryFolder.getRoot());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @After
+ public void shutdownExecutor(){
+ executorService.shutdown();
+ }
+
+ private Tree createSuggestIndex(String name, String indexedNodeType, String indexedPropertyName, boolean addFullText)
+ throws CommitFailedException {
+ Tree index = root.getTree("/");
+
+ Tree def = index.addChild(INDEX_DEFINITIONS_NAME).addChild(name);
+ def.setProperty(JcrConstants.JCR_PRIMARYTYPE,
+ INDEX_DEFINITIONS_NODE_TYPE, Type.NAME);
+ def.setProperty(TYPE_PROPERTY_NAME, LuceneIndexConstants.TYPE_LUCENE);
+ def.setProperty(REINDEX_PROPERTY_NAME, true);
+ def.setProperty("name", name);
+ def.setProperty(LuceneIndexConstants.COMPAT_MODE, IndexFormatVersion.V2.getVersion());
+
+ Tree indexRules = def.addChild("indexRules");
+ indexRules.setProperty(JcrConstants.JCR_PRIMARYTYPE,
+ INDEX_DEFINITIONS_NODE_TYPE, Type.NAME);
+
+ Tree nodeType = indexRules.addChild(indexedNodeType);
+ nodeType.setProperty(JcrConstants.JCR_PRIMARYTYPE,
+ INDEX_DEFINITIONS_NODE_TYPE, Type.NAME);
+
+ Tree properties = nodeType.addChild(LuceneIndexConstants.PROP_NODE);
+ properties.setProperty(JcrConstants.JCR_PRIMARYTYPE,
+ INDEX_DEFINITIONS_NODE_TYPE, Type.NAME);
+
+ Tree propertyIdxDef = properties.addChild("indexedProperty");
+ propertyIdxDef.setProperty(JcrConstants.JCR_PRIMARYTYPE,
+ INDEX_DEFINITIONS_NODE_TYPE, Type.NAME);
+ propertyIdxDef.setProperty("propertyIndex", true);
+ propertyIdxDef.setProperty("analyzed", true);
+ propertyIdxDef.setProperty("useInSuggest", true);
+ if (addFullText) {
+ propertyIdxDef.setProperty("nodeScopeIndex", true);
+ }
+ propertyIdxDef.setProperty("name", indexedPropertyName);
+
+ return index.getChild(INDEX_DEFINITIONS_NAME).getChild(name);
+ }
+
+ /**
+ * Utility method to check suggestion over {@code nodeType} when the index definition also created for
+ * the same type
+ */
+ private void checkSuggestions(final String nodeType,
+ final String indexPropName, final String indexPropValue,
+ final String suggestQueryText, final boolean shouldSuggest)
+ throws CommitFailedException, ParseException {
+ checkSuggestions(nodeType, nodeType, indexPropName, false, indexPropValue, suggestQueryText, shouldSuggest);
+ }
+
+ /**
+ * Utility method to check suggestion over {@code queryNodeType} when the index definition is created for
+ * {@code indexNodeType}
+ */
+ private void checkSuggestions(final String indexNodeType, final String queryNodeType,
+ final String indexPropName, final boolean addFullText, final String indexPropValue,
+ final String suggestQueryText, final boolean shouldSuggest)
+ throws CommitFailedException, ParseException {
+ createSuggestIndex("lucene-suggest", indexNodeType, indexPropName, addFullText);
+
+ Tree test = root.getTree("/").addChild("indexedNode");
+ test.setProperty(indexPropName, indexPropValue);
+ root.commit();
+
+ String suggQuery = createSuggestQuery(queryNodeType, suggestQueryText);
+ Result result = executeQuery(suggQuery, SQL2, QueryEngine.NO_BINDINGS);
+ Iterator<? extends ResultRow> rows = result.getRows().iterator();
+
+ ResultRow firstRow = rows.next();
+ String value = firstRow.getValue("suggestion").getValue(Type.STRING);
+ Suggestion suggestion = Suggestion.fromString(value);
+
+ if (shouldSuggest) {
+ assertNotNull("There should be some suggestion", suggestion.getSuggestion());
+ } else {
+ assertNull("There shouldn't be any suggestion", suggestion.getSuggestion());
+ }
+ }
+
+ private String createSuggestQuery(String nodeTypeName, String suggestFor) {
+ return "SELECT [rep:suggest()] as suggestion FROM [" + nodeTypeName + "] WHERE suggest('" + suggestFor + "')";
+ }
+
+ static class Suggestion {
+ private final long weight;
+ private final String suggestion;
+ Suggestion(String suggestion, long weight) {
+ this.suggestion = suggestion;
+ this.weight = weight;
+ }
+
+ long getWeight() {
+ return weight;
+ }
+
+ String getSuggestion() {
+ return suggestion;
+ }
+
+ static Suggestion fromString(String suggestionResultStr) {
+ if (suggestionResultStr==null || "".equals(suggestionResultStr) || "[]".equals(suggestionResultStr)) {
+ return new Suggestion(null, -1);
+ }
+
+ String [] parts = suggestionResultStr.split(",weight=", 2);
+ int endWeightIdx = parts[1].lastIndexOf("}");
+ long weight = Long.parseLong(parts[1].substring(0, endWeightIdx));
+ String suggestion = parts[0].split("=", 2)[1];
+
+ return new Suggestion(suggestion, weight);
+ }
+ }
+
+ //OAK-3157
+ @Test
+ public void testSuggestQuery() throws Exception {
+ final String nodeType = "nt:base";
+ final String indexPropName = "description";
+ final String indexPropValue = "this is just a sample text which should get some response in suggestions";
+ final String suggestQueryText = "th";
+ final boolean shouldSuggest = true;
+
+ checkSuggestions(nodeType, indexPropName, indexPropValue, suggestQueryText, shouldSuggest);
+ }
+}