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}