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