有没有办法让生成的“常量字段值”页面为char
类型常量使用可读字符而不是整数?
例如,如果一个类包含以下常量:
public static final char YES = 'Y';
public static final char NO = 'N';
public static final char ERROR = 'E';
我希望javadoc常量字段值页面具有字符表示形式('Y','N','E')而不是整数版本(69,78,89)。
我们有数百个,所以我不想去为每个出现添加一些特定的javadoc注释(例如使用@value
)。
更新:感谢SubOptimal的回答,我设法使用我找到ConstantsSummaryWriterImpl
writeValue
的1.6版源代码来修改private void writeValue(FieldDoc member) {
tdAlign("right");
code();
if ("char".equals(member.type().toString())) {
print(Util.escapeHtmlChars("'" + ((char) ((Integer)member.constantValue()).intValue()) + "'"));
} else {
print(Util.escapeHtmlChars(member.constantValueExpression()));
}
codeEnd();
tdEnd();
}
方法如下:
char
一旦这个类被编译并用于覆盖'tools.jar'中的那个类,{{1}}常量将作为字符输出,而不是数字。
答案 0 :(得分:2)
你可以通过调整javadoc
本身来实现这一点。
langtools-ce654f4ecfd8.tar.gz
ConstantsSummaryWriterImpl.java
修改方法getValue(FieldDoc member)
...
private Content getValue(FieldDoc member) {
Content valueContent;
if ("char".equals(member.type().toString())) {
valueContent = new StringContent("'"
+ (char) ((Integer) member.constantValue()).intValue()
+ "'"
);
} else {
valueContent = new StringContent(member.constantValueExpression());
}
Content code = HtmlTree.CODE(valueContent);
return HtmlTree.TD(HtmlStyle.colLast, code);
}
...
编译已更改的文件
javac -cp ${JAVA_HOME}/lib/tools.jar -d . ConstantsSummaryWriterImpl.java
运行javadoc
javadoc -J-Xbootclasspath/p:.;${JAVA_HOME}/lib/tools.jar -d api/ Scratch.java
文件 Scratch.java
public class Scratch {
public static final char YES = 'Y';
public static final char NO = 'N';
public static final char ERROR = 'E';
}
答案 1 :(得分:0)
无法完成。不幸的是,javadoc在这方面有点密集 - char
是数字原语。
您可以使用字符串
来解决它public static final String YES = "Y";
public static final String NO = "N";
public static final String ERROR = "E";
并重构您的代码以使用您之前使用char常量的实用程序方法:
public static char asChar(String str) {
if (str.length() != 1) {
throw new IllegalArgumentException(str + " must be exactly 1 character long");
}
return str.charAt(0);
}
例如
if (ch == asChar(ERROR))
希望这可以让人忍受。
请注意参数检查,以确保您不会意外地声明其中一个字符串而不是单个字符。
答案 2 :(得分:0)
某些后期处理是否可行?
该程序遍历文件树并处理所有名为constant-values.html
的文件。它们使用Jericho HTML Parser加载。检查名为constantValuesContainer
的表:如果第一列包含文本static final char
,并且最后一列中的值是整数值,则将其替换为相应的字符。
请注意,这只是一个草图(但至少在"它自己" JavaDoc ;-)上进行了测试)。替换的条件可以改进。例如,第一列中文本的匹配应该更加健壮(对于有人创建以char
开头的类的情况....)。只有当整数值是有效的 ASCII 字符时,才应该进行替换,以避免弄乱像static final char CHAR_MAX = 0xFFFF
这样的常量。但是这样的调整应该很容易,如果(!)这样的后处理步骤是可行的方法。
import static java.nio.file.FileVisitResult.CONTINUE;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.OutputDocument;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;
public class ConstantsTest
{
private static final char CHAR_A = 'A';
protected static final char CHAR_B = 'B';
static final char CHAR_C = 'C';
public static final char CHAR_D = 'D';
public static final char CHAR_E = 'E';
public static final char CHAR_F = 'F';
public static final int INT_65 = 65;
public static void main(String[] args) throws MalformedURLException, IOException
{
Path path = FileSystems.getDefault().getPath("./doc/");
Files.walkFileTree(path, new FileProcessor());
}
static class FileProcessor extends SimpleFileVisitor<Path>
{
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes)
{
//System.out.println("Visit "+file+" name '"+file.getFileName()+"'");
if (file.getFileName().toString().equals("constant-values.html"))
{
process(file);
}
return CONTINUE;
}
}
private static void process(Path file)
{
try
{
doProcess(file);
}
catch (IOException e)
{
e.printStackTrace();
}
}
private static void doProcess(Path file) throws IOException
{
System.out.println("Processing "+file);
Source source=new Source(file.toFile());
OutputDocument outputDocument=new OutputDocument(source);
for (Element element : source.getAllElementsByClass("constantValuesContainer"))
{
List<Element> colFirsts = element.getAllElementsByClass("colFirst");
List<Element> colLasts = element.getAllElementsByClass("colLast");
for (int i=0; i<colFirsts.size(); i++)
{
Element colFirst = colFirsts.get(i);
Segment colFirstContent = colFirst.getContent();
String colFirstText = colFirstContent.getTextExtractor().toString();
// TODO Generalize this according to your needs,
// maybe with some RegEx...
if (colFirstText.contains("static final char"))
{
Element colLast = colLasts.get(i);
List<Element> children = colLast.getAllElements("code");
if (children.size() == 1)
{
Element child = children.get(0);
Segment childContent = child.getContent();
String childText = childContent.getTextExtractor().toString();
try
{
int value = Integer.parseInt(childText);
outputDocument.replace(childContent, String.valueOf((char)value));
}
catch (NumberFormatException e)
{
System.out.println("Value is not a number: "+childText+", ignoring");
}
}
}
}
}
outputDocument.writeTo(
new OutputStreamWriter(new FileOutputStream(file.toFile())));
System.out.println("Processing "+file+" DONE");
}
}