View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ///////////////////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.checks.regexp;
21  
22  import java.util.Optional;
23  import java.util.regex.Pattern;
24  
25  import com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter;
26  
27  /**
28   * Options for a detector.
29   */
30  public final class DetectorOptions {
31  
32      /**
33       * Flags to compile a regular expression with.
34       * See {@link Pattern#flags()}.
35       */
36      private int compileFlags;
37      /** Used for reporting violations. */
38      private AbstractViolationReporter reporter;
39      /**
40       * Format of the regular expression to check for.
41       */
42      private String format;
43      /** The message to report on detection. If blank, then use the format. */
44      private String message;
45      /** Minimum number of times regular expression should occur in a file. */
46      private int minimum;
47      /** Maximum number of times regular expression should occur in a file. */
48      private int maximum;
49      /** Whether to ignore case when matching. */
50      private boolean ignoreCase;
51      /** Used to determine whether to suppress a detected match. */
52      private MatchSuppressor suppressor;
53      /** Pattern created from format. Lazily initialized. */
54      private Pattern pattern;
55  
56      /** Default constructor.*/
57      private DetectorOptions() {
58      }
59  
60      /**
61       * Returns new Builder object.
62       *
63       * @return Builder object.
64       */
65      public static Builder newBuilder() {
66          return new DetectorOptions().new Builder();
67      }
68  
69      /**
70       * Format of the regular expression.
71       *
72       * @return format of the regular expression.
73       */
74      public String getFormat() {
75          return format;
76      }
77  
78      /**
79       * The violation reporter to use.
80       *
81       * @return the violation reporter to use.
82       */
83      public AbstractViolationReporter getReporter() {
84          return reporter;
85      }
86  
87      /**
88       * The message to report violations with.
89       *
90       * @return the message to report violations with.
91       */
92      public String getMessage() {
93          return message;
94      }
95  
96      /**
97       * The minimum number of allowed detections.
98       *
99       * @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          * Specifies the violation reporter and returns Builder object.
137          *
138          * @param val for reporting violations.
139          * @return Builder object.
140          * @noinspection ReturnOfInnerClass
141          * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class
142          */
143         public Builder reporter(AbstractViolationReporter val) {
144             reporter = val;
145             return this;
146         }
147 
148         /**
149          * Specifies the compile-flags to compile a regular expression with
150          * and returns Builder object.
151          *
152          * @param val the format to use when matching lines.
153          * @return Builder object.
154          * @noinspection ReturnOfInnerClass
155          * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class
156          */
157         public Builder compileFlags(int val) {
158             compileFlags = val;
159             return this;
160         }
161 
162         /**
163          * Specifies the format to use when matching lines and returns Builder object.
164          *
165          * @param val the format to use when matching lines.
166          * @return Builder object.
167          * @noinspection ReturnOfInnerClass
168          * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class
169          */
170         public Builder format(String val) {
171             format = val;
172             return this;
173         }
174 
175         /**
176          * Specifies message to use when reporting a match and returns Builder object.
177          *
178          * @param val message to use when reporting a match.
179          * @return Builder object.
180          * @noinspection ReturnOfInnerClass
181          * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class
182          */
183         public Builder message(String val) {
184             message = val;
185             return this;
186         }
187 
188         /**
189          * Specifies the minimum allowed number of detections and returns Builder object.
190          *
191          * @param val the minimum allowed number of detections.
192          * @return Builder object.
193          * @noinspection ReturnOfInnerClass
194          * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class
195          */
196         public Builder minimum(int val) {
197             minimum = val;
198             return this;
199         }
200 
201         /**
202          * Specifies the maximum allowed number of detections and returns Builder object.
203          *
204          * @param val the maximum allowed number of detections.
205          * @return Builder object.
206          * @noinspection ReturnOfInnerClass
207          * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class
208          */
209         public Builder maximum(int val) {
210             maximum = val;
211             return this;
212         }
213 
214         /**
215          * Specifies whether to ignore case when matching and returns Builder object.
216          *
217          * @param val whether to ignore case when matching.
218          * @return Builder object.
219          * @noinspection ReturnOfInnerClass, BooleanParameter
220          * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class
221          * @noinspectionreason BooleanParameter - check fields are boolean
222          */
223         public Builder ignoreCase(boolean val) {
224             ignoreCase = val;
225             return this;
226         }
227 
228         /**
229          * Specifies the suppressor to use and returns Builder object.
230          *
231          * @param val the suppressor to use.
232          * @return current instance
233          * @noinspection ReturnOfInnerClass
234          * @noinspectionreason ReturnOfInnerClass - builder is only used in enclosing class
235          */
236         public Builder suppressor(MatchSuppressor val) {
237             suppressor = val;
238             return this;
239         }
240 
241         /**
242          * Returns new DetectorOptions instance.
243          *
244          * @return DetectorOptions instance.
245          */
246         public DetectorOptions build() {
247             message = Optional.ofNullable(message).orElse("");
248             suppressor = Optional.ofNullable(suppressor).orElse(NeverSuppress.INSTANCE);
249             pattern = Optional.ofNullable(format).map(this::createPattern).orElse(null);
250             return DetectorOptions.this;
251         }
252 
253         /**
254          * Creates pattern to use by DetectorOptions instance.
255          *
256          * @param formatValue the format to use.
257          * @return Pattern object.
258          */
259         private Pattern createPattern(String formatValue) {
260             int options = compileFlags;
261             if (ignoreCase) {
262                 options |= Pattern.CASE_INSENSITIVE;
263             }
264             return Pattern.compile(formatValue, options);
265         }
266 
267     }
268 
269 }