001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.text.matcher;
019
020import org.apache.commons.lang3.ArrayUtils;
021import org.apache.commons.lang3.StringUtils;
022
023/**
024 * Provides access to matchers defined in this package.
025 *
026 * @since 1.3
027 */
028public final class StringMatcherFactory {
029
030    /**
031     * Matches the comma character.
032     */
033    private static final AbstractStringMatcher.CharMatcher COMMA_MATCHER = new AbstractStringMatcher.CharMatcher(',');
034
035    /**
036     * Matches the double quote character.
037     */
038    private static final AbstractStringMatcher.CharMatcher DOUBLE_QUOTE_MATCHER = new AbstractStringMatcher.CharMatcher(
039        '"');
040
041    /**
042     * Defines the singleton for this class.
043     */
044    public static final StringMatcherFactory INSTANCE = new StringMatcherFactory();
045
046    /**
047     * Matches no characters.
048     */
049    private static final AbstractStringMatcher.NoneMatcher NONE_MATCHER = new AbstractStringMatcher.NoneMatcher();
050
051    /**
052     * Matches the single or double quote character.
053     */
054    private static final AbstractStringMatcher.CharSetMatcher QUOTE_MATCHER = new AbstractStringMatcher.CharSetMatcher(
055        "'\"".toCharArray());
056
057    /**
058     * Matches the double quote character.
059     */
060    private static final AbstractStringMatcher.CharMatcher SINGLE_QUOTE_MATCHER = new AbstractStringMatcher.CharMatcher(
061        '\'');
062
063    /**
064     * Matches the space character.
065     */
066    private static final AbstractStringMatcher.CharMatcher SPACE_MATCHER = new AbstractStringMatcher.CharMatcher(' ');
067
068    /**
069     * Matches the same characters as StringTokenizer, namely space, tab, newline, form feed.
070     */
071    private static final AbstractStringMatcher.CharSetMatcher SPLIT_MATCHER = new AbstractStringMatcher.CharSetMatcher(
072        " \t\n\r\f".toCharArray());
073
074    /**
075     * Matches the tab character.
076     */
077    private static final AbstractStringMatcher.CharMatcher TAB_MATCHER = new AbstractStringMatcher.CharMatcher('\t');
078
079    /**
080     * Matches the String trim() whitespace characters.
081     */
082    private static final AbstractStringMatcher.TrimMatcher TRIM_MATCHER = new AbstractStringMatcher.TrimMatcher();
083
084    /**
085     * No need to build instances for now.
086     */
087    private StringMatcherFactory() {
088        // empty
089    }
090
091    /**
092     * Creates a matcher that matches all of the given matchers in order.
093     *
094     * @param stringMatchers the matcher
095     * @return a matcher that matches all of the given matchers in order.
096     * @since 1.9
097     */
098    public StringMatcher andMatcher(final StringMatcher... stringMatchers) {
099        final int len = ArrayUtils.getLength(stringMatchers);
100        if (len == 0) {
101            return NONE_MATCHER;
102        }
103        if (len == 1) {
104            return stringMatchers[0];
105        }
106        return new AbstractStringMatcher.AndStringMatcher(stringMatchers);
107    }
108
109    /**
110     * Constructor that creates a matcher from a character.
111     *
112     * @param ch the character to match, must not be null
113     * @return a new Matcher for the given char
114     */
115    public StringMatcher charMatcher(final char ch) {
116        return new AbstractStringMatcher.CharMatcher(ch);
117    }
118
119    /**
120     * Constructor that creates a matcher from a set of characters.
121     *
122     * @param chars the characters to match, null or empty matches nothing
123     * @return a new matcher for the given char[]
124     */
125    public StringMatcher charSetMatcher(final char... chars) {
126        final int len = ArrayUtils.getLength(chars);
127        if (len == 0) {
128            return NONE_MATCHER;
129        }
130        if (len == 1) {
131            return new AbstractStringMatcher.CharMatcher(chars[0]);
132        }
133        return new AbstractStringMatcher.CharSetMatcher(chars);
134    }
135
136    /**
137     * Creates a matcher from a string representing a set of characters.
138     *
139     * @param chars the characters to match, null or empty matches nothing
140     * @return a new Matcher for the given characters
141     */
142    public StringMatcher charSetMatcher(final String chars) {
143        final int len = StringUtils.length(chars);
144        if (len == 0) {
145            return NONE_MATCHER;
146        }
147        if (len == 1) {
148            return new AbstractStringMatcher.CharMatcher(chars.charAt(0));
149        }
150        return new AbstractStringMatcher.CharSetMatcher(chars.toCharArray());
151    }
152
153    /**
154     * Returns a matcher which matches the comma character.
155     *
156     * @return a matcher for a comma
157     */
158    public StringMatcher commaMatcher() {
159        return COMMA_MATCHER;
160    }
161
162    /**
163     * Returns a matcher which matches the double quote character.
164     *
165     * @return a matcher for a double quote
166     */
167    public StringMatcher doubleQuoteMatcher() {
168        return DOUBLE_QUOTE_MATCHER;
169    }
170
171    /**
172     * Matches no characters.
173     *
174     * @return a matcher that matches nothing
175     */
176    public StringMatcher noneMatcher() {
177        return NONE_MATCHER;
178    }
179
180    /**
181     * Returns a matcher which matches the single or double quote character.
182     *
183     * @return a matcher for a single or double quote
184     */
185    public StringMatcher quoteMatcher() {
186        return QUOTE_MATCHER;
187    }
188
189    /**
190     * Returns a matcher which matches the single quote character.
191     *
192     * @return a matcher for a single quote
193     */
194    public StringMatcher singleQuoteMatcher() {
195        return SINGLE_QUOTE_MATCHER;
196    }
197
198    /**
199     * Returns a matcher which matches the space character.
200     *
201     * @return a matcher for a space
202     */
203    public StringMatcher spaceMatcher() {
204        return SPACE_MATCHER;
205    }
206
207    /**
208     * Matches the same characters as StringTokenizer, namely space, tab, newline and form feed.
209     *
210     * @return The split matcher
211     */
212    public StringMatcher splitMatcher() {
213        return SPLIT_MATCHER;
214    }
215
216    /**
217     * Creates a matcher from a string.
218     *
219     * @param chars the string to match, null or empty matches nothing
220     * @return a new Matcher for the given String
221     * @since 1.9
222     */
223    public StringMatcher stringMatcher(final char... chars) {
224        final int length = ArrayUtils.getLength(chars);
225        return length == 0 ? NONE_MATCHER
226            : length == 1 ? new AbstractStringMatcher.CharMatcher(chars[0])
227                : new AbstractStringMatcher.CharArrayMatcher(chars);
228    }
229
230    /**
231     * Creates a matcher from a string.
232     *
233     * @param str the string to match, null or empty matches nothing
234     * @return a new Matcher for the given String
235     */
236    public StringMatcher stringMatcher(final String str) {
237        return StringUtils.isEmpty(str) ? NONE_MATCHER : stringMatcher(str.toCharArray());
238    }
239
240    /**
241     * Returns a matcher which matches the tab character.
242     *
243     * @return a matcher for a tab
244     */
245    public StringMatcher tabMatcher() {
246        return TAB_MATCHER;
247    }
248
249    /**
250     * Matches the String trim() whitespace characters.
251     *
252     * @return The trim matcher
253     */
254    public StringMatcher trimMatcher() {
255        return TRIM_MATCHER;
256    }
257
258}