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/09 08:13:20 UTC
[isis] branch master updated: ISIS-2473: adds support for java-doc
link processing
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 38c8c05 ISIS-2473: adds support for java-doc link processing
38c8c05 is described below
commit 38c8c058b9052c2aa78f836ff606a3046481d4b2
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Dec 9 09:10:38 2020 +0100
ISIS-2473: adds support for java-doc link processing
---
.../org/apache/isis/tooling/cli/doclet/Doclet.java | 36 ++++++----
.../isis/tooling/cli/doclet/DocletContext.java | 65 ++++++++++++++++++
.../apache/isis/tooling/cli/doclet/Doclets.java | 40 +++--------
.../cli/doclet/{Doclets.java => ToAsciiDoc.java} | 77 ++++++++++++----------
.../isis/tooling/cli/test/doclet/DocletTest.java | 17 +++--
.../cli/test/doclet/samples/SudoService.java | 6 ++
.../isis/tooling/javamodel/CompilationUnits.java | 9 +--
7 files changed, 165 insertions(+), 85 deletions(-)
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclet.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclet.java
index 55656e7..34b5ae5 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclet.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclet.java
@@ -24,7 +24,7 @@ import java.util.Optional;
import java.util.stream.Stream;
import com.github.javaparser.StaticJavaParser;
-import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.tooling.javamodel.CompilationUnits;
@@ -42,7 +42,7 @@ import lombok.extern.log4j.Log4j2;
@Log4j2
public class Doclet {
- private final TypeDeclaration<?> td;
+ private final ClassOrInterfaceDeclaration td;
public static Optional<Doclet> parse(final @NonNull File sourceFile) {
@@ -51,7 +51,7 @@ public class Doclet {
return Stream.of(cu)
.flatMap(CompilationUnits::streamPublicTypeDeclarations)
- .filter(Doclets::isApacheIsisDoclet)
+ .filter(Doclets::hasIndexDirective)
.map(Doclet::new)
.findFirst();
@@ -61,8 +61,13 @@ public class Doclet {
}
}
+
+ public String getName() {
+ return td.getNameAsString();
+ }
- public String toAsciiDoc() {
+ public String toAsciiDoc(
+ final @NonNull DocletContext docletContext) {
val doc = AsciiDocFactory.doc();
@@ -73,28 +78,34 @@ public class Doclet {
val mds = TypeDeclarations.streamPublicMethodDeclarations(td)
.filter(Javadocs::presentAndNotHidden)
.collect(Can.toCan());
+
+ val toAdocConverter = ToAsciiDoc.of(docletContext);
// -- intro
td.getJavadoc().ifPresent(javadoc->{
- introBlock.setSource(Doclets.toAsciiDoc(javadoc));
+ introBlock.setSource(toAdocConverter.javadoc(javadoc));
});
// -- java content
val java = new StringBuilder();
- java.append(String.format("type %s {\n", td.getName().asString()));
+ java.append(String.format("%s %s {\n",
+ getDeclarationKeyword(),
+ td.getName().asString()));
mds.forEach(md->{
- java.append(String.format("\n %s // <.>\n", Doclets.toNormalizedMethodDeclaration(md)));
+ java.append(String.format("\n %s // <.>\n",
+ Doclets.toNormalizedMethodDeclaration(md)));
});
java.append("}\n");
- javaSourceBlock.setSource(AsciiDocFactory.SourceFactory.java(java.toString(), td.getName().asString()));
+ javaSourceBlock.setSource(
+ AsciiDocFactory.SourceFactory.java(java.toString(), td.getName().asString()));
// -- foot notes
@@ -107,7 +118,7 @@ public class Doclet {
footNotes.append(String.format("\n<.> `%s` %s\n",
Doclets.toNormalizedMethodDeclaration(md),
- Doclets.toAsciiDoc(javadoc)));
+ toAdocConverter.javadoc(javadoc)));
});
@@ -125,10 +136,13 @@ public class Doclet {
}
-
// -- HELPER
-
+ private String getDeclarationKeyword() {
+ return td.isInterface()
+ ? "interface"
+ : "class";
+ }
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/DocletContext.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/DocletContext.java
new file mode 100644
index 0000000..7809488
--- /dev/null
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/DocletContext.java
@@ -0,0 +1,65 @@
+/*
+ * 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.cli.doclet;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+
+import lombok.Builder;
+import lombok.NonNull;
+import lombok.Value;
+import lombok.val;
+
+@Value @Builder
+public class DocletContext {
+
+ private final @NonNull String indexXrefRoot;
+
+ private final Map<String, Doclet> docletIndex = _Maps.newTreeMap();
+
+ public DocletContext add(final @NonNull Doclet doclet) {
+ val previousKey = docletIndex.put(doclet.getName(), doclet);
+ if(previousKey!=null) {
+ throw _Exceptions.unrecoverableFormatted(
+ "doclet index entries must be unique (index key collision on %s)",
+ previousKey);
+ }
+ return this;
+ }
+
+ public DocletContext add(final @NonNull File sourceFile) {
+ Doclet.parse(sourceFile)
+ .ifPresent(this::add);
+ return this;
+ }
+
+ public Stream<Doclet> streamDoclets() {
+ return docletIndex.values().stream();
+ }
+
+ public Optional<Doclet> getDoclet(String key) {
+ return Optional.ofNullable(docletIndex.get(key));
+ }
+
+}
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclets.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclets.java
index 9d7d947..15c0030 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclets.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclets.java
@@ -20,9 +20,6 @@ package org.apache.isis.tooling.cli.doclet;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
-import com.github.javaparser.javadoc.Javadoc;
-import com.github.javaparser.javadoc.description.JavadocInlineTag;
-import com.github.javaparser.javadoc.description.JavadocSnippet;
import org.apache.isis.tooling.javamodel.Javadocs;
@@ -31,7 +28,13 @@ import lombok.val;
final class Doclets {
- static boolean isApacheIsisDoclet(final @NonNull TypeDeclaration<?> td) {
+ /**
+ * Whether to include given {@link TypeDeclaration} with the index.
+ * <p>
+ * This is decided base on whether the type's java-doc has a
+ * {@literal @since} tag that contains the literal {@literal {@index}}.
+ */
+ static boolean hasIndexDirective(final @NonNull TypeDeclaration<?> td) {
return td.getJavadoc()
.map(javadoc->{
@@ -44,35 +47,12 @@ final class Doclets {
.orElse(false);
}
+ /**
+ * Returns given {@link MethodDeclaration} as normal text, without formatting.
+ */
static String toNormalizedMethodDeclaration(final @NonNull MethodDeclaration md) {
return md.getDeclarationAsString(false, false, true).trim();
}
- static String toAsciiDoc(final @NonNull Javadoc javadoc) {
-
- val adoc = new StringBuilder();
-
- javadoc.getDescription().getElements()
- .forEach(e->{
-
- if(e instanceof JavadocSnippet) {
- adoc.append(normalizeHtmlTags(e.toText()));
- } else if(e instanceof JavadocInlineTag) {
- adoc.append(" _").append(((JavadocInlineTag) e).getContent().trim()).append("_ ");
- } else {
- adoc.append(e.toText());
- }
-
- });
-
- return adoc.toString();
- }
-
- // -- HELPER
-
- private static String normalizeHtmlTags(final @NonNull String s) {
- return s.replace("<p>", "\n").replace("</p>", "");
- }
-
}
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclets.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/ToAsciiDoc.java
similarity index 58%
copy from tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclets.java
copy to tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/ToAsciiDoc.java
index 9d7d947..0e7f2a9 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Doclets.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/ToAsciiDoc.java
@@ -18,61 +18,72 @@
*/
package org.apache.isis.tooling.cli.doclet;
-import com.github.javaparser.ast.body.MethodDeclaration;
-import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.javadoc.Javadoc;
import com.github.javaparser.javadoc.description.JavadocInlineTag;
import com.github.javaparser.javadoc.description.JavadocSnippet;
-import org.apache.isis.tooling.javamodel.Javadocs;
-
import lombok.NonNull;
+import lombok.Value;
import lombok.val;
-final class Doclets {
-
- static boolean isApacheIsisDoclet(final @NonNull TypeDeclaration<?> td) {
- return td.getJavadoc()
- .map(javadoc->{
-
- val toBeIncluded = Javadocs.streamTagContent(javadoc, "since")
- .anyMatch(since->since.toText().contains("{@index}"));
-
- return toBeIncluded;
-
- })
- .orElse(false);
- }
-
- static String toNormalizedMethodDeclaration(final @NonNull MethodDeclaration md) {
- return md.getDeclarationAsString(false, false, true).trim();
- }
-
- static String toAsciiDoc(final @NonNull Javadoc javadoc) {
-
+@Value(staticConstructor = "of")
+class ToAsciiDoc {
+
+ private final DocletContext docletContext;
+
+ //TODO method java-doc needs further post processing when spanning multiple paragraphs
+ public String javadoc(
+ final @NonNull Javadoc javadoc) {
+
val adoc = new StringBuilder();
-
+
javadoc.getDescription().getElements()
.forEach(e->{
-
+
if(e instanceof JavadocSnippet) {
adoc.append(normalizeHtmlTags(e.toText()));
} else if(e instanceof JavadocInlineTag) {
- adoc.append(" _").append(((JavadocInlineTag) e).getContent().trim()).append("_ ");
+ adoc.append(inlineTag((JavadocInlineTag) e));
} else {
adoc.append(e.toText());
}
-
+
});
-
+
return adoc.toString();
}
+
+ public String inlineTag(
+ final @NonNull JavadocInlineTag inlineTag) {
+
+ val inlineContent = inlineTag.getContent().trim();
+
+ switch(inlineTag.getType()) {
+ case LINK:
+ val refDoclet = docletContext.getDoclet(inlineContent).orElse(null);
+ if(refDoclet!=null) {
+ return String.format(" %s ", xref(refDoclet));
+ }
+ default:
+ return String.format(" _%s_ ", inlineContent);
+ }
+ }
+ public String xref(
+ final @NonNull Doclet doclet) {
+ return String.format(" xref:%s:%s.adoc[%s] ",
+ docletContext.getIndexXrefRoot(),
+ doclet.getName(),
+ doclet.getName());
+ }
+
// -- HELPER
-
+
+ /*
+ * try to convert HTML formatting directives to normal text
+ */
private static String normalizeHtmlTags(final @NonNull String s) {
return s.replace("<p>", "\n").replace("</p>", "");
}
-
-
+
}
diff --git a/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/doclet/DocletTest.java b/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/doclet/DocletTest.java
index 32077a3..5bf14b4 100644
--- a/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/doclet/DocletTest.java
+++ b/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/doclet/DocletTest.java
@@ -19,11 +19,10 @@
package org.apache.isis.tooling.cli.test.doclet;
import java.io.File;
-import java.util.Optional;
import org.junit.jupiter.api.Test;
-import org.apache.isis.tooling.cli.doclet.Doclet;
+import org.apache.isis.tooling.cli.doclet.DocletContext;
import org.apache.isis.tooling.javamodel.AnalyzerConfigFactory;
import lombok.val;
@@ -40,17 +39,21 @@ class DocletTest {
val projDir = new File("./").getAbsoluteFile();
val analyzerConfig = AnalyzerConfigFactory.mavenTest(projDir, Language.JAVA).main();
+ val docletContext = DocletContext.builder()
+ .indexXrefRoot("system:index")
+ .build();
+
analyzerConfig.getSources(JAVA)
.stream()
- .filter(source->source.toString().contains("UserService"))
+// .filter(source->source.toString().contains("UserService"))
.peek(source->System.out.println("parsing source: " + source))
- .map(Doclet::parse)
- .filter(Optional::isPresent)
- .map(Optional::get)
+ .forEach(docletContext::add);
+
+ docletContext.streamDoclets()
.forEach(doclet->{
System.out.println("--------------------------------------------------");
- System.out.println(doclet.toAsciiDoc());
+ System.out.println(doclet.toAsciiDoc(docletContext));
System.out.println("--------------------------------------------------");
});
diff --git a/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/doclet/samples/SudoService.java b/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/doclet/samples/SudoService.java
index 87f241c..35acc67 100644
--- a/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/doclet/samples/SudoService.java
+++ b/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/doclet/samples/SudoService.java
@@ -18,6 +18,12 @@
*/
package org.apache.isis.tooling.cli.test.doclet.samples;
+/**
+ * If {@link SudoService} has been used to temporarily override the user and/or roles,
+ * then the {@link UserService} will report the overridden values.
+ *
+ * @since 2.0 {@index}
+ */
public interface SudoService {
}
diff --git a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/CompilationUnits.java b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/CompilationUnits.java
index 9e1ad66..5851925 100644
--- a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/CompilationUnits.java
+++ b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/CompilationUnits.java
@@ -24,7 +24,7 @@ import java.util.stream.Stream;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
-import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import lombok.NonNull;
import lombok.SneakyThrows;
@@ -43,14 +43,15 @@ public final class CompilationUnits {
.orElse(false);
}
- public static <T> Stream<TypeDeclaration<?>> streamPublicTypeDeclarations(
+ public static <T> Stream<ClassOrInterfaceDeclaration> streamPublicTypeDeclarations(
final @NonNull CompilationUnit compilationUnit) {
val type = compilationUnit.getPrimaryType().orElse(null);
- if(type==null) {
+ if(type==null
+ || !type.isClassOrInterfaceDeclaration()) {
return Stream.empty();
}
- return Stream.of(type);
+ return Stream.of((ClassOrInterfaceDeclaration)type);
}