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 * Creates a new {@code Builder} instance. 136 */ 137 public Builder() { 138 // no code by default 139 } 140 141 /** 142 * Specifies the violation reporter and returns Builder object. 143 * 144 * @param val for reporting violations. 145 * @return Builder object. 146 * @noinspection ReturnOfInnerClass 147 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 148 */ 149 public Builder reporter(AbstractViolationReporter val) { 150 reporter = val; 151 return this; 152 } 153 154 /** 155 * Specifies the compile-flags to compile a regular expression with 156 * and returns Builder object. 157 * 158 * @param val the format to use when matching lines. 159 * @return Builder object. 160 * @noinspection ReturnOfInnerClass 161 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 162 */ 163 public Builder compileFlags(int val) { 164 compileFlags = val; 165 return this; 166 } 167 168 /** 169 * Specifies the format to use when matching lines and returns Builder object. 170 * 171 * @param val the format to use when matching lines. 172 * @return Builder object. 173 * @noinspection ReturnOfInnerClass 174 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 175 */ 176 public Builder format(String val) { 177 format = val; 178 return this; 179 } 180 181 /** 182 * Specifies message to use when reporting a match and returns Builder object. 183 * 184 * @param val message to use when reporting a match. 185 * @return Builder object. 186 * @noinspection ReturnOfInnerClass 187 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 188 */ 189 public Builder message(String val) { 190 message = val; 191 return this; 192 } 193 194 /** 195 * Specifies the minimum allowed number of detections and returns Builder object. 196 * 197 * @param val the minimum allowed number of detections. 198 * @return Builder object. 199 * @noinspection ReturnOfInnerClass 200 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 201 */ 202 public Builder minimum(int val) { 203 minimum = val; 204 return this; 205 } 206 207 /** 208 * Specifies the maximum allowed number of detections and returns Builder object. 209 * 210 * @param val the maximum allowed number of detections. 211 * @return Builder object. 212 * @noinspection ReturnOfInnerClass 213 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 214 */ 215 public Builder maximum(int val) { 216 maximum = val; 217 return this; 218 } 219 220 /** 221 * Specifies whether to ignore case when matching and returns Builder object. 222 * 223 * @param val whether to ignore case when matching. 224 * @return Builder object. 225 * @noinspection ReturnOfInnerClass, BooleanParameter 226 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 227 * @noinspectionreason BooleanParameter - check fields are boolean 228 */ 229 public Builder ignoreCase(boolean val) { 230 ignoreCase = val; 231 return this; 232 } 233 234 /** 235 * Specifies the suppressor to use and returns Builder object. 236 * 237 * @param val the suppressor to use. 238 * @return current instance 239 * @noinspection ReturnOfInnerClass 240 * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class 241 */ 242 public Builder suppressor(MatchSuppressor val) { 243 suppressor = val; 244 return this; 245 } 246 247 /** 248 * Returns new DetectorOptions instance. 249 * 250 * @return DetectorOptions instance. 251 */ 252 public DetectorOptions build() { 253 message = Optional.ofNullable(message).orElse(""); 254 suppressor = Optional.ofNullable(suppressor).orElse(NeverSuppress.INSTANCE); 255 pattern = Optional.ofNullable(format).map(this::createPattern).orElse(null); 256 return DetectorOptions.this; 257 } 258 259 /** 260 * Creates pattern to use by DetectorOptions instance. 261 * 262 * @param formatValue the format to use. 263 * @return Pattern object. 264 */ 265 private Pattern createPattern(String formatValue) { 266 int options = compileFlags; 267 if (ignoreCase) { 268 options |= Pattern.CASE_INSENSITIVE; 269 } 270 return Pattern.compile(formatValue, options); 271 } 272 273 } 274 275}