001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2020 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.StatelessCheck; 025import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck; 026import com.puppycrawl.tools.checkstyle.api.FileText; 027 028/** 029 * <p> 030 * Checks that a specified pattern matches a single line in any file type. 031 * </p> 032 * <p> 033 * Rationale: This check can be used to prototype checks and to find common bad 034 * practice such as calling {@code ex.printStacktrace()}, 035 * {@code System.out.println()}, {@code System.exit()}, etc. 036 * </p> 037 * <ul> 038 * <li> 039 * Property {@code format} - Specify the format of the regular expression to match. 040 * Default value is {@code "$."}. 041 * </li> 042 * <li> 043 * Property {@code message} - Specify the message which is used to notify about 044 * violations, if empty then default (hard-coded) message is used. 045 * Default value is {@code null}. 046 * </li> 047 * <li> 048 * Property {@code ignoreCase} - Control whether to ignore case when searching. 049 * Default value is {@code false}. 050 * </li> 051 * <li> 052 * Property {@code minimum} - Specify the minimum number of matches required in each file. 053 * Default value is {@code 0}. 054 * </li> 055 * <li> 056 * Property {@code maximum} - Specify the maximum number of matches required in each file. 057 * Default value is {@code 0}. 058 * </li> 059 * <li> 060 * Property {@code fileExtensions} - Specify the file type extension of files to process. 061 * Default value is {@code all files}. 062 * </li> 063 * </ul> 064 * <p> 065 * To configure the check to find trailing whitespace at the end of a line: 066 * </p> 067 * <pre> 068 * <module name="RegexpSingleline"> 069 * <!-- \s matches whitespace character, $ matches end of line. --> 070 * <property name="format" value="\s+$"/> 071 * </module> 072 * </pre> 073 * <p> 074 * To configure the check to find trailing whitespace at the end of a line, 075 * with some <i>slack</i> of allowing two occurrences per file: 076 * </p> 077 * <pre> 078 * <module name="RegexpSingleline"> 079 * <property name="format" value="\s+$"/> 080 * <!-- next line not required as 0 is the default --> 081 * <property name="minimum" value="0"/> 082 * <property name="maximum" value="2"/> 083 * </module> 084 * </pre> 085 * <p> 086 * An example of how to configure the check to make sure a copyright statement 087 * is included in the file: 088 * </p> 089 * <pre> 090 * <module name="RegexpSingleline"> 091 * <property name="format" value="This file is copyrighted"/> 092 * <property name="minimum" value="1"/> 093 * <!-- Need to specify a maximum, so 10 times is more than enough. --> 094 * <property name="maximum" value="10"/> 095 * </module> 096 * </pre> 097 * 098 * @since 5.0 099 */ 100@StatelessCheck 101public class RegexpSinglelineCheck extends AbstractFileSetCheck { 102 103 /** Specify the format of the regular expression to match. */ 104 private String format = "$."; 105 /** 106 * Specify the message which is used to notify about violations, 107 * if empty then default (hard-coded) message is used. 108 */ 109 private String message; 110 /** Specify the minimum number of matches required in each file. */ 111 private int minimum; 112 /** Specify the maximum number of matches required in each file. */ 113 private int maximum; 114 /** Control whether to ignore case when searching. */ 115 private boolean ignoreCase; 116 117 /** The detector to use. */ 118 private SinglelineDetector detector; 119 120 @Override 121 public void beginProcessing(String charset) { 122 final DetectorOptions options = DetectorOptions.newBuilder() 123 .reporter(this) 124 .compileFlags(0) 125 .format(format) 126 .message(message) 127 .minimum(minimum) 128 .maximum(maximum) 129 .ignoreCase(ignoreCase) 130 .build(); 131 detector = new SinglelineDetector(options); 132 } 133 134 @Override 135 protected void processFiltered(File file, FileText fileText) { 136 detector.processLines(fileText); 137 } 138 139 /** 140 * Setter to specify the format of the regular expression to match. 141 * 142 * @param format the format of the regular expression to match. 143 */ 144 public void setFormat(String format) { 145 this.format = format; 146 } 147 148 /** 149 * Setter to specify the message which is used to notify about violations, 150 * if empty then default (hard-coded) message is used. 151 * 152 * @param message the message to report for a match. 153 */ 154 public void setMessage(String message) { 155 this.message = message; 156 } 157 158 /** 159 * Setter to specify the minimum number of matches required in each file. 160 * 161 * @param minimum the minimum number of matches required in each file. 162 */ 163 public void setMinimum(int minimum) { 164 this.minimum = minimum; 165 } 166 167 /** 168 * Setter to specify the maximum number of matches required in each file. 169 * 170 * @param maximum the maximum number of matches required in each file. 171 */ 172 public void setMaximum(int maximum) { 173 this.maximum = maximum; 174 } 175 176 /** 177 * Setter to control whether to ignore case when searching. 178 * 179 * @param ignoreCase whether to ignore case when searching. 180 */ 181 public void setIgnoreCase(boolean ignoreCase) { 182 this.ignoreCase = ignoreCase; 183 } 184 185}