////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2017 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.doclets;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.DocErrorReporter;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.RootDoc;
/**
* Doclet which is used to write property file with short descriptions
* (first sentences) of TokenTypes' constants.
* Request: 724871
* For ide plugins (like the eclipse plugin) it would be useful to have
* programmatic access to the first sentence of the TokenType constants,
* so they can use them in their configuration gui.
* @author o_sukhodolsky
*/
public final class TokenTypesDoclet {
/** Command line option to specify file to write output of the doclet. */
private static final String DEST_FILE_OPT = "-destfile";
/** Stop instances being created. */
private TokenTypesDoclet() {
}
/**
* The doclet's starter method.
* @param root {@code RootDoc} given to the doclet
* @return true if the given {@code RootDoc} is processed.
* @exception FileNotFoundException will be thrown if the doclet
* will be unable to write to the specified file.
*/
public static boolean start(RootDoc root)
throws FileNotFoundException {
final String fileName = getDestFileName(root.options());
final FileOutputStream fos = new FileOutputStream(fileName);
final Writer osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
final PrintWriter writer = new PrintWriter(osw, false);
try {
final ClassDoc[] classes = root.classes();
final FieldDoc[] fields = classes[0].fields();
for (final FieldDoc field : fields) {
if (field.isStatic() && field.isPublic() && field.isFinal()
&& "int".equals(field.type().qualifiedTypeName())) {
if (field.firstSentenceTags().length != 1) {
final String message = "Should be only one tag.";
throw new IllegalArgumentException(message);
}
writer.println(field.name() + "="
+ field.firstSentenceTags()[0].text());
}
}
}
finally {
writer.close();
}
return true;
}
/**
* Returns option length (how many parts are in option).
* @param option option name to process
* @return option length (how many parts are in option).
*/
public static int optionLength(String option) {
int length = 0;
if (DEST_FILE_OPT.equals(option)) {
length = 2;
}
return length;
}
/**
* Checks that only valid options was specified.
* @param options all parsed options
* @param reporter the reporter to report errors.
* @return true if only valid options was specified
*/
public static boolean checkOptions(String[][] options, DocErrorReporter reporter) {
boolean foundDestFileOption = false;
boolean onlyOneDestFileOption = true;
for (final String[] opt : options) {
if (DEST_FILE_OPT.equals(opt[0])) {
if (foundDestFileOption) {
reporter.printError("Only one -destfile option allowed.");
onlyOneDestFileOption = false;
break;
}
foundDestFileOption = true;
}
}
if (!foundDestFileOption) {
reporter.printError("Usage: javadoc -destfile file -doclet TokenTypesDoclet ...");
}
return onlyOneDestFileOption && foundDestFileOption;
}
/**
* Reads destination file name.
* @param options all specified options.
* @return destination file name
*/
private static String getDestFileName(String[]... options) {
String fileName = null;
for (final String[] opt : options) {
if (DEST_FILE_OPT.equals(opt[0])) {
fileName = opt[1];
}
}
return fileName;
}
}