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  
30  /**
31   * Filters files based on the suffix (what the file name ends with).
32   * This is used in retrieving all the files of a particular type.
33   * <p>
34   * For example, to retrieve and print all {@code *.java} files
35   * in the current directory:
36   * </p>
37   * <h2>Using Classic IO</h2>
38   * <pre>
39   * File dir = FileUtils.current();
40   * String[] files = dir.list(new SuffixFileFilter(".java"));
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 SuffixFileFilter(".java"));
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#suffixFileFilter(String)
71   * @see FileFilterUtils#suffixFileFilter(String, IOCase)
72   */
73  public class SuffixFileFilter extends AbstractFileFilter implements Serializable {
74  
75      private static final long serialVersionUID = -3389157631240246157L;
76  
77      /** The file name suffixes to search for */
78      private final String[] suffixes;
79  
80      /** Whether the comparison is case-sensitive. */
81      private final IOCase ioCase;
82  
83      /**
84       * Constructs a new Suffix file filter for a list of suffixes.
85       *
86       * @param suffixes  the suffixes to allow, must not be null
87       * @throws IllegalArgumentException if the suffix list is null
88       * @throws ClassCastException if the list does not contain Strings
89       */
90      public SuffixFileFilter(final List<String> suffixes) {
91          this(suffixes, IOCase.SENSITIVE);
92      }
93  
94      /**
95       * Constructs a new Suffix file filter for a list of suffixes
96       * specifying case-sensitivity.
97       *
98       * @param suffixes  the suffixes to allow, must not be null
99       * @param ioCase  how to handle case sensitivity, null means case-sensitive
100      * @throws IllegalArgumentException if the suffix list is null
101      * @throws ClassCastException if the list does not contain Strings
102      * @since 1.4
103      */
104     public SuffixFileFilter(final List<String> suffixes, final IOCase ioCase) {
105         Objects.requireNonNull(suffixes, "suffixes");
106         this.suffixes = suffixes.toArray(EMPTY_STRING_ARRAY);
107         this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
108     }
109 
110     /**
111      * Constructs a new Suffix file filter for a single extension.
112      *
113      * @param suffix  the suffix to allow, must not be null
114      * @throws IllegalArgumentException if the suffix is null
115      */
116     public SuffixFileFilter(final String suffix) {
117         this(suffix, IOCase.SENSITIVE);
118     }
119 
120     /**
121      * Constructs a new Suffix file filter for an array of suffixes.
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 suffixes  the suffixes to allow, must not be null
127      * @throws NullPointerException if the suffix array is null
128      */
129     public SuffixFileFilter(final String... suffixes) {
130         this(suffixes, IOCase.SENSITIVE);
131     }
132 
133     /**
134      * Constructs a new Suffix file filter for a single extension
135      * specifying case-sensitivity.
136      *
137      * @param suffix  the suffix to allow, must not be null
138      * @param ioCase  how to handle case sensitivity, null means case-sensitive
139      * @throws NullPointerException if the suffix is null
140      * @since 1.4
141      */
142     public SuffixFileFilter(final String suffix, final IOCase ioCase) {
143         Objects.requireNonNull(suffix, "suffix");
144         this.suffixes = new String[] {suffix};
145         this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
146     }
147 
148     /**
149      * Constructs a new Suffix file filter for an array of suffixes
150      * specifying case-sensitivity.
151      *
152      * @param suffixes  the suffixes to allow, must not be null
153      * @param ioCase  how to handle case sensitivity, null means case-sensitive
154      * @throws NullPointerException if the suffix array is null
155      * @since 1.4
156      */
157     public SuffixFileFilter(final String[] suffixes, final IOCase ioCase) {
158         Objects.requireNonNull(suffixes, "suffixes");
159         this.suffixes = suffixes.clone();
160         this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
161     }
162 
163     /**
164      * Checks to see if the file name ends with the suffix.
165      *
166      * @param file  the File to check
167      * @return true if the file name ends with one of our suffixes
168      */
169     @Override
170     public boolean accept(final File file) {
171         return accept(file.getName());
172     }
173 
174     /**
175      * Checks to see if the file name ends with the suffix.
176      *
177      * @param file  the File directory
178      * @param name  the file name
179      * @return true if the file name ends with one of our suffixes
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 ends with the suffix.
188      * @param file  the File to check
189      *
190      * @return true if the file name ends with one of our suffixes
191      * @since 2.9.0
192      */
193     @Override
194     public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
195         return toFileVisitResult(accept(Objects.toString(file.getFileName(), null)));
196     }
197 
198     private boolean accept(final String name) {
199         return Stream.of(suffixes).anyMatch(suffix -> ioCase.checkEndsWith(name, suffix));
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(suffixes, buffer);
213         buffer.append(")");
214         return buffer.toString();
215     }
216 
217 }