Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public static void main(String[] args) {
"since",
"configurationSource",
"configurationType",
"supportRepoIdSuffix");
"supportRepoIdSuffix",
"deprecated");

/**
* Javadoc block tag marking a constant field as a configuration key.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import java.util.Properties;
import java.util.Set;

import com.sun.source.doctree.DeprecatedTree;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.EntityTree;
Expand Down Expand Up @@ -122,7 +123,9 @@ private record ConfigurationEntry(
String since,
String source,
String type,
boolean supportsRepoIdSuffix) {
boolean supportsRepoIdSuffix,
// is empty if not deprecated
String deprecated) {

public ConfigurationEntry {
Objects.requireNonNull(key);
Expand Down Expand Up @@ -188,7 +191,9 @@ public boolean run(DocletEnvironment environment) {
try {
return doRun(environment);
} catch (RuntimeException e) {
reportError("Error running ConfigurationCollectorDoclet: " + e.getMessage());
// catch all runtime exception, as the default javadoc tool emits a confusing message about reporting
// something with Oracle
reportError("Error running ConfigurationCollectorDoclet", e);
return false;
}
}
Expand Down Expand Up @@ -258,6 +263,10 @@ private boolean doRun(DocletEnvironment environment) {
*/
private void reportError(DocTreePath path, Throwable throwable) {
reportError(path, throwable.getMessage());
reportError(throwable);
}

