View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 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   * @author Oliver Burn
30   */
31  public final class DetectorOptions {
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       * Returns new Builder object.
61       * @return Builder object.
62       */
63      public static Builder newBuilder() {
64          return new DetectorOptions().new Builder();
65      }
66  
67      /**
68       * Format of the regular expression.
69       * @return format of the regular expression.
70       */
71      public String getFormat() {
72          return format;
73      }
74  
75      /**
76       * The violation reporter to use.
77       * @return the violation reporter to use.
78       */
79      public AbstractViolationReporter getReporter() {
80          return reporter;
81      }
82  
83      /**
84       * The message to report errors with.
85       * @return the message to report errors with.
86       */
87      public String getMessage() {
88          return message;
89      }
90  
91      /**
92       * The minimum number of allowed detections.
93       * @return the minimum number of allowed detections.
94       */
95      public int getMinimum() {
96          return minimum;
97      }
98  
99      /**
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, BooleanParameter
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 }