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 filenames 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 * @version $Id: PrefixFileFilter.java 1304052 2012-03-22 20:55:29Z ggregory $
041 * @see FileFilterUtils#prefixFileFilter(String)
042 * @see FileFilterUtils#prefixFileFilter(String, IOCase)
043 */
044public class PrefixFileFilter extends AbstractFileFilter implements Serializable {
045    
046    /** The filename prefixes to search for */
047    private final String[] prefixes;
048
049    /** Whether the comparison is case sensitive. */
050    private final IOCase caseSensitivity;
051
052    /**
053     * Constructs a new Prefix file filter for a single prefix.
054     * 
055     * @param prefix  the prefix to allow, must not be null
056     * @throws IllegalArgumentException if the prefix is null
057     */
058    public PrefixFileFilter(String prefix) {
059        this(prefix, IOCase.SENSITIVE);
060    }
061
062    /**
063     * Constructs a new Prefix file filter for a single prefix 
064     * specifying case-sensitivity.
065     * 
066     * @param prefix  the prefix to allow, must not be null
067     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
068     * @throws IllegalArgumentException if the prefix is null
069     * @since 1.4
070     */
071    public PrefixFileFilter(String prefix, IOCase caseSensitivity) {
072        if (prefix == null) {
073            throw new IllegalArgumentException("The prefix must not be null");
074        }
075        this.prefixes = new String[] {prefix};
076        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
077    }
078
079    /**
080     * Constructs a new Prefix file filter for any of an array of prefixes.
081     * <p>
082     * The array is not cloned, so could be changed after constructing the
083     * instance. This would be inadvisable however.
084     * 
085     * @param prefixes  the prefixes to allow, must not be null
086     * @throws IllegalArgumentException if the prefix array is null
087     */
088    public PrefixFileFilter(String[] prefixes) {
089        this(prefixes, IOCase.SENSITIVE);
090    }
091
092    /**
093     * Constructs a new Prefix file filter for any of an array of prefixes
094     * specifying case-sensitivity.
095     * <p>
096     * The array is not cloned, so could be changed after constructing the
097     * instance. This would be inadvisable however.
098     * 
099     * @param prefixes  the prefixes to allow, must not be null
100     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
101     * @throws IllegalArgumentException if the prefix is null
102     * @since 1.4
103     */
104    public PrefixFileFilter(String[] prefixes, IOCase caseSensitivity) {
105        if (prefixes == null) {
106            throw new IllegalArgumentException("The array of prefixes must not be null");
107        }
108        this.prefixes = new String[prefixes.length];
109        System.arraycopy(prefixes, 0, this.prefixes, 0, prefixes.length);
110        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
111    }
112
113    /**
114     * Constructs a new Prefix file filter for a list of prefixes.
115     * 
116     * @param prefixes  the prefixes to allow, must not be null
117     * @throws IllegalArgumentException if the prefix list is null
118     * @throws ClassCastException if the list does not contain Strings
119     */
120    public PrefixFileFilter(List<String> prefixes) {
121        this(prefixes, IOCase.SENSITIVE);
122    }
123
124    /**
125     * Constructs a new Prefix file filter for a list of prefixes
126     * specifying case-sensitivity.
127     * 
128     * @param prefixes  the prefixes to allow, must not be null
129     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
130     * @throws IllegalArgumentException if the prefix list is null
131     * @throws ClassCastException if the list does not contain Strings
132     * @since 1.4
133     */
134    public PrefixFileFilter(List<String> prefixes, IOCase caseSensitivity) {
135        if (prefixes == null) {
136            throw new IllegalArgumentException("The list of prefixes must not be null");
137        }
138        this.prefixes = prefixes.toArray(new String[prefixes.size()]);
139        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
140    }
141
142    /**
143     * Checks to see if the filename starts with the prefix.
144     * 
145     * @param file  the File to check
146     * @return true if the filename starts with one of our prefixes
147     */
148    @Override
149    public boolean accept(File file) {
150        String name = file.getName();
151        for (String prefix : this.prefixes) {
152            if (caseSensitivity.checkStartsWith(name, prefix)) {
153                return true;
154            }
155        }
156        return false;
157    }
158    
159    /**
160     * Checks to see if the filename starts with the prefix.
161     * 
162     * @param file  the File directory
163     * @param name  the filename
164     * @return true if the filename starts with one of our prefixes
165     */
166    @Override
167    public boolean accept(File file, String name) {
168        for (String prefix : prefixes) {
169            if (caseSensitivity.checkStartsWith(name, prefix)) {
170                return true;
171            }
172        }
173        return false;
174    }
175
176    /**
177     * Provide a String representaion of this file filter.
178     *
179     * @return a String representaion
180     */
181    @Override
182    public String toString() {
183        StringBuilder buffer = new StringBuilder();
184        buffer.append(super.toString());
185        buffer.append("(");
186        if (prefixes != null) {
187            for (int i = 0; i < prefixes.length; i++) {
188                if (i > 0) {
189                    buffer.append(",");
190                }
191                buffer.append(prefixes[i]);
192            }
193        }
194        buffer.append(")");
195        return buffer.toString();
196    }
197    
198}