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.Files;
23  import java.nio.file.Path;
24  import java.nio.file.attribute.BasicFileAttributes;
25  import java.util.List;
26  import java.util.Objects;
27  import java.util.stream.Stream;
28  
29  import org.apache.commons.io.FilenameUtils;
30  import org.apache.commons.io.file.PathUtils;
31  
32  /**
33   * Filters files using the supplied wildcards.
34   * <p>
35   * This filter selects files, but not directories, based on one or more wildcards
36   * and using case-sensitive comparison.
37   * </p>
38   * <p>
39   * The wildcard matcher uses the characters '?' and '*' to represent a
40   * single or multiple wildcard characters.
41   * This is the same as often found on DOS/Unix command lines.
42   * The extension check is case-sensitive.
43   * See {@link FilenameUtils#wildcardMatch(String, String)} for more information.
44   * </p>
45   * <p>
46   * For example:
47   * </p>
48   * <h2>Using Classic IO</h2>
49   * <pre>
50   * File dir = FileUtils.current();
51   * FileFilter fileFilter = new WildcardFilter("*test*.java~*~");
52   * File[] files = dir.listFiles(fileFilter);
53   * for (String file : files) {
54   *     System.out.println(file);
55   * }
56   * </pre>
57   *
58   * <h2>Using NIO</h2>
59   * <pre>
60   * final Path dir = PathUtils.current();
61   * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new WildcardFilter("*test*.java~*~"));
62   * //
63   * // Walk one dir
64   * Files.<b>walkFileTree</b>(dir, Collections.emptySet(), 1, visitor);
65   * System.out.println(visitor.getPathCounters());
66   * System.out.println(visitor.getFileList());
67   * //
68   * visitor.getPathCounters().reset();
69   * //
70   * // Walk dir tree
71   * Files.<b>walkFileTree</b>(dir, visitor);
72   * System.out.println(visitor.getPathCounters());
73   * System.out.println(visitor.getDirList());
74   * System.out.println(visitor.getFileList());
75   * </pre>
76   * <h2>Deprecating Serialization</h2>
77   * <p>
78   * <em>Serialization is deprecated and will be removed in 3.0.</em>
79   * </p>
80   *
81   * @since 1.1
82   * @deprecated Use WildcardFileFilter. Deprecated as this class performs directory
83   * filtering which it shouldn't do, but that can't be removed due to compatibility.
84   */
85  @Deprecated
86  public class WildcardFilter extends AbstractFileFilter implements Serializable {
87  
88      private static final long serialVersionUID = -5037645902506953517L;
89  
90      /** The wildcards that will be used to match file names. */
91      private final String[] wildcards;
92  
93      /**
94       * Constructs a new case-sensitive wildcard filter for a list of wildcards.
95       *
96       * @param wildcards  the list of wildcards to match
97       * @throws NullPointerException if the pattern list is null
98       * @throws ClassCastException if the list does not contain Strings
99       */
100     public WildcardFilter(final List<String> wildcards) {
101         Objects.requireNonNull(wildcards, "wildcards");
102         this.wildcards = wildcards.toArray(EMPTY_STRING_ARRAY);
103     }
104 
105     /**
106      * Constructs a new case-sensitive wildcard filter for a single wildcard.
107      *
108      * @param wildcard  the wildcard to match
109      * @throws NullPointerException if the pattern is null
110      */
111     public WildcardFilter(final String wildcard) {
112         Objects.requireNonNull(wildcard, "wildcard");
113         this.wildcards = new String[] { wildcard };
114     }
115 
116     /**
117      * Constructs a new case-sensitive wildcard filter for an array of wildcards.
118      *
119      * @param wildcards  the array of wildcards to match
120      * @throws NullPointerException if the pattern array is null
121      */
122     public WildcardFilter(final String... wildcards) {
123         Objects.requireNonNull(wildcards, "wildcards");
124         this.wildcards = wildcards.clone();
125     }
126 
127     /**
128      * Checks to see if the file name matches one of the wildcards.
129      *
130      * @param file the file to check
131      * @return true if the file name matches one of the wildcards
132      */
133     @Override
134     public boolean accept(final File file) {
135         if (file.isDirectory()) {
136             return false;
137         }
138         return Stream.of(wildcards).anyMatch(wildcard -> FilenameUtils.wildcardMatch(file.getName(), wildcard));
139     }
140 
141     /**
142      * Checks to see if the file name matches one of the wildcards.
143      *
144      * @param dir  the file directory
145      * @param name  the file name
146      * @return true if the file name matches one of the wildcards
147      */
148     @Override
149     public boolean accept(final File dir, final String name) {
150         if (dir != null && new File(dir, name).isDirectory()) {
151             return false;
152         }
153         return Stream.of(wildcards).anyMatch(wildcard -> FilenameUtils.wildcardMatch(name, wildcard));
154     }
155 
156     /**
157      * Checks to see if the file name matches one of the wildcards.
158      * @param path the file to check
159      *
160      * @return true if the file name matches one of the wildcards
161      * @since 2.9.0
162      */
163     @Override
164     public FileVisitResult accept(final Path path, final BasicFileAttributes attributes) {
165         if (Files.isDirectory(path)) {
166             return FileVisitResult.TERMINATE;
167         }
168         return toDefaultFileVisitResult(
169                 Stream.of(wildcards).anyMatch(wildcard -> FilenameUtils.wildcardMatch(PathUtils.getFileNameString(path), wildcard)));
170 
171     }
172 
173 }