    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 */
    017package org.apache.commons.io.filefilter;
    018
    019import java.io.File;
    020import java.io.Serializable;
    021import java.util.List;
    022
    023import org.apache.commons.io.IOCase;
    024
    025/**
    026 * Filters file names for a certain prefix.
    027 * <p>
    028 * For example, to print all files and directories in the
    029 * current directory whose name starts with <code>Test</code>:
    030 *
    031 * <pre>
    032 * File dir = new File(".");
    033 * String[] files = dir.list( new PrefixFileFilter("Test") );
    034 * for ( int i = 0; i &lt; files.length; i++ ) {
    035 *     System.out.println(files[i]);
    036 * }
    037 * </pre>
    038 *
    039 * @since 1.0
    040 *
    041 * @see FileFilterUtils#prefixFileFilter(String)
    042 * @see FileFilterUtils#prefixFileFilter(String, IOCase)
    043 */
    044public class PrefixFileFilter extends AbstractFileFilter implements Serializable {
    045
    046    private static final long serialVersionUID = 8533897440809599867L;
    047
    048    /** The file name prefixes to search for */
    049    private final String[] prefixes;
    050
    051    /** Whether the comparison is case sensitive. */
    052    private final IOCase caseSensitivity;
    053
    054    /**
    055     * Constructs a new Prefix file filter for a single prefix.
    056     *
    057     * @param prefix  the prefix to allow, must not be null
    058     * @throws IllegalArgumentException if the prefix is null
    059     */
    060    public PrefixFileFilter(final String prefix) {
    061        this(prefix, IOCase.SENSITIVE);
    062    }
    063
    064    /**
    065     * Constructs a new Prefix file filter for a single prefix
    066     * specifying case-sensitivity.
    067     *
    068     * @param prefix  the prefix to allow, must not be null
    069     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    070     * @throws IllegalArgumentException if the prefix is null
    071     * @since 1.4
    072     */
    073    public PrefixFileFilter(final String prefix, final IOCase caseSensitivity) {
    074        if (prefix == null) {
    075            throw new IllegalArgumentException("The prefix must not be null");
    076        }
    077        this.prefixes = new String[] {prefix};
    078        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
    079    }
    080
    081    /**
    082     * Constructs a new Prefix file filter for any of an array of prefixes.
    083     * <p>
    084     * The array is not cloned, so could be changed after constructing the
    085     * instance. This would be inadvisable however.
    086     *
    087     * @param prefixes  the prefixes to allow, must not be null
    088     * @throws IllegalArgumentException if the prefix array is null
    089     */
    090    public PrefixFileFilter(final String... prefixes) {
    091        this(prefixes, IOCase.SENSITIVE);
    092    }
    093
    094    /**
    095     * Constructs a new Prefix file filter for any of an array of prefixes
    096     * specifying case-sensitivity.
    097     *
    098     * @param prefixes  the prefixes to allow, must not be null
    099     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    100     * @throws IllegalArgumentException if the prefix is null
    101     * @since 1.4
    102     */
    103    public PrefixFileFilter(final String[] prefixes, final IOCase caseSensitivity) {
    104        if (prefixes == null) {
    105            throw new IllegalArgumentException("The array of prefixes must not be null");
    106        }
    107        this.prefixes = new String[prefixes.length];
    108        System.arraycopy(prefixes, 0, this.prefixes, 0, prefixes.length);
    109        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
    110    }
    111
    112    /**
    113     * Constructs a new Prefix file filter for a list of prefixes.
    114     *
    115     * @param prefixes  the prefixes to allow, must not be null
    116     * @throws IllegalArgumentException if the prefix list is null
    117     * @throws ClassCastException if the list does not contain Strings
    118     */
    119    public PrefixFileFilter(final List<String> prefixes) {
    120        this(prefixes, IOCase.SENSITIVE);
    121    }
    122
    123    /**
    124     * Constructs a new Prefix file filter for a list of prefixes
    125     * specifying case-sensitivity.
    126     *
    127     * @param prefixes  the prefixes to allow, must not be null
    128     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    129     * @throws IllegalArgumentException if the prefix list is null
    130     * @throws ClassCastException if the list does not contain Strings
    131     * @since 1.4
    132     */
    133    public PrefixFileFilter(final List<String> prefixes, final IOCase caseSensitivity) {
    134        if (prefixes == null) {
    135            throw new IllegalArgumentException("The list of prefixes must not be null");
    136        }
    137        this.prefixes = prefixes.toArray(EMPTY_STRING_ARRAY);
    138        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
    139    }
    140
    141    /**
    142     * Checks to see if the file name starts with the prefix.
    143     *
    144     * @param file  the File to check
    145     * @return true if the file name starts with one of our prefixes
    146     */
    147    @Override
    148    public boolean accept(final File file) {
    149        final String name = file.getName();
    150        for (final String prefix : this.prefixes) {
    151            if (caseSensitivity.checkStartsWith(name, prefix)) {
    152                return true;
    153            }
    154        }
    155        return false;
    156    }
    157
    158    /**
    159     * Checks to see if the file name starts with the prefix.
    160     *
    161     * @param file  the File directory
    162     * @param name  the file name
    163     * @return true if the file name starts with one of our prefixes
    164     */
    165    @Override
    166    public boolean accept(final File file, final String name) {
    167        for (final String prefix : prefixes) {
    168            if (caseSensitivity.checkStartsWith(name, prefix)) {
    169                return true;
    170            }
    171        }
    172        return false;
    173    }
    174
    175    /**
    176     * Provide a String representation of this file filter.
    177     *
    178     * @return a String representation
    179     */
    180    @Override
    181    public String toString() {
    182        final StringBuilder buffer = new StringBuilder();
    183        buffer.append(super.toString());
    184        buffer.append("(");
    185        if (prefixes != null) {
    186            for (int i = 0; i < prefixes.length; i++) {
    187                if (i > 0) {
    188                    buffer.append(",");
    189                }
    190                buffer.append(prefixes[i]);
    191            }
    192        }
    193        buffer.append(")");
    194        return buffer.toString();
    195    }
    196
    197}