You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/12/13 14:53:51 UTC

[isis] branch master updated: ISIS-2473: adds namespace support for the global doc index

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

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 2453b64  ISIS-2473: adds namespace support for the global doc index
2453b64 is described below

commit 2453b6490754b26735d3d27e407c975870eb8f98
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Dec 13 15:53:34 2020 +0100

    ISIS-2473: adds namespace support for the global doc index
---
 .../main/java/org/apache/isis/tooling/cli/Cli.java |  2 +-
 .../org/apache/isis/tooling/cli/CliConfig.java     | 25 ++++++---
 .../isis/tooling/cli/projdoc/ProjectDocModel.java  |  1 +
 .../isis/tooling/cli/projdoc/ProjectDocWriter.java | 62 +++++++++++++++++-----
 .../apache/isis/tooling/j2adoc/J2AdocContext.java  |  3 ++
 .../org/apache/isis/tooling/j2adoc/J2AdocUnit.java |  8 +++
 .../tooling/j2adoc/convert/HtmlToAsciiDoc.java     | 34 ++++++------
 .../j2adoc/convert/J2AdocConverterDefault.java     | 11 +++-
 .../isis/tooling/j2adoc/test/J2AdocTest.java       |  1 +
 .../tooling/javamodel/ast/AnyTypeDeclaration.java  | 29 +++++++---
 .../tooling/javamodel/ast/CompilationUnits.java    |  2 +-
 .../tooling/javamodel/ast/PackageDeclarations.java | 41 ++++++++++++++
 12 files changed, 173 insertions(+), 46 deletions(-)

diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/Cli.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/Cli.java
index a6c7367..e6a5aad 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/Cli.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/Cli.java
@@ -83,7 +83,7 @@ class Cli implements Callable<Integer> {
         public Integer call() throws Exception {
             
             if(outputFilePath!=null) {
-                getConfig().getProjectDoc().setOutputFile(new File(outputFilePath));
+                getConfig().getProjectDoc().setOutputRootFolder(new File(outputFilePath));
             }
             
             val projTree = ProjectNodeFactory.maven(getProjectRoot());
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java
index b5ea627..b5ad374 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java
@@ -48,19 +48,30 @@ public class CliConfig {
                 + "the License.";
         private LinkedHashMap<String, String> artifactGroups = new LinkedHashMap<>();
         
-        private File outputFile = null; // where to write eg. system-overview.adoc
+        private File outputRootFolder = null; // where to write eg. system-overview.adoc
         
-        private String documentGlobalIndexPath = "index";
+        private String documentPagesPath = "pages";
+        private String documentGlobalIndexPath = "pages/index";
         private String documentGlobalIndexXrefPageIdFormat = "system:generated:index/%s.adoc";
+        
+        private String systemOverviewFilename = "system-overview.adoc";
 
+        // when 3 eg. skips first three parts of the package names 'org.apache.isis'
+        private int namespacePartsSkipCount = 3;
+        
         public boolean isDryRun() {
-            return getOutputFile() == null;
+            return getOutputRootFolder() == null;
+        }
+        
+        public File getDocumentIndexFolder() {
+            return Optional.ofNullable(getOutputRootFolder())
+                    .map(root->new File(root, getDocumentGlobalIndexPath()))
+                    .orElse(null);
         }
         
-        public File getDocumentGlobalIndexOutputFolder() {
-            return Optional.ofNullable(getOutputFile())
-                    .map(File::getParentFile)
-                    .map(folder->new File(folder, getDocumentGlobalIndexPath()))
+        public File getDocumentPagesFolder() {
+            return Optional.ofNullable(getOutputRootFolder())
+                    .map(root->new File(root, getDocumentPagesPath()))
                     .orElse(null);
         }
         
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocModel.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocModel.java
index d766f07..8084b8c 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocModel.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocModel.java
@@ -92,6 +92,7 @@ public class ProjectDocModel {
                 .javaSourceWithFootnotesFormat()
                 .licenseHeader(cliConfig.getProjectDoc().getLicenseHeader())
                 .xrefPageIdFormat(cliConfig.getProjectDoc().getDocumentGlobalIndexXrefPageIdFormat())
+                .namespacePartsSkipCount(cliConfig.getProjectDoc().getNamespacePartsSkipCount())
                 .build();
         
         val doc = doc();
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocWriter.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocWriter.java
index 87b0f84..3d11875 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocWriter.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocWriter.java
@@ -47,33 +47,49 @@ final class ProjectDocWriter {
                 : AsciiDocWriter::writeToFile;
 
         val currentUnit = _Refs.<J2AdocUnit>objectRef(null);
-                
+        val projectDoc = cliConfig.getProjectDoc();
+            
+        val rootFolder = projectDoc.getOutputRootFolder();
+        val pagesFolder = projectDoc.getDocumentPagesFolder();
+        
+        val deleteCount = _Refs.intRef(0);
+        int writeCount = 0;
+        
         try {
 
-            // write system overview
-            docWriter.accept(systemSummaryAdoc, cliConfig.getProjectDoc().getOutputFile());
-
-            // delete document index
-            
-            val globalDocIndexRootFolder = cliConfig.getProjectDoc().getDocumentGlobalIndexOutputFolder();
-            
-            _Files.searchFiles(globalDocIndexRootFolder, dir->true, file->file.getName().endsWith(".adoc"))
+            // delete all generated documents 
+            _Files.searchFiles(rootFolder, dir->true, file->file.getName().endsWith(".adoc"))
             .stream()
             .peek(adocFile->System.out.println(String.format("deleting file: %s", adocFile.getName())))
+            .peek(__->deleteCount.inc())
             .forEach(_Files::deleteFile);
             
+            // write system overview
+            val sysovFile = new File(pagesFolder, projectDoc.getSystemOverviewFilename()); 
+            System.out.println(String.format("writing system overview: %s", sysovFile.getName()));
+            docWriter.accept(systemSummaryAdoc, sysovFile);
+            ++writeCount;
+            
             // write document index
             for(val unit : j2aContext.getUnitIndex().values()) {
             
                 currentUnit.setValue(unit);
+                         
+                val adocIndexFile = adocDestinationFileForUnit(unit, projectDoc);
+                
+                System.out.println(String.format("writing file: %s", adocIndexFile.getName()));
                 
                 docWriter.accept(
                         unit.toAsciiDoc(j2aContext), 
-                        new File(
-                                cliConfig.getProjectDoc().getDocumentGlobalIndexOutputFolder(), 
-                                unit.getName() + ".adoc"));
+                        adocIndexFile);
+                
+                ++writeCount;
             }
                 
+            System.out.println(
+                    String.format("ProjectDocWriter: all done. (deleted: %d, written: %d)", 
+                            deleteCount.getValue(),
+                            writeCount));
             
         } catch (Exception e) {
             System.err.println(String.format(
@@ -84,6 +100,28 @@ final class ProjectDocWriter {
         } 
         
     }
+    
+    // generate output file based on unit's namespace and unit's name
+    private static File adocDestinationFileForUnit(
+            final @NonNull J2AdocUnit unit,
+            final @NonNull CliConfig.ProjectDoc projectDoc) {
+        
+        val indexFolder = projectDoc.getDocumentIndexFolder();
+     
+        val destFolderBuilder = _Refs.<File>objectRef(indexFolder);
+        
+        unit.getNamespace().stream()
+        .skip(projectDoc.getNamespacePartsSkipCount()) 
+        .forEach(subDir->destFolderBuilder.update(currentDir->new File(currentDir, subDir)));
+        
+        val destFolder = destFolderBuilder.getValueElseDefault(indexFolder);
+        destFolder.mkdirs();
+        
+        return new File(
+                destFolder,
+                unit.getName() + ".adoc");
+        
+    }
 
     
 }
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocContext.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocContext.java
index dcd22a6..f97694a 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocContext.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocContext.java
@@ -48,6 +48,9 @@ public class J2AdocContext {
     private final @Nullable String licenseHeader;
     
     @Builder.Default
+    private final int namespacePartsSkipCount = 0;
+    
+    @Builder.Default
     private final @NonNull String memberNameFormat = "[teal]#*%s*#";
     
     @Builder.Default
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocUnit.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocUnit.java
index 745022c..dd29335 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocUnit.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/J2AdocUnit.java
@@ -27,10 +27,12 @@ import com.github.javaparser.javadoc.Javadoc;
 
 import org.asciidoctor.ast.Document;
 
+import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.tooling.j2adoc.util.AsciiDocIncludeTagFilter;
 import org.apache.isis.tooling.javamodel.ast.AnyTypeDeclaration;
 import org.apache.isis.tooling.javamodel.ast.CompilationUnits;
+import org.apache.isis.tooling.javamodel.ast.PackageDeclarations;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -59,6 +61,8 @@ public final class J2AdocUnit {
 
             val cu = StaticJavaParser.parse(source);
             
+            cu.getPackageDeclaration();
+            
             return Stream.of(cu)
             .flatMap(CompilationUnits::streamTypeDeclarations)
             .filter(AnyTypeDeclaration::hasIndexDirective)
@@ -87,6 +91,10 @@ public final class J2AdocUnit {
         return atd.getSimpleName();
     }
     
+    public Can<String> getNamespace() {
+        return PackageDeclarations.namespace(atd.getPackageDeclaration());
+    }
+    
     public String getDeclarationKeywordFriendlyName() {
         return _Strings.capitalize(atd.getKind().name().toLowerCase());
     }
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/convert/HtmlToAsciiDoc.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/convert/HtmlToAsciiDoc.java
index 0942ddd..875bc94 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/convert/HtmlToAsciiDoc.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/convert/HtmlToAsciiDoc.java
@@ -42,7 +42,7 @@ final class HtmlToAsciiDoc {
         
         val adoc = AsciiDocFactory.doc();
         
-        val stack = new BlockHelper(adoc);
+        val helper = new BlockHelper(adoc);
         
         NodeTraversor.traverse(new NodeVisitor() {
             
@@ -55,39 +55,39 @@ final class HtmlToAsciiDoc {
                     
                     val textNode = (TextNode)node;
                     
-                    val text = stack.isPreFormatted()
+                    val text = helper.isPreFormatted()
                             ? textNode.getWholeText()
                             : textNode.text().trim();
                             
                     if(!text.isBlank()) {
-                        stack.blockAppend(text);    
+                        helper.blockAppend(text);    
                     }
                     return;
                 } 
                 
                 switch(tag) {
                 case "ul":
-                    stack.nextList();
+                    helper.nextList();
                     return;
                 case "p":
-                    stack.nextBlock();
+                    helper.nextBlock();
                     return;
                 case "pre":
-                    stack.nextListingBlock();
-                    stack.onPreHead();
+                    helper.nextListingBlock();
+                    helper.onPreHead();
                     return;
                 case "li":
-                    stack.nextListItem();
+                    helper.nextListItem();
                     return;
                 case "b":
                 case "em":
-                    stack.blockAppend(" *");
+                    helper.blockAppend(" *");
                     return;
                 case "tt":
-                    stack.blockAppend(" `");
+                    helper.blockAppend(" `");
                     return;
                 case "i":
-                    stack.blockAppend(" _");
+                    helper.blockAppend(" _");
                     return;
                 }
             }
@@ -99,23 +99,23 @@ final class HtmlToAsciiDoc {
                 
                 switch(tag) {
                 case "ul":
-                    stack.popList();
+                    helper.popList();
                     return;
                 case "pre":
-                    stack.onPreTail();
+                    helper.onPreTail();
                 case "p":
                 case "li":
-                    stack.pop();
+                    helper.pop();
                     return;
                 case "b":
                 case "em":
-                    stack.blockAppend("* ");
+                    helper.blockAppend("* ");
                     return;
                 case "tt":
-                    stack.blockAppend("` ");
+                    helper.blockAppend("` ");
                     return;
                 case "i":
-                    stack.blockAppend("_ ");
+                    helper.blockAppend("_ ");
                     return;
                 }
                 
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/convert/J2AdocConverterDefault.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/convert/J2AdocConverterDefault.java
index 41a2a64..95fc538 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/convert/J2AdocConverterDefault.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/convert/J2AdocConverterDefault.java
@@ -281,8 +281,17 @@ final class J2AdocConverterDefault implements J2AdocConverter {
     
     @Override
     public String xref(final @NonNull J2AdocUnit unit) {
+
+        val xrefCoordinates = unit.getNamespace()
+        .stream()
+        .skip(j2aContext.getNamespacePartsSkipCount())
+        .collect(Can.toCan())
+        .add(unit.getName())
+        .stream()
+        .collect(Collectors.joining("/"));
+        
         return String.format("xref:%s[%s]", 
-                String.format(j2aContext.getXrefPageIdFormat(), unit.getName()), 
+                xrefCoordinates, 
                 unit.getName()); 
     }
 
diff --git a/tooling/java2adoc/src/test/java/org/apache/isis/tooling/j2adoc/test/J2AdocTest.java b/tooling/java2adoc/src/test/java/org/apache/isis/tooling/j2adoc/test/J2AdocTest.java
index e33b69a..6a43871 100644
--- a/tooling/java2adoc/src/test/java/org/apache/isis/tooling/j2adoc/test/J2AdocTest.java
+++ b/tooling/java2adoc/src/test/java/org/apache/isis/tooling/j2adoc/test/J2AdocTest.java
@@ -67,6 +67,7 @@ class J2AdocTest {
         .forEach(j2aContext::add);
         
         j2aContext.streamUnits()
+        //.peek(unit->System.err.println("namespace "+unit.getNamespace()))
         .map(unit->unit.toAsciiDoc(j2aContext))
         .forEach(adoc->{
             
diff --git a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/AnyTypeDeclaration.java b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/AnyTypeDeclaration.java
index 50f9881..77564b4 100644
--- a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/AnyTypeDeclaration.java
+++ b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/AnyTypeDeclaration.java
@@ -20,7 +20,9 @@ package org.apache.isis.tooling.javamodel.ast;
 
 import java.util.Optional;
 
+import com.github.javaparser.ast.CompilationUnit;
 import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
 import com.github.javaparser.ast.body.AnnotationDeclaration;
 import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
@@ -59,6 +61,7 @@ public final class AnyTypeDeclaration {
         public boolean isInterface() { return this == INTERFACE; }
     }
     
+    private final @NonNull CompilationUnit cu;
     private final @NonNull Kind kind;
     private final TypeDeclaration<?> td;
     private final AnnotationDeclaration annotationDeclaration;
@@ -76,8 +79,11 @@ public final class AnyTypeDeclaration {
     
     
     public static AnyTypeDeclaration of(
-            final @NonNull AnnotationDeclaration annotationDeclaration) {
+            final @NonNull AnnotationDeclaration annotationDeclaration,
+            final @NonNull CompilationUnit cu) {
+        
         return new AnyTypeDeclaration(
+                cu,
                 Kind.ANNOTATION, 
                 annotationDeclaration,
                 annotationDeclaration,
@@ -96,8 +102,10 @@ public final class AnyTypeDeclaration {
     }
     
     public static AnyTypeDeclaration of(
-            final @NonNull ClassOrInterfaceDeclaration classOrInterfaceDeclaration) {
+            final @NonNull ClassOrInterfaceDeclaration classOrInterfaceDeclaration,
+            final @NonNull CompilationUnit cu) {
         return new AnyTypeDeclaration(
+                cu,
                 classOrInterfaceDeclaration.isInterface() ? Kind.INTERFACE : Kind.CLASS, 
                 classOrInterfaceDeclaration,
                 null,
@@ -116,8 +124,10 @@ public final class AnyTypeDeclaration {
     }
     
     public static AnyTypeDeclaration of(
-            final @NonNull EnumDeclaration enumDeclaration) {
+            final @NonNull EnumDeclaration enumDeclaration,
+            final @NonNull CompilationUnit cu) {
         return new AnyTypeDeclaration(
+                cu,
                 Kind.ENUM, 
                 enumDeclaration, 
                 null, 
@@ -137,16 +147,17 @@ public final class AnyTypeDeclaration {
     }
     
     public static AnyTypeDeclaration auto(
-            final @NonNull TypeDeclaration<?> td) {
+            final @NonNull TypeDeclaration<?> td,
+            final @NonNull CompilationUnit cu) {
         
         if(td instanceof ClassOrInterfaceDeclaration) {
-            return of((ClassOrInterfaceDeclaration)td);
+            return of((ClassOrInterfaceDeclaration)td, cu);
         }
         if(td instanceof EnumDeclaration) {
-            return of((EnumDeclaration)td);
+            return of((EnumDeclaration)td, cu);
         }
         if(td instanceof AnnotationDeclaration) {
-            return of((AnnotationDeclaration)td);
+            return of((AnnotationDeclaration)td, cu);
         }
         throw _Exceptions.unsupportedOperation("unsupported TypeDeclaration %s", td.getClass());
     }
@@ -157,6 +168,10 @@ public final class AnyTypeDeclaration {
         return td.getJavadoc();
     }
     
+    public Optional<PackageDeclaration> getPackageDeclaration() {
+        return cu.getPackageDeclaration();
+    }
+    
     public boolean hasIndexDirective() {
         return TypeDeclarations.hasIndexDirective(td);
     }
diff --git a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/CompilationUnits.java b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/CompilationUnits.java
index 2447106..cf2843c 100644
--- a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/CompilationUnits.java
+++ b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/CompilationUnits.java
@@ -53,7 +53,7 @@ public final class CompilationUnits {
         .map(type->type
                 .findAll(TypeDeclaration.class)
                 .stream()
-                .map(AnyTypeDeclaration::auto))
+                .map(td->AnyTypeDeclaration.auto(td, compilationUnit)))
         .orElseGet(Stream::empty);
     }
     
diff --git a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/PackageDeclarations.java b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/PackageDeclarations.java
new file mode 100644
index 0000000..ddce4fd
--- /dev/null
+++ b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/ast/PackageDeclarations.java
@@ -0,0 +1,41 @@
+/*
+ *  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.isis.tooling.javamodel.ast;
+
+import java.util.Optional;
+
+import com.github.javaparser.ast.PackageDeclaration;
+
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._Strings;
+
+import lombok.NonNull;
+
+public final class PackageDeclarations {
+    
+    public static Can<String> namespace(final @NonNull Optional<PackageDeclaration> pdOptional) {
+        return pdOptional
+        .map(PackageDeclaration::getNameAsString)
+        .map(_Strings::nullToEmpty)
+        .map(String::trim)
+        .map(namespace->_Strings.splitThenStream(namespace, ".").collect(Can.toCan()))
+        .orElseGet(()->Can.of("default"));
+    }
+
+}