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.puppycrawl.tools.checkstyle.ConfigurationLoader;
8   import com.puppycrawl.tools.checkstyle.PropertiesExpander;
9   import com.puppycrawl.tools.checkstyle.api.Configuration;
10  import java.util.Collection;
11  import java.util.HashSet;
12  import java.util.Properties;
13  import org.cactoos.scalar.Sticky;
14  import org.cactoos.scalar.Unchecked;
15  
16  /**
17   * Names of the checks that {@code checks.xml} enables.
18   *
19   * <p>Every {@code @checkstyle} suppression comment names its target with
20   * a regular expression that Checkstyle matches against the fully
21   * qualified class name of the check. A name matching none of the enabled
22   * checks suppresses nothing at all, which is what
23   * {@link UnknownSuppressionCheck} reports. Both the short name of a
24   * module and its name with the {@code Check} suffix count as enabled,
25   * since either of them matches the class name of the check.</p>
26   *
27   * @since 1.0
28   */
29  final class ConfiguredChecks {
30  
31      /**
32       * Names of the enabled checks, read from {@code checks.xml} once.
33       */
34      private final Unchecked<Collection<String>> names = new Unchecked<>(
35          new Sticky<>(ConfiguredChecks::load)
36      );
37  
38      /**
39       * Is any of the enabled checks named by this suppression?
40       *
41       * <p>The filters capture the name as {@code \w+}, which holds no
42       * regular expression metacharacter, so their pattern matching comes
43       * down to a search for the name inside the name of a check.</p>
44       *
45       * @param name Name from a {@code @checkstyle} suppression comment
46       * @return True if the name matches at least one enabled check
47       */
48      boolean covers(final String name) {
49          return this.names.value().stream().anyMatch(known -> known.contains(name));
50      }
51  
52      private static Collection<String> load() throws Exception {
53          final Properties props = new Properties();
54          props.setProperty("cache.file", "");
55          return ConfiguredChecks.modules(
56              ConfigurationLoader.loadConfiguration(
57                  ConfiguredChecks.class.getResource("checks.xml").toString(),
58                  new PropertiesExpander(props),
59                  ConfigurationLoader.IgnoredModulesOptions.OMIT
60              )
61          );
62      }
63  
64      private static Collection<String> modules(final Configuration config) {
65          final Collection<String> found = new HashSet<>(0);
66          final String name = config.getName();
67          final String simple = name.substring(name.lastIndexOf('.') + 1);
68          found.add(simple);
69          if (!simple.endsWith("Check")) {
70              found.add(String.format("%sCheck", simple));
71          }
72          for (final Configuration child : config.getChildren()) {
73              found.addAll(ConfiguredChecks.modules(child));
74          }
75          return found;
76      }
77  }