View Javadoc
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.vfs2.filter;
18  
19  import java.io.Serializable;
20  import java.util.Date;
21  import java.util.Objects;
22  
23  import org.apache.commons.vfs2.FileContent;
24  import org.apache.commons.vfs2.FileFilter;
25  import org.apache.commons.vfs2.FileObject;
26  import org.apache.commons.vfs2.FileSelectInfo;
27  import org.apache.commons.vfs2.FileSystemException;
28  
29  /**
30   * Filters files based on a cutoff time, can filter either newer files or files
31   * equal to or older.
32   * <p>
33   * For example, to print all files and directories in the current directory
34   * older than one day:
35   * </p>
36   *
37   * <pre>
38   * FileSystemManager fsManager = VFS.getManager();
39   * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
40   * // We are interested in files older than one day
41   * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
42   * AgeFileFilter filter = new AgeFileFilter(cutoff);
43   * FileObject[] files = dir.findFiles(new FileFilterSelector(filter));
44   * for (int i = 0; i &lt; files.length; i++) {
45   *     System.out.println(files[i]);
46   * }
47   * </pre>
48   *
49   * @author This code was originally ported from Apache Commons IO File Filter
50   * @see "http://commons.apache.org/proper/commons-io/"
51   * @since 2.4
52   */
53  public class AgeFileFilter implements FileFilter, Serializable {
54  
55      private static final long serialVersionUID = 1L;
56  
57      /** Whether the files accepted will be older or newer. */
58      private final boolean acceptOlder;
59  
60      /** The cutoff time threshold. */
61      private final long cutoff;
62  
63      /**
64       * Tests if the specified {@code File} is newer than the specified time
65       * reference.
66       *
67       * @param fileObject the {@code File} of which the modification date must
68       *                   be compared, must not be {@code null}
69       * @param timeMillis the time reference measured in milliseconds since the epoch
70       *                   (00:00:00 GMT, January 1, 1970)
71       * @return true if the {@code File} exists and has been modified after the
72       *         given time reference.
73       * @throws FileSystemException Thrown for file system errors.
74       * @throws IllegalArgumentException if the file is {@code null}
75       */
76      private static boolean isFileNewer(final FileObject fileObject, final long timeMillis) throws FileSystemException {
77          Objects.requireNonNull(fileObject, "fileObject");
78          if (!fileObject.exists()) {
79              return false;
80          }
81          try (final FileContent content = fileObject.getContent()) {
82              return content.getLastModifiedTime() > timeMillis;
83          }
84      }
85  
86      /**
87       * Constructs a new age file filter for files older than (at or before) a
88       * certain cutoff date.
89       *
90       * @param cutoffDate the threshold age of the files
91       */
92      public AgeFileFilter(final Date cutoffDate) {
93          this(cutoffDate, true);
94      }
95  
96      /**
97       * Constructs a new age file filter for files on any one side of a certain
98       * cutoff date.
99       *
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 usesd 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 usesd 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      * <b>IS NOT</b> selected. If last modification time equals cutoff and older
166      * files are required, file <b>IS</b> selected.
167      * </p>
168      *
169      * @param fileInfo the File to check
170      *
171      * @return true if the file name matches
172      * @throws FileSystemException Thrown for file system errors.
173      */
174     @Override
175     public boolean accept(final FileSelectInfo fileInfo) throws FileSystemException {
176         return acceptOlder != isFileNewer(fileInfo.getFile(), cutoff);
177     }
178 
179     /**
180      * Provide a String representaion of this file filter.
181      *
182      * @return a String representaion
183      */
184     @Override
185     public String toString() {
186         final String condition = acceptOlder ? "<=" : ">";
187         return super.toString() + "(" + condition + cutoff + ")";
188     }
189 }