WildcardFilter.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.Files;
  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. import org.apache.commons.io.FilenameUtils;
  28. import org.apache.commons.io.file.PathUtils;

  29. /**
  30.  * Filters files using the supplied wildcards.
  31.  * <p>
  32.  * This filter selects files, but not directories, based on one or more wildcards
  33.  * and using case-sensitive comparison.
  34.  * </p>
  35.  * <p>
  36.  * The wildcard matcher uses the characters '?' and '*' to represent a
  37.  * single or multiple wildcard characters.
  38.  * This is the same as often found on DOS/Unix command lines.
  39.  * The extension check is case-sensitive.
  40.  * See {@link FilenameUtils#wildcardMatch(String, String)} for more information.
  41.  * </p>
  42.  * <p>
  43.  * For example:
  44.  * </p>
  45.  * <h2>Using Classic IO</h2>
  46.  * <pre>
  47.  * File dir = FileUtils.current();
  48.  * FileFilter fileFilter = new WildcardFilter("*test*.java~*~");
  49.  * File[] files = dir.listFiles(fileFilter);
  50.  * for (String file : files) {
  51.  *     System.out.println(file);
  52.  * }
  53.  * </pre>
  54.  *
  55.  * <h2>Using NIO</h2>
  56.  * <pre>
  57.  * final Path dir = PathUtils.current();
  58.  * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new WildcardFilter("*test*.java~*~"));
  59.  * //
  60.  * // Walk one directory
  61.  * Files.<strong>walkFileTree</strong>(dir, Collections.emptySet(), 1, visitor);
  62.  * System.out.println(visitor.getPathCounters());
  63.  * System.out.println(visitor.getFileList());
  64.  * //
  65.  * visitor.getPathCounters().reset();
  66.  * //
  67.  * // Walk directory tree
  68.  * Files.<strong>walkFileTree</strong>(dir, visitor);
  69.  * System.out.println(visitor.getPathCounters());
  70.  * System.out.println(visitor.getDirList());
  71.  * System.out.println(visitor.getFileList());
  72.  * </pre>
  73.  * <h2>Deprecating Serialization</h2>
  74.  * <p>
  75.  * <em>Serialization is deprecated and will be removed in 3.0.</em>
  76.  * </p>
  77.  *
  78.  * @since 1.1
  79.  * @deprecated Use WildcardFileFilter. Deprecated as this class performs directory
  80.  * filtering which it shouldn't do, but that can't be removed due to compatibility.
  81.  */
  82. @Deprecated
  83. public class WildcardFilter extends AbstractFileFilter implements Serializable {

  84.     private static final long serialVersionUID = -5037645902506953517L;

  85.     /** The wildcards that will be used to match file names. */
  86.     private final String[] wildcards;

  87.     /**
  88.      * Constructs a new case-sensitive wildcard filter for a list of wildcards.
  89.      *
  90.      * @param wildcards  the list of wildcards to match
  91.      * @throws NullPointerException if the pattern list is null
  92.      * @throws ClassCastException if the list does not contain Strings
  93.      */
  94.     public WildcardFilter(final List<String> wildcards) {
  95.         Objects.requireNonNull(wildcards, "wildcards");
  96.         this.wildcards = wildcards.toArray(EMPTY_STRING_ARRAY);
  97.     }

  98.     /**
  99.      * Constructs a new case-sensitive wildcard filter for a single wildcard.
  100.      *
  101.      * @param wildcard  the wildcard to match
  102.      * @throws NullPointerException if the pattern is null
  103.      */
  104.     public WildcardFilter(final String wildcard) {
  105.         Objects.requireNonNull(wildcard, "wildcard");
  106.         this.wildcards = new String[] { wildcard };
  107.     }

  108.     /**
  109.      * Constructs a new case-sensitive wildcard filter for an array of wildcards.
  110.      *
  111.      * @param wildcards  the array of wildcards to match
  112.      * @throws NullPointerException if the pattern array is null
  113.      */
  114.     public WildcardFilter(final String... wildcards) {
  115.         Objects.requireNonNull(wildcards, "wildcards");
  116.         this.wildcards = wildcards.clone();
  117.     }

  118.     /**
  119.      * Checks to see if the file name matches one of the wildcards.
  120.      *
  121.      * @param file the file to check
  122.      * @return true if the file name matches one of the wildcards
  123.      */
  124.     @Override
  125.     public boolean accept(final File file) {
  126.         if (file.isDirectory()) {
  127.             return false;
  128.         }
  129.         return Stream.of(wildcards).anyMatch(wildcard -> FilenameUtils.wildcardMatch(file.getName(), wildcard));
  130.     }

  131.     /**
  132.      * Checks to see if the file name matches one of the wildcards.
  133.      *
  134.      * @param dir  the file directory
  135.      * @param name  the file name
  136.      * @return true if the file name matches one of the wildcards
  137.      */
  138.     @Override
  139.     public boolean accept(final File dir, final String name) {
  140.         if (dir != null && new File(dir, name).isDirectory()) {
  141.             return false;
  142.         }
  143.         return Stream.of(wildcards).anyMatch(wildcard -> FilenameUtils.wildcardMatch(name, wildcard));
  144.     }

  145.     /**
  146.      * Checks to see if the file name matches one of the wildcards.
  147.      *
  148.      * @param path the file to check
  149.      * @param attributes the path's basic attributes (may be null).
  150.      * @return true if the file name matches one of the wildcards
  151.      * @since 2.9.0
  152.      */
  153.     @Override
  154.     public FileVisitResult accept(final Path path, final BasicFileAttributes attributes) {
  155.         if (Files.isDirectory(path)) {
  156.             return FileVisitResult.TERMINATE;
  157.         }
  158.         return toDefaultFileVisitResult(
  159.                 Stream.of(wildcards).anyMatch(wildcard -> FilenameUtils.wildcardMatch(PathUtils.getFileNameString(path), wildcard)));

  160.     }

  161. }