You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2022/02/20 10:59:29 UTC
[jackrabbit-filevault-package-maven-plugin] 02/02: JCRVLT-559 add mojo for generating CND file containing used node types and namespace of a package
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch feature/JCVLT-558-generate-cnd
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault-package-maven-plugin.git
commit 5bd4b0c19f41c0c9d59f5d9a67aef5cf147b7916
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Sun Feb 20 11:59:18 2022 +0100
JCRVLT-559 add mojo for generating CND file containing used node types
and namespace of a package
---
pom.xml | 2 +-
.../filevault/maven/packaging/GenerateCndMojo.java | 118 ++++++++++++++++-----
2 files changed, 95 insertions(+), 25 deletions(-)
diff --git a/pom.xml b/pom.xml
index c38113c..dd93ec7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
<!-- ====================================================================== -->
<groupId>org.apache.jackrabbit</groupId>
<artifactId>filevault-package-maven-plugin</artifactId>
- <version>1.2.3-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>Apache Jackrabbit FileVault - Package Maven Plugin</name>
diff --git a/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateCndMojo.java b/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateCndMojo.java
index 3c2804c..7a1fb60 100644
--- a/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateCndMojo.java
+++ b/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/GenerateCndMojo.java
@@ -1,3 +1,19 @@
+/*
+ * 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.filevault.maven.packaging;
import java.io.File;
@@ -24,6 +40,7 @@ import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.commons.cnd.ParseException;
import org.apache.jackrabbit.jcr2spi.nodetype.NodeTypeDefinitionProvider;
import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QNodeDefinition;
import org.apache.jackrabbit.spi.QNodeTypeDefinition;
import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
@@ -34,8 +51,9 @@ import org.apache.jackrabbit.vault.fs.io.DocViewParser.XmlParseException;
import org.apache.jackrabbit.vault.fs.io.DocViewParserHandler;
import org.apache.jackrabbit.vault.util.Constants;
import org.apache.jackrabbit.vault.util.DocViewNode2;
-import org.apache.jackrabbit.vault.validation.spi.impl.nodetype.NodeTypeManagerProvider;
-import org.apache.jackrabbit.vault.validation.spi.impl.nodetype.NodeTypeValidatorFactory;
+import org.apache.jackrabbit.vault.util.StandaloneManagerProvider;
+import org.apache.jackrabbit.vault.validation.spi.util.classloaderurl.CndUtil;
+import org.apache.jackrabbit.vault.validation.spi.util.classloaderurl.URLFactory;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
@@ -63,7 +81,7 @@ public class GenerateCndMojo extends AbstractSourceAndMetadataPackageMojo {
* The source cnd urls.
* Must be urls
*/
- @Parameter()
+ @Parameter(property = "vault.inputCndUrls")
List<String> inputCndUrls = new LinkedList<>();
public GenerateCndMojo() {
@@ -74,20 +92,37 @@ public class GenerateCndMojo extends AbstractSourceAndMetadataPackageMojo {
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("Retrieving used node types and namespaces...");
try {
- NodeTypeManagerProvider ntManagerProvider = new NodeTypeManagerProvider();
- NodeTypeValidatorFactory.registerNodeTypes(inputCndUrls, ntManagerProvider);
- DocViewParser docViewParser = new DocViewParser(ntManagerProvider.getNamespaceResolver());
+ StandaloneManagerProvider managerProvider = new StandaloneManagerProvider();
+ URLFactory.processUrlStreams(CndUtil.resolveJarUrls(inputCndUrls), t -> {
+ try {
+ managerProvider.registerNodeTypes(t);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ catch (ParseException | RepositoryException e) {
+ throw new IllegalArgumentException(e);
+ }
+ });
+ DocViewParser docViewParser = new DocViewParser(managerProvider.getNamespaceResolver());
File cndOutputFile = new File(getGeneratedVaultDir(true), Constants.NODETYPES_CND);
// traverse relevant package files
- Set<String> nodeTypes = collectNodeTypes(getJcrSourceDirectory().toPath(), docViewParser);
- Collection<? extends QNodeTypeDefinition> ntDefinitons = resolveNodeTypes(nodeTypes, ntManagerProvider.getNameResolver(),
- ntManagerProvider.getNodeTypeDefinitionProvider());
+ final Set<String> nodeTypes;
+ try {
+ nodeTypes = collectNodeTypes(getJcrSourceDirectory().toPath(), docViewParser);
+ } catch (UncheckedIOException e) {
+ throw e.getCause();
+ }
+ getLog().info("Found " + nodeTypes.size() + " unique node types" );
+ Collection<? extends QNodeTypeDefinition> ntDefinitons = resolveNodeTypes(nodeTypes, managerProvider.getNameResolver(),
+ managerProvider.getNodeTypeDefinitionProvider());
- // writes the cnd into the given file
+ // writes the CND into the given file
try (Writer writer = Files.newBufferedWriter(cndOutputFile.toPath(), StandardCharsets.US_ASCII)) {
- writeCnd(ntDefinitons, ntManagerProvider.getNamespaceResolver(), writer);
+ writeCnd(ntDefinitons, managerProvider.getNodeTypeDefinitionProvider(), managerProvider.getNamespaceResolver(), writer);
}
- } catch (IOException | RepositoryException | ParseException e) {
+
+ getLog().info("Written CND file to " + getProjectRelativeFilePath(cndOutputFile));
+ } catch (IOException | RepositoryException | ParseException | IllegalStateException e) {
throw new MojoExecutionException("Error while writing CND: " + e.getMessage(), e);
}
}
@@ -101,7 +136,7 @@ public class GenerateCndMojo extends AbstractSourceAndMetadataPackageMojo {
NodeTypeCollectorHandler nodeTypeCollectorHandler = new NodeTypeCollectorHandler(nodeTypes);
// extract types from docview files
- try (Stream<Path> filePaths = Files.find(jcrRootPath, 50, (path, attributes) -> path.getFileName().toString().endsWith(".xml"))) {
+ try (Stream<Path> filePaths = Files.find(jcrRootPath, 50, (path, attributes) -> !attributes.isDirectory() && path.getFileName().toString().endsWith(".xml"))) {
filePaths.forEach(p -> {
try {
getNodeTypes(p, docViewParser, nodeTypeCollectorHandler);
@@ -115,21 +150,22 @@ public class GenerateCndMojo extends AbstractSourceAndMetadataPackageMojo {
private void getNodeTypes(Path docViewFile, DocViewParser docViewParser, NodeTypeCollectorHandler nodeTypeCollectorHandler) throws IOException {
try (Reader reader = Files.newBufferedReader(docViewFile, StandardCharsets.UTF_8)) {
+ reader.mark(1024);
if (!DocViewParser.isDocView(reader)) {
return;
}
- InputSource inputSource = new InputSource();
- inputSource.setCharacterStream(reader);
+ reader.reset();
+ InputSource inputSource = new InputSource(reader);
try {
+ // TODO: get root node path
docViewParser.parse("/", inputSource, nodeTypeCollectorHandler);
} catch (XmlParseException e) {
getLog().warn("Could not parse " + docViewFile + ". Ignore for node type definition generation!", e);
}
}
}
-
- static final class NodeTypeCollectorHandler implements DocViewParserHandler {
+ final class NodeTypeCollectorHandler implements DocViewParserHandler {
private final Set<String> nodeTypes;
public NodeTypeCollectorHandler(Set<String> nodeTypes) {
this.nodeTypes = nodeTypes;
@@ -138,8 +174,15 @@ public class GenerateCndMojo extends AbstractSourceAndMetadataPackageMojo {
@Override
public void startDocViewNode(@NotNull String nodePath, @NotNull DocViewNode2 docViewNode, @NotNull Optional<DocViewNode2> parentDocViewNode, int line, int column)
throws IOException, RepositoryException {
- docViewNode.getPrimaryType().ifPresent(type -> nodeTypes.add(type));
- nodeTypes.addAll(docViewNode.getMixinTypes());
+ Optional<String> primaryType = docViewNode.getPrimaryType();
+ if (primaryType.isPresent()) {
+ if (nodeTypes.add(primaryType.get())) {
+ getLog().debug("Found primary type " + primaryType.get() + " in " + nodePath);
+ }
+ }
+ if (nodeTypes.addAll(docViewNode.getMixinTypes())) {
+ getLog().debug("Found mixin types " + docViewNode.getMixinTypes() + " in " + nodePath);
+ }
}
@Override
@@ -150,20 +193,20 @@ public class GenerateCndMojo extends AbstractSourceAndMetadataPackageMojo {
}
// resolve from cnd file
- private Collection<? extends QNodeTypeDefinition> resolveNodeTypes(Set<String> nodeTypeNames, NameResolver nameResolver, NodeTypeDefinitionProvider ntDefinitionProvider) throws IOException, RepositoryException, ParseException {
+ private Collection<QNodeTypeDefinition> resolveNodeTypes(Set<String> nodeTypeNames, NameResolver nameResolver, NodeTypeDefinitionProvider ntDefinitionProvider) throws IOException, RepositoryException, ParseException {
return resolveNodeTypesFromNames(nodeTypeNames.stream()
.map(name -> {
try {
return nameResolver.getQName(name);
} catch (IllegalNameException|NamespaceException e) {
- throw new IllegalStateException(e);
+ throw new IllegalStateException("Cannot get expanded name for type " + name, e);
}
})
.collect(Collectors.toSet()),
ntDefinitionProvider);
}
- static Collection<? extends QNodeTypeDefinition> resolveNodeTypesFromNames(Set<Name> nodeTypeNames, NodeTypeDefinitionProvider ntDefinitionProvider) throws IOException, RepositoryException, ParseException {
+ static Collection<QNodeTypeDefinition> resolveNodeTypesFromNames(Set<Name> nodeTypeNames, NodeTypeDefinitionProvider ntDefinitionProvider) throws IOException, RepositoryException, ParseException {
return nodeTypeNames.stream().map(name -> {
try {
return ntDefinitionProvider.getNodeTypeDefinition(name);
@@ -173,11 +216,38 @@ public class GenerateCndMojo extends AbstractSourceAndMetadataPackageMojo {
}).collect(Collectors.toList());
}
- private void writeCnd(Collection<? extends QNodeTypeDefinition> nodeTypeDefinitions, NamespaceResolver nsResolver, Writer writer) throws IOException {
+ private void writeCnd(Collection<? extends QNodeTypeDefinition> nodeTypeDefinitions, NodeTypeDefinitionProvider ntDefinitionProvider, NamespaceResolver nsResolver, Writer writer) throws IOException, RepositoryException {
CompactNodeTypeDefWriter cndWriter = new CompactNodeTypeDefWriter(writer, nsResolver, true);
+ Set<Name> written = new HashSet<>();
for (QNodeTypeDefinition nodeTypeDefinition : nodeTypeDefinitions) {
- cndWriter.write(nodeTypeDefinition);
+ writeNodeType(nodeTypeDefinition, cndWriter, written, ntDefinitionProvider);
}
cndWriter.close();
}
+
+ private void writeNodeType(Name nodeType, CompactNodeTypeDefWriter cndWriter, Set<Name> written, NodeTypeDefinitionProvider ntDefinitionProvider) throws IOException, RepositoryException {
+ if (nodeType == null || written.contains(nodeType)) {
+ return;
+ }
+ QNodeTypeDefinition ntDefinition = ntDefinitionProvider.getNodeTypeDefinition(nodeType);
+ writeNodeType(ntDefinition, cndWriter, written, ntDefinitionProvider);
+ }
+
+ private void writeNodeType(QNodeTypeDefinition ntDefinition, CompactNodeTypeDefWriter cndWriter, Set<Name> written, NodeTypeDefinitionProvider ntDefinitionProvider)
+ throws IOException, RepositoryException {
+ cndWriter.write(ntDefinition);
+ written.add(ntDefinition.getName());
+ // also write all referenced node types
+ for (Name superType: ntDefinition.getSupertypes()) {
+ writeNodeType(superType, cndWriter, written, ntDefinitionProvider);
+ }
+ for (QNodeDefinition cntDefinition: ntDefinition.getChildNodeDefs()) {
+ writeNodeType(cntDefinition.getDefaultPrimaryType(), cndWriter, written, ntDefinitionProvider);
+ if (cntDefinition.getRequiredPrimaryTypes() != null) {
+ for (Name name: cntDefinition.getRequiredPrimaryTypes()) {
+ writeNodeType(name, cndWriter, written, ntDefinitionProvider);
+ }
+ }
+ }
+ }
}