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 toDefaultFileVisitResult(final boolean accept)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 */ AbstractFileFilter()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 */ AbstractFileFilter(final FileVisitResult onAccept, final FileVisitResult onReject)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 accept(final File file)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 accept(final File dir, final String name)97 public boolean accept(final File dir, final String name) { 98 Objects.requireNonNull(name, "name"); 99 return accept(new File(dir, name)); 100 } 101 append(final List<?> list, final StringBuilder buffer)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 append(final Object[] array, final StringBuilder buffer)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 get(final IOSupplier<FileVisitResult> supplier)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 */ handle(final Throwable t)135 protected FileVisitResult handle(final Throwable t) { 136 return FileVisitResult.TERMINATE; 137 } 138 139 @Override postVisitDirectory(final Path dir, final IOException exc)140 public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException { 141 return FileVisitResult.CONTINUE; 142 } 143 144 @Override preVisitDirectory(final Path dir, final BasicFileAttributes attributes)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 */ toFileVisitResult(final boolean accept)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 toString()165 public String toString() { 166 return getClass().getSimpleName(); 167 } 168 169 @Override visitFile(final Path file, final BasicFileAttributes attributes)170 public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) throws IOException { 171 return accept(file, attributes); 172 } 173 174 @Override visitFileFailed(final Path file, final IOException exc)175 public FileVisitResult visitFileFailed(final Path file, final IOException exc) throws IOException { 176 return FileVisitResult.CONTINUE; 177 } 178 179 } 180