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.vfs2.filter; 018 019import java.io.Serializable; 020import java.util.Date; 021import java.util.Objects; 022 023import org.apache.commons.vfs2.FileContent; 024import org.apache.commons.vfs2.FileFilter; 025import org.apache.commons.vfs2.FileObject; 026import org.apache.commons.vfs2.FileSelectInfo; 027import org.apache.commons.vfs2.FileSystemException; 028 029/** 030 * Filters files based on a cutoff time, can filter either newer files or files 031 * equal to or older. 032 * <p> 033 * For example, to print all files and directories in the current directory 034 * older than one day: 035 * </p> 036 * 037 * <pre> 038 * FileSystemManager fsManager = VFS.getManager(); 039 * FileObject dir = fsManager.toFileObject(new File(".")); 040 * // We are interested in files older than one day 041 * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000); 042 * AgeFileFilter filter = new AgeFileFilter(cutoff); 043 * FileObject[] files = dir.findFiles(new FileFilterSelector(filter)); 044 * for (int i = 0; i < files.length; i++) { 045 * System.out.println(files[i]); 046 * } 047 * </pre> 048 * 049 * @author This code was originally ported from Apache Commons IO File Filter 050 * @see "https://commons.apache.org/proper/commons-io/" 051 * @since 2.4 052 */ 053public class AgeFileFilter implements FileFilter, Serializable { 054 055 private static final long serialVersionUID = 1L; 056 057 /** 058 * Tests if the specified {@code File} is newer than the specified time 059 * reference. 060 * 061 * @param fileObject the {@code File} of which the modification date must 062 * be compared, must not be {@code null} 063 * @param timeMillis the time reference measured in milliseconds since the epoch 064 * (00:00:00 GMT, January 1, 1970) 065 * @return true if the {@code File} exists and has been modified after the 066 * given time reference. 067 * @throws FileSystemException Thrown for file system errors. 068 * @throws IllegalArgumentException if the file is {@code null} 069 */ 070 private static boolean isFileNewer(final FileObject fileObject, final long timeMillis) throws FileSystemException { 071 Objects.requireNonNull(fileObject, "fileObject"); 072 if (!fileObject.exists()) { 073 return false; 074 } 075 try (FileContent content = fileObject.getContent()) { 076 return content.getLastModifiedTime() > timeMillis; 077 } 078 } 079 080 /** Whether the files accepted will be older or newer. */ 081 private final boolean acceptOlder; 082 083 /** The cutoff time threshold. */ 084 private final long cutoff; 085 086 /** 087 * Constructs a new age file filter for files older than (at or before) a 088 * certain cutoff date. 089 * 090 * @param cutoffDate the threshold age of the files 091 */ 092 public AgeFileFilter(final Date cutoffDate) { 093 this(cutoffDate, true); 094 } 095 096 /** 097 * Constructs a new age file filter for files on any one side of a certain 098 * cutoff date. 099 * 100 * @param cutoffDate the threshold age of the files 101 * @param acceptOlder if true, older files (at or before the cutoff) are 102 * accepted, else newer ones (after the cutoff). 103 */ 104 public AgeFileFilter(final Date cutoffDate, final boolean acceptOlder) { 105 this(cutoffDate.getTime(), acceptOlder); 106 } 107 108 /** 109 * Constructs a new age file filter for files older than (at or before) a 110 * certain File (whose last modification time will be used as reference). 111 * 112 * @param cutoffReference the file whose last modification time is used as the 113 * threshold age of the files 114 * 115 * @throws FileSystemException Error reading the last modification time from the 116 * reference file object. 117 */ 118 public AgeFileFilter(final FileObject cutoffReference) throws FileSystemException { 119 this(cutoffReference, true); 120 } 121 122 /** 123 * Constructs a new age file filter for files on any one side of a certain File 124 * (whose last modification time will be used as reference). 125 * 126 * @param cutoffReference the file whose last modification time is used as the 127 * threshold age of the files 128 * @param acceptOlder if true, older files (at or before the cutoff) are 129 * accepted, else newer ones (after the cutoff). 130 * 131 * @throws FileSystemException Error reading the last modification time from the 132 * reference file object. 133 */ 134 public AgeFileFilter(final FileObject cutoffReference, final boolean acceptOlder) throws FileSystemException { 135 this(cutoffReference.getContent().getLastModifiedTime(), acceptOlder); 136 } 137 138 /** 139 * Constructs a new age file filter for files equal to or older than a certain 140 * cutoff. 141 * 142 * @param cutoff the threshold age of the files 143 */ 144 public AgeFileFilter(final long cutoff) { 145 this(cutoff, true); 146 } 147 148 /** 149 * Constructs a new age file filter for files on any one side of a certain 150 * cutoff. 151 * 152 * @param cutoff the threshold age of the files 153 * @param acceptOlder if true, older files (at or before the cutoff) are 154 * accepted, else newer ones (after the cutoff). 155 */ 156 public AgeFileFilter(final long cutoff, final boolean acceptOlder) { 157 this.acceptOlder = acceptOlder; 158 this.cutoff = cutoff; 159 } 160 161 /** 162 * Checks to see if the last modification of the file matches cutoff favorably. 163 * <p> 164 * If last modification time equals cutoff and newer files are required, file 165 * <strong>IS NOT</strong> selected. If last modification time equals cutoff and older 166 * files are required, file <strong>IS</strong> selected. 167 * </p> 168 * 169 * @param fileInfo the File to check 170 * @return true if the file name matches 171 * @throws FileSystemException Thrown for file system errors. 172 */ 173 @Override 174 public boolean accept(final FileSelectInfo fileInfo) throws FileSystemException { 175 return acceptOlder != isFileNewer(fileInfo.getFile(), cutoff); 176 } 177 178 /** 179 * Provide a String representation of this file filter. 180 * 181 * @return a String representation 182 */ 183 @Override 184 public String toString() { 185 final String condition = acceptOlder ? "<=" : ">"; 186 return super.toString() + "(" + condition + cutoff + ")"; 187 } 188}