This is an automated email from the ASF dual-hosted git repository.
nfsantos pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
The following commit(s) were added to refs/heads/trunk by this push:
new 14c29cabd8 OAK-11515 - Fix indentation and import order (#2106)
14c29cabd8 is described below
commit 14c29cabd892e6f2755d81719d19ec9efd118b8b
Author: Nuno Santos <[email protected]>
AuthorDate: Fri Feb 21 11:44:53 2025 +0100
OAK-11515 - Fix indentation and import order (#2106)
---
.../index/search/spi/editor/DocumentMaker.java | 25 +-
.../search/spi/editor/FulltextDocumentMaker.java | 24 +-
.../search/spi/editor/FulltextIndexEditor.java | 593 ++++++++++-----------
.../spi/editor/FulltextIndexEditorContext.java | 484 ++++++++---------
.../search/spi/editor/FulltextIndexWriter.java | 4 +-
.../spi/editor/FulltextIndexWriterFactory.java | 7 +-
6 files changed, 568 insertions(+), 569 deletions(-)
diff --git
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/DocumentMaker.java
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/DocumentMaker.java
index d9179020fb..7f59cc4e60 100644
---
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/DocumentMaker.java
+++
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/DocumentMaker.java
@@ -18,26 +18,27 @@
*/
package org.apache.jackrabbit.oak.plugins.index.search.spi.editor;
-import java.io.IOException;
-import java.util.List;
-
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import java.io.IOException;
+import java.util.List;
+
/**
* A {@link DocumentMaker} is responsible for creating an instance of a
document D to be indexed.
* For Apache Lucene that would be a Lucene {@code Document}, for Apache Solr
that might be a {@code SolrInputDocument}, etc.
*/
public interface DocumentMaker<D> {
- /**
- * create a document from the current state and list of modified properties
- * @param state the node state
- * @param isUpdate whether it is an update or not
- * @param propertiesModified the list of modified properties
- * @return a document to be indexed
- * @throws IOException whether node state read operations or document
creation fail
- */
- D makeDocument(NodeState state, boolean isUpdate, List<PropertyState>
propertiesModified) throws IOException;
+ /**
+ * create a document from the current state and list of modified properties
+ *
+ * @param state the node state
+ * @param isUpdate whether it is an update or not
+ * @param propertiesModified the list of modified properties
+ * @return a document to be indexed
+ * @throws IOException whether node state read operations or document
creation fail
+ */
+ D makeDocument(NodeState state, boolean isUpdate, List<PropertyState>
propertiesModified) throws IOException;
}
diff --git
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextDocumentMaker.java
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextDocumentMaker.java
index 266dacf047..72d63fa238 100644
---
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextDocumentMaker.java
+++
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextDocumentMaker.java
@@ -18,19 +18,6 @@
*/
package org.apache.jackrabbit.oak.plugins.index.search.spi.editor;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.regex.Pattern;
-
-import javax.jcr.PropertyType;
-
-import org.apache.jackrabbit.guava.common.collect.Iterables;
import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
@@ -49,6 +36,17 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.jcr.PropertyType;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Pattern;
+
import static java.util.Objects.requireNonNull;
import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
import static
org.apache.jackrabbit.oak.plugins.index.search.util.ConfigUtil.getPrimaryTypeName;
diff --git
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexEditor.java
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexEditor.java
index b484af1745..9c70a511ea 100644
---
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexEditor.java
+++
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexEditor.java
@@ -18,13 +18,6 @@
*/
package org.apache.jackrabbit.oak.plugins.index.search.spi.editor;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.jackrabbit.guava.common.collect.Iterables;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -42,6 +35,12 @@ import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
/**
@@ -49,354 +48,354 @@ import static
org.apache.jackrabbit.oak.commons.PathUtils.concat;
*/
public class FulltextIndexEditor<D> implements IndexEditor,
Aggregate.AggregateRoot {
- private static final Logger log =
- LoggerFactory.getLogger(FulltextIndexEditor.class);
-
- public static final String TEXT_EXTRACTION_ERROR = "TextExtractionError";
+ private static final Logger log =
+ LoggerFactory.getLogger(FulltextIndexEditor.class);
- private final FulltextIndexEditorContext<D> context;
+ public static final String TEXT_EXTRACTION_ERROR = "TextExtractionError";
- /* Name of this node, or {@code null} for the root node. */
- private final String name;
+ private final FulltextIndexEditorContext<D> context;
- /* Parent editor or {@code null} if this is the root editor. */
- private final FulltextIndexEditor<D> parent;
+ /* Name of this node, or {@code null} for the root node. */
+ private final String name;
- /* Path of this editor, built lazily in {@link #getPath()}. */
- private String path;
+ /* Parent editor or {@code null} if this is the root editor. */
+ private final FulltextIndexEditor<D> parent;
- private boolean propertiesChanged = false;
+ /* Path of this editor, built lazily in {@link #getPath()}. */
+ private String path;
- private final List<PropertyState> propertiesModified = new ArrayList<>();
+ private boolean propertiesChanged = false;
- /*
- * Flag indicating if the current tree being traversed has a deleted parent.
- */
- private final boolean isDeleted;
+ private final List<PropertyState> propertiesModified = new ArrayList<>();
- private IndexDefinition.IndexingRule indexingRule;
+ /*
+ * Flag indicating if the current tree being traversed has a deleted
parent.
+ */
+ private final boolean isDeleted;
- private List<Aggregate.Matcher> currentMatchers = Collections.emptyList();
+ private IndexDefinition.IndexingRule indexingRule;
- private final MatcherState matcherState;
+ private List<Aggregate.Matcher> currentMatchers = Collections.emptyList();
- private final PathFilter.Result pathFilterResult;
+ private final MatcherState matcherState;
- public FulltextIndexEditor(FulltextIndexEditorContext<D> context) {
- this.parent = null;
- this.name = null;
- this.path = "/";
- this.context = context;
- this.isDeleted = false;
- this.matcherState = MatcherState.NONE;
- this.pathFilterResult =
context.getDefinition().getPathFilter().filter(PathUtils.ROOT_PATH);
- }
+ private final PathFilter.Result pathFilterResult;
- public FulltextIndexEditor(FulltextIndexEditor<D> parent, String name,
- MatcherState matcherState,
- PathFilter.Result pathFilterResult,
- boolean isDeleted) {
- this.parent = parent;
- this.name = name;
- this.path = null;
- this.context = parent.context;
- this.isDeleted = isDeleted;
- this.matcherState = matcherState;
- this.pathFilterResult = pathFilterResult;
- }
+ public FulltextIndexEditor(FulltextIndexEditorContext<D> context) {
+ this.parent = null;
+ this.name = null;
+ this.path = "/";
+ this.context = context;
+ this.isDeleted = false;
+ this.matcherState = MatcherState.NONE;
+ this.pathFilterResult =
context.getDefinition().getPathFilter().filter(PathUtils.ROOT_PATH);
+ }
- public String getPath() {
- if (path == null) { // => parent != null
- path = concat(parent.getPath(), name);
+ public FulltextIndexEditor(FulltextIndexEditor<D> parent, String name,
+ MatcherState matcherState,
+ PathFilter.Result pathFilterResult,
+ boolean isDeleted) {
+ this.parent = parent;
+ this.name = name;
+ this.path = null;
+ this.context = parent.context;
+ this.isDeleted = isDeleted;
+ this.matcherState = matcherState;
+ this.pathFilterResult = pathFilterResult;
}
- return path;
- }
- @Override
- public void enter(NodeState before, NodeState after) {
- if (EmptyNodeState.MISSING_NODE == before && parent == null){
- context.enableReindexMode();
+ public String getPath() {
+ if (path == null) { // => parent != null
+ path = concat(parent.getPath(), name);
+ }
+ return path;
}
- //Only check for indexing if the result is include.
- //In case like TRAVERSE nothing needs to be indexed for those
- //path
- if (pathFilterResult == PathFilter.Result.INCLUDE) {
- //For traversal in deleted sub tree before state has to be used
- NodeState current = after.exists() ? after : before;
- indexingRule = getDefinition().getApplicableIndexingRule(current);
-
- if (indexingRule != null) {
- currentMatchers = indexingRule.getAggregate().createMatchers(this);
- }
+ @Override
+ public void enter(NodeState before, NodeState after) {
+ if (EmptyNodeState.MISSING_NODE == before && parent == null) {
+ context.enableReindexMode();
+ }
+
+ //Only check for indexing if the result is include.
+ //In case like TRAVERSE nothing needs to be indexed for those
+ //path
+ if (pathFilterResult == PathFilter.Result.INCLUDE) {
+ //For traversal in deleted sub tree before state has to be used
+ NodeState current = after.exists() ? after : before;
+ indexingRule = getDefinition().getApplicableIndexingRule(current);
+
+ if (indexingRule != null) {
+ currentMatchers =
indexingRule.getAggregate().createMatchers(this);
+ }
+ }
}
- }
-
- @Override
- public void leave(NodeState before, NodeState after)
- throws CommitFailedException {
- if (propertiesChanged || !before.exists()) {
- String path = getPath();
- if (addOrUpdate(path, after, before.exists())) {
- long indexed = context.incIndexedNodes();
- if (indexed % 1000 == 0) {
- log.debug("[{}] => Indexed {} nodes...", getIndexName(), indexed);
+
+ @Override
+ public void leave(NodeState before, NodeState after)
+ throws CommitFailedException {
+ if (propertiesChanged || !before.exists()) {
+ String path = getPath();
+ if (addOrUpdate(path, after, before.exists())) {
+ long indexed = context.incIndexedNodes();
+ if (indexed % 1000 == 0) {
+ log.debug("[{}] => Indexed {} nodes...", getIndexName(),
indexed);
+ }
+ }
+ }
+
+ for (Aggregate.Matcher m : matcherState.affectedMatchers) {
+ m.markRootDirty();
+ }
+
+ if (parent == null) {
+ PropertyUpdateCallback callback =
context.getPropertyUpdateCallback();
+ if (callback != null) {
+ callback.done();
+ }
+
+ try {
+ context.closeWriter();
+ } catch (IOException e) {
+ CommitFailedException ce = new
CommitFailedException("Fulltext", 4,
+ "Failed to close the Fulltext index " +
context.getIndexingContext().getIndexPath(), e);
+ context.getIndexingContext().indexUpdateFailed(ce);
+ throw ce;
+ }
+ if (context.getIndexedNodes() > 0) {
+ log.debug("[{}] => Indexed {} nodes, done.", getIndexName(),
context.getIndexedNodes());
+ }
}
- }
}
- for (Aggregate.Matcher m : matcherState.affectedMatchers){
- m.markRootDirty();
+ @Override
+ public void propertyAdded(PropertyState after) {
+ markPropertyChanged(after.getName());
+ checkAggregates(after.getName());
+ propertyUpdated(null, after);
}
- if (parent == null) {
- PropertyUpdateCallback callback = context.getPropertyUpdateCallback();
- if (callback != null) {
- callback.done();
- }
-
- try {
- context.closeWriter();
- } catch (IOException e) {
- CommitFailedException ce = new CommitFailedException("Fulltext", 4,
- "Failed to close the Fulltext index " +
context.getIndexingContext().getIndexPath(), e);
- context.getIndexingContext().indexUpdateFailed(ce);
- throw ce;
- }
- if (context.getIndexedNodes() > 0) {
- log.debug("[{}] => Indexed {} nodes, done.", getIndexName(),
context.getIndexedNodes());
- }
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ markPropertyChanged(before.getName());
+ propertiesModified.add(before);
+ checkAggregates(before.getName());
+ propertyUpdated(before, after);
}
- }
-
- @Override
- public void propertyAdded(PropertyState after) {
- markPropertyChanged(after.getName());
- checkAggregates(after.getName());
- propertyUpdated(null, after);
- }
-
- @Override
- public void propertyChanged(PropertyState before, PropertyState after) {
- markPropertyChanged(before.getName());
- propertiesModified.add(before);
- checkAggregates(before.getName());
- propertyUpdated(before, after);
- }
-
- @Override
- public void propertyDeleted(PropertyState before) {
- markPropertyChanged(before.getName());
- propertiesModified.add(before);
- checkAggregates(before.getName());
- propertyUpdated(before, null);
- }
-
- @Override
- public Editor childNodeAdded(String name, NodeState after) {
- PathFilter.Result filterResult = getPathFilterResult(name);
- if (filterResult != PathFilter.Result.EXCLUDE) {
- return new FulltextIndexEditor<>(this, name, getMatcherState(name,
after), filterResult, false);
+
+ @Override
+ public void propertyDeleted(PropertyState before) {
+ markPropertyChanged(before.getName());
+ propertiesModified.add(before);
+ checkAggregates(before.getName());
+ propertyUpdated(before, null);
}
- return null;
- }
-
- @Override
- public Editor childNodeChanged(
- String name, NodeState before, NodeState after) {
- PathFilter.Result filterResult = getPathFilterResult(name);
- if (filterResult != PathFilter.Result.EXCLUDE) {
- return new FulltextIndexEditor<>(this, name, getMatcherState(name,
after), filterResult, false);
+
+ @Override
+ public Editor childNodeAdded(String name, NodeState after) {
+ PathFilter.Result filterResult = getPathFilterResult(name);
+ if (filterResult != PathFilter.Result.EXCLUDE) {
+ return new FulltextIndexEditor<>(this, name, getMatcherState(name,
after), filterResult, false);
+ }
+ return null;
}
- return null;
- }
-
- @Override
- public Editor childNodeDeleted(String name, NodeState before)
- throws CommitFailedException {
- PathFilter.Result filterResult = getPathFilterResult(name);
- if (filterResult == PathFilter.Result.EXCLUDE) {
- return null;
+
+ @Override
+ public Editor childNodeChanged(
+ String name, NodeState before, NodeState after) {
+ PathFilter.Result filterResult = getPathFilterResult(name);
+ if (filterResult != PathFilter.Result.EXCLUDE) {
+ return new FulltextIndexEditor<>(this, name, getMatcherState(name,
after), filterResult, false);
+ }
+ return null;
}
- if (!isDeleted) {
- // tree deletion is handled on the parent node
- String path = concat(getPath(), name);
- try {
- FulltextIndexWriter<D> writer = context.getWriter();
- // Remove all index entries in the removed subtree
- writer.deleteDocuments(path);
- this.context.indexUpdate();
- } catch (IOException e) {
- CommitFailedException ce = new CommitFailedException("Fulltext", 5,
"Failed to remove the index entries of"
- + " the removed subtree " + path + "for index " +
context.getIndexingContext().getIndexPath(), e);
- context.getIndexingContext().indexUpdateFailed(ce);
- throw ce;
- }
+ @Override
+ public Editor childNodeDeleted(String name, NodeState before)
+ throws CommitFailedException {
+ PathFilter.Result filterResult = getPathFilterResult(name);
+ if (filterResult == PathFilter.Result.EXCLUDE) {
+ return null;
+ }
+
+ if (!isDeleted) {
+ // tree deletion is handled on the parent node
+ String path = concat(getPath(), name);
+ try {
+ FulltextIndexWriter<D> writer = context.getWriter();
+ // Remove all index entries in the removed subtree
+ writer.deleteDocuments(path);
+ this.context.indexUpdate();
+ } catch (IOException e) {
+ CommitFailedException ce = new
CommitFailedException("Fulltext", 5, "Failed to remove the index entries of"
+ + " the removed subtree " + path + "for index " +
context.getIndexingContext().getIndexPath(), e);
+ context.getIndexingContext().indexUpdateFailed(ce);
+ throw ce;
+ }
+ }
+
+ MatcherState ms = getMatcherState(name, before);
+ if (!ms.isEmpty()) {
+ return new FulltextIndexEditor<>(this, name, ms, filterResult,
true);
+ }
+ return null; // no need to recurse down the removed subtree
}
- MatcherState ms = getMatcherState(name, before);
- if (!ms.isEmpty()){
- return new FulltextIndexEditor<>(this, name, ms, filterResult, true);
+ public FulltextIndexEditorContext<D> getContext() {
+ return context;
}
- return null; // no need to recurse down the removed subtree
- }
-
- public FulltextIndexEditorContext<D> getContext() {
- return context;
- }
-
- private boolean addOrUpdate(String path, NodeState state, boolean isUpdate)
- throws CommitFailedException {
- try {
- D d = makeDocument(path, state, isUpdate);
- if (d != null) {
- if (log.isTraceEnabled()) {
- log.trace("[{}] Indexed document for {} is {}", getIndexName(),
path, d);
+
+ private boolean addOrUpdate(String path, NodeState state, boolean isUpdate)
+ throws CommitFailedException {
+ try {
+ D d = makeDocument(path, state, isUpdate);
+ if (d != null) {
+ if (log.isTraceEnabled()) {
+ log.trace("[{}] Indexed document for {} is {}",
getIndexName(), path, d);
+ }
+ context.indexUpdate();
+ context.getWriter().updateDocument(path, d);
+ return true;
+ }
+ } catch (IOException e) {
+ log.warn("Failed to index the node [{}] due to {}", path,
e.getMessage());
+ CommitFailedException ce = new CommitFailedException("Fulltext", 3,
+ "Failed to index the node " + path, e);
+ context.getIndexingContext().indexUpdateFailed(ce);
+ throw ce;
+ } catch (IllegalArgumentException ie) {
+ log.warn("Failed to index the node [{}]", path, ie);
}
- context.indexUpdate();
- context.getWriter().updateDocument(path, d);
- return true;
- }
- } catch (IOException e) {
- log.warn("Failed to index the node [{}] due to {}", path,
e.getMessage());
- CommitFailedException ce = new CommitFailedException("Fulltext", 3,
- "Failed to index the node " + path, e);
- context.getIndexingContext().indexUpdateFailed(ce);
- throw ce;
- } catch (IllegalArgumentException ie) {
- log.warn("Failed to index the node [{}]", path, ie);
+ return false;
}
- return false;
- }
- private D makeDocument(String path, NodeState state, boolean isUpdate)
throws IOException {
- if (!isIndexable()) {
- return null;
+ private D makeDocument(String path, NodeState state, boolean isUpdate)
throws IOException {
+ if (!isIndexable()) {
+ return null;
+ }
+ return context.newDocumentMaker(indexingRule,
path).makeDocument(state, isUpdate, propertiesModified);
}
- return context.newDocumentMaker(indexingRule, path).makeDocument(state,
isUpdate, propertiesModified);
- }
- //~-------------------------------------------------------< Aggregate >
+ //~-------------------------------------------------------< Aggregate >
- @Override
- public void markDirty() {
- propertiesChanged = true;
- }
+ @Override
+ public void markDirty() {
+ propertiesChanged = true;
+ }
- private MatcherState getMatcherState(String name, NodeState after) {
- List<Aggregate.Matcher> matched = new ArrayList<>();
- List<Aggregate.Matcher> inherited = new ArrayList<>();
- for (Aggregate.Matcher m :
IterableUtils.chainedIterable(matcherState.inherited, currentMatchers)) {
- Aggregate.Matcher result = m.match(name, after);
- if (result.getStatus() == Aggregate.Matcher.Status.MATCH_FOUND){
- matched.add(result);
- }
+ private MatcherState getMatcherState(String name, NodeState after) {
+ List<Aggregate.Matcher> matched = new ArrayList<>();
+ List<Aggregate.Matcher> inherited = new ArrayList<>();
+ for (Aggregate.Matcher m :
IterableUtils.chainedIterable(matcherState.inherited, currentMatchers)) {
+ Aggregate.Matcher result = m.match(name, after);
+ if (result.getStatus() == Aggregate.Matcher.Status.MATCH_FOUND) {
+ matched.add(result);
+ }
+
+ if (result.getStatus() != Aggregate.Matcher.Status.FAIL) {
+ inherited.addAll(result.nextSet());
+ }
+ }
- if (result.getStatus() != Aggregate.Matcher.Status.FAIL){
- inherited.addAll(result.nextSet());
- }
+ if (!matched.isEmpty() || !inherited.isEmpty()) {
+ return new MatcherState(matched, inherited);
+ }
+ return MatcherState.NONE;
}
- if (!matched.isEmpty() || !inherited.isEmpty()) {
- return new MatcherState(matched, inherited);
- }
- return MatcherState.NONE;
- }
-
-
- /*
- * Determines which all matchers are affected by this property change
- *
- * @param name modified property name
- */
- private void checkAggregates(String name) {
- for (Aggregate.Matcher m : matcherState.matched) {
- if (!matcherState.affectedMatchers.contains(m)
- && m.aggregatesProperty(name)) {
- matcherState.affectedMatchers.add(m);
- }
- }
- }
-
- static class MatcherState {
- final static MatcherState NONE = new MatcherState(List.of(), List.of());
-
- final List<Aggregate.Matcher> matched;
- final List<Aggregate.Matcher> inherited;
- final Set<Aggregate.Matcher> affectedMatchers;
-
- public MatcherState(List<Aggregate.Matcher> matched,
- List<Aggregate.Matcher> inherited){
- this.matched = matched;
- this.inherited = inherited;
-
- //Affected matches would only be used when there are
- //some matched matchers
- if (matched.isEmpty()){
- affectedMatchers = Collections.emptySet();
- } else {
- affectedMatchers = SetUtils.newIdentityHashSet();
- }
+
+ /*
+ * Determines which all matchers are affected by this property change
+ *
+ * @param name modified property name
+ */
+ private void checkAggregates(String name) {
+ for (Aggregate.Matcher m : matcherState.matched) {
+ if (!matcherState.affectedMatchers.contains(m)
+ && m.aggregatesProperty(name)) {
+ matcherState.affectedMatchers.add(m);
+ }
+ }
}
- public boolean isEmpty() {
- return matched.isEmpty() && inherited.isEmpty();
+ static class MatcherState {
+ final static MatcherState NONE = new MatcherState(List.of(),
List.of());
+
+ final List<Aggregate.Matcher> matched;
+ final List<Aggregate.Matcher> inherited;
+ final Set<Aggregate.Matcher> affectedMatchers;
+
+ public MatcherState(List<Aggregate.Matcher> matched,
+ List<Aggregate.Matcher> inherited) {
+ this.matched = matched;
+ this.inherited = inherited;
+
+ //Affected matches would only be used when there are
+ //some matched matchers
+ if (matched.isEmpty()) {
+ affectedMatchers = Collections.emptySet();
+ } else {
+ affectedMatchers = SetUtils.newIdentityHashSet();
+ }
+ }
+
+ public boolean isEmpty() {
+ return matched.isEmpty() && inherited.isEmpty();
+ }
}
- }
- private void markPropertyChanged(String name) {
- if (isIndexable()
- && !propertiesChanged
- && indexingRule.isIndexed(name)) {
- propertiesChanged = true;
+ private void markPropertyChanged(String name) {
+ if (isIndexable()
+ && !propertiesChanged
+ && indexingRule.isIndexed(name)) {
+ propertiesChanged = true;
+ }
}
- }
- private void propertyUpdated(PropertyState before, PropertyState after) {
- PropertyUpdateCallback callback = context.getPropertyUpdateCallback();
+ private void propertyUpdated(PropertyState before, PropertyState after) {
+ PropertyUpdateCallback callback = context.getPropertyUpdateCallback();
- //Avoid further work if no callback is present
- if (callback == null) {
- return;
- }
+ //Avoid further work if no callback is present
+ if (callback == null) {
+ return;
+ }
- String propertyName = before != null ? before.getName() : after.getName();
+ String propertyName = before != null ? before.getName() :
after.getName();
- if (isIndexable()) {
- PropertyDefinition pd = indexingRule.getConfig(propertyName);
- if (pd != null) {
- callback.propertyUpdated(getPath(), propertyName, pd, before, after);
- }
- }
+ if (isIndexable()) {
+ PropertyDefinition pd = indexingRule.getConfig(propertyName);
+ if (pd != null) {
+ callback.propertyUpdated(getPath(), propertyName, pd, before,
after);
+ }
+ }
- for (Aggregate.Matcher m : matcherState.matched) {
- if (m.aggregatesProperty(propertyName)) {
- Aggregate.Include i = m.getCurrentInclude();
- if (i instanceof Aggregate.PropertyInclude) {
- PropertyDefinition pd = ((Aggregate.PropertyInclude)
i).getPropertyDefinition();
- String propertyRelativePath = PathUtils.concat(m.getMatchedPath(),
propertyName);
+ for (Aggregate.Matcher m : matcherState.matched) {
+ if (m.aggregatesProperty(propertyName)) {
+ Aggregate.Include i = m.getCurrentInclude();
+ if (i instanceof Aggregate.PropertyInclude) {
+ PropertyDefinition pd = ((Aggregate.PropertyInclude)
i).getPropertyDefinition();
+ String propertyRelativePath =
PathUtils.concat(m.getMatchedPath(), propertyName);
- callback.propertyUpdated(m.getRootPath(), propertyRelativePath, pd,
before, after);
+ callback.propertyUpdated(m.getRootPath(),
propertyRelativePath, pd, before, after);
+ }
+ }
}
- }
}
- }
- private IndexDefinition getDefinition() {
- return context.getDefinition();
- }
+ private IndexDefinition getDefinition() {
+ return context.getDefinition();
+ }
- private boolean isIndexable(){
- return indexingRule != null;
- }
+ private boolean isIndexable() {
+ return indexingRule != null;
+ }
- private PathFilter.Result getPathFilterResult(String childNodeName) {
- return context.getDefinition().getPathFilter().filter(concat(getPath(),
childNodeName));
- }
+ private PathFilter.Result getPathFilterResult(String childNodeName) {
+ return
context.getDefinition().getPathFilter().filter(concat(getPath(),
childNodeName));
+ }
- private String getIndexName() {
- return context.getDefinition().getIndexName();
- }
+ private String getIndexName() {
+ return context.getDefinition().getIndexName();
+ }
}
diff --git
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexEditorContext.java
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexEditorContext.java
index bcc97eb6e5..b877133228 100644
---
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexEditorContext.java
+++
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexEditorContext.java
@@ -18,10 +18,6 @@
*/
package org.apache.jackrabbit.oak.plugins.index.search.spi.editor;
-import java.io.IOException;
-import java.util.Calendar;
-import java.util.UUID;
-
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
@@ -45,6 +41,10 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.UUID;
+
import static java.util.Objects.requireNonNull;
import static
org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants.PROP_RANDOM_SEED;
import static
org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants.PROP_REFRESH_DEFN;
@@ -55,273 +55,275 @@ import static
org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition.IND
*/
public abstract class FulltextIndexEditorContext<D> {
- private static final Logger log = LoggerFactory
- .getLogger(FulltextIndexEditorContext.class);
+ private static final Logger log = LoggerFactory
+ .getLogger(FulltextIndexEditorContext.class);
- private static final PerfLogger PERF_LOGGER =
- new
PerfLogger(LoggerFactory.getLogger(FulltextIndexEditorContext.class.getName() +
".perf"));
+ private static final PerfLogger PERF_LOGGER =
+ new
PerfLogger(LoggerFactory.getLogger(FulltextIndexEditorContext.class.getName() +
".perf"));
- protected IndexDefinition definition;
+ protected IndexDefinition definition;
- protected final NodeBuilder definitionBuilder;
+ protected final NodeBuilder definitionBuilder;
- private final FulltextIndexWriterFactory<D> indexWriterFactory;
+ private final FulltextIndexWriterFactory<D> indexWriterFactory;
- private FulltextIndexWriter<D> writer = null;
+ private FulltextIndexWriter<D> writer = null;
- private long indexedNodes;
+ private long indexedNodes;
- private final IndexUpdateCallback updateCallback;
+ private final IndexUpdateCallback updateCallback;
- private boolean reindex;
+ private boolean reindex;
- private final ExtractedTextCache extractedTextCache;
+ private final ExtractedTextCache extractedTextCache;
- private final NodeState root;
+ private final NodeState root;
- private final IndexingContext indexingContext;
+ private final IndexingContext indexingContext;
- private final boolean asyncIndexing;
+ private final boolean asyncIndexing;
- //Intentionally static, so that it can be set without passing around clock
objects
- //Set for testing ONLY
- private static Clock clock = Clock.SIMPLE;
+ //Intentionally static, so that it can be set without passing around clock
objects
+ //Set for testing ONLY
+ private static Clock clock = Clock.SIMPLE;
- private final boolean indexDefnRewritten;
+ private final boolean indexDefnRewritten;
- private FulltextBinaryTextExtractor textExtractor;
+ private FulltextBinaryTextExtractor textExtractor;
- private PropertyUpdateCallback propertyUpdateCallback;
+ private PropertyUpdateCallback propertyUpdateCallback;
- protected FulltextIndexEditorContext(NodeState root, NodeBuilder definition,
- @Nullable IndexDefinition
indexDefinition,
- IndexUpdateCallback updateCallback,
- FulltextIndexWriterFactory<D>
indexWriterFactory,
- ExtractedTextCache extractedTextCache,
- IndexingContext indexingContext,
boolean asyncIndexing) {
- this.root = root;
- this.indexingContext = requireNonNull(indexingContext);
- this.definitionBuilder = definition;
- this.indexWriterFactory = indexWriterFactory;
- this.definition = indexDefinition != null ? indexDefinition :
- createIndexDefinition(root, definition, indexingContext,
asyncIndexing);
- this.indexedNodes = 0;
- this.updateCallback = updateCallback;
- this.extractedTextCache = extractedTextCache;
- this.asyncIndexing = asyncIndexing;
- if (this.definition.isOfOldFormat()){
- indexDefnRewritten = true;
- IndexDefinition.updateDefinition(definition,
indexingContext.getIndexPath());
- } else {
- indexDefnRewritten = false;
+ protected FulltextIndexEditorContext(NodeState root, NodeBuilder
definition,
+ @Nullable IndexDefinition
indexDefinition,
+ IndexUpdateCallback updateCallback,
+ FulltextIndexWriterFactory<D>
indexWriterFactory,
+ ExtractedTextCache extractedTextCache,
+ IndexingContext indexingContext,
boolean asyncIndexing) {
+ this.root = root;
+ this.indexingContext = requireNonNull(indexingContext);
+ this.definitionBuilder = definition;
+ this.indexWriterFactory = indexWriterFactory;
+ this.definition = indexDefinition != null ? indexDefinition :
+ createIndexDefinition(root, definition, indexingContext,
asyncIndexing);
+ this.indexedNodes = 0;
+ this.updateCallback = updateCallback;
+ this.extractedTextCache = extractedTextCache;
+ this.asyncIndexing = asyncIndexing;
+ if (this.definition.isOfOldFormat()) {
+ indexDefnRewritten = true;
+ IndexDefinition.updateDefinition(definition,
indexingContext.getIndexPath());
+ } else {
+ indexDefnRewritten = false;
+ }
}
- }
- public abstract IndexDefinition.Builder newDefinitionBuilder();
+ public abstract IndexDefinition.Builder newDefinitionBuilder();
- public abstract DocumentMaker<D>
newDocumentMaker(IndexDefinition.IndexingRule rule, String path);
+ public abstract DocumentMaker<D>
newDocumentMaker(IndexDefinition.IndexingRule rule, String path);
- protected FulltextBinaryTextExtractor
createBinaryTextExtractor(ExtractedTextCache extractedTextCache,
-
IndexDefinition definition, boolean reindex) {
- return new FulltextBinaryTextExtractor(extractedTextCache, definition,
reindex);
- }
+ protected FulltextBinaryTextExtractor
createBinaryTextExtractor(ExtractedTextCache extractedTextCache,
+
IndexDefinition definition, boolean reindex) {
+ return new FulltextBinaryTextExtractor(extractedTextCache, definition,
reindex);
+ }
- public FulltextIndexWriter<D> getWriter() {
- if (writer == null) {
- //Lazy initialization to ensure that definition is based
- //on latest NodeBuilder state specially in case of reindexing
- writer = indexWriterFactory.newInstance(definition, definitionBuilder,
indexingContext.getCommitInfo(), reindex);
+ public FulltextIndexWriter<D> getWriter() {
+ if (writer == null) {
+ //Lazy initialization to ensure that definition is based
+ //on latest NodeBuilder state specially in case of reindexing
+ writer = indexWriterFactory.newInstance(definition,
definitionBuilder, indexingContext.getCommitInfo(), reindex);
+ }
+ return writer;
}
- return writer;
- }
-
- public IndexingContext getIndexingContext() {
- return indexingContext;
- }
-
- @Nullable
- public PropertyUpdateCallback getPropertyUpdateCallback() {
- return propertyUpdateCallback;
- }
-
- public void setPropertyUpdateCallback(PropertyUpdateCallback
propertyUpdateCallback) {
- this.propertyUpdateCallback = propertyUpdateCallback;
- }
-
- /**
- * close writer if it's not null
- */
- public void closeWriter() throws IOException {
- Calendar currentTime = getCalendar();
- final long start = PERF_LOGGER.start();
- boolean indexUpdated = getWriter().close(currentTime.getTimeInMillis());
-
- if (indexUpdated) {
- PERF_LOGGER.end(start, -1, "Closed writer for directory {}", definition);
- //OAK-2029 Record the last updated status so
- //as to make IndexTracker detect changes when index
- //is stored in file system
- NodeBuilder status =
definitionBuilder.child(IndexDefinition.STATUS_NODE);
- status.setProperty(IndexDefinition.STATUS_LAST_UPDATED,
getUpdatedTime(currentTime), Type.DATE);
- status.setProperty("indexedNodes", indexedNodes);
- if (reindex) {
- status.setProperty(IndexDefinition.REINDEX_COMPLETION_TIMESTAMP,
ISO8601.format(currentTime), Type.DATE);
- log.info(IndexDefinition.REINDEX_COMPLETION_TIMESTAMP + " set to
current time for index:" + definition.getIndexPath());
- }
-
- PERF_LOGGER.end(start, -1, "Overall Closed IndexWriter for directory
{}", definition);
-
- if (textExtractor != null){
- textExtractor.done(reindex);
- }
+
+ public IndexingContext getIndexingContext() {
+ return indexingContext;
}
- }
- private String getUpdatedTime(Calendar currentTime) {
- CommitInfo info = getIndexingContext().getCommitInfo();
- String checkpointTime = (String)
info.getInfo().get(IndexConstants.CHECKPOINT_CREATION_TIME);
- if (checkpointTime != null) {
- return checkpointTime;
+ @Nullable
+ public PropertyUpdateCallback getPropertyUpdateCallback() {
+ return propertyUpdateCallback;
}
- return ISO8601.format(currentTime);
- }
-
- /** Only set for testing */
- protected static void setClock(Clock c) {
- requireNonNull(c);
- clock = c;
- }
-
- static private Calendar getCalendar() {
- Calendar ret = Calendar.getInstance();
- ret.setTime(clock.getDate());
- return ret;
- }
-
- public void enableReindexMode(){
- reindex = true;
- ReindexOperations reindexOps =
- new ReindexOperations(root, definitionBuilder,
definition.getIndexPath(), newDefinitionBuilder(),
storedIndexDefinitionEnabled());
- definition = reindexOps.apply(indexDefnRewritten);
- }
-
- public boolean storedIndexDefinitionEnabled() {
- return !IndexDefinition.isDisableStoredIndexDefinition();
- }
-
- public long incIndexedNodes() {
- indexedNodes++;
- return indexedNodes;
- }
-
- public boolean isAsyncIndexing() {
- return asyncIndexing;
- }
-
- public long getIndexedNodes() {
- return indexedNodes;
- }
-
- public void indexUpdate() throws CommitFailedException {
- updateCallback.indexUpdate();
- }
-
- public IndexDefinition getDefinition() {
- return definition;
- }
-
- protected FulltextBinaryTextExtractor getTextExtractor(){
- if (textExtractor == null && isAsyncIndexing()){
- //Create lazily to ensure that if its reindex case then update
definition is picked
- textExtractor = createBinaryTextExtractor(extractedTextCache,
definition, reindex);
+
+ public void setPropertyUpdateCallback(PropertyUpdateCallback
propertyUpdateCallback) {
+ this.propertyUpdateCallback = propertyUpdateCallback;
}
- return textExtractor;
- }
-
- public boolean isReindex() {
- return reindex;
- }
-
- public static String configureUniqueId(NodeBuilder definition) {
- NodeBuilder status = definition.child(IndexDefinition.STATUS_NODE);
- String uid = status.getString(IndexDefinition.PROP_UID);
- if (uid == null) {
- try {
- uid = String.valueOf(Clock.SIMPLE.getTimeIncreasing());
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- uid = String.valueOf(Clock.SIMPLE.getTime());
- }
- status.setProperty(IndexDefinition.PROP_UID, uid);
+
+ /**
+ * close writer if it's not null
+ */
+ public void closeWriter() throws IOException {
+ Calendar currentTime = getCalendar();
+ final long start = PERF_LOGGER.start();
+ boolean indexUpdated =
getWriter().close(currentTime.getTimeInMillis());
+
+ if (indexUpdated) {
+ PERF_LOGGER.end(start, -1, "Closed writer for directory {}",
definition);
+ //OAK-2029 Record the last updated status so
+ //as to make IndexTracker detect changes when index
+ //is stored in file system
+ NodeBuilder status =
definitionBuilder.child(IndexDefinition.STATUS_NODE);
+ status.setProperty(IndexDefinition.STATUS_LAST_UPDATED,
getUpdatedTime(currentTime), Type.DATE);
+ status.setProperty("indexedNodes", indexedNodes);
+ if (reindex) {
+
status.setProperty(IndexDefinition.REINDEX_COMPLETION_TIMESTAMP,
ISO8601.format(currentTime), Type.DATE);
+ log.info(IndexDefinition.REINDEX_COMPLETION_TIMESTAMP + " set
to current time for index:" + definition.getIndexPath());
+ }
+
+ PERF_LOGGER.end(start, -1, "Overall Closed IndexWriter for
directory {}", definition);
+
+ if (textExtractor != null) {
+ textExtractor.done(reindex);
+ }
+ }
}
- return uid;
- }
-
- private IndexDefinition createIndexDefinition(NodeState root, NodeBuilder
definition, IndexingContext
- indexingContext, boolean asyncIndexing) {
- NodeState defnState = definition.getBaseState();
- if (asyncIndexing) {
- // A good time to check and see if we want to inject our random
- // seed - required due to OAK-7929 but could be useful otherwise too.
- Long defRandom =
getLongPropertyOrNull(definition.getProperty(PROP_RANDOM_SEED));
- if (defRandom == null) {
- long seed = UUID.randomUUID().getMostSignificantBits();
- definition.setProperty(PROP_RANDOM_SEED, seed);
- defRandom = seed;
- }
-
- if (storedIndexDefinitionEnabled()) {
- if (definition.getBoolean(PROP_REFRESH_DEFN)) {
- definition.removeProperty(PROP_REFRESH_DEFN);
- NodeState clonedState = NodeStateCloner.cloneVisibleState(defnState);
- definition.setChildNode(INDEX_DEFINITION_NODE, clonedState);
- definition.getChildNode(INDEX_DEFINITION_NODE)
- .setProperty(IndexDefinition.CREATION_TIMESTAMP,
ISO8601.format(Calendar.getInstance()), Type.DATE);
- log.info("Refreshed the index definition for [{}]",
indexingContext.getIndexPath());
- log.info("IndexDefinition creation timestamp updated for [{}]",
indexingContext.getIndexPath());
- if (log.isDebugEnabled()) {
- log.debug("Updated index definition is {}",
NodeStateUtils.toString(clonedState));
- }
- } else if (!definition.hasChildNode(INDEX_DEFINITION_NODE)) {
- definition.setChildNode(INDEX_DEFINITION_NODE,
NodeStateCloner.cloneVisibleState(defnState));
- definition.getChildNode(INDEX_DEFINITION_NODE)
- .setProperty(IndexDefinition.CREATION_TIMESTAMP,
ISO8601.format(Calendar.getInstance()), Type.DATE);
- log.info("Stored the cloned index definition for [{}]. Changes in
index definition would now only be " +
- "effective post reindexing", indexingContext.getIndexPath());
- log.info("IndexDefinition creation timestamp added for [{}]",
indexingContext.getIndexPath());
- } else {
- // This is neither reindex nor refresh. So, let's update cloned def
with random seed
- // if it doesn't match what's there in main definition
- // Reindex would require another indexing cycle to update cloned def.
- // Refresh would anyway is going to do a real clone so that's ok
- NodeState clonedState =
defnState.getChildNode(INDEX_DEFINITION_NODE);
- Long clonedRandom =
getLongPropertyOrNull(clonedState.getProperty(PROP_RANDOM_SEED));
-
- if (clonedRandom == null || clonedRandom != defRandom) {
-
definition.getChildNode(INDEX_DEFINITION_NODE).setProperty(PROP_RANDOM_SEED,
defRandom);
- }
+
+ private String getUpdatedTime(Calendar currentTime) {
+ CommitInfo info = getIndexingContext().getCommitInfo();
+ String checkpointTime = (String)
info.getInfo().get(IndexConstants.CHECKPOINT_CREATION_TIME);
+ if (checkpointTime != null) {
+ return checkpointTime;
+ }
+ return ISO8601.format(currentTime);
+ }
+
+ /**
+ * Only set for testing
+ */
+ protected static void setClock(Clock c) {
+ requireNonNull(c);
+ clock = c;
+ }
+
+ static private Calendar getCalendar() {
+ Calendar ret = Calendar.getInstance();
+ ret.setTime(clock.getDate());
+ return ret;
+ }
+
+ public void enableReindexMode() {
+ reindex = true;
+ ReindexOperations reindexOps =
+ new ReindexOperations(root, definitionBuilder,
definition.getIndexPath(), newDefinitionBuilder(),
storedIndexDefinitionEnabled());
+ definition = reindexOps.apply(indexDefnRewritten);
+ }
+
+ public boolean storedIndexDefinitionEnabled() {
+ return !IndexDefinition.isDisableStoredIndexDefinition();
+ }
+
+ public long incIndexedNodes() {
+ indexedNodes++;
+ return indexedNodes;
+ }
+
+ public boolean isAsyncIndexing() {
+ return asyncIndexing;
+ }
+
+ public long getIndexedNodes() {
+ return indexedNodes;
+ }
+
+ public void indexUpdate() throws CommitFailedException {
+ updateCallback.indexUpdate();
+ }
+
+ public IndexDefinition getDefinition() {
+ return definition;
+ }
+
+ protected FulltextBinaryTextExtractor getTextExtractor() {
+ if (textExtractor == null && isAsyncIndexing()) {
+ //Create lazily to ensure that if its reindex case then update
definition is picked
+ textExtractor = createBinaryTextExtractor(extractedTextCache,
definition, reindex);
+ }
+ return textExtractor;
+ }
+
+ public boolean isReindex() {
+ return reindex;
+ }
+
+ public static String configureUniqueId(NodeBuilder definition) {
+ NodeBuilder status = definition.child(IndexDefinition.STATUS_NODE);
+ String uid = status.getString(IndexDefinition.PROP_UID);
+ if (uid == null) {
+ try {
+ uid = String.valueOf(Clock.SIMPLE.getTimeIncreasing());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ uid = String.valueOf(Clock.SIMPLE.getTime());
+ }
+ status.setProperty(IndexDefinition.PROP_UID, uid);
}
- }
+ return uid;
}
- return newDefinitionBuilder()
- .root(root)
- .defn(defnState)
- .indexPath(indexingContext.getIndexPath())
- .build();
- }
-
- private Long getLongPropertyOrNull(PropertyState propertyState) {
- Long ret = null;
-
- if (propertyState != null) {
- try {
- ret = propertyState.getValue(Type.LONG);
- } catch (Exception e) {
- // It's ok to ignore the exception, but let's log it to help debugging.
- log.debug("Error occurred while reading property as long.", e);
- }
+
+ private IndexDefinition createIndexDefinition(NodeState root, NodeBuilder
definition, IndexingContext
+ indexingContext, boolean asyncIndexing) {
+ NodeState defnState = definition.getBaseState();
+ if (asyncIndexing) {
+ // A good time to check and see if we want to inject our random
+ // seed - required due to OAK-7929 but could be useful otherwise
too.
+ Long defRandom =
getLongPropertyOrNull(definition.getProperty(PROP_RANDOM_SEED));
+ if (defRandom == null) {
+ long seed = UUID.randomUUID().getMostSignificantBits();
+ definition.setProperty(PROP_RANDOM_SEED, seed);
+ defRandom = seed;
+ }
+
+ if (storedIndexDefinitionEnabled()) {
+ if (definition.getBoolean(PROP_REFRESH_DEFN)) {
+ definition.removeProperty(PROP_REFRESH_DEFN);
+ NodeState clonedState =
NodeStateCloner.cloneVisibleState(defnState);
+ definition.setChildNode(INDEX_DEFINITION_NODE,
clonedState);
+ definition.getChildNode(INDEX_DEFINITION_NODE)
+ .setProperty(IndexDefinition.CREATION_TIMESTAMP,
ISO8601.format(Calendar.getInstance()), Type.DATE);
+ log.info("Refreshed the index definition for [{}]",
indexingContext.getIndexPath());
+ log.info("IndexDefinition creation timestamp updated for
[{}]", indexingContext.getIndexPath());
+ if (log.isDebugEnabled()) {
+ log.debug("Updated index definition is {}",
NodeStateUtils.toString(clonedState));
+ }
+ } else if (!definition.hasChildNode(INDEX_DEFINITION_NODE)) {
+ definition.setChildNode(INDEX_DEFINITION_NODE,
NodeStateCloner.cloneVisibleState(defnState));
+ definition.getChildNode(INDEX_DEFINITION_NODE)
+ .setProperty(IndexDefinition.CREATION_TIMESTAMP,
ISO8601.format(Calendar.getInstance()), Type.DATE);
+ log.info("Stored the cloned index definition for [{}].
Changes in index definition would now only be " +
+ "effective post reindexing",
indexingContext.getIndexPath());
+ log.info("IndexDefinition creation timestamp added for
[{}]", indexingContext.getIndexPath());
+ } else {
+ // This is neither reindex nor refresh. So, let's update
cloned def with random seed
+ // if it doesn't match what's there in main definition
+ // Reindex would require another indexing cycle to update
cloned def.
+ // Refresh would anyway is going to do a real clone so
that's ok
+ NodeState clonedState =
defnState.getChildNode(INDEX_DEFINITION_NODE);
+ Long clonedRandom =
getLongPropertyOrNull(clonedState.getProperty(PROP_RANDOM_SEED));
+
+ if (clonedRandom == null || clonedRandom != defRandom) {
+
definition.getChildNode(INDEX_DEFINITION_NODE).setProperty(PROP_RANDOM_SEED,
defRandom);
+ }
+ }
+ }
+ }
+ return newDefinitionBuilder()
+ .root(root)
+ .defn(defnState)
+ .indexPath(indexingContext.getIndexPath())
+ .build();
}
- return ret;
- }
+ private Long getLongPropertyOrNull(PropertyState propertyState) {
+ Long ret = null;
+
+ if (propertyState != null) {
+ try {
+ ret = propertyState.getValue(Type.LONG);
+ } catch (Exception e) {
+ // It's ok to ignore the exception, but let's log it to help
debugging.
+ log.debug("Error occurred while reading property as long.", e);
+ }
+ }
+
+ return ret;
+ }
}
diff --git
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexWriter.java
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexWriter.java
index a736ffc2fd..bc19febc66 100644
---
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexWriter.java
+++
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexWriter.java
@@ -24,8 +24,6 @@ import java.io.IOException;
/**
* A {@link FulltextIndexWriter} is responsible for writing / deleting
documents of type D to the index
* implementation underlying persistence layer.
- *
- *
*/
public interface FulltextIndexWriter<D> {
@@ -33,7 +31,7 @@ public interface FulltextIndexWriter<D> {
* Updates the document having given path
*
* @param path path of the NodeState which the Document represents
- * @param doc updated document
+ * @param doc updated document
*/
void updateDocument(String path, D doc) throws IOException;
diff --git
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexWriterFactory.java
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexWriterFactory.java
index d2ac42ccc8..ef4341d5d3 100644
---
a/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexWriterFactory.java
+++
b/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/spi/editor/FulltextIndexWriterFactory.java
@@ -30,10 +30,11 @@ public interface FulltextIndexWriterFactory<D> {
/**
* create a new index writer instance
- * @param definition the index definition
+ *
+ * @param definition the index definition
* @param definitionBuilder the node builder associated with the index
definition
- * @param commitInfo metadata associated with the commit for this writer
- * @param reindex whether or not reindex should be performed
+ * @param commitInfo metadata associated with the commit for this
writer
+ * @param reindex whether or not reindex should be performed
* @return an index writer
*/
FulltextIndexWriter<D> newInstance(IndexDefinition definition, NodeBuilder
definitionBuilder,