    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 *      https://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}