View Javadoc
1   /*
2    * SPDX-FileCopyrightText: Copyright (c) 2011-2026 Yegor Bugayenko
3    * SPDX-License-Identifier: MIT
4    */
5   package com.qulice.checkstyle;
6   
7   import com.jcabi.log.Logger;
8   import com.puppycrawl.tools.checkstyle.api.AuditEvent;
9   import com.puppycrawl.tools.checkstyle.api.AuditListener;
10  import com.qulice.spi.Environment;
11  import com.qulice.spi.Relative;
12  import java.io.File;
13  import java.util.ArrayList;
14  import java.util.Collections;
15  import java.util.List;
16  
17  /**
18   * Listener of Checkstyle events.
19   *
20   * @since 0.3
21   */
22  final class CheckstyleListener implements AuditListener {
23  
24      /**
25       * Environment.
26       */
27      private final Environment env;
28  
29      /**
30       * Collection of events collected.
31       */
32      private final List<AuditEvent> all;
33  
34      /**
35       * Files that Checkstyle actually processed, cache aside.
36       */
37      private final List<File> started;
38  
39      /**
40       * Public ctor.
41       *
42       * @param environ The environment
43       */
44      CheckstyleListener(final Environment environ) {
45          this.all = new ArrayList<>(0);
46          this.started = new ArrayList<>(0);
47          this.env = environ;
48      }
49  
50      @Override
51      public void auditStarted(final AuditEvent event) {
52          // intentionally empty
53      }
54  
55      @Override
56      public void auditFinished(final AuditEvent event) {
57          // intentionally empty
58      }
59  
60      @Override
61      public void fileStarted(final AuditEvent event) {
62          this.started.add(new File(event.getFileName()));
63      }
64  
65      @Override
66      public void fileFinished(final AuditEvent event) {
67          // intentionally empty
68      }
69  
70      @Override
71      public void addError(final AuditEvent event) {
72          final String path = new Relative(
73              this.env.basedir(), new File(event.getFileName())
74          ).path();
75          if (!this.env.exclude("checkstyle", path)
76              && !this.skipJavadocPackage(event, path)) {
77              this.all.add(event);
78          }
79      }
80  
81      @Override
82      public void addException(final AuditEvent event,
83          final Throwable throwable) {
84          final String check = event.getSourceName();
85          Logger.error(
86              this,
87              "%s[%d]: %s (%s), %[exception]s",
88              new Relative(
89                  this.env.basedir(), new File(event.getFileName())
90              ).path(),
91              event.getLine(),
92              event.getMessage(),
93              check.substring(check.lastIndexOf('.') + 1),
94              throwable
95          );
96      }
97  
98      /**
99       * Get all events.
100      *
101      * @return List of events
102      */
103     List<AuditEvent> events() {
104         return Collections.unmodifiableList(this.all);
105     }
106 
107     /**
108      * Files that Checkstyle processed, leaving out those it took from
109      * its cache and never collected events for.
110      *
111      * @return List of files
112      */
113     List<File> processed() {
114         return Collections.unmodifiableList(this.started);
115     }
116 
117     private boolean skipJavadocPackage(final AuditEvent event, final String path) {
118         final String marker = "src/test/java/";
119         final String unix = path.replace(File.separatorChar, '/');
120         final int idx = unix.indexOf(marker);
121         boolean skip = false;
122         if (event.getSourceName().endsWith(".JavadocPackageCheck") && idx >= 0) {
123             final String tail = unix.substring(idx + marker.length());
124             final int slash = tail.lastIndexOf('/');
125             if (slash > 0) {
126                 final File main = new File(
127                     this.env.basedir(),
128                     String.format(
129                         "%ssrc/main/java/%s/package-info.java",
130                         unix.substring(0, idx),
131                         tail.substring(0, slash)
132                     )
133                 );
134                 skip = main.isFile();
135             }
136         }
137         return skip;
138     }
139 }