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.Serializable; 021import java.nio.file.FileVisitResult; 022import java.nio.file.Path; 023import java.nio.file.attribute.BasicFileAttributes; 024import java.util.List; 025import java.util.Objects; 026 027import org.apache.commons.io.IOCase; 028 029/** 030 * Filters file names for a certain name. 031 * <p> 032 * For example, to print all files and directories in the 033 * current directory whose name is {@code Test}: 034 * </p> 035 * <h2>Using Classic IO</h2> 036 * <pre> 037 * File dir = new File("."); 038 * String[] files = dir.list(new NameFileFilter("Test")); 039 * for (String file : files) { 040 * System.out.println(file); 041 * } 042 * </pre> 043 * 044 * <h2>Using NIO</h2> 045 * <pre> 046 * final Path dir = Paths.get(""); 047 * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new NameFileFilter("Test")); 048 * // 049 * // Walk one dir 050 * Files.<b>walkFileTree</b>(dir, Collections.emptySet(), 1, visitor); 051 * System.out.println(visitor.getPathCounters()); 052 * System.out.println(visitor.getFileList()); 053 * // 054 * visitor.getPathCounters().reset(); 055 * // 056 * // Walk dir tree 057 * Files.<b>walkFileTree</b>(dir, visitor); 058 * System.out.println(visitor.getPathCounters()); 059 * System.out.println(visitor.getDirList()); 060 * System.out.println(visitor.getFileList()); 061 * </pre> 062 * 063 * @since 1.0 064 * @see FileFilterUtils#nameFileFilter(String) 065 * @see FileFilterUtils#nameFileFilter(String, IOCase) 066 */ 067public class NameFileFilter extends AbstractFileFilter implements Serializable { 068 069 private static final long serialVersionUID = 176844364689077340L; 070 071 /** The file names to search for */ 072 private final String[] names; 073 074 /** Whether the comparison is case sensitive. */ 075 private final IOCase caseSensitivity; 076 077 /** 078 * Constructs a new case-sensitive name file filter for a list of names. 079 * 080 * @param names the names to allow, must not be null 081 * @throws IllegalArgumentException if the name list is null 082 * @throws ClassCastException if the list does not contain Strings 083 */ 084 public NameFileFilter(final List<String> names) { 085 this(names, null); 086 } 087 088 /** 089 * Constructs a new name file filter for a list of names specifying case-sensitivity. 090 * 091 * @param names the names to allow, must not be null 092 * @param caseSensitivity how to handle case sensitivity, null means case-sensitive 093 * @throws IllegalArgumentException if the name list is null 094 * @throws ClassCastException if the list does not contain Strings 095 */ 096 public NameFileFilter(final List<String> names, final IOCase caseSensitivity) { 097 if (names == null) { 098 throw new IllegalArgumentException("The list of names must not be null"); 099 } 100 this.names = names.toArray(EMPTY_STRING_ARRAY); 101 this.caseSensitivity = toIOCase(caseSensitivity); 102 } 103 104 /** 105 * Constructs a new case-sensitive name file filter for a single name. 106 * 107 * @param name the name to allow, must not be null 108 * @throws IllegalArgumentException if the name is null 109 */ 110 public NameFileFilter(final String name) { 111 this(name, IOCase.SENSITIVE); 112 } 113 114 /** 115 * Constructs a new case-sensitive name file filter for an array of names. 116 * <p> 117 * The array is not cloned, so could be changed after constructing the 118 * instance. This would be inadvisable however. 119 * </p> 120 * 121 * @param names the names to allow, must not be null 122 * @throws IllegalArgumentException if the names array is null 123 */ 124 public NameFileFilter(final String... names) { 125 this(names, IOCase.SENSITIVE); 126 } 127 128 /** 129 * Construct a new name file filter specifying case-sensitivity. 130 * 131 * @param name the name to allow, must not be null 132 * @param caseSensitivity how to handle case sensitivity, null means case-sensitive 133 * @throws IllegalArgumentException if the name is null 134 */ 135 public NameFileFilter(final String name, final IOCase caseSensitivity) { 136 if (name == null) { 137 throw new IllegalArgumentException("The wildcard must not be null"); 138 } 139 this.names = new String[] {name}; 140 this.caseSensitivity = toIOCase(caseSensitivity); 141 } 142 143 /** 144 * Constructs a new name file filter for an array of names specifying case-sensitivity. 145 * 146 * @param names the names to allow, must not be null 147 * @param caseSensitivity how to handle case sensitivity, null means case-sensitive 148 * @throws IllegalArgumentException if the names array is null 149 */ 150 public NameFileFilter(final String[] names, final IOCase caseSensitivity) { 151 if (names == null) { 152 throw new IllegalArgumentException("The array of names must not be null"); 153 } 154 this.names = new String[names.length]; 155 System.arraycopy(names, 0, this.names, 0, names.length); 156 this.caseSensitivity = toIOCase(caseSensitivity); 157 } 158 159 /** 160 * Checks to see if the file name matches. 161 * 162 * @param file the File to check 163 * @return true if the file name matches 164 */ 165 @Override 166 public boolean accept(final File file) { 167 return acceptBaseName(file.getName()); 168 } 169 170 /** 171 * Checks to see if the file name matches. 172 * 173 * @param dir the File directory (ignored) 174 * @param name the file name 175 * @return true if the file name matches 176 */ 177 @Override 178 public boolean accept(final File dir, final String name) { 179 return acceptBaseName(name); 180 } 181 182 /** 183 * Checks to see if the file name matches. 184 * @param file the File to check 185 * 186 * @return true if the file name matches 187 * @since 2.9.0 188 */ 189 @Override 190 public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { 191 return toFileVisitResult(acceptBaseName(Objects.toString(file.getFileName(), null)), file); 192 } 193 194 private boolean acceptBaseName(final String baseName) { 195 for (final String testName : names) { 196 if (caseSensitivity.checkEquals(baseName, testName)) { 197 return true; 198 } 199 } 200 return false; 201 } 202 203 private IOCase toIOCase(final IOCase caseSensitivity) { 204 return caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity; 205 } 206 207 /** 208 * Provide a String representation of this file filter. 209 * 210 * @return a String representation 211 */ 212 @Override 213 public String toString() { 214 final StringBuilder buffer = new StringBuilder(); 215 buffer.append(super.toString()); 216 buffer.append("("); 217 if (names != null) { 218 for (int i = 0; i < names.length; i++) { 219 if (i > 0) { 220 buffer.append(","); 221 } 222 buffer.append(names[i]); 223 } 224 } 225 buffer.append(")"); 226 return buffer.toString(); 227 } 228 229}