001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.io.filefilter; 018 019import java.io.File; 020import java.io.FileFilter; 021import java.io.FilenameFilter; 022import java.io.IOException; 023import java.nio.file.FileVisitResult; 024import java.nio.file.Path; 025import java.nio.file.attribute.BasicFileAttributes; 026import java.util.List; 027import java.util.Objects; 028 029import org.apache.commons.io.file.PathFilter; 030import org.apache.commons.io.file.PathVisitor; 031import org.apache.commons.io.function.IOSupplier; 032 033/** 034 * Abstracts the implementation of the {@link FileFilter} (IO), {@link FilenameFilter} (IO), {@link PathFilter} (NIO) 035 * interfaces via our own {@link IOFileFilter} interface. 036 * <p> 037 * Note that a subclass MUST override one of the {@code accept} methods, otherwise that subclass will infinitely loop. 038 * </p> 039 * 040 * @since 1.0 041 */ 042public abstract class AbstractFileFilter implements IOFileFilter, PathVisitor { 043 044 static FileVisitResult toDefaultFileVisitResult(final boolean accept) { 045 return accept ? FileVisitResult.CONTINUE : FileVisitResult.TERMINATE; 046 } 047 048 /** 049 * What to do when this filter accepts. 050 */ 051 private final FileVisitResult onAccept; 052 053 /** 054 * What to do when this filter rejects. 055 */ 056 private final FileVisitResult onReject; 057 058 /** 059 * Constructs a new instance. 060 */ 061 public AbstractFileFilter() { 062 this(FileVisitResult.CONTINUE, FileVisitResult.TERMINATE); 063 } 064 065 /** 066 * Constructs a new instance. 067 * 068 * @param onAccept What to do on acceptance. 069 * @param onReject What to do on rejection. 070 * @since 2.12.0. 071 */ 072 protected AbstractFileFilter(final FileVisitResult onAccept, final FileVisitResult onReject) { 073 this.onAccept = onAccept; 074 this.onReject = onReject; 075 } 076 077 /** 078 * Checks to see if the File should be accepted by this filter. 079 * 080 * @param file the File to check 081 * @return true if this file matches the test 082 */ 083 @Override 084 public boolean accept(final File file) { 085 Objects.requireNonNull(file, "file"); 086 return accept(file.getParentFile(), file.getName()); 087 } 088 089 /** 090 * Checks to see if the File should be accepted by this filter. 091 * 092 * @param dir the directory File to check 093 * @param name the file name within the directory to check 094 * @return true if this file matches the test 095 */ 096 @Override 097 public boolean accept(final File dir, final String name) { 098 Objects.requireNonNull(name, "name"); 099 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 (final 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}