001///////////////////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
003// Copyright (C) 2001-2024 the original author or authors.
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018///////////////////////////////////////////////////////////////////////////////////////////////
019
020package com.puppycrawl.tools.checkstyle.checks.regexp;
021
022import java.io.File;
023
024import com.puppycrawl.tools.checkstyle.PropertyType;
025import com.puppycrawl.tools.checkstyle.StatelessCheck;
026import com.puppycrawl.tools.checkstyle.XdocsPropertyType;
027import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
028import com.puppycrawl.tools.checkstyle.api.FileText;
029
030/**
031 * <p>
032 * Checks that a specified pattern matches a single-line in any file type.
033 * </p>
034 * <p>
035 * Rationale: This check can be used to prototype checks and to find common bad
036 * practice such as calling {@code ex.printStacktrace()},
037 * {@code System.out.println()}, {@code System.exit()}, etc.
038 * </p>
039 * <ul>
040 * <li>
041 * Property {@code fileExtensions} - Specify the file extensions of the files to process.
042 * Type is {@code java.lang.String[]}.
043 * Default value is {@code ""}.
044 * </li>
045 * <li>
046 * Property {@code format} - Specify the format of the regular expression to match.
047 * Type is {@code java.util.regex.Pattern}.
048 * Default value is {@code "$."}.
049 * </li>
050 * <li>
051 * Property {@code ignoreCase} - Control whether to ignore case when searching.
052 * Type is {@code boolean}.
053 * Default value is {@code false}.
054 * </li>
055 * <li>
056 * Property {@code maximum} - Specify the maximum number of matches required in each file.
057 * Type is {@code int}.
058 * Default value is {@code 0}.
059 * </li>
060 * <li>
061 * Property {@code message} - Specify the message which is used to notify about
062 * violations, if empty then default (hard-coded) message is used.
063 * Type is {@code java.lang.String}.
064 * Default value is {@code null}.
065 * </li>
066 * <li>
067 * Property {@code minimum} - Specify the minimum number of matches required in each file.
068 * Type is {@code int}.
069 * Default value is {@code 0}.
070 * </li>
071 * </ul>
072 * <p>
073 * Parent is {@code com.puppycrawl.tools.checkstyle.Checker}
074 * </p>
075 * <p>
076 * Violation Message Keys:
077 * </p>
078 * <ul>
079 * <li>
080 * {@code regexp.exceeded}
081 * </li>
082 * <li>
083 * {@code regexp.minimum}
084 * </li>
085 * </ul>
086 *
087 * @since 5.0
088 */
089@StatelessCheck
090public class RegexpSinglelineCheck extends AbstractFileSetCheck {
091
092    /** Specify the format of the regular expression to match. */
093    @XdocsPropertyType(PropertyType.PATTERN)
094    private String format = "$.";
095    /**
096     * Specify the message which is used to notify about violations,
097     * if empty then default (hard-coded) message is used.
098     */
099    private String message;
100    /** Specify the minimum number of matches required in each file. */
101    private int minimum;
102    /** Specify the maximum number of matches required in each file. */
103    private int maximum;
104    /** Control whether to ignore case when searching. */
105    private boolean ignoreCase;
106
107    /** The detector to use. */
108    private SinglelineDetector detector;
109
110    @Override
111    public void beginProcessing(String charset) {
112        final DetectorOptions options = DetectorOptions.newBuilder()
113            .reporter(this)
114            .format(format)
115            .message(message)
116            .minimum(minimum)
117            .maximum(maximum)
118            .ignoreCase(ignoreCase)
119            .build();
120        detector = new SinglelineDetector(options);
121    }
122
123    @Override
124    protected void processFiltered(File file, FileText fileText) {
125        detector.processLines(fileText);
126    }
127
128    /**
129     * Setter to specify the format of the regular expression to match.
130     *
131     * @param format the format of the regular expression to match.
132     * @since 5.0
133     */
134    public void setFormat(String format) {
135        this.format = format;
136    }
137
138    /**
139     * Setter to specify the message which is used to notify about violations,
140     * if empty then default (hard-coded) message is used.
141     *
142     * @param message the message to report for a match.
143     * @since 5.0
144     */
145    public void setMessage(String message) {
146        this.message = message;
147    }
148
149    /**
150     * Setter to specify the minimum number of matches required in each file.
151     *
152     * @param minimum the minimum number of matches required in each file.
153     * @since 5.0
154     */
155    public void setMinimum(int minimum) {
156        this.minimum = minimum;
157    }
158
159    /**
160     * Setter to specify the maximum number of matches required in each file.
161     *
162     * @param maximum the maximum number of matches required in each file.
163     * @since 5.0
164     */
165    public void setMaximum(int maximum) {
166        this.maximum = maximum;
167    }
168
169    /**
170     * Setter to control whether to ignore case when searching.
171     *
172     * @param ignoreCase whether to ignore case when searching.
173     * @since 5.0
174     */
175    public void setIgnoreCase(boolean ignoreCase) {
176        this.ignoreCase = ignoreCase;
177    }
178
179}