1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package org.apache.commons.io.filefilter;
18
19import java.io.File;
20import java.io.Serializable;
21import java.util.List;
22
23import org.apache.commons.io.IOCase;
24
25/**
26 * Filters filenames for a certain prefix.
27 * <p>
28 * For example, to print all files and directories in the
29 * current directory whose name starts with <code>Test</code>:
30 *
31 * <pre>
32 * File dir = new File(".");
33 * String[] files = dir.list( new PrefixFileFilter("Test") );
34 * for ( int i = 0; i &lt; files.length; i++ ) {
35 *     System.out.println(files[i]);
36 * }
37 * </pre>
38 *
39 * @since Commons IO 1.0
40 * @version $Revision: 606381 $ $Date: 2007-12-22 02:03:16 +0000 (Sat, 22 Dec 2007) $
41 *
42 * @author Stephen Colebourne
43 * @author Federico Barbieri
44 * @author Serge Knystautas
45 * @author Peter Donald
46 */
47public class PrefixFileFilter extends AbstractFileFilter implements Serializable {
48
49    /** The filename prefixes to search for */
50    private final String[] prefixes;
51
52    /** Whether the comparison is case sensitive. */
53    private final IOCase caseSensitivity;
54
55    /**
56     * Constructs a new Prefix file filter for a single prefix.
57     *
58     * @param prefix  the prefix to allow, must not be null
59     * @throws IllegalArgumentException if the prefix is null
60     */
61    public PrefixFileFilter(String prefix) {
62        this(prefix, IOCase.SENSITIVE);
63    }
64
65    /**
66     * Constructs a new Prefix file filter for a single prefix
67     * specifying case-sensitivity.
68     *
69     * @param prefix  the prefix to allow, must not be null
70     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
71     * @throws IllegalArgumentException if the prefix is null
72     * @since Commons IO 1.4
73     */
74    public PrefixFileFilter(String prefix, IOCase caseSensitivity) {
75        if (prefix == null) {
76            throw new IllegalArgumentException("The prefix must not be null");
77        }
78        this.prefixes = new String[] {prefix};
79        this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
80    }
81
82    /**
83     * Constructs a new Prefix file filter for any of an array of prefixes.
84     * <p>
85     * The array is not cloned, so could be changed after constructing the
86     * instance. This would be inadvisable however.
87     *
88     * @param prefixes  the prefixes to allow, must not be null
89     * @throws IllegalArgumentException if the prefix array is null
90     */
91    public PrefixFileFilter(String[] prefixes) {
92        this(prefixes, IOCase.SENSITIVE);
93    }
94
95    /**
96     * Constructs a new Prefix file filter for any of an array of prefixes
97     * specifying case-sensitivity.
98     * <p>
99     * The array is not cloned, so could be changed after constructing the
100     * instance. This would be inadvisable however.
101     *
102     * @param prefixes  the prefixes to allow, must not be null
103     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
104     * @throws IllegalArgumentException if the prefix is null
105     * @since Commons IO 1.4
106     */
107    public PrefixFileFilter(String[] prefixes, IOCase caseSensitivity) {
108        if (prefixes == null) {
109            throw new IllegalArgumentException("The array of prefixes must not be null");
110        }
111        this.prefixes = prefixes;
112        this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
113    }
114
115    /**
116     * Constructs a new Prefix file filter for a list of prefixes.
117     *
118     * @param prefixes  the prefixes to allow, must not be null
119     * @throws IllegalArgumentException if the prefix list is null
120     * @throws ClassCastException if the list does not contain Strings
121     */
122    public PrefixFileFilter(List<String> prefixes) {
123        this(prefixes, IOCase.SENSITIVE);
124    }
125
126    /**
127     * Constructs a new Prefix file filter for a list of prefixes
128     * specifying case-sensitivity.
129     *
130     * @param prefixes  the prefixes to allow, must not be null
131     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
132     * @throws IllegalArgumentException if the prefix list is null
133     * @throws ClassCastException if the list does not contain Strings
134     * @since Commons IO 1.4
135     */
136    public PrefixFileFilter(List<String> prefixes, IOCase caseSensitivity) {
137        if (prefixes == null) {
138            throw new IllegalArgumentException("The list of prefixes must not be null");
139        }
140        this.prefixes = prefixes.toArray(new String[prefixes.size()]);
141        this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
142    }
143
144    /**
145     * Checks to see if the filename starts with the prefix.
146     *
147     * @param file  the File to check
148     * @return true if the filename starts with one of our prefixes
149     */
150    @Override
151    public boolean accept(File file) {
152        String name = file.getName();
153        for (int i = 0; i < this.prefixes.length; i++) {
154            if (caseSensitivity.checkStartsWith(name, prefixes[i])) {
155                return true;
156            }
157        }
158        return false;
159    }
160
161    /**
162     * Checks to see if the filename starts with the prefix.
163     *
164     * @param file  the File directory
165     * @param name  the filename
166     * @return true if the filename starts with one of our prefixes
167     */
168    @Override
169    public boolean accept(File file, String name) {
170        for (int i = 0; i < prefixes.length; i++) {
171            if (caseSensitivity.checkStartsWith(name, prefixes[i])) {
172                return true;
173            }
174        }
175        return false;
176    }
177
178    /**
179     * Provide a String representaion of this file filter.
180     *
181     * @return a String representaion
182     */
183    @Override
184    public String toString() {
185        StringBuffer buffer = new StringBuffer();
186        buffer.append(super.toString());
187        buffer.append("(");
188        if (prefixes != null) {
189            for (int i = 0; i < prefixes.length; i++) {
190                if (i > 0) {
191                    buffer.append(",");
192                }
193                buffer.append(prefixes[i]);
194            }
195        }
196        buffer.append(")");
197        return buffer.toString();
198    }
199
200}
201