View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 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.regexp;
21  
22  import com.puppycrawl.tools.checkstyle.PropertyType;
23  import com.puppycrawl.tools.checkstyle.StatelessCheck;
24  import com.puppycrawl.tools.checkstyle.XdocsPropertyType;
25  import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
26  import com.puppycrawl.tools.checkstyle.api.DetailAST;
27  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
28  
29  /**
30   * <p>
31   * Checks that a specified pattern matches a single-line in Java files.
32   * </p>
33   * <p>
34   * This class is variation on
35   * <a href="https://checkstyle.org/checks/regexp/regexpsingleline.html#RegexpSingleline">
36   * RegexpSingleline</a>
37   * for detecting single-lines that match a supplied regular expression in Java files.
38   * It supports suppressing matches in Java comments.
39   * </p>
40   * <ul>
41   * <li>
42   * Property {@code format} - Specify the format of the regular expression to match.
43   * Type is {@code java.util.regex.Pattern}.
44   * Default value is {@code "$."}.
45   * </li>
46   * <li>
47   * Property {@code ignoreCase} - Control whether to ignore case when searching.
48   * Type is {@code boolean}.
49   * Default value is {@code false}.
50   * </li>
51   * <li>
52   * Property {@code ignoreComments} - Control whether to ignore text in comments when searching.
53   * Type is {@code boolean}.
54   * Default value is {@code false}.
55   * </li>
56   * <li>
57   * Property {@code maximum} - Specify the maximum number of matches required in each file.
58   * Type is {@code int}.
59   * Default value is {@code 0}.
60   * </li>
61   * <li>
62   * Property {@code message} - Specify the message which is used to notify about
63   * violations, if empty then default (hard-coded) message is used.
64   * Type is {@code java.lang.String}.
65   * Default value is {@code null}.
66   * </li>
67   * <li>
68   * Property {@code minimum} - Specify the minimum number of matches required in each file.
69   * Type is {@code int}.
70   * Default value is {@code 0}.
71   * </li>
72   * </ul>
73   * <p>
74   * Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker}
75   * </p>
76   * <p>
77   * Violation Message Keys:
78   * </p>
79   * <ul>
80   * <li>
81   * {@code regexp.exceeded}
82   * </li>
83   * <li>
84   * {@code regexp.minimum}
85   * </li>
86   * </ul>
87   *
88   * @since 6.0
89   */
90  @StatelessCheck
91  public class RegexpSinglelineJavaCheck extends AbstractCheck {
92  
93      /** Specify the format of the regular expression to match. */
94      @XdocsPropertyType(PropertyType.PATTERN)
95      private String format = "$.";
96      /**
97       * Specify the message which is used to notify about violations,
98       * if empty then default (hard-coded) message is used.
99       */
100     private String message;
101     /** Specify the minimum number of matches required in each file. */
102     private int minimum;
103     /** Specify the maximum number of matches required in each file. */
104     private int maximum;
105     /** Control whether to ignore case when searching. */
106     private boolean ignoreCase;
107     /** Control whether to ignore text in comments when searching. */
108     private boolean ignoreComments;
109 
110     @Override
111     public int[] getDefaultTokens() {
112         return getRequiredTokens();
113     }
114 
115     @Override
116     public int[] getAcceptableTokens() {
117         return getRequiredTokens();
118     }
119 
120     @Override
121     public int[] getRequiredTokens() {
122         return CommonUtil.EMPTY_INT_ARRAY;
123     }
124 
125     // suppress deprecation until https://github.com/checkstyle/checkstyle/issues/11166
126     @SuppressWarnings("deprecation")
127     @Override
128     public void beginTree(DetailAST rootAST) {
129         MatchSuppressor suppressor = null;
130         if (ignoreComments) {
131             suppressor = new CommentSuppressor(getFileContents());
132         }
133 
134         final DetectorOptions options = DetectorOptions.newBuilder()
135             .reporter(this)
136             .suppressor(suppressor)
137             .format(format)
138             .message(message)
139             .minimum(minimum)
140             .maximum(maximum)
141             .ignoreCase(ignoreCase)
142             .build();
143         final SinglelineDetector detector = new SinglelineDetector(options);
144         detector.processLines(getFileContents().getText());
145     }
146 
147     /**
148      * Setter to specify the format of the regular expression to match.
149      *
150      * @param format the format of the regular expression to match.
151      * @since 5.0
152      */
153     public void setFormat(String format) {
154         this.format = format;
155     }
156 
157     /**
158      * Setter to specify the message which is used to notify about violations,
159      * if empty then default (hard-coded) message is used.
160      *
161      * @param message the message to report for a match.
162      * @since 6.0
163      */
164     public void setMessage(String message) {
165         this.message = message;
166     }
167 
168     /**
169      * Setter to specify the minimum number of matches required in each file.
170      *
171      * @param minimum the minimum number of matches required in each file.
172      * @since 5.0
173      */
174     public void setMinimum(int minimum) {
175         this.minimum = minimum;
176     }
177 
178     /**
179      * Setter to specify the maximum number of matches required in each file.
180      *
181      * @param maximum the maximum number of matches required in each file.
182      * @since 5.0
183      */
184     public void setMaximum(int maximum) {
185         this.maximum = maximum;
186     }
187 
188     /**
189      * Setter to control whether to ignore case when searching.
190      *
191      * @param ignoreCase whether to ignore case when searching.
192      * @since 5.0
193      */
194     public void setIgnoreCase(boolean ignoreCase) {
195         this.ignoreCase = ignoreCase;
196     }
197 
198     /**
199      * Setter to control whether to ignore text in comments when searching.
200      *
201      * @param ignore whether to ignore text in comments when searching.
202      * @since 5.0
203      */
204     public void setIgnoreComments(boolean ignore) {
205         ignoreComments = ignore;
206     }
207 
208 }