Cs-doclet
<meta name="keywords" content="java, doclet, javadoc, checkstyle"></meta> <meta name="description" content="A doclet that generates the metadata files for CHECKSTYLE and ECLIPSE-CS from annotations and DOC tags in the source code of the checks and filters"></meta>
Abstract[edit]
Cs-doclet is a JAVADOC doclet that generates the metadata files for CheckStyle and eclipse-cs from annotations and doc tags in the source code of your checks and filters.
This doclet is useful only for authors of CheckStyle extensions, like cs-contrib.
Intended audience[edit]
This tool is useful for the development of CheckStyle checks and filters, and for their integration in eclipse-cs and MediaWiki.
Extending CheckStyle[edit]
CheckStyle comes with an API to extend it with custom checks and filters. Here is a completely useless, yet typical example of a custom check:
File "src/com/pany/cs/checks/ColorCheck.java":
package com.pany.cs.checks; import com.puppycrawl.tools.checkstyle.api.Check; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; public class ColorCheck extends Check { public void setColor(String value) { this.color = value; } private String color = "Yellow"; @Override public int[] getDefaultTokens() { return new int[] { TokenTypes.ANNOTATION }; } @Override public void visitToken(DetailAST ast) { this.log(ast, "theColorIs", this.color); } }
The CheckStyle extension API supports internationalization be means of "messages.properties" files:
File "src/com/pany/cs/checks/messages.properties":
theColorIs = The color is {0}
File "src/com/pany/cs/checks/messages_de.properties":
theColorIs = Die Farbe ist {0}
To make use of this check, you'd write a "CheckStyle configuration file"
File "checkstyle-config.xml":
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> <module name="Checker"> <property name="severity" value="warning" /> <module name="TreeWalker"> <module name="com.pany: ColorCheck"> <property name="color" value="blue" /> </module> </module> </module>
, and execute CheckStyle on a target project, e.g. on the example project itself:
$ javac -d bin src/com/pany/cs/checks/ColorCheck.java
$ java -classpath 'bin;path/to/checkstyle-6.1-all.jar' \
> com.puppycrawl.tools.checkstyle.Main \
> -c checkstyle-config.xml \
> -r src
Starting audit...
C:\dev\EclipseWS\de.unkrig.cs-contrib\foo\src\com\pany\cs\checks\ColorCheck.java:14:5: warning: The color is 'blue'
C:\dev\EclipseWS\de.unkrig.cs-contrib\foo\src\com\pany\cs\checks\ColorCheck.java:17:5: warning: The color is 'blue'
Audit done.
$
(We get the two warnings because there are two "@Override" annotations in the code.)
Obviously, the Java code and the "messages.properties" files must be kept in sync with the Java code at all times, which is naturally very error-prone.
Cs-doclet facilitates the task by generating the "messages.properties" file from annotations in the source code:
File "src/com/pany/cs/checks/MyCheck.java":
package com.pany.cs.checks; import com.puppycrawl.tools.checkstyle.api.Check; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; public class ColorCheck extends Check { @Message("The color is {0}") private static final String MESSAGE_KEY_THE_COLOR_IS = "theColorIs"; public void setColor(String value) { this.color = value; } private String color = "Yellow"; @Override public int[] getDefaultTokens() { return new int[] { TokenTypes.ANNOTATION }; } @Override public void visitToken(DetailAST ast) { this.log(ast, MESSAGE_KEY_THE_COLOR_IS, this.color); } }
To generate the "messages.properties" file, you'd run JAVADOC with the cs-doclet and the "-messages.properties-dir" command line option:
$ javadoc \ > -doclet de.unkrig.doclet.cs.CsDoclet \ > -docletpath "path/to/cs-doclet.jar;bin;path/to/checkstyle-6.1-all.jar;path/to/net.sf.eclipsecs.core-6.1.jar" \ > -messages.properties-dir src \ > -sourcepath src \ > -classpath ../net.sf.checkstyle-6.1/checkstyle-6.1/checkstyle-6.1-all.jar \ > com.pany.cs.checks Loading source files for package com.pany.cs.checks... Constructing Javadoc information... $
Notice that both "checkstyle.jar" and "net.sf.eclipsecs-core.jar" must be on the "-docletpath".
The generated "src/com/pany/cs/checks/messages.properties" file looks like this:
# This file was generated by the CS doclet; see http://cs-doclet.unkrig.de/ # Custom check messages, in alphabetical order. # --------------- com.pany: ColorCheck --------------- theColorIs = The color is {0}
And voilà! All the messages are where they belong: In the source code.
Integrating with eclipse-cs[edit]
When you integrate your checks with eclipse-cs, then you learn that you have to write two more metadata files:
File "checkstyle-metadata.xml":
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE checkstyle-metadata PUBLIC "-//eclipse-cs//DTD Check Metadata 1.1//EN" "http://eclipse-cs.sourceforge.net/dtds/checkstyle-metadata_1_1.dtd"> <checkstyle-metadata> <rule-group-metadata name="%Whitespace.group" priority="999"> <rule-metadata internal-name="com.pany.cs.checks.ColorCheck" parent="TreeWalker" name="%ColorCheck.name" > <alternative-name internal-name="com.pany.cs.checks.ColorCheck" /> <description>%ColorCheck.desc</description> <property-metadata name="color" datatype="String" default-value="Yellow" > <description>%ColorCheck.color</description> </property-metadata> <message-key key="theColorIs" /> </rule-metadata> </rule-group-metadata> </checkstyle-metadata>
File "checkstyle-metadata.properties":
Whitespace.group = Whitespace ColorCheck.name = com.pany: ColorCheck ColorCheck.desc =\ A completely useless check which merely prints a (localizable) message each \ time it encounters an annotation. ColorCheck.color = A completely useless check parameter.
Tedious, isn't it? Well, you can tell cs-doclet to also generate these files from annotations (and doc comments):
File "src/com/pany/cs/checks/MyCheck.java":
// File "src/com/pany/cs/ColorCheck.java". package com.pany.cs.checks; import com.puppycrawl.tools.checkstyle.api.Check; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; import de.unkrig.csdoclet.StringRuleProperty; import de.unkrig.csdoclet.Rule; /** * A completely useless check which merely prints a * (localizable) message each time it encounters an annotation. */ @Rule( group = "%Whitespace.group", groupName = "Whitespace", name = "com.pany: ColorCheck", parent = "TreeWalker" ) public class ColorCheck extends Check { @Message("The color is {0}") private static final String MESSAGE_KEY_THE_COLOR_IS = "theColorIs"; /** * A completely useless check parameter. */ @StringRuleProperty(defaultValue = DEFAULT_COLOR) public void setColor(String value) { this.color = value; } private String color = DEFAULT_COLOR; private static final String DEFAULT_COLOR = "Yellow"; @Override public int[] getDefaultTokens() { return new int[] { TokenTypes.ANNOTATION }; } @Override public void visitToken(DetailAST ast) { this.log(ast, MESSAGE_KEY_THE_COLOR_IS, this.color); } }
$ javadoc \ > -doclet de.unkrig.doclet.cs.CsDoclet \ > -docletpath "path/to/cs-doclet.jar;bin;path/to/checkstyle-6.1-all.jar;path/to/net.sf.eclipsecs.core-6.1.jar" \ > -checkstyle-metadata.properties-dir src \ > -checkstyle-metadata.xml-dir src \ > -messages.properties-dir src \ > -sourcepath src \ > -classpath ../net.sf.checkstyle-6.1/checkstyle-6.1/checkstyle-6.1-all.jar \ > com.pany.cs.checks Loading source files for package com.pany.cs.checks... Constructing Javadoc information... $
And you'll get:
File "src/com/pany/cs/checks/checkstyle-metadata.properties":
# This file was generated by the CS doclet; see http://cs-doclet.unkrig.de/ # Rule groups: Whitespace.group = Whitespace # Custom checks, in alphabetical order. # --------------- com.pany: ColorCheck --------------- ColorCheck.name = com.pany: ColorCheck ColorCheck.desc =\ A completely useless check which merely prints a (localizable) message each time it encounters an annotation. ColorCheck.color = A completely useless check parameter.
File "src/com/pany/cs/checks/checkstyle-metadata.xml":
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE checkstyle-metadata PUBLIC "-//eclipse-cs//DTD Check Metadata 1.1//EN" "http://eclipse-cs.sourceforge.net/dtds/checkstyle-metadata_1_1.dtd"> <checkstyle-metadata> <!-- This file was generated by the CS doclet; see http://cs-doclet.unkrig.de/ --> <!-- ColorCheck --> <rule-group-metadata name="%Whitespace.group" priority="999"> <rule-metadata internal-name="com.pany.cs.checks.ColorCheck" parent="TreeWalker" name="%ColorCheck.name" > <alternative-name internal-name="com.pany.cs.checks.ColorCheck" /> <description>%ColorCheck.desc</description> <property-metadata name="color" datatype="String" default-value="Yellow" > <description>%ColorCheck.color</description> </property-metadata> <message-key key="theColorIs" /> </rule-metadata> </rule-group-metadata> </checkstyle-metadata>
Javadoc-like documentation[edit]
Typically, you will also want to publish human-readable documentation for your checks and filters, which is more or less identical with the text in the eclipse-cs metadata files. This is also possible with the "-d" command line option:
$ javadoc \ > -doclet de.unkrig.doclet.cs.CsDoclet \ > -docletpath "path/to/cs-doclet.jar;bin;path/to/checkstyle-6.1-all.jar;path/to/net.sf.eclipsecs.core-6.1.jar" \ > -d ./csdoc \ > -sourcepath src \ > -classpath ../net.sf.checkstyle-6.1/checkstyle-6.1/checkstyle-6.1-all.jar \ > com.pany.cs.checks Loading source files for package com.pany.cs.checks... Constructing Javadoc information... $
This will generate a Javadoc-like HTML documentation for all checks and filters that are declared in the given Java packages.
And you're done!
Summary[edit]
Before, you had to write one Java file and four more or less redundant metadata files per check; now you merely have to throw in a few annotations and doc comments and generate all four metadata files from the source code
Source code[edit]
The source code for the plug-in is here:
https://github.com/aunkrig/doclet-cs https://github.com/aunkrig/doclet-cs-annotation