View Javadoc
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   */
17  package org.apache.commons.io.filefilter;
18  
19  import java.io.File;
20  import java.io.Serializable;
21  import java.nio.file.FileVisitResult;
22  import java.nio.file.Path;
23  import java.nio.file.attribute.BasicFileAttributes;
24  import java.util.List;
25  import java.util.Objects;
26  import java.util.stream.Stream;
27  
28  import org.apache.commons.io.IOCase;
29  import org.apache.commons.io.file.PathUtils;
30  
31  /**
32   * Filters file names for a certain prefix.
33   * <p>
34   * For example, to print all files and directories in the
35   * current directory whose name starts with {@code Test}:
36   * </p>
37   * <h2>Using Classic IO</h2>
38   * <pre>
39   * File dir = FileUtils.current();
40   * String[] files = dir.list(new PrefixFileFilter("Test"));
41   * for (String file : files) {
42   *     System.out.println(file);
43   * }
44   * </pre>
45   *
46   * <h2>Using NIO</h2>
47   * <pre>
48   * final Path dir = PathUtils.current();
49   * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new PrefixFileFilter("Test"));
50   * //
51   * // Walk one dir
52   * Files.<b>walkFileTree</b>(dir, Collections.emptySet(), 1, visitor);
53   * System.out.println(visitor.getPathCounters());
54   * System.out.println(visitor.getFileList());
55   * //
56   * visitor.getPathCounters().reset();
57   * //
58   * // Walk dir tree
59   * Files.<b>walkFileTree</b>(dir, visitor);
60   * System.out.println(visitor.getPathCounters());
61   * System.out.println(visitor.getDirList());
62   * System.out.println(visitor.getFileList());
63   * </pre>
64   * <h2>Deprecating Serialization</h2>
65   * <p>
66   * <em>Serialization is deprecated and will be removed in 3.0.</em>
67   * </p>
68   *
69   * @since 1.0
70   * @see FileFilterUtils#prefixFileFilter(String)
71   * @see FileFilterUtils#prefixFileFilter(String, IOCase)
72   */
73  public class PrefixFileFilter extends AbstractFileFilter implements Serializable {
74  
75      private static final long serialVersionUID = 8533897440809599867L;
76  
77      /** The file name prefixes to search for */
78      private final String[] prefixes;
79  
80      /** Whether the comparison is case-sensitive. */
81      private final IOCase isCase;
82  
83      /**
84       * Constructs a new Prefix file filter for a list of prefixes.
85       *
86       * @param prefixes  the prefixes to allow, must not be null
87       * @throws NullPointerException if the prefix list is null
88       * @throws ClassCastException if the list does not contain Strings
89       */
90      public PrefixFileFilter(final List<String> prefixes) {
91          this(prefixes, IOCase.SENSITIVE);
92      }
93  
94      /**
95       * Constructs a new Prefix file filter for a list of prefixes
96       * specifying case-sensitivity.
97       *
98       * @param prefixes  the prefixes to allow, must not be null
99       * @param ioCase  how to handle case sensitivity, null means case-sensitive
100      * @throws NullPointerException if the prefix list is null
101      * @throws ClassCastException if the list does not contain Strings
102      * @since 1.4
103      */
104     public PrefixFileFilter(final List<String> prefixes, final IOCase ioCase) {
105         Objects.requireNonNull(prefixes, "prefixes");
106         this.prefixes = prefixes.toArray(EMPTY_STRING_ARRAY);
107         this.isCase = IOCase.value(ioCase, IOCase.SENSITIVE);
108     }
109 
110     /**
111      * Constructs a new Prefix file filter for a single prefix.
112      *
113      * @param prefix  the prefix to allow, must not be null
114      * @throws IllegalArgumentException if the prefix is null
115      */
116     public PrefixFileFilter(final String prefix) {
117         this(prefix, IOCase.SENSITIVE);
118     }
119 
120     /**
121      * Constructs a new Prefix file filter for any of an array of prefixes.
122      * <p>
123      * The array is not cloned, so could be changed after constructing the
124      * instance. This would be inadvisable however.
125      *
126      * @param prefixes  the prefixes to allow, must not be null
127      * @throws IllegalArgumentException if the prefix array is null
128      */
129     public PrefixFileFilter(final String... prefixes) {
130         this(prefixes, IOCase.SENSITIVE);
131     }
132 
133     /**
134      * Constructs a new Prefix file filter for a single prefix
135      * specifying case-sensitivity.
136      *
137      * @param prefix  the prefix to allow, must not be null
138      * @param ioCase  how to handle case sensitivity, null means case-sensitive
139      * @throws IllegalArgumentException if the prefix is null
140      * @since 1.4
141      */
142     public PrefixFileFilter(final String prefix, final IOCase ioCase) {
143         Objects.requireNonNull(prefix, "prefix");
144         this.prefixes = new String[] {prefix};
145         this.isCase = IOCase.value(ioCase, IOCase.SENSITIVE);
146     }
147 
148     /**
149      * Constructs a new Prefix file filter for any of an array of prefixes
150      * specifying case-sensitivity.
151      *
152      * @param prefixes  the prefixes to allow, must not be null
153      * @param ioCase  how to handle case sensitivity, null means case-sensitive
154      * @throws IllegalArgumentException if the prefix is null
155      * @since 1.4
156      */
157     public PrefixFileFilter(final String[] prefixes, final IOCase ioCase) {
158         Objects.requireNonNull(prefixes, "prefixes");
159         this.prefixes = prefixes.clone();
160         this.isCase = IOCase.value(ioCase, IOCase.SENSITIVE);
161     }
162 
163     /**
164      * Checks to see if the file name starts with the prefix.
165      *
166      * @param file  the File to check
167      * @return true if the file name starts with one of our prefixes
168      */
169     @Override
170     public boolean accept(final File file) {
171         return accept(file == null ? null : file.getName());
172     }
173 
174     /**
175      * Checks to see if the file name starts with the prefix.
176      *
177      * @param file  the File directory
178      * @param name  the file name
179      * @return true if the file name starts with one of our prefixes
180      */
181     @Override
182     public boolean accept(final File file, final String name) {
183         return accept(name);
184     }
185 
186     /**
187      * Checks to see if the file name starts with the prefix.
188      * @param file  the File to check
189      *
190      * @return true if the file name starts with one of our prefixes
191      * @since 2.9.0
192      */
193     @Override
194     public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
195         return toFileVisitResult(accept(PathUtils.getFileName(file, Path::toFile)));
196     }
197 
198     private boolean accept(final String name) {
199         return Stream.of(prefixes).anyMatch(prefix -> isCase.checkStartsWith(name, prefix));
200     }
201 
202     /**
203      * Provide a String representation of this file filter.
204      *
205      * @return a String representation
206      */
207     @Override
208     public String toString() {
209         final StringBuilder buffer = new StringBuilder();
210         buffer.append(super.toString());
211         buffer.append("(");
212         append(prefixes, buffer);
213         buffer.append(")");
214         return buffer.toString();
215     }
216 
217 }