001/////////////////////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code and other text files for adherence to a set of rules. 003// Copyright (C) 2001-2026 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.util.Optional; 023import java.util.regex.Pattern; 024 025import com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter; 026 027/** 028 * Options for a detector. 029 */ 030public final class DetectorOptions { 031 032 /** 033 * Flags to compile a regular expression with. 034 * See {@link Pattern#flags()}. 035 */ 036 private int compileFlags; 037 /** Used for reporting violations. */ 038 private AbstractViolationReporter reporter; 039 /** 040 * Format of the regular expression to check for. 041 */ 042 private String format; 043 /** The message to report on detection. If blank, then use the format. */ 044 private String message; 045 /** Minimum number of times regular expression should occur in a file. */ 046 private int minimum; 047 /** Maximum number of times regular expression should occur in a file. */ 048 private int maximum; 049 /** Whether to ignore case when matching. */ 050 private boolean ignoreCase; 051 /** Used to determine whether to suppress a detected match. */ 052 private MatchSuppressor suppressor; 053 /** Pattern created from format. Lazily initialized. */ 054 private Pattern pattern; 055 056 /** Default constructor.*/ 057 private DetectorOptions() { 058 } 059 060 /** 061 * Returns new Builder object. 062 * 063 * @return Builder object. 064 */ 065 public static Builder newBuilder() { 066 return new DetectorOptions().new Builder(); 067 } 068 069 /** 070 * Format of the regular expression. 071 * 072 * @return format of the regular expression. 073 */ 074 public String getFormat() { 075 return format; 076 } 077 078 /** 079 * The violation reporter to use. 080 * 081 * @return the violation reporter to use. 082 */ 083 public AbstractViolationReporter getReporter() { 084 return reporter; 085 } 086 087 /** 088 * The message to report violations with. 089 * 090 * @return the message to report violations with. 091 */ 092 public String getMessage() { 093 return message; 094 } 095 096 /** 097 * The minimum number of allowed detections. 098 * 099 * @return the minimum number of allowed detections. 100 */ 101 public int getMinimum() { 102 return minimum; 103 } 104 105 /** 106 * The maximum number of allowed detections. 107 * 108 * @return the maximum number of allowed detections. 109 */ 110 public int getMaximum() { 111 return maximum; 112 } 113 114 /** 115 * The suppressor to use. 116 * 117 * @return the suppressor to use. 118 */ 119 public MatchSuppressor getSuppressor() { 120 return suppressor; 121 } 122 123 /** 124 * The pattern to use when matching. 125 * 126 * @return the pattern to use when matching. 127 */ 128 public Pattern getPattern() { 129 return pattern; 130 } 131 132 /** Class which implements Builder pattern to build DetectorOptions instance. */ 133 public final class Builder { 134 135 /** 136 * Creates a new {@code Builder} instance. 137 */ 138 public Builder() { 139 // no code by default 140 } 141 142 /** 143 * Specifies the violation reporter and returns Builder object. 144 * 145 * @param val for reporting violations. 146 * @return Builder object. 147 * @noinspection ReturnOfInnerClass 148 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 149 */ 150 public Builder reporter(AbstractViolationReporter val) { 151 reporter = val; 152 return this; 153 } 154 155 /** 156 * Specifies the compile-flags to compile a regular expression with 157 * and returns Builder object. 158 * 159 * @param val the format to use when matching lines. 160 * @return Builder object. 161 * @noinspection ReturnOfInnerClass 162 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 163 */ 164 public Builder compileFlags(int val) { 165 compileFlags = val; 166 return this; 167 } 168 169 /** 170 * Specifies the format to use when matching lines and returns Builder object. 171 * 172 * @param val the format to use when matching lines. 173 * @return Builder object. 174 * @noinspection ReturnOfInnerClass 175 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 176 */ 177 public Builder format(String val) { 178 format = val; 179 return this; 180 } 181 182 /** 183 * Specifies message to use when reporting a match and returns Builder object. 184 * 185 * @param val message to use when reporting a match. 186 * @return Builder object. 187 * @noinspection ReturnOfInnerClass 188 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 189 */ 190 public Builder message(String val) { 191 message = val; 192 return this; 193 } 194 195 /** 196 * Specifies the minimum allowed number of detections and returns Builder object. 197 * 198 * @param val the minimum allowed number of detections. 199 * @return Builder object. 200 * @noinspection ReturnOfInnerClass 201 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 202 */ 203 public Builder minimum(int val) { 204 minimum = val; 205 return this; 206 } 207 208 /** 209 * Specifies the maximum allowed number of detections and returns Builder object. 210 * 211 * @param val the maximum allowed number of detections. 212 * @return Builder object. 213 * @noinspection ReturnOfInnerClass 214 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 215 */ 216 public Builder maximum(int val) { 217 maximum = val; 218 return this; 219 } 220 221 /** 222 * Specifies whether to ignore case when matching and returns Builder object. 223 * 224 * @param val whether to ignore case when matching. 225 * @return Builder object. 226 * @noinspection ReturnOfInnerClass, BooleanParameter 227 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 228 * @noinspectionreason BooleanParameter - check fields are boolean 229 */ 230 public Builder ignoreCase(boolean val) { 231 ignoreCase = val; 232 return this; 233 } 234 235 /** 236 * Specifies the suppressor to use and returns Builder object. 237 * 238 * @param val the suppressor to use. 239 * @return current instance 240 * @noinspection ReturnOfInnerClass 241 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 242 */ 243 public Builder suppressor(MatchSuppressor val) { 244 suppressor = val; 245 return this; 246 } 247 248 /** 249 * Returns new DetectorOptions instance. 250 * 251 * @return DetectorOptions instance. 252 */ 253 public DetectorOptions build() { 254 message = Optional.ofNullable(message).orElse(""); 255 suppressor = Optional.ofNullable(suppressor).orElse(NeverSuppress.INSTANCE); 256 pattern = Optional.ofNullable(format).map(this::createPattern).orElse(null); 257 return DetectorOptions.this; 258 } 259 260 /** 261 * Creates pattern to use by DetectorOptions instance. 262 * 263 * @param formatValue the format to use. 264 * @return Pattern object. 265 */ 266 private Pattern createPattern(String formatValue) { 267 int options = compileFlags; 268 if (ignoreCase) { 269 options |= Pattern.CASE_INSENSITIVE; 270 } 271 return Pattern.compile(formatValue, options); 272 } 273 274 } 275 276}