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/14 21:53:31 UTC

[isis] 01/02: ISIS-2473: use a LookupKey class to model J2AdocUnit lookup keys

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

commit 55fc96886fa998fa1bbcb20714d7ff4b93c1cd84
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Dec 14 20:34:38 2020 +0100

    ISIS-2473: use a LookupKey class to model J2AdocUnit lookup keys
---
 .../isis/commons/resource/ResourceCoordinates.java | 24 ++++---
 .../cli/adocfix/OrphanedIncludeStatementFixer.java |  2 +-
 .../isis/tooling/cli/projdoc/ProjectDocWriter.java |  4 +-
 .../apache/isis/tooling/j2adoc/J2AdocContext.java  | 11 +++-
 .../org/apache/isis/tooling/j2adoc/J2AdocUnit.java | 75 ++++++++++++++++++----
 .../j2adoc/convert/J2AdocConverterDefault.java     | 13 ++--
 .../j2adoc/format/UnitFormatterAbstract.java       |  2 +-
 .../tooling/javamodel/ast/AnyTypeDeclaration.java  | 15 +++--
 .../model4adoc/include/IncludeStatements.java      | 12 ++--
 .../apache/isis/tooling/model4adoc/xref/Xref.java  | 67 +++++++++++++++++++
 10 files changed, 181 insertions(+), 44 deletions(-)

diff --git a/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/ProjectResourceCoordinates.java b/commons/src/main/java/org/apache/isis/commons/resource/ResourceCoordinates.java
similarity index 79%
rename from tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/ProjectResourceCoordinates.java
rename to commons/src/main/java/org/apache/isis/commons/resource/ResourceCoordinates.java
index ff5a6c2..3b7ed9a 100644
--- a/tooling/projectmodel/src/main/java/org/apache/isis/tooling/projectmodel/ProjectResourceCoordinates.java
+++ b/commons/src/main/java/org/apache/isis/commons/resource/ResourceCoordinates.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.tooling.projectmodel;
+package org.apache.isis.commons.resource;
 
 import java.util.Comparator;
 
@@ -28,9 +28,12 @@ import lombok.Builder;
 import lombok.NonNull;
 import lombok.Value;
 
+/**
+ * @since 2.0 {@index}
+ */
 @Value @Builder
-public class ProjectResourceCoordinates 
-implements Comparable<ProjectResourceCoordinates> {
+public class ResourceCoordinates 
+implements Comparable<ResourceCoordinates> {
 
     /**
      * multi-part top level location specifier 
@@ -50,6 +53,11 @@ implements Comparable<ProjectResourceCoordinates> {
      * or a nested class name {@code A$B},       
      */
     private final @NonNull Can<String> name;
+
+    /**
+     * String representation of {@link #getName()}; 
+     */
+    private final @NonNull String nameAsString;
     
     /**
      * usually part of the multi-part name;  
@@ -64,13 +72,13 @@ implements Comparable<ProjectResourceCoordinates> {
      */
     private final @NonNull String friendlyName;
 
-    private final static Comparator<ProjectResourceCoordinates> comparator =
-            Comparator.comparing(ProjectResourceCoordinates::getLocation)
-           .thenComparing(ProjectResourceCoordinates::getNamespace)
-           .thenComparing(ProjectResourceCoordinates::getName);
+    private final static Comparator<ResourceCoordinates> comparator =
+            Comparator.comparing(ResourceCoordinates::getLocation)
+           .thenComparing(ResourceCoordinates::getNamespace)
+           .thenComparing(ResourceCoordinates::getName);
     
     @Override
-    public int compareTo(final @Nullable ProjectResourceCoordinates other) {
+    public int compareTo(final @Nullable ResourceCoordinates other) {
      // when returning
         // -1 ... this is before other 
         // +1 ... this is after other
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/adocfix/OrphanedIncludeStatementFixer.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/adocfix/OrphanedIncludeStatementFixer.java
index b9fc99f..331aa19 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/adocfix/OrphanedIncludeStatementFixer.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/adocfix/OrphanedIncludeStatementFixer.java
@@ -82,7 +82,7 @@ public final class OrphanedIncludeStatementFixer {
             
         });
         
-        System.out.println(String.format("IncludeStatementFixer: all done. (%d orphanded inlcudes fixed)", totalFixed));
+        System.out.println(String.format("IncludeStatementFixer: all done. (%d orphanded inlcudes fixed)", totalFixed.getValue()));
         
     }
 
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 5546ab4..66ac7ec 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
@@ -95,7 +95,7 @@ final class ProjectDocWriter {
         } catch (Exception e) {
             System.err.println(String.format(
                     "failed to write adoc for unit %s", 
-                    currentUnit.getValue().map(J2AdocUnit::getName).orElse("none")));
+                    currentUnit.getValue().map(J2AdocUnit::getCanonicalName).orElse("none")));
             e.printStackTrace();
             System.exit(1);
         } 
