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