KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > doclets > CheckDocsDoclet


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2005 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19

20 package com.puppycrawl.tools.checkstyle.doclets;
21
22 import com.sun.javadoc.RootDoc;
23 import com.sun.javadoc.ClassDoc;
24 import com.sun.javadoc.Tag;
25
26 import java.io.IOException JavaDoc;
27 import java.io.PrintWriter JavaDoc;
28 import java.io.File JavaDoc;
29 import java.io.FileWriter JavaDoc;
30 import java.util.Arrays JavaDoc;
31 import java.util.Comparator JavaDoc;
32
33 /**
34  * Doclet which is used to extract Anakia input files from the
35  * Javadoc of Check implementations, so the Check's docs are
36  * autogenerated.
37  *
38  * @author lkuehne
39  */

40 public final class CheckDocsDoclet
41 {
42     /** javadoc command line option for dest dir. */
43     private static final String JavaDoc DEST_DIR_OPT = "-d";
44
45     /**
46      * Comparator that compares the {@link ClassDoc ClassDocs} of two checks
47      * by their check name.
48      */

49     private static class ClassDocByCheckNameComparator implements Comparator JavaDoc
50     {
51         /** {@inheritDoc} */
52         public int compare(Object JavaDoc aObject1, Object JavaDoc aObject2)
53         {
54             final ClassDoc classDoc1 = (ClassDoc) aObject1;
55             final ClassDoc classDoc2 = (ClassDoc) aObject2;
56             final String JavaDoc checkName1 = getCheckName(classDoc1);
57             final String JavaDoc checkName2 = getCheckName(classDoc2);
58             return checkName1.compareTo(checkName2);
59         }
60     }
61
62     /**
63      * The first sentence of the check description.
64      *
65      * @param aClassDoc class doc of the check, e.g. EmptyStatement
66      * @return The first sentence of the check description.
67      */

68     private static String JavaDoc getDescription(final ClassDoc aClassDoc)
69     {
70         final Tag[] tags = aClassDoc.firstSentenceTags();
71         final StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
72         if (tags.length > 0) {
73             buf.append(tags[0].text());
74         }
75         removeOpeningParagraphTag(buf);
76         return buf.toString();
77     }
78
79     /**
80      * Removes an opening p tag from a StringBuffer.
81      * @param aText the text to process
82      */

83     private static void removeOpeningParagraphTag(final StringBuffer JavaDoc aText)
84     {
85         final String JavaDoc openTag = "<p>";
86         final int tagLen = openTag.length();
87         if ((aText.length() > tagLen)
88                 && aText.substring(0, tagLen).equals(openTag))
89         {
90             aText.delete(0, tagLen);
91         }
92     }
93
94     /**
95      * Returns the official name of a check.
96      *
97      * @param aClassDoc the the check's documentation as extracted by javadoc
98      * @return the check name, e.g. "IllegalImport" for
99      * the "c.p.t.c.c.i.IllegalImportCheck" class.
100      */

101     private static String JavaDoc getCheckName(final ClassDoc aClassDoc)
102     {
103         final String JavaDoc strippedClassName = aClassDoc.typeName();
104         final String JavaDoc checkName;
105         if (strippedClassName.endsWith("Check")) {
106             checkName = strippedClassName.substring(
107                     0, strippedClassName.length() - "Check".length());
108         }
109         else {
110             checkName = strippedClassName;
111         }
112         return checkName;
113     }
114
115     /**
116      * Writes the opening tags of an xdoc.
117      * @param aPrintWriter you guessed it ... the target to print to :)
118      * @param aTitle the title to use for the document.
119      */

120     private static void writeXdocsHeader(
121             final PrintWriter JavaDoc aPrintWriter,
122             final String JavaDoc aTitle)
123     {
124         aPrintWriter.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
125         aPrintWriter.println("<document>");
126         aPrintWriter.println("<properties>");
127         aPrintWriter.println("<title>" + aTitle + "</title>");
128         aPrintWriter.println("<author "
129                 + "email=\"checkstyle-devel@lists.sourceforge.net"
130                 + "\">Checkstyle Development Team</author>");
131         aPrintWriter.println("</properties>");
132         aPrintWriter.println("<body>");
133         aPrintWriter.flush();
134     }
135
136     /**
137      * Writes the closing tags of an xdoc document.
138      * @param aPrintWriter you guessed it ... the target to print to :)
139      */

140     private static void writeXdocsFooter(final PrintWriter JavaDoc aPrintWriter)
141     {
142         aPrintWriter.println("</body>");
143         aPrintWriter.println("</document>");
144         aPrintWriter.flush();
145     }
146
147     /**
148      * Doclet entry point.
149      * @param aRoot parsed javadoc of all java files passed to the javadoc task
150      * @return true (TODO: semantics of the return value is not clear to me)
151      * @throws IOException if there are problems writing output
152      */

153     public static boolean start(RootDoc aRoot) throws IOException JavaDoc
154     {
155         final ClassDoc[] classDocs = aRoot.classes();
156
157         final File JavaDoc destDir = new File JavaDoc(getDestDir(aRoot.options()));
158
159         final File JavaDoc checksIndexFile = new File JavaDoc(destDir, "availablechecks.xml");
160         final PrintWriter JavaDoc fileWriter = new PrintWriter JavaDoc(
161                 new FileWriter JavaDoc(checksIndexFile));
162         writeXdocsHeader(fileWriter, "Available Checks");
163
164         fileWriter.println("<p>Checkstyle provides many checks that you can"
165                 + " apply to your sourcecode. Below is an alphabetical"
166                 + " reference, the site navigation menu provides a reference"
167                 + " organized by functionality.</p>");
168         fileWriter.println("<table>");
169
170         Arrays.sort(classDocs, new ClassDocByCheckNameComparator());
171
172         for (int i = 0; i < classDocs.length; i++) {
173
174             final ClassDoc classDoc = classDocs[i];
175
176             // TODO: introduce a "CheckstyleModule" interface
177
// so we can do better in the next line...
178
if (classDoc.typeName().endsWith("Check")
179                     && !classDoc.isAbstract())
180             {
181                 String JavaDoc pageName = getPageName(classDoc);
182
183                 // allow checks to override pageName when
184
// java package hierarchy is not reflected in doc structure
185
final Tag[] docPageTags = classDoc.tags("checkstyle-docpage");
186                 if ((docPageTags != null) && (docPageTags.length > 0)) {
187                     pageName = docPageTags[0].text();
188                 }
189
190                 final String JavaDoc descr = getDescription(classDoc);
191                 final String JavaDoc checkName = getCheckName(classDoc);
192
193
194                 fileWriter.println("<tr>"
195                         + "<td><a HREF=\""
196                         + "config_" + pageName + ".html#" + checkName
197                         + "\">" + checkName + "</a></td><td>"
198                         + descr
199                         + "</td></tr>");
200             }
201         }
202
203         fileWriter.println("</table>");
204         writeXdocsFooter(fileWriter);
205         fileWriter.close();
206
207         return true;
208     }
209
210     /**
211      * Calculates the human readable page name for a doc page.
212      *
213      * @param aClassDoc the doc page.
214      * @return the human readable page name for the doc page.
215      */

216     private static String JavaDoc getPageName(ClassDoc aClassDoc)
217     {
218         final String JavaDoc packageName = aClassDoc.containingPackage().name();
219         final String JavaDoc pageName =
220                 packageName.substring(packageName.lastIndexOf('.') + 1);
221         if ("checks".equals(pageName)) {
222             return "misc";
223         }
224         return pageName;
225     }
226
227     /**
228      * Return the destination directory for this Javadoc run.
229      * @param aOptions Javadoc commandline options
230      * @return the dest dir specified on the command line (or ant task)
231      */

232     public static String JavaDoc getDestDir(String JavaDoc[][] aOptions)
233     {
234         for (int i = 0; i < aOptions.length; i++) {
235             final String JavaDoc[] opt = aOptions[i];
236             if (DEST_DIR_OPT.equalsIgnoreCase(opt[0])) {
237                 return opt[1];
238             }
239         }
240         return null; // TODO: throw exception here ???
241
}
242
243     /**
244      * Returns option length (how many parts are in option).
245      * @param aOption option name to process
246      * @return option length (how many parts are in option).
247      */

248     public static int optionLength(String JavaDoc aOption)
249     {
250         if (DEST_DIR_OPT.equals(aOption)) {
251             return 2;
252         }
253         return 0;
254     }
255
256 }
257
Popular Tags