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 17:38:44 UTC

[jackrabbit-filevault-package-maven-plugin] branch feature/JCVLT-558-generate-cnd updated (5bd4b0c -> c1d6dcd)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a change to branch feature/JCVLT-558-generate-cnd
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault-package-maven-plugin.git.


 discard 5bd4b0c  JCRVLT-559 add mojo for generating CND file containing used node types and namespace of a package
     new c1d6dcd  JCRVLT-559 add mojo for generating CND file containing used node types and namespace of a package

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (5bd4b0c)
            \
             N -- N -- N   refs/heads/feature/JCVLT-558-generate-cnd (c1d6dcd)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/jackrabbit/filevault/maven/packaging/GenerateCndMojo.java | 1 -
 1 file changed, 1 deletion(-)

[jackrabbit-filevault-package-maven-plugin] 01/01: JCRVLT-559 add mojo for generating CND file containing used node types and namespace of a package

Posted by kw...@apache.org.
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 c1d6dcd8872476f39f5a6553a0fd05ca3cfb2afe
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 | 119 ++++++++++++++++-----
 2 files changed, 95 insertions(+), 26 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..ec8dede 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;
@@ -45,7 +63,6 @@ import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.jetbrains.annotations.NotNull;
 import org.xml.sax.InputSource;
 
-
 /**
  * Generates a <a href="https://jackrabbit.apache.org/jcr/node-type-notation.html">CND file</a> containing all
  * used node types and namespaces.
@@ -63,7 +80,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 +91,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 +135,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 +149,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 +173,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 +192,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 +215,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);
+                }
+            }
+        }
+    }
 }