Merge branch 'develop' into stable

This commit is contained in:
Brian Long 2022-12-22 15:58:35 -05:00
commit a97ca48f1a
10 changed files with 245 additions and 86 deletions

View File

@ -21,12 +21,12 @@ This library provides a Javadoc Doclet for the generation of Activiti API docume
<docletArtifact> <docletArtifact>
<groupId>com.inteligr8.activiti</groupId> <groupId>com.inteligr8.activiti</groupId>
<artifactId>activiti-api-doclet</artifactId> <artifactId>activiti-api-doclet</artifactId>
<version>1.0.0</version> <version>1.0.1</version>
</docletArtifact> </docletArtifact>
<useStandardDocletOptions>false</useStandardDocletOptions> <useStandardDocletOptions>false</useStandardDocletOptions>
<destDir>destDir</destDir> <destDir>apidocs</destDir>
<reportOutputDirectory>${basedir}</reportOutputDirectory>
<additionalOptions> <additionalOptions>
<additionalOption>-d d</additionalOption>
<additionalOption>--flavor bitbucket</additionalOption> <additionalOption>--flavor bitbucket</additionalOption>
<additionalOption>--title 'API Documentation'</additionalOption> <additionalOption>--title 'API Documentation'</additionalOption>
<additionalOption>--apiName '${project.name}</additionalOption> <additionalOption>--apiName '${project.name}</additionalOption>
@ -46,4 +46,4 @@ You can generate the docs with the following command:
mvn -Papidocs generate-resources mvn -Papidocs generate-resources
``` ```
The documentation is always generated relative to the `target/site/apidocs` directory. Hopefully that can be fixed in the future. The documentation will be placed in `<reportOutputDirectory>/<destDir>`.

View File

@ -50,10 +50,12 @@
<version>@pom.version@</version> <version>@pom.version@</version>
</docletArtifact> </docletArtifact>
<useStandardDocletOptions>false</useStandardDocletOptions> <useStandardDocletOptions>false</useStandardDocletOptions>
<destDir>destDir</destDir> <destDir>apidocs</destDir>
<reportOutputDirectory>${basedir}</reportOutputDirectory>
<additionalOptions> <additionalOptions>
<additionalOption>-d d</additionalOption>
<additionalOption>--flavor bitbucket</additionalOption> <additionalOption>--flavor bitbucket</additionalOption>
<additionalOption>--title 'Example Title'</additionalOption>
<additionalOption>--apiName '${project.name}'</additionalOption>
</additionalOptions> </additionalOptions>
</configuration> </configuration>
</execution> </execution>

View File

