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/10 10:46:28 UTC
[isis] 02/02: ISIS-2473: adds support for rendering 'deprecated'
from java-doc
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 63aa2d12e45fdb37823b83955567e05844270f77
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Dec 10 11:46:10 2020 +0100
ISIS-2473: adds support for rendering 'deprecated' from java-doc
---
.../generated/pages/index/FactoryService.adoc | 24 ++--
.../modules/generated/pages/index/UserMemento.adoc | 12 +-
.../modules/generated/pages/index/UserService.adoc | 8 +-
.../apache/isis/tooling/cli/doclet/Adoclet.java | 3 +-
.../isis/tooling/cli/doclet/AdocletContext.java | 17 ++-
.../isis/tooling/cli/doclet/HtmlToAsciiDoc.java | 122 ++++++++++-----------
.../apache/isis/tooling/cli/doclet/ToAsciiDoc.java | 84 ++++++++++----
.../apache/isis/tooling/javamodel/Javadocs.java | 8 ++
.../isis/tooling/model4adoc/AsciiDocWriter.java | 5 +-
9 files changed, 168 insertions(+), 115 deletions(-)
diff --git a/antora/components/system/modules/generated/pages/index/FactoryService.adoc b/antora/components/system/modules/generated/pages/index/FactoryService.adoc
index 781c7d3..4ba272a 100644
--- a/antora/components/system/modules/generated/pages/index/FactoryService.adoc
+++ b/antora/components/system/modules/generated/pages/index/FactoryService.adoc
@@ -4,54 +4,54 @@
-* `*getOrCreate*(Class<T> requiredType)` : `T`
+* `[teal]#*getOrCreate*#<T>(Class<T> requiredType)` : `T`
+
General purpose factory method, to automatically get or create an instance of _requiredType_ .
+
Maps onto one of the specialized factory methods _#get(Class)_ or _#create(Class)_ based on the type's meta-data.
-* `*get*(Class<T> requiredType)` : `T`
+* `[teal]#*get*#<T>(Class<T> requiredType)` : `T`
+
Gets an instance (possibly shared or independent) of the specified _requiredType_ , with injection points resolved and any life-cycle callback processed.
-* `*detachedEntity*(Class<T> domainClass)` : `T`
+* `[teal]#*detachedEntity*#<T>(Class<T> domainClass)` : `T`
+
Creates a new detached entity instance, with injection points resolved and defaults applied.
-* `*detachedEntity*(T entity)` : `T`
+* `[teal]#*detachedEntity*#<T>(T entity)` : `T`
+
Creates a new detached entity instance, with injection points resolved.
-* `*mixin*(Class<T> mixinClass, Object mixedIn)` : `T`
+* `[teal]#*mixin*#<T>(Class<T> mixinClass, Object mixedIn)` : `T`
+
Creates a new Mixin instance, with injection points resolved.
-* `*viewModel*(Class<T> viewModelClass, String mementoStr)` : `T`
+* `[teal]#*viewModel*#<T>(Class<T> viewModelClass, String mementoStr)` : `T`
+
Creates a new ViewModel instance, with injection points resolved, and initialized according to the given _mementoStr_
-* `*viewModel*(Class<T> viewModelClass)` : `T`
+* `[teal]#*viewModel*#<T>(Class<T> viewModelClass)` : `T`
+
Creates a new ViewModel instance, with injection points resolved and defaults applied.
-* `*viewModel*(T viewModel)` : `T`
+* `[teal]#*viewModel*#<T>(T viewModel)` : `T`
+
Resolves injection points for given ViewModel instance.
-* `*create*(Class<T> domainClass)` : `T`
+* `[teal]#*create*#<T>(Class<T> domainClass)` : `T`
+
Creates a new instance of the specified class, with injection points resolved and defaults applied.
-* `*instantiate*(Class<T> domainClass)` : `T`
+* `[line-through gray]#*instantiate*#<T>(Class<T> domainClass)` : `T`
+
Creates a new instance of the specified class, but does not persist it.
+
@@ -64,3 +64,7 @@ It is recommended that the object be initially instantiated using this method, t
** the `created()` callback will not be called.
+
The corollary is: if your code never uses `default _Xxx_ ()` supporting methods or the `created()` callback, then you can alternatively just _new()_ up the object rather than call this method.
++
+[red]#_deprecated:_#
++
+with semantic changes since 2.0 previous behavior is no longer guaranteed, instead consider use of @ _#detachedEntity(Class)_ or _#getOrCreate(Class)_ if applicable
diff --git a/antora/components/system/modules/generated/pages/index/UserMemento.adoc b/antora/components/system/modules/generated/pages/index/UserMemento.adoc
index d0bdb89..a7031f8 100644
--- a/antora/components/system/modules/generated/pages/index/UserMemento.adoc
+++ b/antora/components/system/modules/generated/pages/index/UserMemento.adoc
@@ -4,32 +4,32 @@
Immutable serializable value holding details about a user and its roles.
-* `*_system_*()` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+* `[teal]#*_system_*#()` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+
The framework's internal user with unrestricted privileges.
-* `*_ofName_*(String name)` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+* `[teal]#*_ofName_*#(String name)` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+
Creates a new user with the specified name and no roles.
-* `*_ofNameAndRoles_*(String name, xref:system:generated:index/RoleMemento.adoc[RoleMemento]... roles)` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+* `[teal]#*_ofNameAndRoles_*#(String name, xref:system:generated:index/RoleMemento.adoc[RoleMemento]... roles)` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+
Creates a new user with the specified name and assigned roles.
-* `*_ofNameAndRoleNames_*(String name, String... roleNames)` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+* `[teal]#*_ofNameAndRoleNames_*#(String name, String... roleNames)` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+
Creates a new user with the specified name and assigned role names.
-* `*_ofNameAndRoleNames_*(String name, Stream<String> roleNames)` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+* `[teal]#*_ofNameAndRoleNames_*#(String name, Stream<String> roleNames)` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+
Creates a new user with the specified name and assigned role names.
-* `*isCurrentUser*(String userName)` : `boolean`
+* `[teal]#*isCurrentUser*#(String userName)` : `boolean`
+
Determine if the specified name is this user.
+
diff --git a/antora/components/system/modules/generated/pages/index/UserService.adoc b/antora/components/system/modules/generated/pages/index/UserService.adoc
index b25d4ed..1dff20b 100644
--- a/antora/components/system/modules/generated/pages/index/UserService.adoc
+++ b/antora/components/system/modules/generated/pages/index/UserService.adoc
@@ -5,21 +5,21 @@
The xref:system:generated:index/UserService.adoc[UserService] allows the domain object to obtain the identity of the user interacting with said object.
If _SudoService_ has been used to temporarily override the user and/or roles, then this service will report the overridden values instead.
-* `*currentUser*()` : `Optional<xref:system:generated:index/UserMemento.adoc[UserMemento]>`
+* `[teal]#*currentUser*#()` : `Optional<xref:system:generated:index/UserMemento.adoc[UserMemento]>`
+
Optionally gets the details about the current user, based on whether an _ExecutionContext_ can be found with the current thread's context.
-* `*getUser*()` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+* `[teal]#*getUser*#()` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+
Gets the details about the current user.
-* `*currentUserElseFail*()` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+* `[teal]#*currentUserElseFail*#()` : `xref:system:generated:index/UserMemento.adoc[UserMemento]`
+
Gets the details about the current user.
-* `*currentUserName*()` : `Optional<String>`
+* `[teal]#*currentUserName*#()` : `Optional<String>`
+
Optionally gets the the current user's name, based on whether an _ExecutionContext_ can be found with the current thread's context.
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Adoclet.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Adoclet.java
index 874f472..6326024 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Adoclet.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/Adoclet.java
@@ -19,7 +19,6 @@
package org.apache.isis.tooling.cli.doclet;
import java.io.File;
-import java.io.IOException;
import java.util.stream.Stream;
import com.github.javaparser.StaticJavaParser;
@@ -148,7 +147,7 @@ public class Adoclet {
doc.setTitle(title);
return AsciiDocWriter.toString(doc);
- } catch (IOException e) {
+ } catch (Exception e) {
e.printStackTrace();
return "ERROR: " + e.getMessage();
}
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/AdocletContext.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/AdocletContext.java
index 684ca93..c77815b 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/AdocletContext.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/AdocletContext.java
@@ -44,11 +44,17 @@ public class AdocletContext {
@Builder.Default
private final @NonNull String methodFormat = "`%s %s %s(%s)`";
- /**
- * method-generic-type | return-type | name | param-list
- */
@Builder.Default
- private final @NonNull String staticMethodFormat = "`%s %s _%s_(%s)`";
+ private final @NonNull String methodNameFormat = "[teal]#*%s*#";
+
+ @Builder.Default
+ private final @NonNull String staticMethodNameFormat = "[teal]#*_%s_*#";
+
+ @Builder.Default
+ private final @NonNull String deprecatedMethodNameFormat = "[line-through gray]#*%s*#";
+
+ @Builder.Default
+ private final @NonNull String deprecatedStaticMethodNameFormat = "[line-through gray]#*_%s_*#";
/**
* method | description
@@ -94,8 +100,7 @@ public class AdocletContext {
public static AdocletContextBuilder compactFormat() {
return AdocletContext.builder()
- .methodFormat("`*%3$s*%1$s(%4$s)` : `%2$s`") // method-generic-type | return-type | name | param-list)
- .staticMethodFormat("`*_%3$s_*%1$s(%4$s)` : `%2$s`") // method-generic-type | return-type | name | param-list)
+ .methodFormat("`%3$s%1$s(%4$s)` : `%2$s`") // method-generic-type | return-type | name | param-list)
.methodDescriptionFormat("\n* %s\n%s\n") // method | description
.includeJavaSource(false)
;
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/HtmlToAsciiDoc.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/HtmlToAsciiDoc.java
index bed41a7..6c6b903 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/HtmlToAsciiDoc.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/HtmlToAsciiDoc.java
@@ -31,72 +31,14 @@ import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor;
import org.apache.isis.tooling.model4adoc.AsciiDocFactory;
-import org.apache.isis.tooling.model4adoc.AsciiDocWriter;
import lombok.SneakyThrows;
import lombok.val;
final class HtmlToAsciiDoc {
- private final static class BlockHelper {
- private final Stack<StructuralNode> stack = new Stack<StructuralNode>();
- private final Stack<org.asciidoctor.ast.List> listStack = new Stack<org.asciidoctor.ast.List>();
-
- BlockHelper(Document adoc){
- stack.push(adoc);
- }
-
- void pop() {
- stack.pop();
- }
-
- void popList() {
- stack.pop();
- listStack.pop();
- }
-
- Block nextBlock() {
- val block = AsciiDocFactory.block(stack.peek());
- stack.push(block);
- return block;
- }
-
- Block getBlock() {
- return (stack.peek() instanceof Block)
- ? (Block) stack.peek()
- : nextBlock();
- }
-
- void blockAppend(String source) {
- val block = getBlock();
- block.setSource(block.getSource()+source);
- }
-
- org.asciidoctor.ast.List nextList() {
- val nextList = AsciiDocFactory.list(stack.peek());
- stack.push(nextList);
- listStack.push(nextList);
- return nextList;
- }
-
- ListItem nextListItem() {
- val list = listStack.isEmpty()
- ? nextList()
- : listStack.peek();
-
- // pop until stack top points to list
- while(!list.equals(stack.peek())) {
- stack.pop();
- }
- val listItem = AsciiDocFactory.listItem(list);
- stack.push(listItem);
- return listItem;
- }
-
- }
-
@SneakyThrows
- public static String body(Element body, int level) {
+ public static Document body(Element body, int level) {
val adoc = AsciiDocFactory.doc();
adoc.setLevel(level);
@@ -169,8 +111,66 @@ final class HtmlToAsciiDoc {
}, body);
- return //adoc.toString();
- AsciiDocWriter.toString(adoc);
+ return adoc;
+ }
+
+ // -- HELPER
+
+ private final static class BlockHelper {
+ private final Stack<StructuralNode> stack = new Stack<StructuralNode>();
+ private final Stack<org.asciidoctor.ast.List> listStack = new Stack<org.asciidoctor.ast.List>();
+
+ BlockHelper(Document adoc){
+ stack.push(adoc);
+ }
+
+ void pop() {
+ stack.pop();
+ }
+
+ void popList() {
+ stack.pop();
+ listStack.pop();
+ }
+
+ Block nextBlock() {
+ val block = AsciiDocFactory.block(stack.peek());
+ stack.push(block);
+ return block;
+ }
+
+ Block getBlock() {
+ return (stack.peek() instanceof Block)
+ ? (Block) stack.peek()
+ : nextBlock();
+ }
+
+ void blockAppend(String source) {
+ val block = getBlock();
+ block.setSource(block.getSource()+source);
+ }
+
+ org.asciidoctor.ast.List nextList() {
+ val nextList = AsciiDocFactory.list(stack.peek());
+ stack.push(nextList);
+ listStack.push(nextList);
+ return nextList;
+ }
+
+ ListItem nextListItem() {
+ val list = listStack.isEmpty()
+ ? nextList()
+ : listStack.peek();
+
+ // pop until stack top points to list
+ while(!list.equals(stack.peek())) {
+ stack.pop();
+ }
+ val listItem = AsciiDocFactory.listItem(list);
+ stack.push(listItem);
+ return listItem;
+ }
+
}
}
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/ToAsciiDoc.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/ToAsciiDoc.java
index 237e909..f8aa58e 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/ToAsciiDoc.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/doclet/ToAsciiDoc.java
@@ -30,11 +30,17 @@ import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.type.TypeParameter;
import com.github.javaparser.javadoc.Javadoc;
+import com.github.javaparser.javadoc.description.JavadocDescription;
import com.github.javaparser.javadoc.description.JavadocInlineTag;
import com.github.javaparser.javadoc.description.JavadocSnippet;
+import org.asciidoctor.ast.Document;
import org.jsoup.Jsoup;
+import org.apache.isis.tooling.javamodel.Javadocs;
+import org.apache.isis.tooling.model4adoc.AsciiDocFactory;
+import org.apache.isis.tooling.model4adoc.AsciiDocWriter;
+
import lombok.NonNull;
import lombok.Value;
import lombok.val;
@@ -46,14 +52,24 @@ class ToAsciiDoc {
public String methodDeclaration(final @NonNull MethodDeclaration md) {
- val methodFormat = md.isStatic()
- ? docletContext.getStaticMethodFormat()
- : docletContext.getMethodFormat();
+ val isDeprecated = md.getAnnotations().stream()
+ .anyMatch(a->a.getNameAsString().equals("Deprecated"))
+ || md.getJavadoc()
+ .map(Javadocs::hasDeprecated)
+ .orElse(false);
+
+ val methodNameFormat = isDeprecated
+ ? md.isStatic()
+ ? docletContext.getDeprecatedStaticMethodNameFormat()
+ : docletContext.getDeprecatedMethodNameFormat()
+ : md.isStatic()
+ ? docletContext.getStaticMethodNameFormat()
+ : docletContext.getMethodNameFormat();
- return String.format(methodFormat,
+ return String.format(docletContext.getMethodFormat(),
typeParamters(md.getTypeParameters()),
type(md.getType()),
- md.getNameAsString(),
+ String.format(methodNameFormat, md.getNameAsString()),
md.getParameters()
.stream()
.map(this::parameterDeclaration)
@@ -105,28 +121,25 @@ class ToAsciiDoc {
p.getNameAsString());
}
- //TODO method java-doc needs further post processing when spanning multiple paragraphs
public String javadoc(final @NonNull Javadoc javadoc, final int level) {
- val javadocResolved = new StringBuilder();
-
- javadoc.getDescription().getElements()
- .forEach(e->{
-
- if(e instanceof JavadocSnippet) {
- javadocResolved.append(javadocSnippet((JavadocSnippet)e));
- } else if(e instanceof JavadocInlineTag) {
- javadocResolved.append(inlineTag((JavadocInlineTag) e));
- } else {
- javadocResolved.append(e.toText());
- }
-
- });
-
- val doc = Jsoup.parse(javadocResolved.toString());
- return HtmlToAsciiDoc.body(doc.selectFirst("body"), level);
+ val descriptionAdoc = javadocDescription(javadoc.getDescription(), level);
+
+ Javadocs.streamTagContent(javadoc, "deprecated")
+ .findFirst()
+ .map(javadocDescription->javadocDescription(javadocDescription, level))
+ .ifPresent(deprecatedAdoc->{
+
+ val deprecatedBlock = AsciiDocFactory.block(descriptionAdoc);
+
+ deprecatedBlock.setSource("[red]#_deprecated:_#");
+
+ deprecatedBlock.getBlocks().addAll(deprecatedAdoc.getBlocks());
+ });
+
+ return AsciiDocWriter.toString(descriptionAdoc);
}
-
+
public String inlineTag(final @NonNull JavadocInlineTag inlineTag) {
val inlineContent = inlineTag.getContent().trim();
@@ -157,5 +170,28 @@ class ToAsciiDoc {
public String javadocSnippet(final @NonNull JavadocSnippet snippet) {
return snippet.toText();
}
+
+ // -- HELPER
+
+ private Document javadocDescription(final @NonNull JavadocDescription javadocDescription, final int level) {
+ val javadocResolved = new StringBuilder();
+
+ javadocDescription.getElements()
+ .forEach(e->{
+
+ if(e instanceof JavadocSnippet) {
+ javadocResolved.append(javadocSnippet((JavadocSnippet)e));
+ } else if(e instanceof JavadocInlineTag) {
+ javadocResolved.append(inlineTag((JavadocInlineTag) e));
+ } else {
+ javadocResolved.append(e.toText());
+ }
+
+ });
+
+ val descriptionAsHtml = Jsoup.parse(javadocResolved.toString());
+ val adoc = HtmlToAsciiDoc.body(descriptionAsHtml.selectFirst("body"), level);
+ return adoc;
+ }
}
diff --git a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/Javadocs.java b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/Javadocs.java
index c591d09..5458d10 100644
--- a/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/Javadocs.java
+++ b/tooling/javamodel/src/main/java/org/apache/isis/tooling/javamodel/Javadocs.java
@@ -53,6 +53,14 @@ public final class Javadocs {
.orElse(false);
}
+ public static boolean hasDeprecated(
+ final @NonNull Javadoc javadoc) {
+
+ return streamTagsByName(javadoc, "deprecated")
+ .findAny()
+ .isPresent();
+ }
+
public static boolean hasHidden(
final @NonNull Javadoc javadoc) {
diff --git a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/AsciiDocWriter.java b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/AsciiDocWriter.java
index 6531342..8ae4cbe 100644
--- a/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/AsciiDocWriter.java
+++ b/tooling/model4adoc/src/main/java/org/apache/isis/tooling/model4adoc/AsciiDocWriter.java
@@ -35,6 +35,7 @@ import org.asciidoctor.ast.Table;
import org.apache.isis.commons.internal.base._Strings;
import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@@ -55,9 +56,9 @@ public class AsciiDocWriter {
/**
* the inverse of {@link Asciidoctor#load(String, java.util.Map)}}
- * @throws IOException
*/
- public static String toString(Document doc) throws IOException {
+ @SneakyThrows
+ public static String toString(Document doc) {
if(doc==null) {
return "";
}