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