SuffixFileFilter.java

  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. import java.io.File;
  19. import java.io.Serializable;
  20. import java.nio.file.FileVisitResult;
  21. import java.nio.file.Path;
  22. import java.nio.file.attribute.BasicFileAttributes;
  23. import java.util.List;
  24. import java.util.Objects;
  25. import java.util.stream.Stream;

  26. import org.apache.commons.io.IOCase;
  27. import org.apache.commons.io.file.PathUtils;

  28. /**
  29.  * Filters files based on the suffix (what the file name ends with).
  30.  * This is used in retrieving all the files of a particular type.
  31.  * <p>
  32.  * For example, to retrieve and print all {@code *.java} files
  33.  * in the current directory:
  34.  * </p>
  35.  * <h2>Using Classic IO</h2>
  36.  * <pre>
  37.  * File dir = FileUtils.current();
  38.  * String[] files = dir.list(new SuffixFileFilter(".java"));
  39.  * for (String file : files) {
  40.  *     System.out.println(file);
  41.  * }
  42.  * </pre>
  43.  *
  44.  * <h2>Using NIO</h2>
  45.  * <pre>
  46.  * final Path dir = PathUtils.current();
  47.  * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new SuffixFileFilter(".java"));
  48.  * //
  49.  * // Walk one directory
  50.  * Files.<strong>walkFileTree</strong>(dir, Collections.emptySet(), 1, visitor);
  51.  * System.out.println(visitor.getPathCounters());
  52.  * System.out.println(visitor.getFileList());
  53.  * //
  54.  * visitor.getPathCounters().reset();
  55.  * //
  56.  * // Walk directory tree
  57.  * Files.<strong>walkFileTree</strong>(dir, visitor);
  58.  * System.out.println(visitor.getPathCounters());
  59.  * System.out.println(visitor.getDirList());
  60.  * System.out.println(visitor.getFileList());
  61.  * </pre>
  62.  * <h2>Deprecating Serialization</h2>
  63.  * <p>
  64.  * <em>Serialization is deprecated and will be removed in 3.0.</em>
  65.  * </p>
  66.  *
  67.  * @since 1.0
  68.  * @see FileFilterUtils#suffixFileFilter(String)
  69.  * @see FileFilterUtils#suffixFileFilter(String, IOCase)
  70.  */
  71. public class SuffixFileFilter extends AbstractFileFilter implements Serializable {

  72.     private static final long serialVersionUID = -3389157631240246157L;

  73.     /** The file name suffixes to search for */
  74.     private final String[] suffixes;

  75.     /** Whether the comparison is case-sensitive. */
  76.     private final IOCase ioCase;

  77.     /**
  78.      * Constructs a new Suffix file filter for a list of suffixes.
  79.      *
  80.      * @param suffixes  the suffixes to allow, must not be null
  81.      * @throws IllegalArgumentException if the suffix list is null
  82.      * @throws ClassCastException if the list does not contain Strings
  83.      */
  84.     public SuffixFileFilter(final List<String> suffixes) {
  85.         this(suffixes, IOCase.SENSITIVE);
  86.     }

  87.     /**
  88.      * Constructs a new Suffix file filter for a list of suffixes
  89.      * specifying case-sensitivity.
  90.      *
  91.      * @param suffixes  the suffixes to allow, must not be null
  92.      * @param ioCase  how to handle case sensitivity, null means case-sensitive
  93.      * @throws IllegalArgumentException if the suffix list is null
  94.      * @throws ClassCastException if the list does not contain Strings
  95.      * @since 1.4
  96.      */
  97.     public SuffixFileFilter(final List<String> suffixes, final IOCase ioCase) {
  98.         Objects.requireNonNull(suffixes, "suffixes");
  99.         this.suffixes = suffixes.toArray(EMPTY_STRING_ARRAY);
  100.         this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
  101.     }

  102.     /**
  103.      * Constructs a new Suffix file filter for a single extension.
  104.      *
  105.      * @param suffix  the suffix to allow, must not be null
  106.      * @throws IllegalArgumentException if the suffix is null
  107.      */
  108.     public SuffixFileFilter(final String suffix) {
  109.         this(suffix, IOCase.SENSITIVE);
  110.     }

  111.     /**
  112.      * Constructs a new Suffix file filter for an array of suffixes.
  113.      * <p>
  114.      * The array is not cloned, so could be changed after constructing the
  115.      * instance. This would be inadvisable however.
  116.      * </p>
  117.      *
  118.      * @param suffixes  the suffixes to allow, must not be null
  119.      * @throws NullPointerException if the suffix array is null
  120.      */
  121.     public SuffixFileFilter(final String... suffixes) {
  122.         this(suffixes, IOCase.SENSITIVE);
  123.     }

  124.     /**
  125.      * Constructs a new Suffix file filter for a single extension
  126.      * specifying case-sensitivity.
  127.      *
  128.      * @param suffix  the suffix to allow, must not be null
  129.      * @param ioCase  how to handle case sensitivity, null means case-sensitive
  130.      * @throws NullPointerException if the suffix is null
  131.      * @since 1.4
  132.      */
  133.     public SuffixFileFilter(final String suffix, final IOCase ioCase) {
  134.         Objects.requireNonNull(suffix, "suffix");
  135.         this.suffixes = new String[] {suffix};
  136.         this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
  137.     }

  138.     /**
  139.      * Constructs a new Suffix file filter for an array of suffixes
  140.      * specifying case-sensitivity.
  141.      *
  142.      * @param suffixes  the suffixes to allow, must not be null
  143.      * @param ioCase  how to handle case sensitivity, null means case-sensitive
  144.      * @throws NullPointerException if the suffix array is null
  145.      * @since 1.4
  146.      */
  147.     public SuffixFileFilter(final String[] suffixes, final IOCase ioCase) {
  148.         Objects.requireNonNull(suffixes, "suffixes");
  149.         this.suffixes = suffixes.clone();
  150.         this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
  151.     }

  152.     /**
  153.      * Checks to see if the file name ends with the suffix.
  154.      *
  155.      * @param file  the File to check
  156.      * @return true if the file name ends with one of our suffixes
  157.      */
  158.     @Override
  159.     public boolean accept(final File file) {
  160.         return accept(file.getName());
  161.     }

  162.     /**
  163.      * Checks to see if the file name ends with the suffix.
  164.      *
  165.      * @param file  the File directory
  166.      * @param name  the file name
  167.      * @return true if the file name ends with one of our suffixes
  168.      */
  169.     @Override
  170.     public boolean accept(final File file, final String name) {
  171.         return accept(name);
  172.     }

  173.     /**
  174.      * Checks to see if the file name ends with the suffix.
  175.      *
  176.      * @param path       the File to check
  177.      * @param attributes the path's basic attributes (may be null).
  178.      * @return true if the file name ends with one of our suffixes
  179.      * @since 2.9.0
  180.      */
  181.     @Override
  182.     public FileVisitResult accept(final Path path, final BasicFileAttributes attributes) {
  183.         return toFileVisitResult(accept(PathUtils.getFileNameString(path)));
  184.     }

  185.     private boolean accept(final String name) {
  186.         return Stream.of(suffixes).anyMatch(suffix -> ioCase.checkEndsWith(name, suffix));
  187.     }

  188.     /**
  189.      * Provide a String representation of this file filter.
  190.      *
  191.      * @return a String representation
  192.      */
  193.     @Override
  194.     public String toString() {
  195.         final StringBuilder buffer = new StringBuilder();
  196.         buffer.append(super.toString());
  197.         buffer.append("(");
  198.         append(suffixes, buffer);
  199.         buffer.append(")");
  200.         return buffer.toString();
  201.     }

  202. }