@@ -120,7 +120,7 @@ final class ProjectDocWriter {
         
         return new File(
                 destFolder,
-                unit.getName() + ".adoc");
+                unit.getCanonicalName()+ ".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 f97694a..cb507bb 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
@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
 
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.tooling.j2adoc.J2AdocUnit.LookupKey;
 import org.apache.isis.tooling.j2adoc.convert.J2AdocConverter;
 import org.apache.isis.tooling.j2adoc.format.UnitFormatter;
 import org.apache.isis.tooling.j2adoc.format.UnitFormatterCompact;
@@ -78,10 +79,10 @@ public class J2AdocContext {
 
     // -- UNIT INDEX
     
-    private final Map<String, J2AdocUnit> unitIndex = _Maps.newTreeMap();
+    private final Map<LookupKey, J2AdocUnit> unitIndex = _Maps.newTreeMap();
     
     public J2AdocContext add(final @NonNull J2AdocUnit unit) {
-        val previousKey = unitIndex.put(unit.getName(), unit);
+        val previousKey = unitIndex.put(LookupKey.of(unit.getResourceCoordinates()), unit);
         if(previousKey!=null) {
             throw _Exceptions.unrecoverableFormatted(
                     "J2AUnit index entries must be unique (index key collision on %s)", 
@@ -103,7 +104,11 @@ public class J2AdocContext {
         return unitIndex.values().stream();
     }
 
-    public Optional<J2AdocUnit> getUnit(String key) {
+    /**
+     * @param key - unique key for types 
+     * @return optionally the unit available for given key
+     */
+    public Optional<J2AdocUnit> getUnit(final @NonNull LookupKey key) {
         return Optional.ofNullable(unitIndex.get(key));
     }
     
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 dd29335..c15dd21 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
@@ -20,6 +20,7 @@ package org.apache.isis.tooling.j2adoc;
 
 import java.io.File;
 import java.util.Optional;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import com.github.javaparser.StaticJavaParser;
@@ -29,6 +30,7 @@ import org.asciidoctor.ast.Document;
 
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.resource.ResourceCoordinates;
 import org.apache.isis.tooling.j2adoc.util.AsciiDocIncludeTagFilter;
 import org.apache.isis.tooling.javamodel.ast.AnyTypeDeclaration;
 import org.apache.isis.tooling.javamodel.ast.CompilationUnits;
@@ -37,15 +39,40 @@ import org.apache.isis.tooling.javamodel.ast.PackageDeclarations;
 import lombok.Getter;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
+import lombok.Value;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
 @RequiredArgsConstructor
 @Log4j2
 public final class J2AdocUnit {
-
-    private final AnyTypeDeclaration atd;
     
+    //TODO not namespace aware yet
+    @Value
+    public static class LookupKey implements Comparable<LookupKey> {
+        private final @NonNull String key;
+
+        //XXX resco has all the info, to make keys namespace aware
+        public static LookupKey of(final @NonNull ResourceCoordinates resco) {
+            return new LookupKey(resco.getName().stream().collect(Collectors.joining(".")));
+        }
+        //XXX in a better world we would resolve these types to fqn type names
+        public static @NonNull LookupKey typeSimpleName(final @NonNull String typeSimpleName) {
+            return new LookupKey(typeSimpleName);
+        }
+        //XXX in a better world we would resolve these links to fqn type names
+        public static @NonNull LookupKey javadocLink(final @NonNull String javadocLink) {
+            return new LookupKey(javadocLink);
+        }
+        @Override
+        public int compareTo(LookupKey other) {
+            return _Strings.compareNullsFirst(this.key, other==null ? null : other.key);
+        }
+    }
+
+    @Getter private final ResourceCoordinates resourceCoordinates;
+    @Getter private final AnyTypeDeclaration typeDeclaration;
+
     public static Stream<J2AdocUnit> parse(final @NonNull File sourceFile) {
 
         if("package-info.java".equals(sourceFile.getName())) {
@@ -63,10 +90,26 @@ public final class J2AdocUnit {
             
             cu.getPackageDeclaration();
             
+            
             return Stream.of(cu)
             .flatMap(CompilationUnits::streamTypeDeclarations)
             .filter(AnyTypeDeclaration::hasIndexDirective)
-            .map(J2AdocUnit::new);
+            .map(atd->{
+               
+                val resourceCoordinates = ResourceCoordinates.builder()
+                .friendlyName(atd.getName().stream()
+                        .collect(Collectors.joining(".")))
+                .nameAsString(atd.getName().stream()
+                        .collect(Collectors.joining("~")))
+                .simpleName(atd.getSimpleName())
+                .location(Can.empty()) //TODO get from file name
+                .namespace(PackageDeclarations.namespace(atd.getPackageDeclaration()))
+                .name(atd.getName())
+                .build();
+                
+                return new J2AdocUnit(resourceCoordinates, atd);
+                
+            });
 
         } catch (Exception e) {
             log.error("failed to parse java source file {}", sourceFile, e);
@@ -74,37 +117,41 @@ public final class J2AdocUnit {
         }
 
     }
-
-    public AnyTypeDeclaration getTypeDeclaration() {
-        return atd;
+    
+    public String getCanonicalName() {
+        return resourceCoordinates.getNameAsString();
     }
     
     /**
      * Returns the recursively resolved (nested) type name. 
      * Same as {@link #getSimpleName()} if type is not nested. 
      */
-    public String getName() {
-        return atd.getName();
+    public Can<String> getName() {
+        return resourceCoordinates.getName();
+    }
+    
+    public String getFriendlyName() {
+        return resourceCoordinates.getFriendlyName();
     }
     
     public String getSimpleName() {
-        return atd.getSimpleName();
+        return resourceCoordinates.getSimpleName();
     }
     
     public Can<String> getNamespace() {
-        return PackageDeclarations.namespace(atd.getPackageDeclaration());
+        return resourceCoordinates.getNamespace();
     }
     
     public String getDeclarationKeywordFriendlyName() {
-        return _Strings.capitalize(atd.getKind().name().toLowerCase());
+        return _Strings.capitalize(typeDeclaration.getKind().name().toLowerCase());
     }
     
     public String getDeclarationKeyword() {
-        return atd.getKind().getJavaKeyword();
+        return typeDeclaration.getKind().getJavaKeyword();
     }
     
     @Getter(lazy = true)
-    private final Optional<Javadoc> javadoc = atd.getJavadoc();
+    private final Optional<Javadoc> javadoc = typeDeclaration.getJavadoc();
     
     public String getAsciiDocXref(
             final @NonNull J2AdocContext j2aContext) {
@@ -117,4 +164,6 @@ public final class J2AdocUnit {
     }
 
 
+
+
 }
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 3fac035..9cfcb9d 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
@@ -45,6 +45,7 @@ import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal._Constants;
 import org.apache.isis.tooling.j2adoc.J2AdocContext;
 import org.apache.isis.tooling.j2adoc.J2AdocUnit;
+import org.apache.isis.tooling.j2adoc.J2AdocUnit.LookupKey;
 import org.apache.isis.tooling.javamodel.ast.AnnotationMemberDeclarations;
 import org.apache.isis.tooling.javamodel.ast.ConstructorDeclarations;
 import org.apache.isis.tooling.javamodel.ast.EnumConstantDeclarations;
@@ -270,7 +271,7 @@ final class J2AdocConverterDefault implements J2AdocConverter {
 
         switch(inlineTag.getType()) {
         case LINK:
-            val referencedUnit = j2aContext.getUnit(inlineContent).orElse(null);
+            val referencedUnit = j2aContext.getUnit(LookupKey.javadocLink(inlineContent)).orElse(null);
             if(referencedUnit!=null) {
                 return String.format(" %s ", xref(referencedUnit));
             }
@@ -286,19 +287,19 @@ final class J2AdocConverterDefault implements J2AdocConverter {
         .stream()
         .skip(j2aContext.getNamespacePartsSkipCount())
         .collect(Can.toCan())
-        .add(unit.getName())
+        .add(unit.getCanonicalName()) 
         .stream()
         .collect(Collectors.joining("/"));
         
         return String.format("xref:%s[%s]", 
                 String.format(j2aContext.getXrefPageIdFormat(), xrefCoordinates), 
-                unit.getName()); 
+                unit.getFriendlyName()); 
     }
 
-    public String xrefIfRequired(final @NonNull String docIndexKey) {
-        return j2aContext.getUnit(docIndexKey)
+    private String xrefIfRequired(final @NonNull String typeSimpleName) {
+        return j2aContext.getUnit(LookupKey.typeSimpleName(typeSimpleName))
                 .map(this::xref)
-                .orElse(docIndexKey);
+                .orElse(typeSimpleName);
     }
     
     public String javadocSnippet(final @NonNull JavadocSnippet snippet) {
diff --git a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterAbstract.java b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterAbstract.java
index 8c50ae8..7e0c8c6 100644
--- a/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterAbstract.java
+++ b/tooling/java2adoc/src/main/java/org/apache/isis/tooling/j2adoc/format/UnitFormatterAbstract.java
@@ -82,7 +82,7 @@ implements UnitFormatter {
     protected Optional<String> title(final J2AdocUnit unit) {
         return Optional.of(
                 String.format("%s : _%s_", 
-                        unit.getName(),
+                        unit.getFriendlyName(),
                         unit.getDeclarationKeywordFriendlyName().toLowerCase()));
     }
     
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 77564b4..24383b1 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
@@ -36,12 +36,14 @@ import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
 import com.github.javaparser.javadoc.Javadoc;
 
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 
 import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
+import lombok.val;
 
 @Getter
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@@ -146,7 +148,7 @@ public final class AnyTypeDeclaration {
                 );
     }
     
-    public static AnyTypeDeclaration auto(
+      public static AnyTypeDeclaration auto(
             final @NonNull TypeDeclaration<?> td,
             final @NonNull CompilationUnit cu) {
         
@@ -181,7 +183,7 @@ public final class AnyTypeDeclaration {
      * Same as {@link #getSimpleName()} if type is not nested. 
      */
     @Getter(lazy = true)
-    private final String name = createName();
+    private final Can<String> name = createName();
     
     public String getSimpleName() {
         return td.getNameAsString();
@@ -189,16 +191,17 @@ public final class AnyTypeDeclaration {
     
     // -- HELPER 
     
-    private String createName() {
-        String name = td.getNameAsString(); 
+    private Can<String> createName() {
+        val nameParts = _Lists.<String>newLinkedList();
+        nameParts.push(td.getNameAsString());
         Node walker = td; 
         while(walker.getParentNode().isPresent()) {
             walker = walker.getParentNode().get();
             if(walker instanceof NodeWithSimpleName) {
-                name = ((NodeWithSimpleName<?>)walker).getNameAsString() + "." + name;
+                nameParts.addFirst(((NodeWithSimpleName<?>)walker).getNameAsString());
             } else break;
         }
-        return name;
+        return Can.ofCollection(nameParts);
     }
 
     
diff --git a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/include/IncludeStatements.java b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/include/IncludeStatements.java
index 64becc3..687e8c2 100644
--- a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/include/IncludeStatements.java
+++ b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/include/IncludeStatements.java
@@ -53,10 +53,14 @@ public final class IncludeStatements {
         
         val processedLines = _Lists.<String>newArrayList();
         visit(lines, (originalLine, inclOptional)->{
-            inclOptional.ifPresentOrElse(
-                    incl->processedLines.add(rewriter.apply(incl).toAdocAsString()),
-                    ()->processedLines.add(originalLine)
-            );
+            
+            val incl = inclOptional.map(rewriter::apply).orElse(null);
+            if(incl!=null) {
+                processedLines.add(incl.toAdocAsString());
+            } else {
+                processedLines.add(originalLine);
+            }
+            
         });
         return Can.ofCollection(processedLines); 
     }
diff --git a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/xref/Xref.java b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/xref/Xref.java
new file mode 100644
index 0000000..b460d32
--- /dev/null
+++ b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/xref/Xref.java
@@ -0,0 +1,67 @@
+/*
+ *  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.model4adoc.xref;
+
+import java.util.stream.Collectors;
+
+import org.apache.isis.commons.collections.Can;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.Value;
+import lombok.val;
+
+@Value @Builder
+public final class Xref {
+    
+    // model for
+    // xref:system:generated:index/applib/services/xmlsnapshot/XmlSnapshotService~Snapshot.adoc[XmlSnapshotService.Snapshot]
+    // location: system, generated
+    // namespace: index, applib, services, xmlsnapshot
+    // canonicalName: XmlSnapshotService~Snapshot.adoc
+    // friendlyName: XmlSnapshotService.Snapshot
+    
+    private final @NonNull Can<String> location; 
+    private final @NonNull Can<String> namespace; 
+    private final @NonNull String canonicalName;
+    private final @NonNull String friendlyName;  // as used for display
+    
+    @Getter(lazy = true)
+    private final @NonNull String xref = xref(); // full xref string
+
+    private String xref() {
+        val sb = new StringBuilder();
+        
+        sb.append("xref:")
+        .append(location.stream().collect(Collectors.joining(":")))
+        .append(":");
+        
+        namespace.stream().forEach(part->sb.append(part).append("/"));
+        
+        sb.append(canonicalName)
+        .append("[")
+        .append(friendlyName)
+        .append("]");
+        
+        return sb.toString();
+    }
+     
+    
+}