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 java.io.File;
23
24 import com.puppycrawl.tools.checkstyle.PropertyType;
25 import com.puppycrawl.tools.checkstyle.StatelessCheck;
26 import com.puppycrawl.tools.checkstyle.XdocsPropertyType;
27 import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
28 import com.puppycrawl.tools.checkstyle.api.FileText;
29
30 /**
31 * <div>
32 * Checks that a specified pattern matches a single-line in any file type.
33 * </div>
34 *
35 * <p>
36 * Rationale: This check can be used to prototype checks and to find common bad
37 * practice such as calling {@code ex.printStacktrace()},
38 * {@code System.out.println()}, {@code System.exit()}, etc.
39 * </p>
40 *
41 * @since 5.0
42 */
43 @StatelessCheck
44 public class RegexpSinglelineCheck extends AbstractFileSetCheck {
45
46 /** A key is pointing to the warning message text in "messages.properties" file. */
47 public static final String MSG_REGEXP_EXCEEDED = "regexp.exceeded";
48
49 /** A key is pointing to the warning message text in "messages.properties" file. */
50 public static final String MSG_REGEXP_MINIMUM = "regexp.minimum";
51
52 /** Specify the format of the regular expression to match. */
53 @XdocsPropertyType(PropertyType.PATTERN)
54 private String format = "$.";
55 /**
56 * Specify the message which is used to notify about violations,
57 * if empty then default (hard-coded) message is used.
58 */
59 private String message;
60 /** Specify the minimum number of matches required in each file. */
61 private int minimum;
62 /** Specify the maximum number of matches required in each file. */
63 private int maximum;
64 /** Control whether to ignore case when searching. */
65 private boolean ignoreCase;
66
67 /** The detector to use. */
68 private SinglelineDetector detector;
69
70 /**
71 * Creates a new {@code RegexpSinglelineCheck} instance.
72 */
73 public RegexpSinglelineCheck() {
74 // no code by default
75 }
76
77 @Override
78 public void beginProcessing(String charset) {
79 final DetectorOptions options = DetectorOptions.newBuilder()
80 .reporter(this)
81 .format(format)
82 .message(message)
83 .minimum(minimum)
84 .maximum(maximum)
85 .ignoreCase(ignoreCase)
86 .build();
87 detector = new SinglelineDetector(options,
88 MSG_REGEXP_EXCEEDED, MSG_REGEXP_MINIMUM);
89 }
90
91 @Override
92 protected void processFiltered(File file, FileText fileText) {
93 detector.processLines(fileText);
94 }
95
96 /**
97 * Setter to specify the format of the regular expression to match.
98 *
99 * @param format the format of the regular expression to match.
100 * @since 5.0
101 */
102 public void setFormat(String format) {
103 this.format = format;
104 }
105
106 /**
107 * Setter to specify the message which is used to notify about violations,
108 * if empty then default (hard-coded) message is used.
109 *
110 * @param message the message to report for a match.
111 * @since 5.0
112 */
113 public void setMessage(String message) {
114 this.message = message;
115 }
116
117 /**
118 * Setter to specify the minimum number of matches required in each file.
119 *
120 * @param minimum the minimum number of matches required in each file.
121 * @since 5.0
122 */
123 public void setMinimum(int minimum) {
124 this.minimum = minimum;
125 }
126
127 /**
128 * Setter to specify the maximum number of matches required in each file.
129 *
130 * @param maximum the maximum number of matches required in each file.
131 * @since 5.0
132 */
133 public void setMaximum(int maximum) {
134 this.maximum = maximum;
135 }
136
137 /**
138 * Setter to control whether to ignore case when searching.
139 *
140 * @param ignoreCase whether to ignore case when searching.
141 * @since 5.0
142 */
143 public void setIgnoreCase(boolean ignoreCase) {
144 this.ignoreCase = ignoreCase;
145 }
146
147 }