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 name.
33   * <p>
34   * For example, to print all files and directories in the
35   * current directory whose name is {@code Test}:
36   * </p>
37   * <h2>Using Classic IO</h2>
38   * <pre>
39   * File dir = FileUtils.current();
40   * String[] files = dir.list(new NameFileFilter("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 NameFileFilter("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#nameFileFilter(String)
71   * @see FileFilterUtils#nameFileFilter(String, IOCase)
72   */
73  public class NameFileFilter extends AbstractFileFilter implements Serializable {
74  
75      private static final long serialVersionUID = 176844364689077340L;
76  
77      /** The file names to search for */
78      private final String[] names;
79  
80      /** Whether the comparison is case-sensitive. */
81      private final IOCase ioCase;
82  
83      /**
84       * Constructs a new case-sensitive name file filter for a list of names.
85       *
86       * @param names  the names to allow, must not be null
87       * @throws IllegalArgumentException if the name list is null
88       * @throws ClassCastException if the list does not contain Strings
89       */
90      public NameFileFilter(final List<String> names) {
91          this(names, null);
92      }
93  
94      /**
95       * Constructs a new name file filter for a list of names specifying case-sensitivity.
96       *
97       * @param names  the names to allow, must not be null
98       * @param ioCase  how to handle case sensitivity, null means case-sensitive
99       * @throws NullPointerException if the name list is null
100      * @throws ClassCastException if the list does not contain Strings
101      */
102     public NameFileFilter(final List<String> names, final IOCase ioCase) {
103         Objects.requireNonNull(names, "names");
104         this.names = names.toArray(EMPTY_STRING_ARRAY);
105         this.ioCase = toIOCase(ioCase);
106     }
107 
108     /**
109      * Constructs a new case-sensitive name file filter for a single name.
110      *
111      * @param name  the name to allow, must not be null
112      * @throws IllegalArgumentException if the name is null
113      */
114     public NameFileFilter(final String name) {
115         this(name, IOCase.SENSITIVE);
116     }
117 
118     /**
119      * Constructs a new case-sensitive name file filter for an array of names.
120      * <p>
121      * The array is not cloned, so could be changed after constructing the
122      * instance. This would be inadvisable however.
123      * </p>
124      *
125      * @param names  the names to allow, must not be null
126      * @throws IllegalArgumentException if the names array is null
127      */
128     public NameFileFilter(final String... names) {
129         this(names, IOCase.SENSITIVE);
130     }
131 
132     /**
133      * Constructs a new name file filter specifying case-sensitivity.
134      *
135      * @param name  the name to allow, must not be null
136      * @param ioCase  how to handle case sensitivity, null means case-sensitive
137      * @throws NullPointerException if the name is null
138      */
139     public NameFileFilter(final String name, final IOCase ioCase) {
140         Objects.requireNonNull(name, "name");
141         this.names = new String[] {name};
142         this.ioCase = toIOCase(ioCase);
143     }
144 
145     /**
146      * Constructs a new name file filter for an array of names specifying case-sensitivity.
147      *
148      * @param names  the names to allow, must not be null
149      * @param ioCase  how to handle case sensitivity, null means case-sensitive
150      * @throws NullPointerException if the names array is null
151      */
152     public NameFileFilter(final String[] names, final IOCase ioCase) {
153         Objects.requireNonNull(names, "names");
154         this.names = names.clone();
155         this.ioCase = toIOCase(ioCase);
156     }
157 
158     /**
159      * Checks to see if the file name matches.
160      *
161      * @param file  the File to check
162      * @return true if the file name matches
163      */
164     @Override
165     public boolean accept(final File file) {
166         return file != null && acceptBaseName(file.getName());
167     }
168 
169     /**
170      * Checks to see if the file name matches.
171      *
172      * @param dir  the File directory (ignored)
173      * @param name  the file name
174      * @return true if the file name matches
175      */
176     @Override
177     public boolean accept(final File dir, final String name) {
178         return acceptBaseName(name);
179     }
180 
181     /**
182      * Checks to see if the file name matches.
183      * @param path  the File to check
184      *
185      * @return true if the file name matches
186      * @since 2.9.0
187      */
188     @Override
189     public FileVisitResult accept(final Path path, final BasicFileAttributes attributes) {
190         return toFileVisitResult(acceptBaseName(PathUtils.getFileNameString(path)));
191     }
192 
193     private boolean acceptBaseName(final String baseName) {
194         return Stream.of(names).anyMatch(testName -> ioCase.checkEquals(baseName, testName));
195     }
196 
197     private IOCase toIOCase(final IOCase ioCase) {
198         return IOCase.value(ioCase, IOCase.SENSITIVE);
199     }
200 
201     /**
202      * Provide a String representation of this file filter.
203      *
204      * @return a String representation
205      */
206     @Override
207     public String toString() {
208         final StringBuilder buffer = new StringBuilder();
209         buffer.append(super.toString());
210         buffer.append("(");
211         append(names, buffer);
212         buffer.append(")");
213         return buffer.toString();
214     }
215 
216 }