1 ///////////////////////////////////////////////////////////////////////////////////////////////
2 // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3 // Copyright (C) 2001-2026 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 * <div>
31 * Checks that a specified pattern matches a single-line in Java files.
32 * </div>
33 *
34 * <p>
35 * This class is variation on
36 * <a href="https://checkstyle.org/checks/regexp/regexpsingleline.html">
37 * RegexpSingleline</a>
38 * for detecting single-lines that match a supplied regular expression in Java files.
39 * It supports suppressing matches in Java comments.
40 * </p>
41 *
42 * @since 5.0
43 */
44 @StatelessCheck
45 public class RegexpSinglelineJavaCheck extends AbstractCheck {
46
47 /** A key is pointing to the warning message text in "messages.properties" file. */
48 public static final String MSG_REGEXP_EXCEEDED = "regexp.exceeded";
49
50 /** A key is pointing to the warning message text in "messages.properties" file. */
51 public static final String MSG_REGEXP_MINIMUM = "regexp.minimum";
52
53 /** Specify the format of the regular expression to match. */
54 @XdocsPropertyType(PropertyType.PATTERN)
55 private String format = "$.";
56 /**
57 * Specify the message which is used to notify about violations,
58 * if empty then default (hard-coded) message is used.
59 */
60 private String message;
61 /** Specify the minimum number of matches required in each file. */
62 private int minimum;
63 /** Specify the maximum number of matches required in each file. */
64 private int maximum;
65 /** Control whether to ignore case when searching. */
66 private boolean ignoreCase;
67 /** Control whether to ignore text in comments when searching. */
68 private boolean ignoreComments;
69
70 /**
71 * Creates a new {@code RegexpSinglelineJavaCheck} instance.
72 */
73 public RegexpSinglelineJavaCheck() {
74 // no code by default
75 }
76
77 @Override
78 public int[] getDefaultTokens() {
79 return getRequiredTokens();
80 }
81
82 @Override
83 public int[] getAcceptableTokens() {
84 return getRequiredTokens();
85 }
86
87 @Override
88 public int[] getRequiredTokens() {
89 return CommonUtil.EMPTY_INT_ARRAY;
90 }
91
92 @Override
93 @SuppressWarnings("deprecation")
94 public void beginTree(DetailAST rootAST) {
95 MatchSuppressor suppressor = null;
96 if (ignoreComments) {
97 suppressor = new CommentSuppressor(getFileContents());
98 }
99
100 final DetectorOptions options = DetectorOptions.newBuilder()
101 .reporter(this)
102 .suppressor(suppressor)
103 .format(format)
104 .message(message)
105 .minimum(minimum)
106 .maximum(maximum)
107 .ignoreCase(ignoreCase)
108 .build();
109 final SinglelineDetector detector = new SinglelineDetector(options,
110 MSG_REGEXP_EXCEEDED, MSG_REGEXP_MINIMUM);
111 detector.processLines(getFileContents().getText());
112 }
113
114 /**
115 * Setter to specify the format of the regular expression to match.
116 *
117 * @param format the format of the regular expression to match.
118 * @since 5.0
119 */
120 public void setFormat(String format) {
121 this.format = format;
122 }
123
124 /**
125 * Setter to specify the message which is used to notify about violations,
126 * if empty then default (hard-coded) message is used.
127 *
128 * @param message the message to report for a match.
129 * @since 6.0
130 */
131 public void setMessage(String message) {
132 this.message = message;
133 }
134
135 /**
136 * Setter to specify the minimum number of matches required in each file.
137 *
138 * @param minimum the minimum number of matches required in each file.
139 * @since 5.0
140 */
141 public void setMinimum(int minimum) {
142 this.minimum = minimum;
143 }
144
145 /**
146 * Setter to specify the maximum number of matches required in each file.
147 *
148 * @param maximum the maximum number of matches required in each file.
149 * @since 5.0
150 */
151 public void setMaximum(int maximum) {
152 this.maximum = maximum;
153 }
154
155 /**
156 * Setter to control whether to ignore case when searching.
157 *
158 * @param ignoreCase whether to ignore case when searching.
159 * @since 5.0
160 */
161 public void setIgnoreCase(boolean ignoreCase) {
162 this.ignoreCase = ignoreCase;
163 }
164
165 /**
166 * Setter to control whether to ignore text in comments when searching.
167 *
168 * @param ignore whether to ignore text in comments when searching.
169 * @since 5.0
170 */
171 public void setIgnoreComments(boolean ignore) {
172 ignoreComments = ignore;
173 }
174
175 }