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