This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git
The following commit(s) were added to refs/heads/master by this push:
new 8ff5dea SLING-12469 - Index definitions are not extracted when
individual definitions are defined in the filter.xml as roots (#179)
8ff5dea is described below
commit 8ff5dead11ee7b84f962b9a7496e50828ad19a15
Author: Robert Munteanu <[email protected]>
AuthorDate: Wed Nov 6 11:05:22 2024 +0100
SLING-12469 - Index definitions are not extracted when individual
definitions are defined in the filter.xml as roots (#179)
---
.../handlers/IndexDefinitionsEntryHandler.java | 130 ++++++++++++++++-----
.../handlers/IndexDefinitionsEntryHandlerTest.java | 23 ++++
.../index/full_aggregate/META-INF/vault/filter.xml | 20 ++++
.../jcr_root/_oak_index/.content.xml | 19 +++
.../jcr_root/_oak_index/jcrCreated.xml | 63 ++++++++++
5 files changed, 226 insertions(+), 29 deletions(-)
diff --git
a/src/main/java/org/apache/sling/feature/cpconverter/handlers/IndexDefinitionsEntryHandler.java
b/src/main/java/org/apache/sling/feature/cpconverter/handlers/IndexDefinitionsEntryHandler.java
index 2da38f2..cda7033 100644
---
a/src/main/java/org/apache/sling/feature/cpconverter/handlers/IndexDefinitionsEntryHandler.java
+++
b/src/main/java/org/apache/sling/feature/cpconverter/handlers/IndexDefinitionsEntryHandler.java
@@ -16,6 +16,8 @@
*/
package org.apache.sling.feature.cpconverter.handlers;
+import static java.lang.String.format;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
@@ -61,35 +63,33 @@ public class IndexDefinitionsEntryHandler extends
AbstractRegexEntryHandler {
String.join("|", EXCLUDED_EXTENSIONS) +
")$)[^.]+$"; // match everything else
- private final class IndexDefinitionsParserHandler implements
DocViewParserHandler {
- private final WorkspaceFilter filter;
- private IndexDefinitions definitions;
-
- public IndexDefinitionsParserHandler(WorkspaceFilter filter,
IndexDefinitions definitions) {
- this.filter = filter;
- this.definitions = definitions;
- }
-
- @Override
- public void startDocViewNode(@NotNull String nodePath, @NotNull
DocViewNode2 docViewNode,
- @NotNull Optional<DocViewNode2> parentDocViewNode, int line,
int column)
- throws IOException, RepositoryException {
-
- if ( nodePath.contains(IndexDefinitions.OAK_INDEX_PATH) &&
filter.contains(nodePath) ) {
- definitions.addNode(Text.getRelativeParent(nodePath, 1),
docViewNode);
- }
- }
-
- @Override
- public void endDocViewNode(@NotNull String nodePath, @NotNull
DocViewNode2 docViewNode,
- @NotNull Optional<DocViewNode2> parentDocViewNode, int line,
int column)
- throws IOException, RepositoryException {
- // nothing to do
- }
-
- @Override
- public void startPrefixMapping(String prefix, String uri) {
- definitions.registerPrefixMapping(prefix, uri);
+ private static final String EXTENSION_XML = ".xml";
+
+ // we hardcode the node type name to avoid a dependency on oak-core
+ private static final String NODETYPE_OAK_QUERY_INDEX_DEFINITION =
"oak:QueryIndexDefinition";
+
+ private static final String removeXmlExtension(String input) {
+ if ( !input.endsWith(EXTENSION_XML) )
+ throw new IllegalArgumentException(format("Input string '%s' does
not end in '%s'", input, EXTENSION_XML));
+
+ return input.substring(0, input.length() - EXTENSION_XML.length());
+
+ }
+
+ private static boolean
isOakIndexDefinitionAsFullCoverageAggregate(@NotNull String repositoryPath,
+ @NotNull Archive archive, @NotNull Entry entry) throws
IOException, XmlParseException {
+
+ if ( !repositoryPath.endsWith(EXTENSION_XML) )
+ return false;
+
+ DocViewParser parser = new DocViewParser(new
SimpleNamespaceResolver());
+
+ try (InputStream isCheck = archive.openInputStream(entry)) {
+ IndexDefinitionAsFullCoverageDetectorParserHandler parserHandler =
new IndexDefinitionAsFullCoverageDetectorParserHandler(repositoryPath);
+
+ parser.parse(repositoryPath, new InputSource(isCheck),
parserHandler);
+
+ return parserHandler.isIsIndexDefinitionAsFullCoverage();
}
}
@@ -120,6 +120,11 @@ public class IndexDefinitionsEntryHandler extends
AbstractRegexEntryHandler {
}
if ( isDocView ) {
DocViewParser parser = new DocViewParser(new
SimpleNamespaceResolver());
+
+ // SLING-12469 - support index definitions serialized as
full coverage aggregates
+ if
(isOakIndexDefinitionAsFullCoverageAggregate(repositoryPath, archive, entry)) {
+ repositoryPath = removeXmlExtension(repositoryPath);
+ }
IndexDefinitionsParserHandler handler = new
IndexDefinitionsParserHandler(archive.getMetaInf().getFilter(),
indexManager.getIndexes());
parser.parse(repositoryPath, inputSource, handler);
@@ -139,4 +144,71 @@ public class IndexDefinitionsEntryHandler extends
AbstractRegexEntryHandler {
converter.getMainPackageAssembler().addEntry(path, archive, entry);
}
+
+ static class DocViewParserHandlerAdapter implements DocViewParserHandler {
+
+ @Override
+ public void startDocViewNode(@NotNull String nodePath, @NotNull
DocViewNode2 docViewNode,
+ @NotNull Optional<DocViewNode2> parentDocViewNode, int line,
int column)
+ throws IOException, RepositoryException {
+ // override as needed
+ }
+
+ @Override
+ public void endDocViewNode(@NotNull String nodePath, @NotNull
DocViewNode2 docViewNode,
+ @NotNull Optional<DocViewNode2> parentDocViewNode, int line,
int column)
+ throws IOException, RepositoryException {
+ // override as needed
+ }
+ }
+
+ static class IndexDefinitionsParserHandler extends
DocViewParserHandlerAdapter {
+
+ private final WorkspaceFilter filter;
+ private IndexDefinitions definitions;
+
+ public IndexDefinitionsParserHandler(WorkspaceFilter filter,
IndexDefinitions definitions) {
+ this.filter = filter;
+ this.definitions = definitions;
+ }
+
+ @Override
+ public void startDocViewNode(@NotNull String nodePath, @NotNull
DocViewNode2 docViewNode,
+ @NotNull Optional<DocViewNode2> parentDocViewNode, int line,
int column)
+ throws IOException, RepositoryException {
+
+ if ( nodePath.contains(IndexDefinitions.OAK_INDEX_PATH) &&
filter.contains(nodePath) ) {
+ definitions.addNode(Text.getRelativeParent(nodePath, 1),
docViewNode);
+ }
+ }
+
+ @Override
+ public void startPrefixMapping(String prefix, String uri) {
+ definitions.registerPrefixMapping(prefix, uri);
+ }
+ }
+
+ static final class IndexDefinitionAsFullCoverageDetectorParserHandler
extends DocViewParserHandlerAdapter {
+ private final @NotNull String repositoryPath;
+ private boolean isIndexDefinitionAsFullCoverage;
+
+ private IndexDefinitionAsFullCoverageDetectorParserHandler(@NotNull
String repositoryPath) {
+ this.repositoryPath = repositoryPath;
+ }
+
+ @Override
+ public void startDocViewNode(@NotNull String nodePath, @NotNull
DocViewNode2 docViewNode,
+ @NotNull Optional<DocViewNode2> parentDocViewNode, int line,
int column)
+ throws IOException, RepositoryException {
+ boolean isTopLevelDocViewNode = nodePath.equals(repositoryPath);
+ boolean isOakQueryIndexDefinition =
docViewNode.getPrimaryType().orElse("").equals(NODETYPE_OAK_QUERY_INDEX_DEFINITION);
+ if ( isTopLevelDocViewNode && isOakQueryIndexDefinition) { //
top-level node
+ isIndexDefinitionAsFullCoverage = true;
+ }
+ }
+ public boolean isIsIndexDefinitionAsFullCoverage() {
+ return isIndexDefinitionAsFullCoverage;
+ }
+
+ }
}
diff --git
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/IndexDefinitionsEntryHandlerTest.java
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/IndexDefinitionsEntryHandlerTest.java
index e724dd4..257a844 100644
---
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/IndexDefinitionsEntryHandlerTest.java
+++
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/IndexDefinitionsEntryHandlerTest.java
@@ -255,6 +255,29 @@ public class IndexDefinitionsEntryHandlerTest {
traverseForIndexing(manager, "index_missing_namespaces");
}
+
+ @Test
+ public void handleIndexDefinitionsAsFullAggregates() throws IOException,
ConverterException {
+
+ DefaultIndexManager manager = new DefaultIndexManager();
+
+ traverseForIndexing(manager, "full_aggregate");
+
+ IndexDefinitions defs = manager.getIndexes();
+ Map<String, List<DocViewNode2>> indexes = defs.getIndexes();
+
+ assertThat(indexes).as("index definitions")
+ .hasSize(1)
+ .containsKey("/oak:index");
+
+ List<DocViewNode2> rootIndexes = indexes.get("/oak:index");
+ assertThat(rootIndexes).as("root oak indexes")
+ .hasSize(1)
+ .element(0)
+ .has( Conditions.localName("jcrCreated") )
+ .has( Conditions.property("type", "lucene") )
+ .has( Conditions.childWithLocalName("/oak:index/jcrCreated",
"indexRules", defs));
+ }
private void assertIsValidXml(byte[] tikeConfig) throws
ParserConfigurationException, SAXException, IOException {
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/META-INF/vault/filter.xml
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/META-INF/vault/filter.xml
new file mode 100644
index 0000000..dd1b898
--- /dev/null
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/META-INF/vault/filter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<workspaceFilter version="1.0">
+ <filter root="/oak:index/jcrCreated"/>
+</workspaceFilter>
\ No newline at end of file
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/jcr_root/_oak_index/.content.xml
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/jcr_root/_oak_index/.content.xml
new file mode 100644
index 0000000..bbb035e
--- /dev/null
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/jcr_root/_oak_index/.content.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
xmlns:oak="http://jackrabbit.apache.org/oak/ns/1.0"
+ jcr:primaryType="nt:unstructured"/>
\ No newline at end of file
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/jcr_root/_oak_index/jcrCreated.xml
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/jcr_root/_oak_index/jcrCreated.xml
new file mode 100644
index 0000000..8f541bb
--- /dev/null
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/index/full_aggregate/jcr_root/_oak_index/jcrCreated.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
xmlns:oak="http://jackrabbit.apache.org/oak/ns/1.0"
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
+ jcr:primaryType="oak:QueryIndexDefinition"
+ propertyNames="{Name}[jcr:created]"
+ async="async"
+ includePropertyTypes="[String,Binary]"
+ reindex="{Boolean}false"
+ reindexCount="{Long}3"
+ seed="{Long}8337987644672197141"
+ type="lucene">
+ <indexRules jcr:primaryType="nt:unstructured">
+ <nt:base
+ jcr:primaryType="nt:unstructured"
+ includePropertyTypes="[String,Binary]">
+ <properties jcr:primaryType="nt:unstructured">
+ <sling:alias
+ jcr:primaryType="nt:unstructured"
+ index="{Boolean}false"
+ name="sling:alias"/>
+ <jcr:lastmodifiedby
+ jcr:primaryType="nt:unstructured"
+ index="{Boolean}false"
+ name="jcr:lastmodifiedby"/>
+ <sling:resourcetype
+ jcr:primaryType="nt:unstructured"
+ index="{Boolean}false"
+ name="sling:resourcetype"/>
+ <jcr:createdby
+ jcr:primaryType="nt:unstructured"
+ index="{Boolean}false"
+ name="jcr:createdby"/>
+ <sling:vanitypath
+ jcr:primaryType="nt:unstructured"
+ index="{Boolean}false"
+ name="sling:vanitypath"/>
+ <prop0
+ jcr:primaryType="nt:unstructured"
+ analyzed="{Boolean}true"
+ isRegexp="{Boolean}true"
+ name="^[^\\/]*$"
+ nodeScopeIndex="{Boolean}true"
+ propertyIndex="{Boolean}false"
+ useInExcerpt="{Boolean}true"/>
+ </properties>
+ </nt:base>
+ </indexRules>
+</jcr:root>
\ No newline at end of file