1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.Checker.EXCEPTION_MSG;
24 import static com.puppycrawl.tools.checkstyle.DefaultLogger.AUDIT_FINISHED_MESSAGE;
25 import static com.puppycrawl.tools.checkstyle.DefaultLogger.AUDIT_STARTED_MESSAGE;
26 import static com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck.MSG_KEY_NO_NEWLINE_EOF;
27 import static com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck.MSG_KEY;
28
29 import java.io.BufferedReader;
30 import java.io.BufferedWriter;
31 import java.io.ByteArrayInputStream;
32 import java.io.ByteArrayOutputStream;
33 import java.io.File;
34 import java.io.IOError;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.InputStreamReader;
38 import java.io.LineNumberReader;
39 import java.io.OutputStream;
40 import java.io.Serial;
41 import java.io.UnsupportedEncodingException;
42 import java.lang.reflect.Field;
43 import java.lang.reflect.Method;
44 import java.nio.charset.StandardCharsets;
45 import java.nio.file.Files;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.Collections;
49 import java.util.HashSet;
50 import java.util.List;
51 import java.util.Locale;
52 import java.util.Objects;
53 import java.util.Properties;
54 import java.util.Set;
55 import java.util.SortedSet;
56 import java.util.TreeSet;
57 import java.util.UUID;
58
59 import org.junit.jupiter.api.Test;
60 import org.junit.jupiter.api.io.TempDir;
61
62 import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean.OutputStreamOptions;
63 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
64 import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
65 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
66 import com.puppycrawl.tools.checkstyle.api.AuditListener;
67 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
68 import com.puppycrawl.tools.checkstyle.api.Configuration;
69 import com.puppycrawl.tools.checkstyle.api.Context;
70 import com.puppycrawl.tools.checkstyle.api.DetailAST;
71 import com.puppycrawl.tools.checkstyle.api.ExternalResourceHolder;
72 import com.puppycrawl.tools.checkstyle.api.FileText;
73 import com.puppycrawl.tools.checkstyle.api.Filter;
74 import com.puppycrawl.tools.checkstyle.api.FilterSet;
75 import com.puppycrawl.tools.checkstyle.api.MessageDispatcher;
76 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
77 import com.puppycrawl.tools.checkstyle.api.Violation;
78 import com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck;
79 import com.puppycrawl.tools.checkstyle.checks.TranslationCheck;
80 import com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck;
81 import com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck;
82 import com.puppycrawl.tools.checkstyle.filefilters.BeforeExecutionExclusionFileFilter;
83 import com.puppycrawl.tools.checkstyle.filters.SuppressionFilter;
84 import com.puppycrawl.tools.checkstyle.internal.testmodules.CheckWhichThrowsError;
85 import com.puppycrawl.tools.checkstyle.internal.testmodules.DebugAuditAdapter;
86 import com.puppycrawl.tools.checkstyle.internal.testmodules.DebugFilter;
87 import com.puppycrawl.tools.checkstyle.internal.testmodules.TestBeforeExecutionFileFilter;
88 import com.puppycrawl.tools.checkstyle.internal.testmodules.TestFileSetCheck;
89 import com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream;
90 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
91 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
92 import de.thetaphi.forbiddenapis.SuppressForbidden;
93
94
95
96
97
98
99
100
101 public class CheckerTest extends AbstractModuleTestSupport {
102
103 @TempDir
104 public File temporaryFolder;
105
106 private File createTempFile(String prefix) throws IOException {
107 return createTempFile(prefix, ".tmp");
108 }
109
110 private File createTempFile(String prefix, String suffix) throws IOException {
111 final String name = Objects.requireNonNull(prefix)
112 + UUID.randomUUID()
113 + Objects.requireNonNull(suffix);
114 return Files.createFile(temporaryFolder.toPath().resolve(name)).toFile();
115 }
116
117 private static Method getFireAuditFinished() throws NoSuchMethodException {
118 final Class<Checker> checkerClass = Checker.class;
119 final Method fireAuditFinished = checkerClass.getDeclaredMethod("fireAuditFinished");
120 fireAuditFinished.setAccessible(true);
121 return fireAuditFinished;
122 }
123
124 private static Method getFireAuditStartedMethod() throws NoSuchMethodException {
125 final Class<Checker> checkerClass = Checker.class;
126 final Method fireAuditStarted = checkerClass.getDeclaredMethod("fireAuditStarted");
127 fireAuditStarted.setAccessible(true);
128 return fireAuditStarted;
129 }
130
131 @Override
132 protected String getPackageLocation() {
133 return "com/puppycrawl/tools/checkstyle/checker";
134 }
135
136 @Test
137 public void testDestroy() throws Exception {
138 final Checker checker = new Checker();
139 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
140 checker.addListener(auditAdapter);
141 final TestFileSetCheck fileSet = new TestFileSetCheck();
142 checker.addFileSetCheck(fileSet);
143 final DebugFilter filter = new DebugFilter();
144 checker.addFilter(filter);
145 final TestBeforeExecutionFileFilter fileFilter = new TestBeforeExecutionFileFilter();
146 checker.addBeforeExecutionFileFilter(fileFilter);
147
148
149 checker.destroy();
150
151 final File tempFile = createTempFile("junit");
152 checker.process(Collections.singletonList(tempFile));
153 final SortedSet<Violation> violations = new TreeSet<>();
154 violations.add(new Violation(1, 0, "a Bundle", "message.key",
155 new Object[] {"arg"}, null, getClass(), null));
156 checker.fireErrors("Some File Name", violations);
157
158 assertWithMessage("Checker.destroy() doesn't remove listeners.")
159 .that(auditAdapter.wasCalled())
160 .isFalse();
161 assertWithMessage("Checker.destroy() doesn't remove file sets.")
162 .that(fileSet.wasCalled())
163 .isFalse();
164 assertWithMessage("Checker.destroy() doesn't remove filters.")
165 .that(filter.wasCalled())
166 .isFalse();
167 assertWithMessage("Checker.destroy() doesn't remove file filters.")
168 .that(fileFilter.wasCalled())
169 .isFalse();
170 }
171
172 @Test
173 public void testAddListener() throws Exception {
174 final Checker checker = new Checker();
175 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
176 checker.addListener(auditAdapter);
177
178
179 getFireAuditStartedMethod().invoke(checker);
180 assertWithMessage("Checker.fireAuditStarted() doesn't call listener")
181 .that(auditAdapter.wasCalled())
182 .isTrue();
183 assertWithMessage("Checker.fireAuditStarted() doesn't pass event")
184 .that(auditAdapter.wasEventPassed())
185 .isTrue();
186
187 auditAdapter.resetListener();
188 getFireAuditFinished().invoke(checker);
189 assertWithMessage("Checker.fireAuditFinished() doesn't call listener")
190 .that(auditAdapter.wasCalled())
191 .isTrue();
192 assertWithMessage("Checker.fireAuditFinished() doesn't pass event")
193 .that(auditAdapter.wasEventPassed())
194 .isTrue();
195
196 auditAdapter.resetListener();
197 checker.fireFileStarted("Some File Name");
198 assertWithMessage("Checker.fireFileStarted() doesn't call listener")
199 .that(auditAdapter.wasCalled())
200 .isTrue();
201 assertWithMessage("Checker.fireFileStarted() doesn't pass event")
202 .that(auditAdapter.wasEventPassed())
203 .isTrue();
204
205 auditAdapter.resetListener();
206 checker.fireFileFinished("Some File Name");
207 assertWithMessage("Checker.fireFileFinished() doesn't call listener")
208 .that(auditAdapter.wasCalled())
209 .isTrue();
210 assertWithMessage("Checker.fireFileFinished() doesn't pass event")
211 .that(auditAdapter.wasEventPassed())
212 .isTrue();
213
214 auditAdapter.resetListener();
215 final SortedSet<Violation> violations = new TreeSet<>();
216 violations.add(new Violation(1, 0, "a Bundle", "message.key",
217 new Object[] {"arg"}, null, getClass(), null));
218 checker.fireErrors("Some File Name", violations);
219 assertWithMessage("Checker.fireErrors() doesn't call listener")
220 .that(auditAdapter.wasCalled())
221 .isTrue();
222 assertWithMessage("Checker.fireErrors() doesn't pass event")
223 .that(auditAdapter.wasEventPassed())
224 .isTrue();
225 }
226
227 @Test
228 public void testRemoveListener() throws Exception {
229 final Checker checker = new Checker();
230 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
231 final DebugAuditAdapter aa2 = new DebugAuditAdapter();
232 checker.addListener(auditAdapter);
233 checker.addListener(aa2);
234 checker.removeListener(auditAdapter);
235
236
237 getFireAuditStartedMethod().invoke(checker);
238 assertWithMessage("Checker.fireAuditStarted() doesn't call listener")
239 .that(aa2.wasCalled())
240 .isTrue();
241 assertWithMessage("Checker.fireAuditStarted() does call removed listener")
242 .that(auditAdapter.wasCalled())
243 .isFalse();
244
245 aa2.resetListener();
246 getFireAuditFinished().invoke(checker);
247 assertWithMessage("Checker.fireAuditFinished() doesn't call listener")
248 .that(aa2.wasCalled())
249 .isTrue();
250 assertWithMessage("Checker.fireAuditFinished() does call removed listener")
251 .that(auditAdapter.wasCalled())
252 .isFalse();
253
254 aa2.resetListener();
255 checker.fireFileStarted("Some File Name");
256 assertWithMessage("Checker.fireFileStarted() doesn't call listener")
257 .that(aa2.wasCalled())
258 .isTrue();
259 assertWithMessage("Checker.fireFileStarted() does call removed listener")
260 .that(auditAdapter.wasCalled())
261 .isFalse();
262
263 aa2.resetListener();
264 checker.fireFileFinished("Some File Name");
265 assertWithMessage("Checker.fireFileFinished() doesn't call listener")
266 .that(aa2.wasCalled())
267 .isTrue();
268 assertWithMessage("Checker.fireFileFinished() does call removed listener")
269 .that(auditAdapter.wasCalled())
270 .isFalse();
271
272 aa2.resetListener();
273 final SortedSet<Violation> violations = new TreeSet<>();
274 violations.add(new Violation(1, 0, "a Bundle", "message.key",
275 new Object[] {"arg"}, null, getClass(), null));
276 checker.fireErrors("Some File Name", violations);
277 assertWithMessage("Checker.fireErrors() doesn't call listener")
278 .that(aa2.wasCalled())
279 .isTrue();
280 assertWithMessage("Checker.fireErrors() does call removed listener")
281 .that(auditAdapter.wasCalled())
282 .isFalse();
283 }
284
285 @Test
286 public void testAddBeforeExecutionFileFilter() throws Exception {
287 final Checker checker = new Checker();
288 final TestBeforeExecutionFileFilter filter = new TestBeforeExecutionFileFilter();
289
290 checker.addBeforeExecutionFileFilter(filter);
291
292 filter.resetFilter();
293 checker.process(Collections.singletonList(new File("dummy.java")));
294 assertWithMessage("Checker.acceptFileStarted() doesn't call filter")
295 .that(filter.wasCalled())
296 .isTrue();
297 }
298
299 @Test
300 public void testRemoveBeforeExecutionFileFilter() throws Exception {
301 final Checker checker = new Checker();
302 final TestBeforeExecutionFileFilter filter = new TestBeforeExecutionFileFilter();
303 final TestBeforeExecutionFileFilter f2 = new TestBeforeExecutionFileFilter();
304 checker.addBeforeExecutionFileFilter(filter);
305 checker.addBeforeExecutionFileFilter(f2);
306 checker.removeBeforeExecutionFileFilter(filter);
307
308 f2.resetFilter();
309 checker.process(Collections.singletonList(new File("dummy.java")));
310 assertWithMessage("Checker.acceptFileStarted() doesn't call filter")
311 .that(f2.wasCalled())
312 .isTrue();
313 assertWithMessage("Checker.acceptFileStarted() does call removed filter")
314 .that(filter.wasCalled())
315 .isFalse();
316 }
317
318 @Test
319 public void testAddFilter() {
320 final Checker checker = new Checker();
321 final DebugFilter filter = new DebugFilter();
322
323 checker.addFilter(filter);
324
325 filter.resetFilter();
326 final SortedSet<Violation> violations = new TreeSet<>();
327 violations.add(new Violation(1, 0, "a Bundle", "message.key",
328 new Object[] {"arg"}, null, getClass(), null));
329 checker.fireErrors("Some File Name", violations);
330 assertWithMessage("Checker.fireErrors() doesn't call filter")
331 .that(filter.wasCalled())
332 .isTrue();
333 }
334
335 @Test
336 public void testRemoveFilter() {
337 final Checker checker = new Checker();
338 final DebugFilter filter = new DebugFilter();
339 final DebugFilter f2 = new DebugFilter();
340 checker.addFilter(filter);
341 checker.addFilter(f2);
342 checker.removeFilter(filter);
343
344 f2.resetFilter();
345 final SortedSet<Violation> violations = new TreeSet<>();
346 violations.add(new Violation(1, 0, "a Bundle", "message.key",
347 new Object[] {"arg"}, null, getClass(), null));
348 checker.fireErrors("Some File Name", violations);
349 assertWithMessage("Checker.fireErrors() doesn't call filter")
350 .that(f2.wasCalled())
351 .isTrue();
352 assertWithMessage("Checker.fireErrors() does call removed filter")
353 .that(filter.wasCalled())
354 .isFalse();
355 }
356
357 @Test
358 public void testFileExtensions() throws Exception {
359 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
360 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
361 checkerConfig.addProperty("cacheFile", createTempFile("junit").getPath());
362
363 final Checker checker = new Checker();
364 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
365 checker.configure(checkerConfig);
366
367 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
368 checker.addListener(auditAdapter);
369
370 final List<File> files = new ArrayList<>();
371 final File file = new File("file.pdf");
372 files.add(file);
373 final File otherFile = new File("file.java");
374 files.add(otherFile);
375 final String[] fileExtensions = {"java", "xml", "properties"};
376 checker.setFileExtensions(fileExtensions);
377 checker.setCacheFile(createTempFile("junit").getPath());
378 final int counter = checker.process(files);
379
380
381 final int numLegalFiles = 1;
382 final PropertyCacheFile cache = TestUtil.getInternalState(checker, "cacheFile");
383 assertWithMessage("There were more legal files than expected")
384 .that(counter)
385 .isEqualTo(numLegalFiles);
386 assertWithMessage("Audit was started on larger amount of files than expected")
387 .that(auditAdapter.getNumFilesStarted())
388 .isEqualTo(numLegalFiles);
389 assertWithMessage("Audit was finished on larger amount of files than expected")
390 .that(auditAdapter.getNumFilesFinished())
391 .isEqualTo(numLegalFiles);
392 assertWithMessage("Cache shout not contain any file")
393 .that(cache.get(new File("file.java").getCanonicalPath()))
394 .isNull();
395 }
396
397 @Test
398 public void testIgnoredFileExtensions() throws Exception {
399 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
400 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
401 final File tempFile = createTempFile("junit");
402 checkerConfig.addProperty("cacheFile", tempFile.getPath());
403
404 final Checker checker = new Checker();
405 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
406 checker.configure(checkerConfig);
407
408 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
409 checker.addListener(auditAdapter);
410
411 final List<File> allIgnoredFiles = new ArrayList<>();
412 final File ignoredFile = new File("file.pdf");
413 allIgnoredFiles.add(ignoredFile);
414 final String[] fileExtensions = {"java", "xml", "properties"};
415 checker.setFileExtensions(fileExtensions);
416 checker.setCacheFile(createTempFile("junit").getPath());
417 final int counter = checker.process(allIgnoredFiles);
418
419
420 final int numLegalFiles = 0;
421 assertWithMessage("There were more legal files than expected")
422 .that(counter)
423 .isEqualTo(numLegalFiles);
424 assertWithMessage("Audit was started on larger amount of files than expected")
425 .that(auditAdapter.getNumFilesStarted())
426 .isEqualTo(numLegalFiles);
427 assertWithMessage("Audit was finished on larger amount of files than expected")
428 .that(auditAdapter.getNumFilesFinished())
429 .isEqualTo(numLegalFiles);
430 }
431
432 @Test
433 public void testSetters() {
434
435 final Checker checker = new Checker();
436 checker.setBasedir("some");
437 checker.setSeverity("ignore");
438
439 final PackageObjectFactory factory = new PackageObjectFactory(
440 new HashSet<>(), Thread.currentThread().getContextClassLoader());
441 checker.setModuleFactory(factory);
442
443 checker.setFileExtensions((String[]) null);
444 checker.setFileExtensions(".java", "xml");
445
446 try {
447 checker.setCharset("UNKNOWN-CHARSET");
448 assertWithMessage("Exception is expected").fail();
449 }
450 catch (UnsupportedEncodingException exc) {
451 assertWithMessage("Error message is not expected")
452 .that(exc.getMessage())
453 .isEqualTo("unsupported charset: 'UNKNOWN-CHARSET'");
454 }
455 }
456
457 @Test
458 public void testSetSeverity() throws Exception {
459 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
460
461 verifyWithInlineXmlConfig(getPath("InputCheckerTestSeverity.java"), expected);
462 }
463
464 @Test
465 public void testNoClassLoaderNoModuleFactory() {
466 final Checker checker = new Checker();
467
468 try {
469 checker.finishLocalSetup();
470 assertWithMessage("Exception is expected").fail();
471 }
472 catch (CheckstyleException exc) {
473 assertWithMessage("Error message is not expected")
474 .that(exc.getMessage())
475 .isEqualTo("if no custom moduleFactory is set,"
476 + " moduleClassLoader must be specified");
477 }
478 }
479
480 @Test
481 public void testNoModuleFactory() throws Exception {
482 final Checker checker = new Checker();
483 final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
484
485 checker.setModuleClassLoader(classLoader);
486 checker.finishLocalSetup();
487 final Context actualCtx = TestUtil.getInternalState(checker, "childContext");
488
489 assertWithMessage("Default module factory should be created when it is not specified")
490 .that(actualCtx.get("moduleFactory"))
491 .isNotNull();
492 }
493
494 @Test
495 public void testFinishLocalSetupFullyInitialized() throws Exception {
496 final Checker checker = new Checker();
497 final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
498 checker.setModuleClassLoader(contextClassLoader);
499 final PackageObjectFactory factory = new PackageObjectFactory(
500 new HashSet<>(), contextClassLoader);
501 checker.setModuleFactory(factory);
502 checker.setBasedir("testBaseDir");
503 checker.setLocaleLanguage("it");
504 checker.setLocaleCountry("IT");
505 checker.finishLocalSetup();
506
507 final Context context = TestUtil.getInternalState(checker, "childContext");
508 final String encoding = StandardCharsets.UTF_8.name();
509 assertWithMessage("Charset was different than expected")
510 .that(context.get("charset"))
511 .isEqualTo(encoding);
512 assertWithMessage("Severity is set to unexpected value")
513 .that(context.get("severity"))
514 .isEqualTo("error");
515 assertWithMessage("Basedir is set to unexpected value")
516 .that(context.get("basedir"))
517 .isEqualTo("testBaseDir");
518
519 final Field sLocale = LocalizedMessage.class.getDeclaredField("sLocale");
520 sLocale.setAccessible(true);
521 final Locale locale = (Locale) sLocale.get(null);
522 assertWithMessage("Locale is set to unexpected value")
523 .that(locale)
524 .isEqualTo(Locale.ITALY);
525 }
526
527 @Test
528 public void testSetupChildExceptions() {
529 final Checker checker = new Checker();
530 final PackageObjectFactory factory = new PackageObjectFactory(
531 new HashSet<>(), Thread.currentThread().getContextClassLoader());
532 checker.setModuleFactory(factory);
533
534 final Configuration config = new DefaultConfiguration("java.lang.String");
535 try {
536 checker.setupChild(config);
537 assertWithMessage("Exception is expected").fail();
538 }
539 catch (CheckstyleException exc) {
540 assertWithMessage("Error message is not expected")
541 .that(exc.getMessage())
542 .isEqualTo("java.lang.String is not allowed as a child in Checker");
543 }
544 }
545
546 @Test
547 public void testSetupChildInvalidProperty() throws Exception {
548 final DefaultConfiguration checkConfig = createModuleConfig(HiddenFieldCheck.class);
549 checkConfig.addProperty("$$No such property", null);
550 try {
551 createChecker(checkConfig);
552 assertWithMessage("Exception is expected").fail();
553 }
554 catch (CheckstyleException exc) {
555 assertWithMessage("Error message is not expected")
556 .that(exc.getMessage())
557 .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker"
558 + " - cannot initialize module " + checkConfig.getName()
559 + " - Property '$$No such property'"
560 + " does not exist, please check the documentation");
561 }
562 }
563
564 @Test
565 public void testSetupChildListener() throws Exception {
566 final Checker checker = new Checker();
567 final PackageObjectFactory factory = new PackageObjectFactory(
568 new HashSet<>(), Thread.currentThread().getContextClassLoader());
569 checker.setModuleFactory(factory);
570
571 final Configuration config = new DefaultConfiguration(
572 DebugAuditAdapter.class.getCanonicalName());
573 checker.setupChild(config);
574
575 final List<AuditListener> listeners = TestUtil.getInternalState(checker, "listeners");
576 assertWithMessage("Invalid child listener class")
577 .that(listeners.get(listeners.size() - 1) instanceof DebugAuditAdapter)
578 .isTrue();
579 }
580
581 @Test
582 public void testDestroyCheckerWithWrongCacheFileNameLength() throws Exception {
583 final Checker checker = new Checker();
584 final PackageObjectFactory factory = new PackageObjectFactory(
585 new HashSet<>(), Thread.currentThread().getContextClassLoader());
586 checker.setModuleFactory(factory);
587 checker.configure(new DefaultConfiguration("default config"));
588
589
590
591 checker.setCacheFile(String.format(Locale.ENGLISH, "%0300d", 0));
592 try {
593 checker.destroy();
594 assertWithMessage("Exception did not happen").fail();
595 }
596 catch (IllegalStateException exc) {
597 assertWithMessage("Cause of exception differs from IOException")
598 .that(exc.getCause())
599 .isInstanceOf(IOException.class);
600 }
601 }
602
603
604
605
606 @Test
607 public void testCacheAndCheckWhichDoesNotImplementExternalResourceHolderInterface()
608 throws Exception {
609 assertWithMessage("ExternalResourceHolder has changed his parent")
610 .that(ExternalResourceHolder.class.isAssignableFrom(HiddenFieldCheck.class))
611 .isFalse();
612 final DefaultConfiguration checkConfig = createModuleConfig(HiddenFieldCheck.class);
613
614 final DefaultConfiguration treeWalkerConfig = createModuleConfig(TreeWalker.class);
615 treeWalkerConfig.addChild(checkConfig);
616
617 final DefaultConfiguration checkerConfig = createRootConfig(treeWalkerConfig);
618 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
619
620 final File cacheFile = createTempFile("junit");
621 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
622
623 final File tmpFile = createTempFile("file", ".java");
624
625 execute(checkerConfig, tmpFile.getPath());
626 final Properties cacheAfterFirstRun = new Properties();
627 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
628 cacheAfterFirstRun.load(reader);
629 }
630
631
632 execute(checkerConfig, tmpFile.getPath());
633 final Properties cacheAfterSecondRun = new Properties();
634 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
635 cacheAfterSecondRun.load(reader);
636 }
637
638 assertWithMessage("Cache from first run differs from second run cache")
639 .that(cacheAfterSecondRun)
640 .isEqualTo(cacheAfterFirstRun);
641 }
642
643 @Test
644 public void testWithCacheWithNoViolation() throws Exception {
645 final Checker checker = new Checker();
646 final PackageObjectFactory factory = new PackageObjectFactory(
647 new HashSet<>(), Thread.currentThread().getContextClassLoader());
648 checker.setModuleFactory(factory);
649 checker.configure(createModuleConfig(TranslationCheck.class));
650
651 final File cacheFile = createTempFile("junit");
652 checker.setCacheFile(cacheFile.getPath());
653
654 checker.setupChild(createModuleConfig(TranslationCheck.class));
655 final File tmpFile = createTempFile("file", ".java");
656 final List<File> files = new ArrayList<>(1);
657 files.add(tmpFile);
658 checker.process(files);
659
660
661 checker.destroy();
662
663 final Properties cache = new Properties();
664 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
665 cache.load(reader);
666 }
667
668
669 final int expectedNumberOfObjectsInCache = 2;
670 assertWithMessage("Cache has unexpected size")
671 .that(cache)
672 .hasSize(expectedNumberOfObjectsInCache);
673
674 final String expectedConfigHash = "D581D4A2BD482D4E1EF1F82459356BA2D8A3B" + "FC3";
675 assertWithMessage("Cache has unexpected hash")
676 .that(cache.getProperty(PropertyCacheFile.CONFIG_HASH_KEY))
677 .isEqualTo(expectedConfigHash);
678
679 assertWithMessage("Cache file has null path")
680 .that(cache.getProperty(tmpFile.getPath()))
681 .isNotNull();
682 }
683
684 @Test
685 public void testClearExistingCache() throws Exception {
686 final DefaultConfiguration checkerConfig = createRootConfig(null);
687 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
688 final File cacheFile = createTempFile("junit");
689 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
690
691 final Checker checker = new Checker();
692 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
693 checker.configure(checkerConfig);
694 checker.addListener(getBriefUtLogger());
695
696 checker.clearCache();
697
698 checker.destroy();
699
700 final Properties cacheAfterClear = new Properties();
701 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
702 cacheAfterClear.load(reader);
703 }
704
705 assertWithMessage("Cache has unexpected size")
706 .that(cacheAfterClear)
707 .hasSize(1);
708 assertWithMessage("Cache has null hash")
709 .that(cacheAfterClear.getProperty(PropertyCacheFile.CONFIG_HASH_KEY))
710 .isNotNull();
711
712 final String pathToEmptyFile = createTempFile("file", ".java").getPath();
713
714
715 execute(checkerConfig, pathToEmptyFile);
716 final Properties cacheAfterSecondRun = new Properties();
717 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
718 cacheAfterSecondRun.load(reader);
719 }
720
721 assertWithMessage("Cache has null path")
722 .that(cacheAfterSecondRun.getProperty(pathToEmptyFile))
723 .isNotNull();
724 final String cacheHash = cacheAfterSecondRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY);
725 assertWithMessage("Cash have changed it hash")
726 .that(cacheHash)
727 .isEqualTo(cacheAfterClear.getProperty(PropertyCacheFile.CONFIG_HASH_KEY));
728 final int expectedNumberOfObjectsInCacheAfterSecondRun = 2;
729 assertWithMessage("Cache has changed number of items")
730 .that(cacheAfterSecondRun)
731 .hasSize(expectedNumberOfObjectsInCacheAfterSecondRun);
732 }
733
734 @Test
735 public void testClearCache() throws Exception {
736 final DefaultConfiguration violationCheck =
737 createModuleConfig(DummyFileSetViolationCheck.class);
738 final DefaultConfiguration checkerConfig = new DefaultConfiguration("myConfig");
739 checkerConfig.addProperty("charset", "UTF-8");
740 final File cacheFile = createTempFile("junit");
741 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
742 checkerConfig.addChild(violationCheck);
743 final Checker checker = new Checker();
744 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
745 checker.configure(checkerConfig);
746 checker.addListener(getBriefUtLogger());
747
748 checker.process(Collections.singletonList(new File("dummy.java")));
749 checker.clearCache();
750
751 final PropertyCacheFile cache = TestUtil.getInternalState(checker, "cacheFile");
752 cache.persist();
753
754 final Properties cacheAfterClear = new Properties();
755 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
756 cacheAfterClear.load(reader);
757 }
758
759 assertWithMessage("Cache has unexpected size")
760 .that(cacheAfterClear)
761 .hasSize(1);
762 }
763
764 @Test
765 public void setFileExtension() {
766 final Checker checker = new Checker();
767 checker.setFileExtensions(".test1", "test2");
768 final String[] actual = TestUtil.getInternalState(checker, "fileExtensions");
769 assertWithMessage("Extensions are not expected")
770 .that(actual)
771 .isEqualTo(new String[] {".test1", ".test2"});
772 }
773
774 @Test
775 public void testClearCacheWhenCacheFileIsNotSet() {
776
777
778 final Checker checker = new Checker();
779 checker.clearCache();
780 final PropertyCacheFile cache = TestUtil.getInternalState(checker, "cacheFile");
781 assertWithMessage("If cache file is not set the cache should default to null")
782 .that(cache)
783 .isNull();
784 }
785
786
787
788
789
790
791
792
793 @Test
794 public void testCatchErrorInProcessFilesMethod() throws Exception {
795
796 final String errorMessage = "Java Virtual Machine is broken"
797 + " or has run out of resources necessary for it to continue operating.";
798 final Error expectedError = new IOError(new InternalError(errorMessage));
799
800 final File mock = new File("testFile") {
801 @Serial
802 private static final long serialVersionUID = 1L;
803
804
805
806
807
808
809
810
811 @Override
812 public long lastModified() {
813 throw expectedError;
814 }
815 };
816
817 final Checker checker = new Checker();
818 final List<File> filesToProcess = new ArrayList<>();
819 filesToProcess.add(mock);
820 try {
821 checker.process(filesToProcess);
822 assertWithMessage("IOError is expected!").fail();
823 }
824
825 catch (Error error) {
826 assertWithMessage("Error cause differs from IOError")
827 .that(error.getCause())
828 .isInstanceOf(IOError.class);
829 assertWithMessage("Error cause is not InternalError")
830 .that(error.getCause().getCause())
831 .isInstanceOf(InternalError.class);
832 assertWithMessage("Error message is not expected")
833 .that(error)
834 .hasCauseThat()
835 .hasCauseThat()
836 .hasMessageThat()
837 .isEqualTo(errorMessage);
838 }
839 }
840
841
842
843
844
845
846
847
848 @Test
849 public void testCatchErrorWithNoFileName() throws Exception {
850
851 final String errorMessage = "Java Virtual Machine is broken"
852 + " or has run out of resources necessary for it to continue operating.";
853 final Error expectedError = new IOError(new InternalError(errorMessage));
854
855 final File mock = new File("testFile") {
856 @Serial
857 private static final long serialVersionUID = 1L;
858
859
860
861
862
863
864
865 @Override
866 public long lastModified() {
867 throw expectedError;
868 }
869
870 @Override
871 public String getAbsolutePath() {
872 return null;
873 }
874 };
875
876 final Checker checker = new Checker();
877 final List<File> filesToProcess = new ArrayList<>();
878 filesToProcess.add(mock);
879 try {
880 checker.process(filesToProcess);
881 assertWithMessage("IOError is expected!").fail();
882 }
883
884 catch (Error error) {
885 assertWithMessage("Error cause differs from IOError")
886 .that(error)
887 .hasCauseThat()
888 .isInstanceOf(IOError.class);
889 assertWithMessage("Error cause is not InternalError")
890 .that(error)
891 .hasCauseThat()
892 .hasCauseThat()
893 .isInstanceOf(InternalError.class);
894 assertWithMessage("Error message is not expected")
895 .that(error)
896 .hasCauseThat()
897 .hasCauseThat()
898 .hasMessageThat()
899 .isEqualTo(errorMessage);
900 }
901 }
902
903
904
905
906 @Test
907 public void testCacheAndFilterWhichDoesNotImplementExternalResourceHolderInterface()
908 throws Exception {
909 assertWithMessage("ExternalResourceHolder has changed its parent")
910 .that(ExternalResourceHolder.class.isAssignableFrom(DummyFilter.class))
911 .isFalse();
912 final DefaultConfiguration filterConfig = createModuleConfig(DummyFilter.class);
913
914 final DefaultConfiguration checkerConfig = createRootConfig(filterConfig);
915 final File cacheFile = createTempFile("junit");
916 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
917
918 final String pathToEmptyFile = createTempFile("file", ".java").getPath();
919
920 execute(checkerConfig, pathToEmptyFile);
921 final Properties cacheAfterFirstRun = new Properties();
922 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
923 cacheAfterFirstRun.load(reader);
924 }
925
926
927 execute(checkerConfig, pathToEmptyFile);
928 final Properties cacheAfterSecondRun = new Properties();
929 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
930 cacheAfterSecondRun.load(reader);
931 }
932
933 final String cacheFilePath = cacheAfterSecondRun.getProperty(pathToEmptyFile);
934 assertWithMessage("Cache file has changed its path")
935 .that(cacheFilePath)
936 .isEqualTo(cacheAfterFirstRun.getProperty(pathToEmptyFile));
937 final String cacheHash = cacheAfterSecondRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY);
938 assertWithMessage("Cache has changed its hash")
939 .that(cacheHash)
940 .isEqualTo(cacheAfterFirstRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY));
941 final int expectedNumberOfObjectsInCache = 2;
942 assertWithMessage("Number of items in cache differs from expected")
943 .that(cacheAfterFirstRun)
944 .hasSize(expectedNumberOfObjectsInCache);
945 assertWithMessage("Number of items in cache differs from expected")
946 .that(cacheAfterSecondRun)
947 .hasSize(expectedNumberOfObjectsInCache);
948 }
949
950
951
952
953
954 @Test
955 public void testCacheAndCheckWhichAddsNewResourceLocationButKeepsSameCheckerInstance()
956 throws Exception {
957
958
959
960
961
962
963 final DynamicalResourceHolderCheck check = new DynamicalResourceHolderCheck();
964 final String firstExternalResourceLocation = getPath("InputCheckerImportControlOne.xml");
965 final String firstExternalResourceKey = PropertyCacheFile.EXTERNAL_RESOURCE_KEY_PREFIX
966 + firstExternalResourceLocation;
967 check.setFirstExternalResourceLocation(firstExternalResourceLocation);
968
969 final DefaultConfiguration checkerConfig = createRootConfig(null);
970 final File cacheFile = createTempFile("junit");
971 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
972
973 final Checker checker = new Checker();
974 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
975 checker.addFileSetCheck(check);
976 checker.addFilter(new DummyFilterSet());
977 checker.configure(checkerConfig);
978 checker.addListener(getBriefUtLogger());
979
980 final String pathToEmptyFile = createTempFile("file", ".java").getPath();
981
982 execute(checker, pathToEmptyFile);
983 final Properties cacheAfterFirstRun = new Properties();
984 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
985 cacheAfterFirstRun.load(reader);
986 }
987
988 final int expectedNumberOfObjectsInCacheAfterFirstRun = 4;
989 assertWithMessage("Number of items in cache differs from expected")
990 .that(cacheAfterFirstRun)
991 .hasSize(expectedNumberOfObjectsInCacheAfterFirstRun);
992
993
994 final String secondExternalResourceLocation = "InputCheckerImportControlTwo.xml";
995 final String secondExternalResourceKey = PropertyCacheFile.EXTERNAL_RESOURCE_KEY_PREFIX
996 + secondExternalResourceLocation;
997 check.setSecondExternalResourceLocation(secondExternalResourceLocation);
998
999 checker.addFileSetCheck(check);
1000 checker.configure(checkerConfig);
1001
1002 execute(checker, pathToEmptyFile);
1003 final Properties cacheAfterSecondRun = new Properties();
1004 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1005 cacheAfterSecondRun.load(reader);
1006 }
1007
1008 final String cacheFilePath = cacheAfterSecondRun.getProperty(pathToEmptyFile);
1009 assertWithMessage("Cache file has changed its path")
1010 .that(cacheFilePath)
1011 .isEqualTo(cacheAfterFirstRun.getProperty(pathToEmptyFile));
1012 final String cacheHash = cacheAfterSecondRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY);
1013 assertWithMessage("Cache has changed its hash")
1014 .that(cacheHash)
1015 .isEqualTo(cacheAfterFirstRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY));
1016 final String resourceKey = cacheAfterSecondRun.getProperty(firstExternalResourceKey);
1017 assertWithMessage("Cache has changed its resource key")
1018 .that(resourceKey)
1019 .isEqualTo(cacheAfterFirstRun.getProperty(firstExternalResourceKey));
1020 assertWithMessage("Cache has null as a resource key")
1021 .that(cacheAfterFirstRun.getProperty(firstExternalResourceKey))
1022 .isNotNull();
1023 final int expectedNumberOfObjectsInCacheAfterSecondRun = 4;
1024 assertWithMessage("Number of items in cache differs from expected")
1025 .that(cacheAfterSecondRun)
1026 .hasSize(expectedNumberOfObjectsInCacheAfterSecondRun);
1027 assertWithMessage("Cache has not null as a resource key")
1028 .that(cacheAfterFirstRun.getProperty(secondExternalResourceKey))
1029 .isNull();
1030 assertWithMessage("Cache has null as a resource key")
1031 .that(cacheAfterSecondRun.getProperty(secondExternalResourceKey))
1032 .isNotNull();
1033 }
1034
1035 @Test
1036 public void testClearLazyLoadCacheInDetailAST() throws Exception {
1037
1038 final String filePath = getPath("InputCheckerClearDetailAstLazyLoadCache.java");
1039
1040 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
1041 verifyWithInlineConfigParser(filePath, expected);
1042 }
1043
1044 @Test
1045 public void testCacheOnViolationSuppression() throws Exception {
1046 final File cacheFile = createTempFile("junit");
1047 final DefaultConfiguration violationCheck =
1048 createModuleConfig(DummyFileSetViolationCheck.class);
1049
1050 final DefaultConfiguration filterConfig = createModuleConfig(SuppressionFilter.class);
1051 filterConfig.addProperty("file", getPath("InputCheckerSuppressAll.xml"));
1052
1053 final DefaultConfiguration checkerConfig = createRootConfig(violationCheck);
1054 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1055 checkerConfig.addChild(filterConfig);
1056
1057 final String fileViolationPath = createTempFile("ViolationFile", ".java").getPath();
1058
1059 execute(checkerConfig, fileViolationPath);
1060
1061 try (InputStream input = Files.newInputStream(cacheFile.toPath())) {
1062 final Properties details = new Properties();
1063 details.load(input);
1064
1065 assertWithMessage("suppressed violation file saved in cache")
1066 .that(details.getProperty(fileViolationPath))
1067 .isNotNull();
1068 }
1069 }
1070
1071 @Test
1072 public void testHaltOnException() throws Exception {
1073 final DefaultConfiguration checkConfig =
1074 createModuleConfig(CheckWhichThrowsError.class);
1075 final String filePath = getPath("InputChecker.java");
1076 try {
1077 execute(checkConfig, filePath);
1078 assertWithMessage("Exception is expected").fail();
1079 }
1080 catch (CheckstyleException exc) {
1081 assertWithMessage("Error message is not expected")
1082 .that(exc.getMessage())
1083 .isEqualTo("Exception was thrown while processing " + filePath);
1084 }
1085 }
1086
1087 @Test
1088 public void testExceptionWithCache() throws Exception {
1089 final File cacheFile = createTempFile("junit");
1090
1091 final DefaultConfiguration checkConfig =
1092 createModuleConfig(CheckWhichThrowsError.class);
1093
1094 final DefaultConfiguration treewalkerConfig =
1095 createModuleConfig(TreeWalker.class);
1096 treewalkerConfig.addChild(checkConfig);
1097
1098 final DefaultConfiguration checkerConfig = createRootConfig(treewalkerConfig);
1099 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
1100 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1101 checkerConfig.addChild(treewalkerConfig);
1102
1103 final Checker checker = createChecker(checkerConfig);
1104
1105 final String filePath = getPath("InputChecker.java");
1106 try {
1107 checker.process(Collections.singletonList(new File(filePath)));
1108 assertWithMessage("Exception is expected").fail();
1109 }
1110 catch (CheckstyleException exc) {
1111 assertWithMessage("Error message is not expected")
1112 .that(exc.getMessage())
1113 .isEqualTo("Exception was thrown while processing " + filePath);
1114
1115
1116 checker.destroy();
1117
1118 final Properties cache = new Properties();
1119 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1120 cache.load(reader);
1121 }
1122
1123 assertWithMessage("Cache has unexpected size")
1124 .that(cache)
1125 .hasSize(1);
1126 assertWithMessage("testFile is not in cache")
1127 .that(cache.getProperty(filePath))
1128 .isNull();
1129 }
1130 }
1131
1132
1133
1134
1135
1136
1137
1138
1139 @Test
1140 public void testCatchErrorWithCache() throws Exception {
1141 final File cacheFile = createTempFile("junit");
1142
1143 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
1144 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
1145 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1146
1147 final String errorMessage = "Java Virtual Machine is broken"
1148 + " or has run out of resources necessary for it to continue operating.";
1149 final Error expectedError = new IOError(new InternalError(errorMessage));
1150
1151 final File mock = new File("testFile") {
1152 @Serial
1153 private static final long serialVersionUID = 1L;
1154 @Override
1155 public String getAbsolutePath() {
1156 return "testFile";
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166 @Override
1167 public File getAbsoluteFile() {
1168 throw expectedError;
1169 }
1170 };
1171
1172 final Checker checker = new Checker();
1173 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1174 checker.configure(checkerConfig);
1175 final List<File> filesToProcess = new ArrayList<>();
1176 filesToProcess.add(mock);
1177 try {
1178 checker.process(filesToProcess);
1179 assertWithMessage("IOError is expected!").fail();
1180 }
1181
1182 catch (Error error) {
1183 assertWithMessage("Error cause differs from IOError")
1184 .that(error.getCause())
1185 .isInstanceOf(IOError.class);
1186 assertWithMessage("Error message is not expected")
1187 .that(error)
1188 .hasCauseThat()
1189 .hasCauseThat()
1190 .hasMessageThat()
1191 .isEqualTo(errorMessage);
1192
1193
1194 checker.destroy();
1195
1196 final Properties cache = new Properties();
1197 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1198 cache.load(reader);
1199 }
1200
1201 assertWithMessage("Cache has unexpected size")
1202 .that(cache)
1203 .hasSize(1);
1204 assertWithMessage("testFile is not in cache")
1205 .that(cache.getProperty("testFile"))
1206 .isNull();
1207 }
1208 }
1209
1210
1211
1212
1213
1214
1215
1216
1217 @Test
1218 public void testCatchErrorWithCacheWithNoFileName() throws Exception {
1219 final File cacheFile = createTempFile("junit");
1220
1221 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
1222 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
1223 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1224
1225 final String errorMessage = "Java Virtual Machine is broken"
1226 + " or has run out of resources necessary for it to continue operating.";
1227 final Error expectedError = new IOError(new InternalError(errorMessage));
1228
1229 final File mock = new File("testFile") {
1230 @Serial
1231 private static final long serialVersionUID = 1L;
1232
1233
1234
1235
1236
1237
1238
1239
1240 @Override
1241 public String getAbsolutePath() {
1242 throw expectedError;
1243 }
1244 };
1245
1246 final Checker checker = new Checker();
1247 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1248 checker.configure(checkerConfig);
1249 final List<File> filesToProcess = new ArrayList<>();
1250 filesToProcess.add(mock);
1251 try {
1252 checker.process(filesToProcess);
1253 assertWithMessage("IOError is expected!").fail();
1254 }
1255
1256 catch (Error error) {
1257 assertWithMessage("Error cause differs from IOError")
1258 .that(error)
1259 .hasCauseThat()
1260 .isInstanceOf(IOError.class);
1261 assertWithMessage("Error message is not expected")
1262 .that(error)
1263 .hasCauseThat()
1264 .hasCauseThat()
1265 .hasMessageThat()
1266 .isEqualTo(errorMessage);
1267
1268
1269 checker.destroy();
1270
1271 final Properties cache = new Properties();
1272 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1273 cache.load(reader);
1274 }
1275
1276 assertWithMessage("Cache has unexpected size")
1277 .that(cache)
1278 .hasSize(1);
1279 }
1280 }
1281
1282
1283
1284
1285
1286
1287
1288
1289 @Test
1290 public void testExceptionWithNoFileName() {
1291 final String errorMessage = "Security Exception";
1292 final RuntimeException expectedError = new SecurityException(errorMessage);
1293
1294 final File mock = new File("testFile") {
1295 @Serial
1296 private static final long serialVersionUID = 1L;
1297
1298
1299
1300
1301
1302
1303
1304
1305 @Override
1306 public String getAbsolutePath() {
1307 throw expectedError;
1308 }
1309 };
1310
1311 final Checker checker = new Checker();
1312 final List<File> filesToProcess = new ArrayList<>();
1313 filesToProcess.add(mock);
1314 try {
1315 checker.process(filesToProcess);
1316 assertWithMessage("SecurityException is expected!").fail();
1317 }
1318 catch (CheckstyleException exc) {
1319 assertWithMessage("Error cause differs from SecurityException")
1320 .that(exc)
1321 .hasCauseThat()
1322 .isInstanceOf(SecurityException.class);
1323 assertWithMessage("Error message is not expected")
1324 .that(exc)
1325 .hasCauseThat()
1326 .hasMessageThat()
1327 .isEqualTo(errorMessage);
1328 }
1329 }
1330
1331
1332
1333
1334
1335
1336
1337
1338 @Test
1339 public void testExceptionWithCacheAndNoFileName() throws Exception {
1340 final File cacheFile = createTempFile("junit");
1341
1342 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
1343 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
1344 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1345
1346 final String errorMessage = "Security Exception";
1347 final RuntimeException expectedError = new SecurityException(errorMessage);
1348
1349 final File mock = new File("testFile") {
1350 @Serial
1351 private static final long serialVersionUID = 1L;
1352
1353
1354
1355
1356
1357
1358
1359
1360 @Override
1361 public String getAbsolutePath() {
1362 throw expectedError;
1363 }
1364 };
1365
1366 final Checker checker = new Checker();
1367 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1368 checker.configure(checkerConfig);
1369 final List<File> filesToProcess = new ArrayList<>();
1370 filesToProcess.add(mock);
1371 try {
1372 checker.process(filesToProcess);
1373 assertWithMessage("SecurityException is expected!").fail();
1374 }
1375 catch (CheckstyleException exc) {
1376 assertWithMessage("Error cause differs from SecurityException")
1377 .that(exc)
1378 .hasCauseThat()
1379 .isInstanceOf(SecurityException.class);
1380 assertWithMessage("Error message is not expected")
1381 .that(exc)
1382 .hasCauseThat()
1383 .hasMessageThat()
1384 .isEqualTo(errorMessage);
1385
1386
1387 checker.destroy();
1388
1389 final Properties cache = new Properties();
1390 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1391 cache.load(reader);
1392 }
1393
1394 assertWithMessage("Cache has unexpected size")
1395 .that(cache)
1396 .hasSize(1);
1397 }
1398 }
1399
1400 @Test
1401 public void testHaltOnExceptionOff() throws Exception {
1402 final String filePath = getPath("InputChecker.java");
1403 final String[] expected = {
1404 "1: " + getCheckMessage(EXCEPTION_MSG, "java.lang.IndexOutOfBoundsException: test"),
1405 };
1406
1407 verifyWithInlineXmlConfig(filePath, expected);
1408 }
1409
1410 @Test
1411 public void testTabViolationDefault() throws Exception {
1412 final String[] expected = {
1413 "17:17: violation",
1414 "21:49: violation",
1415 };
1416 verifyWithInlineConfigParser(getPath("InputCheckerTabCharacter.java"),
1417 expected);
1418 }
1419
1420 @Test
1421 public void testTabViolationCustomWidth() throws Exception {
1422 final String[] expected = {
1423 "18:17: violation",
1424 "22:37: violation",
1425 };
1426
1427 verifyWithInlineXmlConfig(getPath("InputCheckerTabCharacterCustomWidth.java"), expected);
1428 }
1429
1430 @Test
1431 public void testCheckerProcessCallAllNeededMethodsOfFileSets() throws Exception {
1432 final DummyFileSet fileSet = new DummyFileSet();
1433 final Checker checker = new Checker();
1434 checker.addFileSetCheck(fileSet);
1435 checker.process(Collections.singletonList(new File("dummy.java")));
1436 final List<String> expected =
1437 Arrays.asList("beginProcessing", "finishProcessing", "destroy");
1438 assertWithMessage("Method calls were not expected")
1439 .that(fileSet.getMethodCalls())
1440 .isEqualTo(expected);
1441 }
1442
1443 @Test
1444 public void testSetFileSetCheckSetsMessageDispatcher() {
1445 final DummyFileSet fileSet = new DummyFileSet();
1446 final Checker checker = new Checker();
1447 checker.addFileSetCheck(fileSet);
1448 assertWithMessage("Message dispatcher was not expected")
1449 .that(fileSet.getInternalMessageDispatcher())
1450 .isEqualTo(checker);
1451 }
1452
1453 @Test
1454 public void testAddAuditListenerAsChild() throws Exception {
1455 final Checker checker = new Checker();
1456 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
1457 final PackageObjectFactory factory = new PackageObjectFactory(
1458 new HashSet<>(), Thread.currentThread().getContextClassLoader()) {
1459 @Override
1460 public Object createModule(String name) throws CheckstyleException {
1461 Object adapter = auditAdapter;
1462 if (!name.equals(DebugAuditAdapter.class.getName())) {
1463 adapter = super.createModule(name);
1464 }
1465 return adapter;
1466 }
1467 };
1468 checker.setModuleFactory(factory);
1469 checker.setupChild(createModuleConfig(DebugAuditAdapter.class));
1470
1471 checker.process(Collections.singletonList(new File("dummy.java")));
1472 assertWithMessage("Checker.fireAuditStarted() doesn't call listener")
1473 .that(auditAdapter.wasCalled())
1474 .isTrue();
1475 }
1476
1477 @Test
1478 public void testAddBeforeExecutionFileFilterAsChild() throws Exception {
1479 final Checker checker = new Checker();
1480 final TestBeforeExecutionFileFilter fileFilter = new TestBeforeExecutionFileFilter();
1481 final PackageObjectFactory factory = new PackageObjectFactory(
1482 new HashSet<>(), Thread.currentThread().getContextClassLoader()) {
1483 @Override
1484 public Object createModule(String name) throws CheckstyleException {
1485 Object filter = fileFilter;
1486 if (!name.equals(TestBeforeExecutionFileFilter.class.getName())) {
1487 filter = super.createModule(name);
1488 }
1489 return filter;
1490 }
1491 };
1492 checker.setModuleFactory(factory);
1493 checker.setupChild(createModuleConfig(TestBeforeExecutionFileFilter.class));
1494 checker.process(Collections.singletonList(new File("dummy.java")));
1495 assertWithMessage("Checker.acceptFileStarted() doesn't call listener")
1496 .that(fileFilter.wasCalled())
1497 .isTrue();
1498 }
1499
1500 @Test
1501 public void testFileSetCheckInitWhenAddedAsChild() throws Exception {
1502 final Checker checker = new Checker();
1503 final DummyFileSet fileSet = new DummyFileSet();
1504 final PackageObjectFactory factory = new PackageObjectFactory(
1505 new HashSet<>(), Thread.currentThread().getContextClassLoader()) {
1506 @Override
1507 public Object createModule(String name) throws CheckstyleException {
1508 Object check = fileSet;
1509 if (!name.equals(DummyFileSet.class.getName())) {
1510 check = super.createModule(name);
1511 }
1512 return check;
1513 }
1514 };
1515 checker.setModuleFactory(factory);
1516 checker.finishLocalSetup();
1517 checker.setupChild(createModuleConfig(DummyFileSet.class));
1518 assertWithMessage("FileSetCheck.init() wasn't called")
1519 .that(fileSet.isInitCalled())
1520 .isTrue();
1521 }
1522
1523
1524 @Test
1525 public void testDefaultLoggerClosesItStreams() throws Exception {
1526 final Checker checker = new Checker();
1527 try (CloseAndFlushTestByteArrayOutputStream testInfoOutputStream =
1528 new CloseAndFlushTestByteArrayOutputStream();
1529 CloseAndFlushTestByteArrayOutputStream testErrorOutputStream =
1530 new CloseAndFlushTestByteArrayOutputStream()) {
1531 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1532 checker.addListener(new DefaultLogger(testInfoOutputStream,
1533 OutputStreamOptions.CLOSE, testErrorOutputStream, OutputStreamOptions.CLOSE));
1534
1535 final File tmpFile = createTempFile("file", ".java");
1536
1537 execute(checker, tmpFile.getPath());
1538
1539 assertWithMessage("Output stream close count")
1540 .that(testInfoOutputStream.getCloseCount())
1541 .isEqualTo(1);
1542 assertWithMessage("Output stream flush count")
1543 .that(testInfoOutputStream.getFlushCount())
1544 .isEqualTo(TestUtil.adjustFlushCountForOutputStreamClose(3));
1545 assertWithMessage("Error stream close count")
1546 .that(testErrorOutputStream.getCloseCount())
1547 .isEqualTo(1);
1548 assertWithMessage("Error stream flush count")
1549 .that(testErrorOutputStream.getFlushCount())
1550 .isEqualTo(TestUtil.adjustFlushCountForOutputStreamClose(1));
1551 }
1552 }
1553
1554
1555 @Test
1556 public void testXmlLoggerClosesItStreams() throws Exception {
1557 final Checker checker = new Checker();
1558 try (CloseAndFlushTestByteArrayOutputStream testInfoOutputStream =
1559 new CloseAndFlushTestByteArrayOutputStream()) {
1560 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1561 checker.addListener(new XMLLogger(testInfoOutputStream, OutputStreamOptions.CLOSE));
1562
1563 final File tmpFile = createTempFile("file", ".java");
1564
1565 execute(checker, tmpFile.getPath(), tmpFile.getPath());
1566
1567 assertWithMessage("Output stream close count")
1568 .that(testInfoOutputStream.getCloseCount())
1569 .isEqualTo(1);
1570 assertWithMessage("Output stream flush count")
1571 .that(testInfoOutputStream.getFlushCount())
1572 .isEqualTo(TestUtil.adjustFlushCountForOutputStreamClose(0));
1573 }
1574 }
1575
1576 @Test
1577 public void testDuplicatedModule() throws Exception {
1578
1579 final DefaultConfiguration moduleConfig1 =
1580 createModuleConfig(NewlineAtEndOfFileCheck.class);
1581 final DefaultConfiguration moduleConfig2 =
1582 createModuleConfig(NewlineAtEndOfFileCheck.class);
1583 moduleConfig2.addProperty("id", "ModuleId");
1584 final DefaultConfiguration root = new DefaultConfiguration("root");
1585 root.addChild(moduleConfig1);
1586 root.addChild(moduleConfig2);
1587 final Checker checker = new Checker();
1588 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1589 checker.configure(root);
1590
1591
1592 final ByteArrayOutputStream out = TestUtil.getInternalState(this, "stream");
1593 final DefaultLogger logger = new DefaultLogger(out, OutputStreamOptions.CLOSE, out,
1594 OutputStreamOptions.NONE, new AuditEventDefaultFormatter());
1595 checker.addListener(logger);
1596
1597 final File tempFile = createTempFile("file", ".java");
1598 try (BufferedWriter bufferedWriter = Files.newBufferedWriter(tempFile.toPath())) {
1599 bufferedWriter.write(';');
1600 }
1601 final String path = tempFile.getPath();
1602 final String violationMessage =
1603 getCheckMessage(NewlineAtEndOfFileCheck.class, MSG_KEY_NO_NEWLINE_EOF);
1604 final String[] expected = {
1605 "1: " + violationMessage + " [NewlineAtEndOfFile]",
1606 "1: " + violationMessage + " [ModuleId]",
1607 };
1608
1609
1610 out.flush();
1611 final int errs = checker.process(Collections.singletonList(new File(path)));
1612 try (ByteArrayInputStream inputStream =
1613 new ByteArrayInputStream(out.toByteArray());
1614 LineNumberReader lnr = new LineNumberReader(
1615 new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
1616
1617 final List<String> actual = lnr.lines()
1618 .filter(line -> !getCheckMessage(AUDIT_STARTED_MESSAGE).equals(line))
1619 .filter(line -> !getCheckMessage(AUDIT_FINISHED_MESSAGE).equals(line))
1620 .limit(expected.length)
1621 .sorted()
1622 .toList();
1623 Arrays.sort(expected);
1624
1625 for (int i = 0; i < expected.length; i++) {
1626 final String expectedResult = "[ERROR] " + path + ":" + expected[i];
1627 assertWithMessage("error message " + i)
1628 .that(actual.get(i))
1629 .isEqualTo(expectedResult);
1630 }
1631
1632 assertWithMessage("unexpected output: " + lnr.readLine())
1633 .that(errs)
1634 .isEqualTo(expected.length);
1635 }
1636
1637 checker.destroy();
1638 }
1639
1640 @Test
1641 public void testCachedFile() throws Exception {
1642 final Checker checker = createChecker(createModuleConfig(TranslationCheck.class));
1643 final OutputStream infoStream = new ByteArrayOutputStream();
1644 final OutputStream errorStream = new ByteArrayOutputStream();
1645 final DefaultLoggerWithCounter loggerWithCounter =
1646 new DefaultLoggerWithCounter(infoStream, OutputStreamOptions.CLOSE,
1647 errorStream, OutputStreamOptions.CLOSE);
1648 checker.addListener(loggerWithCounter);
1649 final File cacheFile = createTempFile("cacheFile", ".txt");
1650 checker.setCacheFile(cacheFile.getAbsolutePath());
1651
1652 final File testFile = createTempFile("testFile", ".java");
1653 final List<File> files = List.of(testFile, testFile);
1654 checker.process(files);
1655
1656 assertWithMessage("Cached file should not be processed twice")
1657 .that(loggerWithCounter.fileStartedCount)
1658 .isEqualTo(1);
1659
1660 checker.destroy();
1661 }
1662
1663 @Test
1664 public void testUnmappableCharacters() throws Exception {
1665 final String[] expected = {
1666 "14: " + getCheckMessage(LineLengthCheck.class, MSG_KEY, 80, 225),
1667 };
1668
1669 verifyWithInlineXmlConfig(getPath("InputCheckerTestCharset.java"),
1670 expected);
1671 }
1672
1673
1674
1675
1676
1677
1678
1679
1680 @SuppressForbidden
1681 @Test
1682 public void testViolationMessageOnIoException() throws Exception {
1683 final DefaultConfiguration checkConfig =
1684 createModuleConfig(CheckWhichThrowsError.class);
1685
1686 final DefaultConfiguration treeWalkerConfig = createModuleConfig(TreeWalker.class);
1687 treeWalkerConfig.addChild(checkConfig);
1688
1689 final DefaultConfiguration checkerConfig = createRootConfig(treeWalkerConfig);
1690 checkerConfig.addChild(treeWalkerConfig);
1691
1692 checkerConfig.addProperty("haltOnException", "false");
1693 final File file = new File("InputNonChecker.java");
1694 final String filePath = file.getAbsolutePath();
1695 final String[] expected = {
1696 "1: " + getCheckMessage(EXCEPTION_MSG, filePath
1697 + " (No such file or directory)"),
1698 };
1699
1700 verify(checkerConfig, filePath, expected);
1701 }
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711 @Test
1712 public void testRelativizedFileExclusion() throws Exception {
1713 final DefaultConfiguration newLineAtEndOfFileConfig =
1714 createModuleConfig(NewlineAtEndOfFileCheck.class);
1715
1716 final DefaultConfiguration beforeExecutionExclusionFileFilterConfig =
1717 createModuleConfig(BeforeExecutionExclusionFileFilter.class);
1718
1719 beforeExecutionExclusionFileFilterConfig.addProperty("fileNamePattern",
1720 "^(?!InputCheckerTestExcludeRelativizedFile.*\\.java).*");
1721
1722 final DefaultConfiguration checkerConfig = createRootConfig(null);
1723 checkerConfig.addChild(newLineAtEndOfFileConfig);
1724 checkerConfig.addChild(beforeExecutionExclusionFileFilterConfig);
1725
1726
1727 checkerConfig.addProperty("basedir",
1728 temporaryFolder.getPath());
1729
1730 final String violationMessage =
1731 getCheckMessage(NewlineAtEndOfFileCheck.class, MSG_KEY_NO_NEWLINE_EOF);
1732
1733 final String[] expected = {
1734 "1: " + violationMessage,
1735 };
1736
1737 final File tempFile = createTempFile("InputCheckerTestExcludeRelativizedFile", ".java");
1738 try (BufferedWriter bufferedWriter = Files.newBufferedWriter(tempFile.toPath())) {
1739 bufferedWriter.write(';');
1740 }
1741
1742 final File[] processedFiles = {tempFile};
1743
1744 verify(createChecker(checkerConfig), processedFiles,
1745 tempFile.getName(), expected);
1746 }
1747
1748 public static class DefaultLoggerWithCounter extends DefaultLogger {
1749
1750 private int fileStartedCount;
1751
1752 public DefaultLoggerWithCounter(OutputStream infoStream,
1753 OutputStreamOptions infoStreamOptions,
1754 OutputStream errorStream,
1755 OutputStreamOptions errorStreamOptions) {
1756 super(infoStream, infoStreamOptions, errorStream, errorStreamOptions);
1757 }
1758
1759 @Override
1760 public void fileStarted(AuditEvent event) {
1761 fileStartedCount++;
1762 }
1763 }
1764
1765 public static class DummyFilter implements Filter {
1766
1767 @Override
1768 public boolean accept(AuditEvent event) {
1769 return false;
1770 }
1771
1772 }
1773
1774 public static class DummyFileSetViolationCheck extends AbstractFileSetCheck
1775 implements ExternalResourceHolder {
1776
1777 @Override
1778 protected void processFiltered(File file, FileText fileText) {
1779 log(1, "test");
1780 }
1781
1782 @Override
1783 public Set<String> getExternalResourceLocations() {
1784 final Set<String> externalResourceLocation = new HashSet<>(1);
1785 externalResourceLocation.add("non_existent_external_resource.xml");
1786 return externalResourceLocation;
1787 }
1788
1789 }
1790
1791 public static class DummyFilterSet extends FilterSet implements ExternalResourceHolder {
1792
1793 @Override
1794 public Set<String> getExternalResourceLocations() {
1795 final Set<String> strings = new HashSet<>();
1796 strings.add("test");
1797 return strings;
1798 }
1799
1800 }
1801
1802 public static final class DynamicalResourceHolderCheck extends AbstractFileSetCheck
1803 implements ExternalResourceHolder {
1804
1805 private String firstExternalResourceLocation;
1806 private String secondExternalResourceLocation;
1807
1808 public void setFirstExternalResourceLocation(String firstExternalResourceLocation) {
1809 this.firstExternalResourceLocation = firstExternalResourceLocation;
1810 }
1811
1812 public void setSecondExternalResourceLocation(String secondExternalResourceLocation) {
1813 this.secondExternalResourceLocation = secondExternalResourceLocation;
1814 }
1815
1816 @Override
1817 protected void processFiltered(File file, FileText fileText) {
1818
1819 }
1820
1821 @Override
1822 public Set<String> getExternalResourceLocations() {
1823 final Set<String> locations = new HashSet<>();
1824 locations.add(firstExternalResourceLocation);
1825
1826 if (secondExternalResourceLocation != null) {
1827 locations.add(secondExternalResourceLocation);
1828 }
1829 return locations;
1830 }
1831
1832 }
1833
1834 public static class CheckWhichDoesNotRequireCommentNodes extends AbstractCheck {
1835
1836
1837 private static final int METHOD_DEF_CHILD_COUNT = 7;
1838
1839 @Override
1840 public int[] getDefaultTokens() {
1841 return new int[] {TokenTypes.METHOD_DEF};
1842 }
1843
1844 @Override
1845 public int[] getAcceptableTokens() {
1846 return new int[] {TokenTypes.METHOD_DEF};
1847 }
1848
1849 @Override
1850 public int[] getRequiredTokens() {
1851 return new int[] {TokenTypes.METHOD_DEF};
1852 }
1853
1854 @Override
1855 public void visitToken(DetailAST ast) {
1856 if (ast.findFirstToken(TokenTypes.MODIFIERS).findFirstToken(
1857 TokenTypes.BLOCK_COMMENT_BEGIN) != null) {
1858 log(ast, "AST has incorrect structure structure."
1859 + " The check does not require comment nodes but there were comment nodes"
1860 + " in the AST.");
1861 }
1862 final int childCount = ast.getChildCount();
1863 if (childCount != METHOD_DEF_CHILD_COUNT) {
1864 final String msg = String.format(Locale.ENGLISH,
1865 "AST node in no comment tree has wrong number of children. "
1866 + "Expected is %d but was %d",
1867 METHOD_DEF_CHILD_COUNT, childCount);
1868 log(ast, msg);
1869 }
1870
1871 int actualChildCount = 0;
1872 for (DetailAST child = ast.getFirstChild().getFirstChild(); child != null; child =
1873 child.getNextSibling()) {
1874 actualChildCount++;
1875 }
1876 final int cacheChildCount = ast.getFirstChild().getChildCount();
1877 if (cacheChildCount != actualChildCount) {
1878 final String msg = String.format(Locale.ENGLISH,
1879 "AST node with no comment has wrong number of children. "
1880 + "Expected is %d but was %d",
1881 cacheChildCount, actualChildCount);
1882 log(ast, msg);
1883 }
1884 }
1885
1886 }
1887
1888 public static class CheckWhichRequiresCommentNodes extends AbstractCheck {
1889
1890
1891 private static final int METHOD_DEF_CHILD_COUNT = 7;
1892
1893 @Override
1894 public boolean isCommentNodesRequired() {
1895 return true;
1896 }
1897
1898 @Override
1899 public int[] getDefaultTokens() {
1900 return new int[] {TokenTypes.METHOD_DEF};
1901 }
1902
1903 @Override
1904 public int[] getAcceptableTokens() {
1905 return new int[] {TokenTypes.METHOD_DEF};
1906 }
1907
1908 @Override
1909 public int[] getRequiredTokens() {
1910 return new int[] {TokenTypes.METHOD_DEF};
1911 }
1912
1913
1914 @Override
1915 public void visitToken(DetailAST ast) {
1916 if (ast.findFirstToken(TokenTypes.MODIFIERS).findFirstToken(
1917 TokenTypes.BLOCK_COMMENT_BEGIN) == null) {
1918 log(ast, "Incorrect AST structure.");
1919 }
1920 final int childCount = ast.getChildCount();
1921 if (childCount != METHOD_DEF_CHILD_COUNT) {
1922 final String msg = String.format(Locale.ENGLISH,
1923 "AST node in comment tree has wrong number of children. "
1924 + "Expected is %d but was %d",
1925 METHOD_DEF_CHILD_COUNT, childCount);
1926 log(ast, msg);
1927 }
1928
1929 int actualChildCount = 0;
1930 for (DetailAST child = ast.getFirstChild().getFirstChild(); child != null; child =
1931 child.getNextSibling()) {
1932 actualChildCount++;
1933 }
1934 final int cacheChildCount = ast.getFirstChild().getChildCount();
1935 if (cacheChildCount != actualChildCount) {
1936 final String msg = String.format(Locale.ENGLISH,
1937 "AST node with comment has wrong number of children. "
1938 + "Expected is %d but was %d",
1939 cacheChildCount, actualChildCount);
1940 log(ast, msg);
1941 }
1942 }
1943
1944 }
1945
1946 public static final class DummyFileSet extends AbstractFileSetCheck {
1947
1948 private final List<String> methodCalls = new ArrayList<>();
1949
1950 private boolean initCalled;
1951
1952 @Override
1953 public void init() {
1954 super.init();
1955 initCalled = true;
1956 }
1957
1958 @Override
1959 public void beginProcessing(String charset) {
1960 methodCalls.add("beginProcessing");
1961 super.beginProcessing(charset);
1962 }
1963
1964 @Override
1965 public void finishProcessing() {
1966 methodCalls.add("finishProcessing");
1967 super.finishProcessing();
1968 }
1969
1970 @Override
1971 protected void processFiltered(File file, FileText fileText) {
1972 methodCalls.add("processFiltered");
1973 }
1974
1975 @Override
1976 public void destroy() {
1977 methodCalls.add("destroy");
1978 super.destroy();
1979 }
1980
1981 public List<String> getMethodCalls() {
1982 return Collections.unmodifiableList(methodCalls);
1983 }
1984
1985 public boolean isInitCalled() {
1986 return initCalled;
1987 }
1988
1989 public MessageDispatcher getInternalMessageDispatcher() {
1990 return getMessageDispatcher();
1991 }
1992
1993 }
1994
1995 }