PrefixFileFilter.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 file names for a certain prefix.
  30.  * <p>
  31.  * For example, to print all files and directories in the
  32.  * current directory whose name starts with {@code Test}:
  33.  * </p>
  34.  * <h2>Using Classic IO</h2>
  35.  * <pre>
  36.  * File dir = FileUtils.current();
  37.  * String[] files = dir.list(new PrefixFileFilter("Test"));
  38.  * for (String file : files) {
  39.  *     System.out.println(file);
  40.  * }
  41.  * </pre>
  42.  *
  43.  * <h2>Using NIO</h2>
  44.  * <pre>
  45.  * final Path dir = PathUtils.current();
  46.  * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new PrefixFileFilter("Test"));
  47.  * //
  48.  * // Walk one directory
  49.  * Files.<strong>walkFileTree</strong>(dir, Collections.emptySet(), 1, visitor);
  50.  * System.out.println(visitor.getPathCounters());
  51.  * System.out.println(visitor.getFileList());
  52.  * //
  53.  * visitor.getPathCounters().reset();
  54.  * //
  55.  * // Walk directory tree
  56.  * Files.<strong>walkFileTree</strong>(dir, visitor);
  57.  * System.out.println(visitor.getPathCounters());
  58.  * System.out.println(visitor.getDirList());
  59.  * System.out.println(visitor.getFileList());
  60.  * </pre>
  61.  * <h2>Deprecating Serialization</h2>
  62.  * <p>
  63.  * <em>Serialization is deprecated and will be removed in 3.0.</em>
  64.  * </p>
  65.  *
  66.  * @since 1.0
  67.  * @see FileFilterUtils#prefixFileFilter(String)
  68.  * @see FileFilterUtils#prefixFileFilter(String, IOCase)
  69.  */
  70. public class PrefixFileFilter extends AbstractFileFilter implements Serializable {

  71.     private static final long serialVersionUID = 8533897440809599867L;

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

  74.     /** Whether the comparison is case-sensitive. */
  75.     private final IOCase isCase;

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

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

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

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

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

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

  151.     /**
  152.      * Checks to see if the file name starts with the prefix.
  153.      *
  154.      * @param file  the File to check
  155.      * @return true if the file name starts with one of our prefixes
  156.      */
  157.     @Override
  158.     public boolean accept(final File file) {
  159.         return accept(file == null ? null : file.getName());
  160.     }

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

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

  184.     private boolean accept(final String name) {
  185.         return Stream.of(prefixes).anyMatch(prefix -> isCase.checkStartsWith(name, prefix));
  186.     }

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

  201. }