private void reportError(Throwable throwable) {
// also emit stack trace
PrintWriter pw = reporter.getDiagnosticWriter();
if (pw == null) {
Expand All @@ -280,6 +289,17 @@ private void reportError(DocTreePath path, String message) {
}
}

/**
* Reports a global error message without location information.
*
* @param message the error message
* @param throwable the exception whose stack trace is printed
*/
private void reportError(String message, Throwable throwable) {
reporter.print(Diagnostic.Kind.ERROR, message);
reportError(throwable);
}

/**
* Reports a global error message without location information.
*
Expand Down Expand Up @@ -310,7 +330,42 @@ private ConfigurationEntry processResolverField(DocTreePath path, VariableElemen
getSince(path).orElse(""),
getConfigurationSource(path, blockTags).orElse(""),
getConfigurationType(path, blockTags),
isSupportsRepoIdSuffix(path, blockTags));
isSupportsRepoIdSuffix(path, blockTags),
getDeprecated(path, field).orElse(""));
}

private Optional<String> getDeprecated(DocTreePath path, Element element) {
Objects.requireNonNull(path, "path must not be null");
Objects.requireNonNull(element, "field must not be null");

// first check for deprecated annotation
if (element.getAnnotation(Deprecated.class) == null) {
// if not existing check enclosing elements recursively
return getDeprecated(element.getEnclosingElement());
}
Optional<? extends DocTree> deprecatedTag = path.getDocComment().getBlockTags().stream()
.filter(t -> com.sun.source.doctree.DocTree.Kind.DEPRECATED == t.getKind())
.findFirst();
if (deprecatedTag.isPresent()) {
return Optional.of(renderContent(DocTreePath.getPath(path, deprecatedTag.get()), RenderMode.HTML, true));
}
return Optional.of("");
}

private Optional<String> getDeprecated(Element element) {
if (element == null) {
return Optional.empty();
}
DocCommentTree docCommentTree = docTrees.getDocCommentTree(element);
if (docCommentTree == null) {
if (element.getAnnotation(Deprecated.class) != null) {
return Optional.of("");
}
// traverse to enclosing element
return getDeprecated(element.getEnclosingElement());
Comment thread
kwin marked this conversation as resolved.
} else {
return getDeprecated(new DocTreePath(docTrees.getPath(element), docCommentTree), element);
}
}

private boolean isSupportsRepoIdSuffix(DocTreePath path, Map<String, UnknownBlockTagTree> blockTags) {
Expand Down Expand Up @@ -380,7 +435,6 @@ private ConfigurationEntry processMavenField(DocTreePath path, VariableElement f
} else if (configurationType.startsWith("java.util.")) {
configurationType = configurationType.substring("java.util.".length());
}

return new ConfigurationEntry(
String.valueOf(field.getConstantValue()),
path.getDocComment() != null ? getFullBodyContent(path) : "",
Expand All @@ -389,7 +443,8 @@ private ConfigurationEntry processMavenField(DocTreePath path, VariableElement f
getSince(path).orElse(""),
source,
configurationType,
false);
false,
getDeprecated(path, field).orElse(""));
}

private AnnotationMirror getAnnotation(Element element, String fqName) {
Expand Down Expand Up @@ -427,12 +482,16 @@ private void writeEntry(Properties properties, ConfigurationEntry entry, String
properties.setProperty(prefix + "configurationSource", entry.source());
properties.setProperty(prefix + "configurationType", entry.type());
properties.setProperty(prefix + "supportRepoIdSuffix", toYesNo(entry.supportsRepoIdSuffix()));
properties.setProperty(prefix + "deprecated", entry.deprecated());
}

// --- Javadoc extraction helpers -------------------------------------------------------------------------------

private Map<String, UnknownBlockTagTree> collectBlockTags(DocCommentTree docComment) {
Map<String, UnknownBlockTagTree> result = new LinkedHashMap<>();
if (docComment == null) {
return result;
}
for (DocTree tag : docComment.getBlockTags()) {
if (tag instanceof UnknownBlockTagTree unknownBlockTree) {
result.put(unknownBlockTree.getTagName(), unknownBlockTree);
Expand Down Expand Up @@ -675,6 +734,13 @@ public String visitSince(SinceTree node, Void p) {
return escape(mode, node.getBody().toString());
}

@Override
public String visitDeprecated(DeprecatedTree node, Void p) {
StringBuilder sb = new StringBuilder();
node.getBody().forEach(child -> sb.append(child.accept(this, p)));
return sb.toString();
}

@Override
protected String defaultAction(DocTree node, Void p) {
// the default action internally calls node.toString(), which uses
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ To modify this file, edit the template and regenerate.
| Key | Type | Description | Default Value | Since | Supports Repo ID suffix | Source |
| --- | --- | --- | --- | --- | --- | --- |
#foreach($key in $keys)
| `$key.key` | `$key.configurationType` | $key.description | #value( $key.defaultValue ) | $key.since | $key.supportRepoIdSuffix | $key.configurationSource |
| `$key.key` | `$key.configurationType` | #if($key.deprecated) **Deprecated**. *$key.deprecated*<br/>#end$key.description | #value( $key.defaultValue ) | $key.since | $key.supportRepoIdSuffix | $key.configurationSource |
#end

#[[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ void extractsBooleanStringAndEnumConfigurations(@TempDir Path tempDir) throws Ex
assertEquals("No", bool.get("supportRepoIdSuffix"));
assertEquals("Java System Properties", bool.get("configurationSource"));
assertEquals("A boolean flag.", bool.get("description"));
assertEquals("", bool.get("deprecated"));

Map<String, String> string = keys.get("sample.string");
assertNotNull(string, "string key missing");
Expand All @@ -118,6 +119,7 @@ void extractsBooleanStringAndEnumConfigurations(@TempDir Path tempDir) throws Ex
assertEquals("VALUE_A", enumKey.get("defaultValue"));
// no @configurationRepoIdSuffix -> defaults to "No"
assertEquals("No", enumKey.get("supportRepoIdSuffix"));
assertEquals("Use <code>#ENUM2_KEY</code> instead", enumKey.get("deprecated"));

Map<String, String> enum2Key = keys.get("sample.enum2");
assertNotNull(enum2Key, "enum key missing");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ public final class SampleConfigurationKeys {
* @configurationSource {@link System#getProperty(String,String)}
* @configurationType {@link SampleEnum}
* @configurationDefaultValue {@link #DEFAULT_ENUM}
* @deprecated Use {@link #ENUM2_KEY} instead
*/
@Deprecated()
public static final String ENUM_KEY = "sample.enum";

public static final SampleEnum DEFAULT_ENUM = SampleEnum.VALUE_A;
Expand Down
Loading