@ -7,6 +7,8 @@ import org.springframework.stereotype.Component;
* Here is a second line that happens * Here is a second line that happens
* to span multiple lines. * to span multiple lines.
* *
* Here is a {@link http://inteligr8.com} for testing purposes. And here is another { @link http://inteligr8.com } one.
*
* @author brian@inteligr8.com * @author brian@inteligr8.com
* @version 1.0 * @version 1.0
*/ */
@ -81,6 +83,10 @@ public class TestNamedBean {
* @param param A parameter comment. * @param param A parameter comment.
* @return A return comment. * @return A return comment.
* @throws java.lang.Exception An exception comment. * @throws java.lang.Exception An exception comment.
* @throws org.activiti.engine.delegate.BpmnError http-404
* @throws BpmnError http-400 A client error.
* @see `test.bean`
* @see http://inteligr8.com
*/ */
public String apiMethod8(String param) throws Exception { public String apiMethod8(String param) throws Exception {
return null; return null;

View File

@ -54,9 +54,12 @@ class ActivitiApiBeanDoc {
return this; return this;
} }
public List<ExecutableElement> getMethodElements() {
return new ArrayList<>(this.methodElements.values());
}
public List<ExecutableElement> getSortedMethodElements() { public List<ExecutableElement> getSortedMethodElements() {
List<ExecutableElement> methodElements = new ArrayList<>(this.methodElements.size()); List<ExecutableElement> methodElements = this.getMethodElements();
methodElements.addAll(this.methodElements.values());
Collections.sort(methodElements, new Comparator<ExecutableElement>() { Collections.sort(methodElements, new Comparator<ExecutableElement>() {
@Override @Override
public int compare(ExecutableElement methodElement1, ExecutableElement methodElement2) { public int compare(ExecutableElement methodElement1, ExecutableElement methodElement2) {

View File

@ -91,7 +91,6 @@ class ActivitiDocFilter {
// getAllTypeElements() will get inherited interfaces // getAllTypeElements() will get inherited interfaces
for (TypeMirror interfaceType : classElement.getInterfaces()) { for (TypeMirror interfaceType : classElement.getInterfaces()) {
this.logger.info("{} contains {}", beanId, interfaceType);
this.logger.trace("Found interface '{}' on bean '{}'", interfaceType, beanId); this.logger.trace("Found interface '{}' on bean '{}'", interfaceType, beanId);
switch (interfaceType.toString()) { switch (interfaceType.toString()) {

View File

@ -44,7 +44,7 @@ import jdk.javadoc.doclet.Reporter;
public class ActivitiDoclet implements Doclet { public class ActivitiDoclet implements Doclet {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());
private String outputDirectory;
private String flavor; private String flavor;
private String title; private String title;
private String apiName; private String apiName;
@ -57,13 +57,6 @@ public class ActivitiDoclet implements Doclet {
@Override @Override
public Set<? extends Option> getSupportedOptions() { public Set<? extends Option> getSupportedOptions() {
return new HashSet<>(Arrays.asList( return new HashSet<>(Arrays.asList(
new PathOption("-d", "Destination directory for output files", Kind.STANDARD, "--destDir") {
@Override
public boolean process(String name, List<String> valueAndClasses) {
outputDirectory = valueAndClasses.get(0);
return true;
}
},
new ValueOption("--flavor", "Flavor of the markdown host: github or bitbucket", Kind.STANDARD) { new ValueOption("--flavor", "Flavor of the markdown host: github or bitbucket", Kind.STANDARD) {
@Override @Override
public boolean process(String name, List<String> valueAndClasses) { public boolean process(String name, List<String> valueAndClasses) {
@ -122,7 +115,7 @@ public class ActivitiDoclet implements Doclet {
List<ActivitiApiBeanDoc> beandocs = docfilter.build(); List<ActivitiApiBeanDoc> beandocs = docfilter.build();
try { try {
MarkdownWriter mdwriter = new MarkdownWriter(docenv, this.outputDirectory); MarkdownWriter mdwriter = new MarkdownWriter(docenv);
if (this.title != null) if (this.title != null)
mdwriter.setTitle(this.title); mdwriter.setTitle(this.title);
if (this.apiName != null) if (this.apiName != null)
@ -193,17 +186,4 @@ public class ActivitiDoclet implements Doclet {
} }
private abstract class PathOption extends ValueOption {
public PathOption(String name, String description, Kind kind, String... additionalNames) {
super(name, description, kind, additionalNames);
}
@Override
public String getParameters() {
return "<dir>";
}
}
} }

View File

@ -0,0 +1,95 @@
package com.inteligr8.activiti.doclet;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public class FluentMap<K, V> implements Map<K, V> {
private Map<K, V> map;
public FluentMap(Map<K, V> map) {
this.map = map;
}
@Override
public void clear() {
this.map.clear();
}
@Override
public boolean containsKey(Object key) {
return this.map.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return this.map.containsValue(value);
}
@Override
public Set<Entry<K, V>> entrySet() {
return this.map.entrySet();
}
@Override
public boolean equals(Object obj) {
return this.map.equals(obj);
}
@Override
public V get(Object key) {
return this.map.get(key);
}
@Override
public int hashCode() {
return this.map.hashCode();
}
@Override
public boolean isEmpty() {
return this.map.isEmpty();
}
@Override
public Set<K> keySet() {
return this.map.keySet();
}
@Override
public V put(K key, V value) {
return this.map.put(key, value);
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
this.map.putAll(m);
}
@Override
public V remove(Object key) {
return this.map.remove(key);
}
@Override
public int size() {
return this.map.size();
}
@Override
public Collection<V> values() {
return this.map.values();
}
public FluentMap<K, V> with(K key, V value) {
this.map.put(key, value);
return this;
}
public FluentMap<K, V> without(K key) {
this.map.remove(key);
return this;
}
}

View File

@ -18,11 +18,15 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -52,24 +56,32 @@ import jdk.javadoc.doclet.DocletEnvironment;
class MarkdownWriter { class MarkdownWriter {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final Pattern tagPattern = Pattern.compile("@[^ ]+ ?(.*)$"); private final Set<String> bpmnErrorSet = new HashSet<>(Arrays.asList(
private final Pattern namedTagPattern = Pattern.compile("@[^ ]+ ([^ ]+) ?(.*)$"); "BpmnError".toLowerCase(),
"org.activiti.engine.delegate.BpmnError".toLowerCase()));
private final Pattern tagPattern = Pattern.compile("@([^ ]+) ?(.*)$");
private final Pattern namedCommentPattern = Pattern.compile("([^ ]+) ?(.*)$");
private final Map<Pattern, String> sanitizations = new FluentMap<>(new LinkedHashMap<Pattern, String>())
.with(Pattern.compile("^[ ]+", Pattern.MULTILINE), "")
.with(Pattern.compile("\r\n", Pattern.MULTILINE), "\n")
.with(Pattern.compile("([^\n])\n([^\n])", Pattern.MULTILINE), "$1 $2")
.with(Pattern.compile("([^\\.\\?!])[ ]{2}", Pattern.MULTILINE), "$1 ")
.with(Pattern.compile("\\{ ?(@[^}]+) \\}"), "{$1}")
.with(Pattern.compile("\\{@link ([^}]+)\\}"), "[$1]($1)")
.with(Pattern.compile("([A-Za-z0-9\\-\\._]+@[A-Za-z0-9\\-\\._]+)"), "[$1](mailto:$1)");
private final DocletEnvironment docenv; private final DocletEnvironment docenv;
private final File outputDirectory; private final File outputDirectory;
private final Configuration fmconfig; private final Configuration fmconfig;
private String title = "API Documentation"; private String title = "API Documentation";
private String apiName; private String apiName;
private String flavor; private String flavor;
public MarkdownWriter(DocletEnvironment docenv, String outputDirectory) throws IOException { public MarkdownWriter(DocletEnvironment docenv) throws IOException {
this.docenv = docenv; this.docenv = docenv;
this.outputDirectory = (outputDirectory == null || outputDirectory.trim().length() == 0) ? new File(".") : new File(outputDirectory); this.outputDirectory = new File(".");
this.fmconfig = this.getFreemarkerConfiguration();
}
public MarkdownWriter(DocletEnvironment docenv, File outputDirectory) throws IOException {
this.docenv = docenv;
this.outputDirectory = outputDirectory == null ? new File(".") : outputDirectory;
this.fmconfig = this.getFreemarkerConfiguration(); this.fmconfig = this.getFreemarkerConfiguration();
} }
@ -111,7 +123,6 @@ class MarkdownWriter {
this.logger.debug("Building documentation index model"); this.logger.debug("Building documentation index model");
IndexFreemarkerModel indexModel = new IndexFreemarkerModel(); IndexFreemarkerModel indexModel = new IndexFreemarkerModel();
System.out.println("title: " + this.title);
indexModel.setTitle(this.title); indexModel.setTitle(this.title);
indexModel.setApiName(this.apiName); indexModel.setApiName(this.apiName);
@ -135,9 +146,9 @@ class MarkdownWriter {
this.logger.debug("Found documentation for bean: {}", beandoc.getBeanId()); this.logger.debug("Found documentation for bean: {}", beandoc.getBeanId());
if (commentTree.getFirstSentence() != null) if (commentTree.getFirstSentence() != null)
beanModel.setDocFirstSentence(commentTree.getFirstSentence().toString()); beanModel.setDocFirstSentence(this.sanitize(commentTree.getFirstSentence()));
if (commentTree.getBody() != null) if (commentTree.getBody() != null)
beanModel.setDocBody(commentTree.getFullBody().toString()); beanModel.setDocBody(this.sanitize(commentTree.getFullBody()));
for (DocTree tag : commentTree.getBlockTags()) { for (DocTree tag : commentTree.getBlockTags()) {
String tagName = null; String tagName = null;
if (tag instanceof BlockTagTree) { if (tag instanceof BlockTagTree) {
@ -172,50 +183,57 @@ class MarkdownWriter {
} }
Map<String, String> paramComments = new HashMap<>(); Map<String, String> paramComments = new HashMap<>();
Map<String, String> throwComments = new HashMap<>(); Map<String, String> throwComments = new LinkedHashMap<>();
Map<String, String> errorComments = new LinkedHashMap<>();
MethodSignatureFreemarkerModel sigModel = new MethodSignatureFreemarkerModel(); MethodSignatureFreemarkerModel sigModel = new MethodSignatureFreemarkerModel();
if (methodCommentTree != null) { if (methodCommentTree != null) {
this.logger.debug("Found documentation for method: {}.{}", beandoc.getBeanId(), methodElement); this.logger.debug("Found documentation for method: {}.{}", beandoc.getBeanId(), methodElement);
if (methodCommentTree.getFirstSentence() != null) { if (methodCommentTree.getFirstSentence() != null) {
sigModel.setDocFirstSentence(this.sanitize(methodCommentTree.getFirstSentence()));
if (methodModel.getDocFirstSentence() == null) if (methodModel.getDocFirstSentence() == null)
methodModel.setDocFirstSentence(methodCommentTree.getFirstSentence().toString()); methodModel.setDocFirstSentence(sigModel.getDocFirstSentence());
sigModel.setDocFirstSentence(methodCommentTree.getFirstSentence().toString());
} }
if (methodCommentTree.getBody() != null) if (methodCommentTree.getBody() != null)
sigModel.setDocBody(methodCommentTree.getFullBody().toString()); sigModel.setDocBody(this.sanitize(methodCommentTree.getFullBody()));
for (DocTree tag : methodCommentTree.getBlockTags()) { for (DocTree tag : methodCommentTree.getBlockTags()) {
String tagName = null; Matcher matcher = this.tagPattern.matcher(tag.toString());
if (tag instanceof BlockTagTree) { if (!matcher.find()) {
tagName = ((BlockTagTree)tag).getTagName(); this.logger.warn("A tag for the {} bean and {} method is improperly formatted", beanModel.getBeanId(), methodElement);
} else if (tag instanceof InlineTagTree) {
tagName = ((InlineTagTree)tag).getTagName();
} else {
this.logger.error("A tag comment is not of an expected type: {}", tag.getClass());
continue; continue;
} }
this.logger.trace("Found tag '{}' for method: {}.{}", tagName, beandoc.getBeanId(), methodElement); String tagName = matcher.group(1);
String tagComment = matcher.group(2).trim();
this.logger.info("Found tag '{}' for method: {}.{}", tagName, beandoc.getBeanId(), methodElement);
Matcher matcher;
switch (tagName) { switch (tagName) {
case "param": case "param":
matcher = this.namedTagPattern.matcher(tag.toString()); matcher = this.namedCommentPattern.matcher(tagComment);
if (matcher.find()) if (matcher.find())
paramComments.put(matcher.group(1), matcher.group(2).trim()); paramComments.put(matcher.group(1), this.sanitize(matcher.group(2).trim()));
else this.logger.warn("A @param for the {} bean and {} method is improperly formatted", beanModel.getBeanId(), methodElement); else this.logger.warn("A @param for the {} bean and {} method is improperly formatted", beanModel.getBeanId(), methodElement);
break;
case "throws": case "throws":
matcher = this.namedTagPattern.matcher(tag.toString()); matcher = this.namedCommentPattern.matcher(tagComment);
if (matcher.find()) if (matcher.find()) {
throwComments.put(matcher.group(1), matcher.group(2).trim()); if (this.bpmnErrorSet.contains(matcher.group(1).toLowerCase())) {
Matcher ecmatcher = this.namedCommentPattern.matcher(matcher.group(2).trim());
if (ecmatcher.find()) {
errorComments.put(ecmatcher.group(1), this.sanitize(ecmatcher.group(2).trim()));
} else {
this.logger.warn("A @throws for the {} bean and {} method is improperly formatted", beanModel.getBeanId(), methodElement);
}
} else {
throwComments.put(matcher.group(1), this.sanitize(matcher.group(2).trim()));
}
}
else this.logger.warn("A @throws for the {} bean and {} method is improperly formatted", beanModel.getBeanId(), methodElement); else this.logger.warn("A @throws for the {} bean and {} method is improperly formatted", beanModel.getBeanId(), methodElement);
break; break;
default: default:
matcher = this.tagPattern.matcher(tag.toString()); this.putAdd(sigModel.getTags(), tagName, this.sanitize(tagComment));
if (matcher.find())
this.putAdd(sigModel.getTags(), tagName, matcher.group(1).trim());
else this.logger.warn("A '@{}' tag for the {} bean and {} method is improperly formatted", tagName, beanModel.getBeanId(), methodElement);
} }
} }
} }
@ -228,22 +246,48 @@ class MarkdownWriter {
ParamFreemarkerModel paramModel = new ParamFreemarkerModel(); ParamFreemarkerModel paramModel = new ParamFreemarkerModel();
paramModel.setName(varElement.getSimpleName().toString()); paramModel.setName(varElement.getSimpleName().toString());
paramModel.setType(varElement.asType().toString()); paramModel.setType(varElement.asType().toString());
paramModel.setComment(paramComments.get(paramModel.getName())); paramModel.setComment(paramComments.remove(paramModel.getName()));
sigModel.getParams().put(paramModel.getName(), paramModel); sigModel.getParams().put(paramModel.getName(), paramModel);
methodSignature.append(varElement.getSimpleName()).append(": ").append(varElement.asType()).append(", "); methodSignature.append(varElement.getSimpleName()).append(": ").append(varElement.asType()).append(", ");
} }
if (!paramComments.isEmpty())
this.logger.warn("The {} bean and {} method has documented parameters that don't exist; ignoring ...", beandoc.getBeanId(), methodElement);
for (TypeMirror thrownType : methodElement.getThrownTypes()) { for (TypeMirror thrownType : methodElement.getThrownTypes()) {
this.logger.trace("Found thrown '{}' for method: {}.{}", thrownType, beandoc.getBeanId(), methodElement); this.logger.trace("Found thrown '{}' for method: {}.{}", thrownType, beandoc.getBeanId(), methodElement);
if ("org.activiti.engine.delegate.BpmnError".equals(thrownType.toString()) && !errorComments.isEmpty())
continue;
ThrowFreemarkerModel throwModel = new ThrowFreemarkerModel(); ThrowFreemarkerModel throwModel = new ThrowFreemarkerModel();
throwModel.setType(thrownType.toString()); throwModel.setType(thrownType.toString());
throwModel.setComment(throwComments.get(throwModel.getType())); throwModel.setComment(throwComments.remove(throwModel.getType()));
sigModel.getThrowTypes().put(throwModel.getType(), throwModel); sigModel.getThrowTypes().put(throwModel.getType(), throwModel);
} }
for (Entry<String, String> throwComment : throwComments.entrySet()) {
this.logger.trace("Found documented but not declared thrown '{}' for method: {}.{}", throwComment.getKey(), beandoc.getBeanId(), methodElement);
ThrowFreemarkerModel throwModel = new ThrowFreemarkerModel();
throwModel.setType(throwComment.getKey());
throwModel.setComment(throwComment.getValue());
sigModel.getThrowTypes().put(throwModel.getType(), throwModel);
}
for (Entry<String, String> errorComment : errorComments.entrySet()) {
this.logger.trace("Found BPMN error thrown code '{}' for method: {}.{}", errorComment.getKey(), beandoc.getBeanId(), methodElement);
ThrowFreemarkerModel errorModel = new ThrowFreemarkerModel();
errorModel.setType(errorComment.getKey());
errorModel.setComment(errorComment.getValue());
sigModel.getBpmnErrors().put(errorModel.getType(), errorModel);
}
this.logger.trace("Found return '{}' for method: {}.{}", methodElement.getReturnType(), beandoc.getBeanId(), methodElement); this.logger.trace("Found return '{}' for method: {}.{}", methodElement.getReturnType(), beandoc.getBeanId(), methodElement);
if (!"void".equals(methodElement.getReturnType().toString())) if (!"void".equals(methodElement.getReturnType().toString()))
sigModel.setReturnType(methodElement.getReturnType().toString()); sigModel.setReturnType(methodElement.getReturnType().toString());
@ -300,6 +344,16 @@ class MarkdownWriter {
} }
} }
private String sanitize(List<? extends DocTree> docs) {
return this.sanitize(docs.toString());
}
private String sanitize(String str) {
for (Entry<Pattern, String> sanitize : this.sanitizations.entrySet())
str = sanitize.getKey().matcher(str).replaceAll(sanitize.getValue());
return str;
}
private <T> T putAdd(Map<String, List<T>> map, String key, T value) { private <T> T putAdd(Map<String, List<T>> map, String key, T value) {
List<T> values = map.get(key); List<T> values = map.get(key);
if (values == null) if (values == null)

View File

@ -28,6 +28,8 @@ public class MethodSignatureFreemarkerModel {
private Map<String, ThrowFreemarkerModel> throwTypes = new LinkedHashMap<>(); private Map<String, ThrowFreemarkerModel> throwTypes = new LinkedHashMap<>();
private Map<String, ThrowFreemarkerModel> bpmnErrors = new LinkedHashMap<>();
private String docFirstSentence; private String docFirstSentence;
private String docBody; private String docBody;
@ -66,6 +68,14 @@ public class MethodSignatureFreemarkerModel {
this.throwTypes = throwTypes; this.throwTypes = throwTypes;
} }
public Map<String, ThrowFreemarkerModel> getBpmnErrors() {
return bpmnErrors;
}
public void setBpmnErrors(Map<String, ThrowFreemarkerModel> bpmnErrors) {
this.bpmnErrors = bpmnErrors;
}
public String getDocFirstSentence() { public String getDocFirstSentence() {
return docFirstSentence; return docFirstSentence;
} }

View File

@ -1,19 +1,22 @@
# ${title}<#if apiName??>: ${apiName}</#if>: `${beanId}` # ${title}<#if apiName??>: ${apiName}</#if>: `${beanId}`
<#if docBody??>${docBody}<#else>No documentation available.</#if> <#if (tags.author?? || tags.since?? || tags.deprecated??)>
<#if (tags.author?? || tags.since?? || tags.see?? || tags.deprecated??)>
<#if tags.author??><#list tags.author as author> <#if tags.author??><#list tags.author as author>
*Author*: ${author} *Author*: ${author}
</#list></#if> </#list></#if>
<#if tags.since??>*Since*: ${tags.since[0]}</#if> <#if tags.since??>*Since*: ${tags.since[0]}</#if>
<#if tags.see??><#list tags.see as see>
*See Also*: ${see}
</#list></#if>
<#if tags.deprecated??>*Deprecated*</#if> <#if tags.deprecated??>*Deprecated*</#if>
</#if><#if (delegateRoles?size > 0)> </#if>
<#if docBody??>${docBody}<#else>No documentation available.</#if>
<#if tags.see??><#list tags.see as see>
*See Also*: ${see}
</#list>
</#if>
<#if (delegateRoles?size > 0)>
## Delegate Uses ## Delegate Uses
This bean may be used in the following entities and their fields in Activiti. In these cases, the value of the "Delegate Expression" field should be as shown in the snippet below. This bean may be used in the following entities and their fields in Activiti. In these cases, the value of the "Delegate Expression" field should be as shown in the snippet below.
@ -48,38 +51,45 @@ This bean and its methods may be used in any "Expression" field or script in a S
<#list method.signatures as sig> <#list method.signatures as sig>
**`${beanId}.${sig.methodSignature}`** **`${beanId}.${sig.methodSignature}`**
<#if (sig.tags.author?? || sig.tags.since?? || sig.tags.deprecated??)>
<#if sig.tags.author??><#list sig.tags.author as author>
*Author*: ${author}
</#list></#if>
<#if sig.tags.since??>*Since*: ${sig.tags.since[0]}</#if>
<#if sig.tags.deprecated??>*Deprecated*</#if>
</#if>
<#if sig.docBody??>${sig.docBody}<#else>No documentation available.</#if> <#if sig.docBody??>${sig.docBody}<#else>No documentation available.</#if>
<#if (sig.params?size > 0)> <#if (sig.params?size > 0)>
| Parameter Name | Java Type | Documentation | | Parameter Name | Java Type | Documentation |
| ------------------------ | ------------------------------------------------ | ------------------------ | | ------------------------ | ------------------------------------------------ | ------------------------ |
<#list sig.params as paramName, param> <#list sig.params as paramName, param>
| ${("`" + paramName + "`")?right_pad(24)} | ${("`" + param.type + "`")?right_pad(48)} | <#if param.comment??>${param.comment?right_pad(24)}<#else>No documentation available.</#if> | | ${("`" + paramName + "`")?right_pad(24)} | ${("`" + param.type + "`")?right_pad(48)} | <#if (param.comment?? && param.comment?length > 0)>${param.comment?right_pad(24)}<#else>No documentation available.</#if> |
</#list> </#list>
</#if> </#if>
<#if (sig.returnType?? || sig.throwTypes?size > 0)> <#if (sig.returnType?? || sig.throwTypes?size > 0)>
| Result Type | Java Type | Documentation | | Result Type | Java Type or BPMN Error Code | Documentation |
| ------------------------ | ------------------------------------------------ | ------------------------ | | ------------------------ | ------------------------------------------------ | ------------------------ |
<#if sig.returnType??> <#if sig.returnType??>
| Return Value | ${("`" + sig.returnType + "`")?right_pad(48)} | <#if sig.tags.return??>${sig.tags.return[0]?right_pad(24)}<#else>No documentation available.</#if> | | Return Value | ${("`" + sig.returnType + "`")?right_pad(48)} | <#if (sig.tags.return?? && sig.tags.return[0]?length > 0)>${sig.tags.return[0]?right_pad(24)}<#else>No documentation available.</#if> |
</#if> </#if>
<#if (sig.throwTypes?size > 0)> <#if (sig.throwTypes?size > 0)>
<#list sig.throwTypes as throwType, throw> <#list sig.throwTypes as throwType, throw>
| Thrown Exception | ${("`" + throwType + "`")?right_pad(48)} | <#if throw.comment??>${throw.comment?right_pad(24)}<#else>No documentation available.</#if> | | Thrown Exception | ${("`" + throwType + "`")?right_pad(48)} | <#if (throw.comment?? && throw.comment?length > 0)>${throw.comment?right_pad(24)}<#else>No documentation available.</#if> |
</#list>
</#if>
<#if (sig.bpmnErrors?size > 0)>
<#list sig.bpmnErrors as errorCode, bpmnError>
| Thrown BPMN Error | ${("`" + errorCode + "`")?right_pad(48)} | <#if (bpmnError.comment?? && bpmnError.comment?length > 0)>${bpmnError.comment?right_pad(24)}<#else>No documentation available.</#if> |
</#list> </#list>
</#if> </#if>
</#if> </#if>
<#if (sig.tags.author?? || sig.tags.since?? || sig.tags.see?? || sig.tags.deprecated??)>
<#if sig.tags.author??><#list sig.tags.author as author>
*Author*: ${author}
</#list></#if>
<#if sig.tags.since??>*Since*: ${sig.tags.since[0]}</#if>
<#if sig.tags.see??><#list sig.tags.see as see> <#if sig.tags.see??><#list sig.tags.see as see>
*See Also*: ${see} *See Also*: ${see}
</#list></#if> </#list>
<#if sig.tags.deprecated??>*Deprecated*</#if>
</#if> </#if>
</#list> </#list>