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 com.puppycrawl.tools.checkstyle.PropertyType; 023import com.puppycrawl.tools.checkstyle.StatelessCheck; 024import com.puppycrawl.tools.checkstyle.XdocsPropertyType; 025import com.puppycrawl.tools.checkstyle.api.AbstractCheck; 026import com.puppycrawl.tools.checkstyle.api.DetailAST; 027import com.puppycrawl.tools.checkstyle.utils.CommonUtil; 028 029/** 030 * <div> 031 * Checks that a specified pattern matches a single-line in Java files. 032 * </div> 033 * 034 * <p> 035 * This class is variation on 036 * <a href="https://checkstyle.org/checks/regexp/regexpsingleline.html#RegexpSingleline"> 037 * RegexpSingleline</a> 038 * for detecting single-lines that match a supplied regular expression in Java files. 039 * It supports suppressing matches in Java comments. 040 * </p> 041 * <ul> 042 * <li> 043 * Property {@code format} - Specify the format of the regular expression to match. 044 * Type is {@code java.util.regex.Pattern}. 045 * Default value is {@code "$."}. 046 * </li> 047 * <li> 048 * Property {@code ignoreCase} - Control whether to ignore case when searching. 049 * Type is {@code boolean}. 050 * Default value is {@code false}. 051 * </li> 052 * <li> 053 * Property {@code ignoreComments} - Control whether to ignore text in comments when searching. 054 * Type is {@code boolean}. 055 * Default value is {@code false}. 056 * </li> 057 * <li> 058 * Property {@code maximum} - Specify the maximum number of matches required in each file. 059 * Type is {@code int}. 060 * Default value is {@code 0}. 061 * </li> 062 * <li> 063 * Property {@code message} - Specify the message which is used to notify about 064 * violations, if empty then default (hard-coded) message is used. 065 * Type is {@code java.lang.String}. 066 * Default value is {@code null}. 067 * </li> 068 * <li> 069 * Property {@code minimum} - Specify the minimum number of matches required in each file. 070 * Type is {@code int}. 071 * Default value is {@code 0}. 072 * </li> 073 * </ul> 074 * 075 * <p> 076 * Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker} 077 * </p> 078 * 079 * <p> 080 * Violation Message Keys: 081 * </p> 082 * <ul> 083 * <li> 084 * {@code regexp.exceeded} 085 * </li> 086 * <li> 087 * {@code regexp.minimum} 088 * </li> 089 * </ul> 090 * 091 * @since 6.0 092 */ 093@StatelessCheck 094public class RegexpSinglelineJavaCheck extends AbstractCheck { 095 096 /** Specify the format of the regular expression to match. */ 097 @XdocsPropertyType(PropertyType.PATTERN) 098 private String format = "$."; 099 /** 100 * Specify the message which is used to notify about violations, 101 * if empty then default (hard-coded) message is used. 102 */ 103 private String message; 104 /** Specify the minimum number of matches required in each file. */ 105 private int minimum; 106 /** Specify the maximum number of matches required in each file. */ 107 private int maximum; 108 /** Control whether to ignore case when searching. */ 109 private boolean ignoreCase; 110 /** Control whether to ignore text in comments when searching. */ 111 private boolean ignoreComments; 112 113 @Override 114 public int[] getDefaultTokens() { 115 return getRequiredTokens(); 116 } 117 118 @Override 119 public int[] getAcceptableTokens() { 120 return getRequiredTokens(); 121 } 122 123 @Override 124 public int[] getRequiredTokens() { 125 return CommonUtil.EMPTY_INT_ARRAY; 126 } 127 128 // suppress deprecation until https://github.com/checkstyle/checkstyle/issues/11166 129 @SuppressWarnings("deprecation") 130 @Override 131 public void beginTree(DetailAST rootAST) { 132 MatchSuppressor suppressor = null; 133 if (ignoreComments) { 134 suppressor = new CommentSuppressor(getFileContents()); 135 } 136 137 final DetectorOptions options = DetectorOptions.newBuilder() 138 .reporter(this) 139 .suppressor(suppressor) 140 .format(format) 141 .message(message) 142 .minimum(minimum) 143 .maximum(maximum) 144 .ignoreCase(ignoreCase) 145 .build(); 146 final SinglelineDetector detector = new SinglelineDetector(options); 147 detector.processLines(getFileContents().getText()); 148 } 149 150 /** 151 * Setter to specify the format of the regular expression to match. 152 * 153 * @param format the format of the regular expression to match. 154 * @since 5.0 155 */ 156 public void setFormat(String format) { 157 this.format = format; 158 } 159 160 /** 161 * Setter to specify the message which is used to notify about violations, 162 * if empty then default (hard-coded) message is used. 163 * 164 * @param message the message to report for a match. 165 * @since 6.0 166 */ 167 public void setMessage(String message) { 168 this.message = message; 169 } 170 171 /** 172 * Setter to specify the minimum number of matches required in each file. 173 * 174 * @param minimum the minimum number of matches required in each file. 175 * @since 5.0 176 */ 177 public void setMinimum(int minimum) { 178 this.minimum = minimum; 179 } 180 181 /** 182 * Setter to specify the maximum number of matches required in each file. 183 * 184 * @param maximum the maximum number of matches required in each file. 185 * @since 5.0 186 */ 187 public void setMaximum(int maximum) { 188 this.maximum = maximum; 189 } 190 191 /** 192 * Setter to control whether to ignore case when searching. 193 * 194 * @param ignoreCase whether to ignore case when searching. 195 * @since 5.0 196 */ 197 public void setIgnoreCase(boolean ignoreCase) { 198 this.ignoreCase = ignoreCase; 199 } 200 201 /** 202 * Setter to control whether to ignore text in comments when searching. 203 * 204 * @param ignore whether to ignore text in comments when searching. 205 * @since 5.0 206 */ 207 public void setIgnoreComments(boolean ignore) { 208 ignoreComments = ignore; 209 } 210 211}