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.ArrayList; 025import java.util.Collections; 026import java.util.List; 027import java.util.Objects; 028 029/** 030 * A {@link java.io.FileFilter} providing conditional AND logic across a list of 031 * file filters. This filter returns {@code true} if all filters in the 032 * list return {@code true}. Otherwise, it returns {@code false}. 033 * Checking of the file filter list stops when the first filter returns 034 * {@code false}. 035 * 036 * @since 1.0 037 * @see FileFilterUtils#and(IOFileFilter...) 038 */ 039public class AndFileFilter 040 extends AbstractFileFilter 041 implements ConditionalFileFilter, Serializable { 042 043 private static final long serialVersionUID = 7215974688563965257L; 044 045 /** The list of file filters. */ 046 private final List<IOFileFilter> fileFilters; 047 048 /** 049 * Constructs a new empty instance. 050 * 051 * @since 1.1 052 */ 053 public AndFileFilter() { 054 this(0); 055 } 056 057 /** 058 * Constructs a new instance with the given initial list. 059 * 060 * @param initialList the initial list. 061 */ 062 private AndFileFilter(final ArrayList<IOFileFilter> initialList) { 063 this.fileFilters = Objects.requireNonNull(initialList, "initialList"); 064 } 065 066 /** 067 * Constructs a new instance with the given initial capacity. 068 * 069 * @param initialCapacity the initial capacity. 070 */ 071 private AndFileFilter(final int initialCapacity) { 072 this(new ArrayList<>(initialCapacity)); 073 } 074 075 /** 076 * Constructs a new file filter that ANDs the result of other filters. 077 * 078 * @param filter1 the first filter, must second be null 079 * @param filter2 the first filter, must not be null 080 * @throws IllegalArgumentException if either filter is null 081 */ 082 public AndFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { 083 this(2); 084 addFileFilter(filter1); 085 addFileFilter(filter2); 086 } 087 088 /** 089 * Constructs a new instance for the give filters. 090 * @param fileFilters filters to OR. 091 * 092 * @since 2.9.0 093 */ 094 public AndFileFilter(final IOFileFilter... fileFilters) { 095 this(Objects.requireNonNull(fileFilters, "fileFilters").length); 096 addFileFilter(fileFilters); 097 } 098 099 /** 100 * Constructs a new instance of {@code AndFileFilter} 101 * with the specified list of filters. 102 * 103 * @param fileFilters a List of IOFileFilter instances, copied. 104 * @since 1.1 105 */ 106 public AndFileFilter(final List<IOFileFilter> fileFilters) { 107 this(new ArrayList<>(Objects.requireNonNull(fileFilters, "fileFilters"))); 108 } 109 110 /** 111 * {@inheritDoc} 112 */ 113 @Override 114 public boolean accept(final File file) { 115 if (isEmpty()) { 116 return false; 117 } 118 for (final IOFileFilter fileFilter : fileFilters) { 119 if (!fileFilter.accept(file)) { 120 return false; 121 } 122 } 123 return true; 124 } 125 126 /** 127 * {@inheritDoc} 128 */ 129 @Override 130 public boolean accept(final File file, final String name) { 131 if (isEmpty()) { 132 return false; 133 } 134 for (final IOFileFilter fileFilter : fileFilters) { 135 if (!fileFilter.accept(file, name)) { 136 return false; 137 } 138 } 139 return true; 140 } 141 142 /** 143 * {@inheritDoc} 144 * @since 2.9.0 145 */ 146 @Override 147 public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { 148 if (isEmpty()) { 149 return FileVisitResult.TERMINATE; 150 } 151 for (final IOFileFilter fileFilter : fileFilters) { 152 if (fileFilter.accept(file, attributes) != FileVisitResult.CONTINUE) { 153 return FileVisitResult.TERMINATE; 154 } 155 } 156 return FileVisitResult.CONTINUE; 157 } 158 159 /** 160 * {@inheritDoc} 161 */ 162 @Override 163 public void addFileFilter(final IOFileFilter fileFilter) { 164 this.fileFilters.add(Objects.requireNonNull(fileFilter, "fileFilter")); 165 } 166 167 /** 168 * Adds the given file filters. 169 * 170 * @param fileFilters the filters to add. 171 * @since 2.9.0 172 */ 173 public void addFileFilter(final IOFileFilter... fileFilters) { 174 for (final IOFileFilter fileFilter : Objects.requireNonNull(fileFilters, "fileFilters")) { 175 addFileFilter(fileFilter); 176 } 177 } 178 179 /** 180 * {@inheritDoc} 181 */ 182 @Override 183 public List<IOFileFilter> getFileFilters() { 184 return Collections.unmodifiableList(this.fileFilters); 185 } 186 187 private boolean isEmpty() { 188 return this.fileFilters.isEmpty(); 189 } 190 191 /** 192 * {@inheritDoc} 193 */ 194 @Override 195 public boolean removeFileFilter(final IOFileFilter ioFileFilter) { 196 return this.fileFilters.remove(ioFileFilter); 197 } 198 199 /** 200 * {@inheritDoc} 201 */ 202 @Override 203 public void setFileFilters(final List<IOFileFilter> fileFilters) { 204 this.fileFilters.clear(); 205 this.fileFilters.addAll(fileFilters); 206 } 207 208 /** 209 * Provide a String representation of this file filter. 210 * 211 * @return a String representation 212 */ 213 @Override 214 public String toString() { 215 final StringBuilder buffer = new StringBuilder(); 216 buffer.append(super.toString()); 217 buffer.append("("); 218 for (int i = 0; i < fileFilters.size(); i++) { 219 if (i > 0) { 220 buffer.append(","); 221 } 222 buffer.append(fileFilters.get(i)); 223 } 224 buffer.append(")"); 225 return buffer.toString(); 226 } 227 228}