Char constant display in the Javadoc "Constant field values"

Is there a way to get the generated "Constant Field Values" page to use readable characters instead of integers for type constants char

?

For example, if the class contains the following constants:

public static final char YES = 'Y';
public static final char NO  = 'N';
public static final char ERROR  = 'E';

      

I want the javadoc field constant values ​​page to have a character representation ('Y', 'N', 'E'), not an integer version (69, 78, 89).

We have hundreds of them, so I don't want to go and add some specific javadoc comment for every event (using for example @value

).


UPDATE: Thanks to SubOptimal below, I was able to use the 1.6 source code for ConstantsSummaryWriterImpl

which I found here to change the method writeValue

like this:

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();
}

      

After this class is compiled and used to override the value in "tools.jar", the constants char

are output as a symbol, not a number.

+3


source to share


3 answers


You can achieve this by changing slightly javadoc

.

  • get the source for the javadoc tool (don't worry, we only need one file to configure ;-))
    I took the file langtools-ce654f4ecfd8.tar.gz

    here JDK 7 langtools source
  • extract the file ConstantsSummaryWriterImpl.java

  • change method 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);
    }
    ...
    
          

  • compile modified file
    javac -cp ${JAVA_HOME}/lib/tools.jar -d . ConstantsSummaryWriterImpl.java

  • run javadoc
    javadoc -J-Xbootclasspath/p:.;${JAVA_HOME}/lib/tools.jar -d api/ Scratch.java



Scratch.java file

public class Scratch {
    public static final char YES = 'Y';
    public static final char NO  = 'N';
    public static final char ERROR  = 'E';
}

      

+2


source


It's impossible. Unfortunately the javadoc is a bit tight in this regard - a char

is a numeric primitive.

You can get around this using the lines

public static final String YES = "Y";
public static final String NO  = "N";
public static final String ERROR  = "E";

      

and refactoring the code to use the utility where you previously used char constants:

public static char asChar(String str) {
    if (str.length() != 1) {
         throw new IllegalArgumentException(str + " must be exactly 1 character long");
    }
    return str.charAt(0);
}

      



eg,

if (ch == asChar(ERROR))

      

which will hopefully make this portable.

Pay attention to parameter validation to ensure that you don't accidentally declare one of the strings with more than one character.

0


source


Could some post-processing be valid?

This program looks through the file tree and processes all files that are named constant-values.html

. They are loaded with Jericho HTML Parser . A table is considered, which is called constantValuesContainer

: if the first column contains text static final char

, and the value in the last column is an integer value, then it is replaced by the corresponding symbol.

Please note that this is just a sketch (but at least tested on "my" JavaDoc ;-)). Replacement conditions may be specified. For example, matching the text in the first column should be more robust (for the case where someone creates a class starting with char

....). The replacement should probably only be done when the integer value is a valid ASCII character to avoid messing up constants such as static final char CHAR_MAX = 0xFFFF

. But such adjustments should be easy if (!) Such a post-processing step is a possible way.

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");
    }


}

      

0


source







All Articles