001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2017 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 * @author Oliver Burn 030 */ 031public final class DetectorOptions { 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 * Returns new Builder object. 061 * @return Builder object. 062 */ 063 public static Builder newBuilder() { 064 return new DetectorOptions().new Builder(); 065 } 066 067 /** 068 * Format of the regular expression. 069 * @return format of the regular expression. 070 */ 071 public String getFormat() { 072 return format; 073 } 074 075 /** 076 * The violation reporter to use. 077 * @return the violation reporter to use. 078 */ 079 public AbstractViolationReporter getReporter() { 080 return reporter; 081 } 082 083 /** 084 * The message to report errors with. 085 * @return the message to report errors with. 086 */ 087 public String getMessage() { 088 return message; 089 } 090 091 /** 092 * The minimum number of allowed detections. 093 * @return the minimum number of allowed detections. 094 */ 095 public int getMinimum() { 096 return minimum; 097 } 098 099 /** 100 * The maximum number of allowed detections. 101 * @return the maximum number of allowed detections. 102 */ 103 public int getMaximum() { 104 return maximum; 105 } 106 107 /** 108 * The suppressor to use. 109 * @return the suppressor to use. 110 */ 111 public MatchSuppressor getSuppressor() { 112 return suppressor; 113 } 114 115 /** 116 * The pattern to use when matching. 117 * @return the pattern to use when matching. 118 */ 119 public Pattern getPattern() { 120 if (pattern == null) { 121 int options = compileFlags; 122 123 if (ignoreCase) { 124 options |= Pattern.CASE_INSENSITIVE; 125 } 126 pattern = Pattern.compile(format, options); 127 } 128 return pattern; 129 } 130 131 /** Class which implements Builder pattern to build DetectorOptions instance. */ 132 public final class Builder { 133 134 /** 135 * Specifies the violation reporter and returns Builder object. 136 * @param val for reporting violations. 137 * @return Builder object. 138 * @noinspection ReturnOfInnerClass 139 */ 140 public Builder reporter(AbstractViolationReporter val) { 141 reporter = val; 142 return this; 143 } 144 145 /** 146 * Specifies the compile flags to compile a regular expression with 147 * and returns Builder object. 148 * @param val the format to use when matching lines. 149 * @return Builder object. 150 * @noinspection ReturnOfInnerClass 151 */ 152 public Builder compileFlags(int val) { 153 compileFlags = val; 154 return this; 155 } 156 157 /** 158 * Specifies the format to use when matching lines and returns Builder object. 159 * @param val the format to use when matching lines. 160 * @return Builder object. 161 * @noinspection ReturnOfInnerClass 162 */ 163 public Builder format(String val) { 164 format = val; 165 return this; 166 } 167 168 /** 169 * Specifies message to use when reporting a match and returns Builder object. 170 * @param val message to use when reporting a match. 171 * @return Builder object. 172 * @noinspection ReturnOfInnerClass 173 */ 174 public Builder message(String val) { 175 message = val; 176 return this; 177 } 178 179 /** 180 * Specifies the minimum allowed number of detections and returns Builder object. 181 * @param val the minimum allowed number of detections. 182 * @return Builder object. 183 * @noinspection ReturnOfInnerClass 184 */ 185 public Builder minimum(int val) { 186 minimum = val; 187 return this; 188 } 189 190 /** 191 * Specifies the maximum allowed number of detections and returns Builder object. 192 * @param val the maximum allowed number of detections. 193 * @return Builder object. 194 * @noinspection ReturnOfInnerClass 195 */ 196 public Builder maximum(int val) { 197 maximum = val; 198 return this; 199 } 200 201 /** 202 * Specifies whether to ignore case when matching and returns Builder object. 203 * @param val whether to ignore case when matching. 204 * @return Builder object. 205 * @noinspection ReturnOfInnerClass 206 */ 207 public Builder ignoreCase(boolean val) { 208 ignoreCase = val; 209 return this; 210 } 211 212 /** 213 * Specifies the suppressor to use and returns Builder object. 214 * @param val the suppressor to use. 215 * @return current instance 216 * @noinspection ReturnOfInnerClass 217 */ 218 public Builder suppressor(MatchSuppressor val) { 219 suppressor = val; 220 return this; 221 } 222 223 /** 224 * Returns new DetectorOptions instance. 225 * @return DetectorOptions instance. 226 */ 227 public DetectorOptions build() { 228 message = Optional.ofNullable(message).orElse(""); 229 suppressor = Optional.ofNullable(suppressor).orElse(NeverSuppress.INSTANCE); 230 return DetectorOptions.this; 231 } 232 } 233}