1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.puppycrawl.tools.checkstyle.doclets;
20
21 import java.io.File;
22 import java.io.FileWriter;
23 import java.io.IOException;
24 import java.io.PrintWriter;
25 import java.util.Arrays;
26 import java.util.Comparator;
27 import com.sun.javadoc.ClassDoc;
28 import com.sun.javadoc.RootDoc;
29 import com.sun.javadoc.Tag;
30
31
32
33
34
35
36
37
38
39
40 public final class CheckDocsDoclet
41 {
42
43 private static final String DEST_DIR_OPT = "-d";
44
45
46 private CheckDocsDoclet()
47 {
48 }
49
50
51
52
53
54 private static class ClassDocByCheckNameComparator implements
55 Comparator<ClassDoc>
56 {
57
58 public int compare(ClassDoc object1, ClassDoc object2)
59 {
60 final String checkName1 = getCheckName(object1);
61 final String checkName2 = getCheckName(object2);
62 return checkName1.compareTo(checkName2);
63 }
64 }
65
66
67
68
69
70
71
72 private static String getDescription(final ClassDoc classDoc)
73 {
74 final Tag[] tags = classDoc.firstSentenceTags();
75 final StringBuffer buf = new StringBuffer();
76 if (tags.length > 0) {
77 buf.append(tags[0].text());
78 }
79 removeOpeningParagraphTag(buf);
80 return buf.toString();
81 }
82
83
84
85
86
87 private static void removeOpeningParagraphTag(final StringBuffer text)
88 {
89 final String openTag = "<p>";
90 final int tagLen = openTag.length();
91 if (text.length() > tagLen
92 && text.substring(0, tagLen).equals(openTag))
93 {
94 text.delete(0, tagLen);
95 }
96 }
97
98
99
100
101
102
103
104
105 private static String getCheckName(final ClassDoc classDoc)
106 {
107 final String strippedClassName = classDoc.typeName();
108 final String checkName;
109 if (strippedClassName.endsWith("Check")) {
110 checkName = strippedClassName.substring(
111 0, strippedClassName.length() - "Check".length());
112 }
113 else {
114 checkName = strippedClassName;
115 }
116 return checkName;
117 }
118
119
120
121
122
123
124 private static void writeXdocsHeader(
125 final PrintWriter printWriter,
126 final String title)
127 {
128 printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
129 printWriter.println("<document>");
130 printWriter.println("<properties>");
131 printWriter.println("<title>" + title + "</title>");
132 printWriter.println("<author "
133 + "email=\"checkstyle-devel@lists.sourceforge.net"
134 + "\">Checkstyle Development Team</author>");
135 printWriter.println("</properties>");
136 printWriter.println("<body>");
137 printWriter.flush();
138 }
139
140
141
142
143
144 private static void writeXdocsFooter(final PrintWriter printWriter)
145 {
146 printWriter.println("</body>");
147 printWriter.println("</document>");
148 printWriter.flush();
149 }
150
151
152
153
154
155
156
157 public static boolean start(RootDoc root) throws IOException
158 {
159 final ClassDoc[] classDocs = root.classes();
160
161 final File destDir = new File(getDestDir(root.options()));
162
163 final File checksIndexFile = new File(destDir, "availablechecks.xml");
164 final PrintWriter fileWriter = new PrintWriter(
165 new FileWriter(checksIndexFile));
166 writeXdocsHeader(fileWriter, "Available Checks");
167
168 fileWriter.println("<p>Checkstyle provides many checks that you can"
169 + " apply to your source code. Below is an alphabetical"
170 + " reference, the site navigation menu provides a reference"
171 + " organized by functionality.</p>");
172 fileWriter.println("<table>");
173
174 Arrays.sort(classDocs, new ClassDocByCheckNameComparator());
175
176 for (final ClassDoc classDoc : classDocs) {
177
178
179
180 if (classDoc.typeName().endsWith("Check")
181 && !classDoc.isAbstract())
182 {
183 String pageName = getPageName(classDoc);
184
185
186
187 final Tag[] docPageTags = classDoc.tags("checkstyle-docpage");
188 if (docPageTags != null && docPageTags.length > 0) {
189 pageName = docPageTags[0].text();
190 }
191
192 final String descr = getDescription(classDoc);
193 final String checkName = getCheckName(classDoc);
194
195
196 fileWriter.println("<tr>"
197 + "<td><a href=\""
198 + "config_" + pageName + ".html#" + checkName
199 + "\">" + checkName + "</a></td><td>"
200 + descr
201 + "</td></tr>");
202 }
203 }
204
205 fileWriter.println("</table>");
206 writeXdocsFooter(fileWriter);
207 fileWriter.close();
208 return true;
209 }
210
211
212
213
214
215
216
217 private static String getPageName(ClassDoc classDoc)
218 {
219 final String packageName = classDoc.containingPackage().name();
220 final String pageName =
221 packageName.substring(packageName.lastIndexOf('.') + 1);
222 if ("checks".equals(pageName)) {
223 return "misc";
224 }
225 return pageName;
226 }
227
228
229
230
231
232
233 public static String getDestDir(String[][] options)
234 {
235 for (final String[] opt : options) {
236 if (DEST_DIR_OPT.equalsIgnoreCase(opt[0])) {
237 return opt[1];
238 }
239 }
240 return null;
241 }
242
243
244
245
246
247
248 public static int optionLength(String option)
249 {
250 if (DEST_DIR_OPT.equals(option)) {
251 return 2;
252 }
253 return 0;
254 }
255
256 }