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.FileFilter;
21  import java.io.FilenameFilter;
22  import java.io.IOException;
23  import java.nio.file.FileVisitResult;
24  import java.nio.file.Path;
25  import java.nio.file.attribute.BasicFileAttributes;
26  import java.util.List;
27  import java.util.Objects;
28  
29  import org.apache.commons.io.file.PathFilter;
30  import org.apache.commons.io.file.PathVisitor;
31  import org.apache.commons.io.function.IOSupplier;
32  
33  /**
34   * Abstracts the implementation of the {@link FileFilter} (IO), {@link FilenameFilter} (IO), {@link PathFilter} (NIO)
35   * interfaces via our own {@link IOFileFilter} interface.
36   * <p>
37   * Note that a subclass MUST override one of the {@code accept} methods, otherwise that subclass will infinitely loop.
38   * </p>
39   *
40   * @since 1.0
41   */
42  public abstract class AbstractFileFilter implements IOFileFilter, PathVisitor {
43  
44      static FileVisitResult toDefaultFileVisitResult(final boolean accept) {
45          return accept ? FileVisitResult.CONTINUE : FileVisitResult.TERMINATE;
46      }
47  
48      /**
49       * What to do when this filter accepts.
50       */
51      private final FileVisitResult onAccept;
52  
53      /**
54       * What to do when this filter rejects.
55       */
56      private final FileVisitResult onReject;
57  
58      /**
59       * Constructs a new instance.
60       */
61      public AbstractFileFilter() {
62          this(FileVisitResult.CONTINUE, FileVisitResult.TERMINATE);
63      }
64  
65      /**
66       * Constructs a new instance.
67       *
68       * @param onAccept What to do on acceptance.
69       * @param onReject What to do on rejection.
70       * @since 2.12.0.
71       */
72      protected AbstractFileFilter(final FileVisitResult onAccept, final FileVisitResult onReject) {
73          this.onAccept = onAccept;
74          this.onReject = onReject;
75      }
76  
77      /**
78       * Checks to see if the File should be accepted by this filter.
79       *
80       * @param file the File to check
81       * @return true if this file matches the test
82       */
83      @Override
84      public boolean accept(final File file) {
85          Objects.requireNonNull(file, "file");
86          return accept(file.getParentFile(), file.getName());
87      }
88  
89      /**
90       * Checks to see if the File should be accepted by this filter.
91       *
92       * @param dir the directory File to check
93       * @param name the file name within the directory to check
94       * @return true if this file matches the test
95       */
96      @Override
97      public boolean accept(final File dir, final String name) {
98          Objects.requireNonNull(name, "name");
99          return accept(new File(dir, name));
100     }
101 
102     void append(final List<?> list, final StringBuilder buffer) {
103         for (int i = 0; i < list.size(); i++) {
104             if (i > 0) {
105                 buffer.append(",");
106             }
107             buffer.append(list.get(i));
108         }
109     }
110 
111     void append(final Object[] array, final StringBuilder buffer) {
112         for (int i = 0; i < array.length; i++) {
113             if (i > 0) {
114                 buffer.append(",");
115             }
116             buffer.append(array[i]);
117         }
118     }
119 
120     FileVisitResult get(final IOSupplier<FileVisitResult> supplier) {
121         try {
122             return supplier.get();
123         } catch (IOException e) {
124             return handle(e);
125         }
126     }
127 
128     /**
129      * Handles exceptions caught while accepting.
130      *
131      * @param t the caught Throwable.
132      * @return the given Throwable.
133      * @since 2.9.0
134      */
135     protected FileVisitResult handle(final Throwable t) {
136         return FileVisitResult.TERMINATE;
137     }
138 
139     @Override
140     public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
141         return FileVisitResult.CONTINUE;
142     }
143 
144     @Override
145     public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attributes) throws IOException {
146         return accept(dir, attributes);
147     }
148 
149     /**
150      * Converts a boolean into a FileVisitResult.
151      *
152      * @param accept accepted or rejected.
153      * @return a FileVisitResult.
154      */
155     FileVisitResult toFileVisitResult(final boolean accept) {
156         return accept ? onAccept : onReject;
157     }
158 
159     /**
160      * Provides a String representation of this file filter.
161      *
162      * @return a String representation
163      */
164     @Override
165     public String toString() {
166         return getClass().getSimpleName();
167     }
168 
169     @Override
170     public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) throws IOException {
171         return accept(file, attributes);
172     }
173 
174     @Override
175     public FileVisitResult visitFileFailed(final Path file, final IOException exc) throws IOException {
176         return FileVisitResult.CONTINUE;
177     }
178 
179 }