View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2018 the original author or authors.
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.checks.javadoc;
21  
22  import static com.puppycrawl.tools.checkstyle.JavadocDetailNodeParser.MSG_JAVADOC_PARSE_RULE_ERROR;
23  import static com.puppycrawl.tools.checkstyle.JavadocDetailNodeParser.MSG_UNCLOSED_HTML_TAG;
24  import static com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck.MSG_JAVADOC_MISSED_HTML_CLOSE;
25  import static com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck.MSG_JAVADOC_WRONG_SINGLETON_TAG;
26  import static com.puppycrawl.tools.checkstyle.checks.javadoc.SummaryJavadocCheck.MSG_SUMMARY_FIRST_SENTENCE;
27  import static java.util.Arrays.asList;
28  import static java.util.Collections.singletonList;
29  import static org.junit.Assert.assertEquals;
30  
31  import java.io.File;
32  import java.util.LinkedHashMap;
33  import java.util.List;
34  import java.util.Map;
35  
36  import org.junit.Assert;
37  import org.junit.Rule;
38  import org.junit.Test;
39  import org.junit.contrib.java.lang.system.SystemErrRule;
40  import org.junit.rules.TemporaryFolder;
41  
42  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
43  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
44  import com.puppycrawl.tools.checkstyle.TreeWalker;
45  import com.puppycrawl.tools.checkstyle.api.DetailNode;
46  import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
47  import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
48  import com.puppycrawl.tools.checkstyle.utils.JavadocUtils;
49  
50  public class AbstractJavadocCheckTest extends AbstractModuleTestSupport {
51  
52      @Rule
53      public final SystemErrRule systemErr = new SystemErrRule().enableLog().mute();
54  
55      @Rule
56      public final TemporaryFolder temporaryFolder = new TemporaryFolder();
57  
58      @Override
59      protected String getPackageLocation() {
60          return "com/puppycrawl/tools/checkstyle/checks/javadoc/abstractjavadoc";
61      }
62  
63      @Test
64      public void testJavadocTagsWithoutArgs() throws Exception {
65          final DefaultConfiguration checkconfig = createModuleConfig(TempCheck.class);
66          final String[] expected = {
67              "5: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 7,
68                      "mismatched input '<EOF>' expecting {WS, NEWLINE}", "JAVADOC_TAG"),
69              "10: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 4,
70                      "no viable alternative at input '<EOF>'", "JAVADOC_TAG"),
71              "13: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 6,
72                      "mismatched input '<EOF>' expecting {WS, NEWLINE}", "JAVADOC_TAG"),
73              "16: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 8,
74                      "mismatched input '<EOF>' expecting {WS, NEWLINE}", "JAVADOC_TAG"),
75              "22: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 10,
76                      "no viable alternative at input '<EOF>'", "JAVADOC_TAG"),
77              "27: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 7,
78                      "no viable alternative at input '<EOF>'", "JAVADOC_TAG"),
79              "32: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 7,
80                      "mismatched input '<EOF>' expecting {WS, NEWLINE}", "JAVADOC_TAG"),
81              "37: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 6,
82                      "no viable alternative at input '<EOF>'", "JAVADOC_TAG"),
83              "58: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 13,
84                      "mismatched input '}' expecting {LEADING_ASTERISK, WS, NEWLINE}",
85                      "JAVADOC_INLINE_TAG"),
86              "65: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 19,
87                      "no viable alternative at input '}'", "REFERENCE"),
88          };
89          verify(checkconfig, getPath("InputAbstractJavadocJavadocTagsWithoutArgs.java"), expected);
90      }
91  
92      @Test
93      public void testNumberFormatException() throws Exception {
94          final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
95          final String[] expected = {
96              "3: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 52,
97                      "mismatched input ';' expecting MEMBER", "REFERENCE"),
98          };
99          verify(checkConfig, getPath("InputAbstractJavadocNumberFormatException.java"), expected);
100     }
101 
102     @Test
103     public void testCustomTag() throws Exception {
104         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
105         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
106         verify(checkConfig, getPath("InputAbstractJavadocCustomTag.java"), expected);
107     }
108 
109     @Test
110     public void testParsingErrors() throws Exception {
111         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
112         final String[] expected = {
113             "4: " + getCheckMessage(MSG_JAVADOC_MISSED_HTML_CLOSE, 4, "unclosedTag"),
114             "8: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 35, "img"),
115         };
116         verify(checkConfig, getPath("InputAbstractJavadocParsingErrors.java"), expected);
117         assertEquals("Error is unexpected", "", systemErr.getLog());
118     }
119 
120     @Test
121     public void testWithMultipleChecks() throws Exception {
122         final DefaultConfiguration checksConfig = createModuleConfig(TreeWalker.class);
123         checksConfig.addChild(createModuleConfig(AtclauseOrderCheck.class));
124         checksConfig.addChild(createModuleConfig(JavadocParagraphCheck.class));
125 
126         final DefaultConfiguration checkerConfig = createRootConfig(checksConfig);
127 
128         verify(checkerConfig, getPath("InputAbstractJavadocCorrectParagraph.java"));
129     }
130 
131     @Test
132     public void testAntlrError() throws Exception {
133         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
134         final String[] expected = {
135             "4: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 78,
136                     "mismatched input '(' expecting <EOF>", "JAVADOC"),
137         };
138         verify(checkConfig, getPath("InputAbstractJavadocInvalidAtSeeReference.java"), expected);
139         assertEquals("Error is unexpected", "", systemErr.getLog());
140     }
141 
142     @Test
143     public void testCheckReuseAfterParseErrorWithFollowingAntlrErrorInTwoFiles() throws Exception {
144         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
145         final Map<String, List<String>> expectedMessages = new LinkedHashMap<>(2);
146         expectedMessages.put(getPath("InputAbstractJavadocParsingErrors.java"), asList(
147             "4: " + getCheckMessage(MSG_JAVADOC_MISSED_HTML_CLOSE, 4, "unclosedTag"),
148             "8: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 35, "img")
149         ));
150         expectedMessages.put(getPath("InputAbstractJavadocInvalidAtSeeReference.java"),
151             singletonList("4: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 78,
152                     "mismatched input '(' expecting <EOF>", "JAVADOC")
153         ));
154         verify(createChecker(checkConfig), new File[] {
155             new File(getPath("InputAbstractJavadocParsingErrors.java")),
156             new File(getPath("InputAbstractJavadocInvalidAtSeeReference.java")), },
157                 expectedMessages);
158         assertEquals("Error is unexpected", "", systemErr.getLog());
159     }
160 
161     @Test
162     public void testCheckReuseAfterParseErrorWithFollowingAntlrErrorInSingleFile()
163             throws Exception {
164         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
165         final String[] expected = {
166             "4: " + getCheckMessage(MSG_JAVADOC_MISSED_HTML_CLOSE, 4, "unclosedTag"),
167             "8: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 82,
168                     "mismatched input '(' expecting <EOF>", "JAVADOC"),
169         };
170         verify(checkConfig,
171             getPath("InputAbstractJavadocUnclosedTagAndInvalidAtSeeReference.java"), expected);
172     }
173 
174     @Test
175     public void testPosition()
176             throws Exception {
177         JavadocCatchCheck.clearCounter();
178         final DefaultConfiguration checkConfig = createModuleConfig(JavadocCatchCheck.class);
179         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
180         verify(checkConfig, getPath("InputAbstractJavadocPosition.java"), expected);
181         assertEquals("Invalid number of javadocs",
182             65, JavadocCatchCheck.javadocsNumber);
183     }
184 
185     @Test
186     public void testPositionWithSinglelineComments()
187             throws Exception {
188         JavadocCatchCheck.clearCounter();
189         final DefaultConfiguration checkConfig = createModuleConfig(JavadocCatchCheck.class);
190         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
191         verify(checkConfig,
192             getPath("InputAbstractJavadocPositionWithSinglelineComments.java"), expected);
193         assertEquals("Invalid number of javadocs",
194                 65, JavadocCatchCheck.javadocsNumber);
195     }
196 
197     @Test
198     public void testPositionOnlyComments()
199             throws Exception {
200         JavadocCatchCheck.clearCounter();
201         final DefaultConfiguration checkConfig = createModuleConfig(JavadocCatchCheck.class);
202         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
203         verify(checkConfig, getPath("InputAbstractJavadocPositionOnlyComments.java"), expected);
204         assertEquals("Invalid number of javadocs",
205                 0, JavadocCatchCheck.javadocsNumber);
206     }
207 
208     @Test
209     public void testTokens() {
210         final int[] defaultJavadocTokens = {JavadocTokenTypes.JAVADOC};
211         final AbstractJavadocCheck check = new AbstractJavadocCheck() {
212             @Override
213             public void visitJavadocToken(DetailNode ast) {
214                 // no code necessary
215             }
216 
217             @Override
218             public int[] getDefaultJavadocTokens() {
219                 return defaultJavadocTokens;
220             }
221         };
222 
223         Assert.assertNotNull("Default tokens should not be null", check.getDefaultTokens());
224         Assert.assertArrayEquals("Acceptable tokens should be equal to default",
225                 check.getDefaultTokens(), check.getAcceptableTokens());
226         Assert.assertArrayEquals("Required tokens should be equal to default",
227                 check.getDefaultTokens(), check.getRequiredTokens());
228         Assert.assertArrayEquals("Invalid default javadoc tokens",
229                 defaultJavadocTokens, check.getDefaultJavadocTokens());
230         Assert.assertArrayEquals("Invalid acceptable javadoc tokens",
231                 defaultJavadocTokens, check.getAcceptableJavadocTokens());
232         Assert.assertNotEquals("Invalid required javadoc tokens",
233                 defaultJavadocTokens, check.getRequiredJavadocTokens());
234     }
235 
236     @Test
237     public void testAcceptableTokensFail()
238             throws Exception {
239         final DefaultConfiguration checkConfig =
240             createModuleConfig(TokenIsNotInAcceptablesJavadocCheck.class);
241         checkConfig.addAttribute("javadocTokens", "RETURN_LITERAL");
242         try {
243             final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
244             verify(checkConfig, getPath("InputAbstractJavadocMain.java"), expected);
245             Assert.fail("CheckstyleException is expected");
246         }
247         catch (IllegalStateException ex) {
248             final String expected = "Javadoc Token "
249                     + "\"RETURN_LITERAL\" was not found in "
250                     + "Acceptable javadoc tokens list in check";
251             Assert.assertTrue("Invalid exception, should start with: " + expected,
252                     ex.getMessage().startsWith(expected));
253         }
254     }
255 
256     @Test
257     public void testAcceptableTokensPass()
258             throws Exception {
259         final DefaultConfiguration checkConfig =
260             createModuleConfig(TokenIsNotInAcceptablesJavadocCheck.class);
261         checkConfig.addAttribute("javadocTokens", "DEPRECATED_LITERAL");
262 
263         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
264         verify(checkConfig, getPath("InputAbstractJavadocMain.java"), expected);
265     }
266 
267     @Test
268     public void testRequiredTokenIsNotInDefaultTokens() throws Exception {
269         final DefaultConfiguration checkConfig =
270             createModuleConfig(RequiredTokenIsNotInDefaultsJavadocCheck.class);
271         final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
272 
273         try {
274             final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
275             verify(checkConfig, pathToEmptyFile, expected);
276             Assert.fail("CheckstyleException is expected");
277         }
278         catch (IllegalStateException ex) {
279             final String expected = "Javadoc Token \""
280                     + JavadocTokenTypes.RETURN_LITERAL + "\" from required"
281                     + " javadoc tokens was not found in default javadoc tokens list in check";
282             Assert.assertTrue("Invalid exception, should start with: " + expected,
283                     ex.getMessage().startsWith(expected));
284         }
285     }
286 
287     @Test
288     public void testVisitLeaveToken()
289             throws Exception {
290         JavadocVisitLeaveCheck.clearCounter();
291         final DefaultConfiguration checkConfig = createModuleConfig(JavadocVisitLeaveCheck.class);
292         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
293         verify(checkConfig, getPath("InputAbstractJavadocPosition.java"), expected);
294         Assert.assertTrue("Javadoc visit count should be greater than zero",
295                 JavadocVisitLeaveCheck.visitCount > 0);
296         assertEquals("Javadoc visit and leave count should be equal",
297                 JavadocVisitLeaveCheck.visitCount, JavadocVisitLeaveCheck.leaveCount);
298     }
299 
300     @Test
301     public void testNoWsBeforeDescriptionInJavadocTags() throws Exception {
302         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
303         final String[] expected = {
304             "13: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
305                     23, "mismatched input 'd' expecting <EOF>", "JAVADOC"),
306             "22: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
307                     30, "mismatched input '-' expecting <EOF>", "JAVADOC"),
308             "28: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
309                     39, "mismatched input '-' expecting <EOF>", "JAVADOC"),
310             "40: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
311                     34, "mismatched input '-' expecting <EOF>", "JAVADOC"),
312             "48: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
313                     31, "mismatched input '-' expecting <EOF>", "JAVADOC"),
314             "57: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
315                     15, "mismatched input '-' expecting <EOF>", "JAVADOC"),
316             "64: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
317                     32, "mismatched input '-' expecting <EOF>", "JAVADOC"),
318             "71: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
319                     17, "mismatched input '<' expecting <EOF>", "JAVADOC"),
320             "78: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
321                     34, "no viable alternative at input '-'", "JAVADOC_INLINE_TAG"),
322             "85: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
323                     39, "no viable alternative at input '-'", "JAVADOC_INLINE_TAG"),
324             "92: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
325                     19, "no viable alternative at input '<'", "JAVADOC_INLINE_TAG"),
326         };
327         verify(checkConfig, getPath("InputAbstractJavadocNoWsBeforeDescriptionInJavadocTags.java"),
328                 expected);
329     }
330 
331     @Test
332     public void testWrongSingletonTagInJavadoc() throws Exception {
333         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
334         final String[] expected = {
335             "5: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "embed"),
336             "10: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "keygen"),
337             "15: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "SOURCE"),
338             "20: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "TRACK"),
339             "25: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "WBR"),
340         };
341         verify(checkConfig, getPath("InputAbstractJavadocWrongSingletonTagInJavadoc.java"),
342                 expected);
343     }
344 
345     @Test
346     public void testNonTightHtmlTagIntolerantCheck() throws Exception {
347         final DefaultConfiguration checkConfig =
348                 createModuleConfig(NonTightHtmlTagIntolerantCheck.class);
349         checkConfig.addAttribute("violateExecutionOnNonTightHtml", "true");
350         final String[] expected = {
351             "6: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
352             "13: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
353             "16: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
354             "21: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
355             "27: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
356             "34: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
357             "54: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
358             "71: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
359             "80: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
360             "124: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
361         };
362         verify(checkConfig, getPath("InputAbstractJavadocNonTightHtmlTags.java"), expected);
363     }
364 
365     @Test
366     public void testNonTightHtmlTagIntolerantCheckReportingNoViolation() throws Exception {
367         final DefaultConfiguration checkConfig =
368                 createModuleConfig(NonTightHtmlTagIntolerantCheck.class);
369         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
370         verify(checkConfig, getPath("InputAbstractJavadocNonTightHtmlTags.java"), expected);
371     }
372 
373     @Test
374     public void testNonTightHtmlTagIntolerantCheckVisitCount()
375             throws Exception {
376         final DefaultConfiguration checkConfig =
377                 createModuleConfig(NonTightHtmlTagIntolerantCheck.class);
378         checkConfig.addAttribute("violateExecutionOnNonTightHtml", "true");
379         checkConfig.addAttribute("reportVisitJavadocToken", "true");
380         final String[] expected = {
381             "6: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
382             "13: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
383             "16: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
384             "21: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
385             "27: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
386             "34: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
387             "41:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
388             "54: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
389             "62:13: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
390             "71: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
391             "80: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
392             "99:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
393             "105:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
394             "109:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
395             "124: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
396         };
397         verify(checkConfig, getPath("InputAbstractJavadocNonTightHtmlTags.java"), expected);
398     }
399 
400     @Test
401     public void testVisitCountForCheckAcceptingJavadocWithNonTightHtml()
402             throws Exception {
403         final DefaultConfiguration checkConfig =
404                 createModuleConfig(NonTightHtmlTagTolerantCheck.class);
405         checkConfig.addAttribute("violateExecutionOnNonTightHtml", "true");
406         checkConfig.addAttribute("reportVisitJavadocToken", "true");
407         final String[] expected = {
408             "4:4: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
409             "5:4: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
410             "6: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
411             "6:4: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
412             "7:4: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
413             "7:39: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
414             "13: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
415             "13:9: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
416             "13:13: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
417             "16: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
418             "16:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
419             "20:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
420             "21: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
421             "21:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
422             "21:30: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
423             "26:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
424             "26:22: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
425             "27: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
426             "32:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
427             "33:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
428             "34: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
429             "34:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
430             "34:23: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
431             "39:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
432             "39:20: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
433             "39:34: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
434             "41: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
435             "41:16: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
436             "41:21: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
437             "49:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
438             "51: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
439             "51:22: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
440             "56:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
441             "57:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
442             "60: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
443             "79:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
444             "85: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
445             "85:9: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
446             "85:13: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
447             "85:33: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
448         };
449         verify(checkConfig, getPath("InputAbstractJavadocNonTightHtmlTags2.java"), expected);
450     }
451 
452     private static class TempCheck extends AbstractJavadocCheck {
453 
454         @Override
455         public int[] getDefaultJavadocTokens() {
456             return CommonUtils.EMPTY_INT_ARRAY;
457         }
458 
459         @Override
460         public void visitJavadocToken(DetailNode ast) {
461             // do nothing
462         }
463 
464     }
465 
466     private static class JavadocCatchCheck extends AbstractJavadocCheck {
467 
468         private static int javadocsNumber;
469 
470         public static void clearCounter() {
471             javadocsNumber = 0;
472         }
473 
474         @Override
475         public int[] getDefaultJavadocTokens() {
476             return new int[] {JavadocTokenTypes.JAVADOC};
477         }
478 
479         @Override
480         public void visitJavadocToken(DetailNode ast) {
481             assertEquals(ast.toString(), "JAVADOC", ast.getText());
482             final DetailNode text = JavadocUtils.findFirstToken(ast, JavadocTokenTypes.TEXT);
483             Assert.assertNotNull("Empty javadoc text at " + ast, text);
484             assertEquals(ast.toString(), "Javadoc", text.getText());
485             javadocsNumber++;
486         }
487 
488     }
489 
490     private static class RequiredTokenIsNotInDefaultsJavadocCheck extends AbstractJavadocCheck {
491 
492         @Override
493         public int[] getRequiredJavadocTokens() {
494             return new int[] {JavadocTokenTypes.RETURN_LITERAL};
495         }
496 
497         @Override
498         public int[] getDefaultJavadocTokens() {
499             return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
500         }
501 
502         @Override
503         public int[] getAcceptableJavadocTokens() {
504             return CommonUtils.EMPTY_INT_ARRAY;
505         }
506 
507         @Override
508         public void visitJavadocToken(DetailNode ast) {
509             // not used
510         }
511 
512     }
513 
514     private static class TokenIsNotInAcceptablesJavadocCheck extends AbstractJavadocCheck {
515 
516         @Override
517         public int[] getRequiredJavadocTokens() {
518             return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
519         }
520 
521         @Override
522         public int[] getDefaultJavadocTokens() {
523             return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
524         }
525 
526         @Override
527         public int[] getAcceptableJavadocTokens() {
528             return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
529         }
530 
531         @Override
532         public void visitJavadocToken(DetailNode ast) {
533             // not used
534         }
535 
536     }
537 
538     private static class JavadocVisitLeaveCheck extends AbstractJavadocCheck {
539 
540         private static int visitCount;
541         private static int leaveCount;
542 
543         public static void clearCounter() {
544             visitCount = 0;
545             leaveCount = 0;
546         }
547 
548         @Override
549         public int[] getRequiredJavadocTokens() {
550             return new int[] {JavadocTokenTypes.TEXT};
551         }
552 
553         @Override
554         public int[] getDefaultJavadocTokens() {
555             return getRequiredJavadocTokens();
556         }
557 
558         @Override
559         public int[] getAcceptableJavadocTokens() {
560             return getRequiredJavadocTokens();
561         }
562 
563         @Override
564         public void visitJavadocToken(DetailNode ast) {
565             visitCount++;
566         }
567 
568         @Override
569         public void leaveJavadocToken(DetailNode ast) {
570             leaveCount++;
571         }
572 
573     }
574 
575     public static class NonTightHtmlTagIntolerantCheck extends AbstractJavadocCheck {
576 
577         private boolean reportVisitJavadocToken;
578 
579         public final void setReportVisitJavadocToken(boolean reportVisitJavadocToken) {
580             this.reportVisitJavadocToken = reportVisitJavadocToken;
581         }
582 
583         @Override
584         public int[] getDefaultJavadocTokens() {
585             return new int[] {
586                 JavadocTokenTypes.P_TAG_START,
587                 JavadocTokenTypes.LI_TAG_START,
588                 JavadocTokenTypes.BODY_TAG_START,
589             };
590         }
591 
592         @Override
593         public void visitJavadocToken(DetailNode ast) {
594             if (reportVisitJavadocToken) {
595                 log(ast.getLineNumber(), ast.getColumnNumber(), MSG_SUMMARY_FIRST_SENTENCE);
596             }
597         }
598 
599         @Override
600         public boolean acceptJavadocWithNonTightHtml() {
601             return false;
602         }
603 
604     }
605 
606     public static class NonTightHtmlTagTolerantCheck extends AbstractJavadocCheck {
607 
608         private boolean reportVisitJavadocToken;
609 
610         public final void setReportVisitJavadocToken(boolean reportVisitJavadocToken) {
611             this.reportVisitJavadocToken = reportVisitJavadocToken;
612         }
613 
614         @Override
615         public int[] getDefaultJavadocTokens() {
616             return new int[] {
617                 JavadocTokenTypes.P_TAG_START,
618                 JavadocTokenTypes.LI_TAG_START,
619                 JavadocTokenTypes.BODY_TAG_START,
620             };
621         }
622 
623         @Override
624         public void visitJavadocToken(DetailNode ast) {
625             if (reportVisitJavadocToken) {
626                 log(ast.getLineNumber(), ast.getColumnNumber(), MSG_SUMMARY_FIRST_SENTENCE);
627             }
628         }
629 
630     }
631 
632 }