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  
18  package org.apache.commons.io.file;
19  
20  import java.io.IOException;
21  import java.nio.file.Path;
22  import java.nio.file.attribute.BasicFileAttributes;
23  import java.util.ArrayList;
24  import java.util.Comparator;
25  import java.util.List;
26  import java.util.Objects;
27  
28  import org.apache.commons.io.file.Counters.PathCounters;
29  
30  /**
31   * Accumulates normalized paths during visitation.
32   * <p>
33   * Use with care on large file trees as each visited Path element is remembered.
34   * </p>
35   * <h2>Example</h2>
36   *
37   * <pre>
38   * Path dir = Paths.get("");
39   * // We are interested in files older than one day
40   * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
41   * AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new AgeFileFilter(cutoff));
42   * //
43   * // Walk one dir
44   * Files.walkFileTree(dir, Collections.emptySet(), 1, visitor);
45   * System.out.println(visitor.getPathCounters());
46   * System.out.println(visitor.getFileList());
47   * //
48   * visitor.getPathCounters().reset();
49   * //
50   * // Walk dir tree
51   * Files.walkFileTree(dir, visitor);
52   * System.out.println(visitor.getPathCounters());
53   * System.out.println(visitor.getDirList());
54   * System.out.println(visitor.getFileList());
55   * </pre>
56   *
57   * @since 2.7
58   */
59  public class AccumulatorPathVisitor extends CountingPathVisitor {
60  
61      /**
62       * Creates a new instance configured with a BigInteger {@link PathCounters}.
63       *
64       * @return a new instance configured with a BigInteger {@link PathCounters}.
65       */
66      public static AccumulatorPathVisitor withBigIntegerCounters() {
67          return new AccumulatorPathVisitor(Counters.bigIntegerPathCounters());
68      }
69  
70      /**
71       * Creates a new instance configured with a BigInteger {@link PathCounters}.
72       *
73       * @param fileFilter Filters files to accumulate and count.
74       * @param dirFilter Filters directories to accumulate and count.
75       * @return a new instance configured with a long {@link PathCounters}.
76       * @since 2.9.0
77       */
78      public static AccumulatorPathVisitor withBigIntegerCounters(final PathFilter fileFilter,
79          final PathFilter dirFilter) {
80          return new AccumulatorPathVisitor(Counters.bigIntegerPathCounters(), fileFilter, dirFilter);
81      }
82  
83      /**
84       * Creates a new instance configured with a long {@link PathCounters}.
85       *
86       * @return a new instance configured with a long {@link PathCounters}.
87       */
88      public static AccumulatorPathVisitor withLongCounters() {
89          return new AccumulatorPathVisitor(Counters.longPathCounters());
90      }
91  
92      /**
93       * Creates a new instance configured with a long {@link PathCounters}.
94       *
95       * @param fileFilter Filters files to accumulate and count.
96       * @param dirFilter Filters directories to accumulate and count.
97       * @return a new instance configured with a long {@link PathCounters}.
98       * @since 2.9.0
99       */
100     public static AccumulatorPathVisitor withLongCounters(final PathFilterter.html#PathFilter">PathFilter fileFilter, final PathFilter dirFilter) {
101         return new AccumulatorPathVisitor(Counters.longPathCounters(), fileFilter, dirFilter);
102     }
103 
104     private final List<Path> dirList = new ArrayList<>();
105 
106     private final List<Path> fileList = new ArrayList<>();
107 
108     /**
109      * Constructs a new instance.
110      *
111      * @since 2.9.0
112      */
113     public AccumulatorPathVisitor() {
114         super(Counters.noopPathCounters());
115     }
116 
117     /**
118      * Constructs a new instance that counts file system elements.
119      *
120      * @param pathCounter How to count path visits.
121      */
122     public AccumulatorPathVisitor(final PathCounters pathCounter) {
123         super(pathCounter);
124     }
125 
126     /**
127      * Constructs a new instance.
128      *
129      * @param pathCounter How to count path visits.
130      * @param fileFilter Filters which files to count.
131      * @param dirFilter Filters which directories to count.
132      * @since 2.9.0
133      */
134     public AccumulatorPathVisitor(final PathCounters pathCounter, final PathFilter fileFilter,
135         final PathFilter dirFilter) {
136         super(pathCounter, fileFilter, dirFilter);
137     }
138 
139     private void add(final List<Path> list, final Path dir) {
140         list.add(dir.normalize());
141     }
142 
143     @Override
144     public boolean equals(final Object obj) {
145         if (this == obj) {
146             return true;
147         }
148         if (!super.equals(obj)) {
149             return false;
150         }
151         if (!(obj instanceof AccumulatorPathVisitor)) {
152             return false;
153         }
154         final AccumulatorPathVisitororg/apache/commons/io/file/AccumulatorPathVisitor.html#AccumulatorPathVisitor">AccumulatorPathVisitor other = (AccumulatorPathVisitor) obj;
155         return Objects.equals(dirList, other.dirList) && Objects.equals(fileList, other.fileList);
156     }
157 
158     /**
159      * Gets the list of visited directories.
160      *
161      * @return the list of visited directories.
162      */
163     public List<Path> getDirList() {
164         return dirList;
165     }
166 
167     /**
168      * Gets the list of visited files.
169      *
170      * @return the list of visited files.
171      */
172     public List<Path> getFileList() {
173         return fileList;
174     }
175 
176     @Override
177     public int hashCode() {
178         final int prime = 31;
179         int result = super.hashCode();
180         result = prime * result + Objects.hash(dirList, fileList);
181         return result;
182     }
183 
184     /**
185      * Relativizes each directory path with {@link Path#relativize(Path)} against the given {@code parent}, optionally
186      * sorting the result.
187      *
188      * @param parent A parent path
189      * @param sort Whether to sort
190      * @param comparator How to sort, null uses default sorting.
191      * @return A new list
192      */
193     public List<Path> relativizeDirectories(final Path parent, final boolean sort,
194         final Comparator<? super Path> comparator) {
195         return PathUtils.relativize(getDirList(), parent, sort, comparator);
196     }
197 
198     /**
199      * Relativizes each file path with {@link Path#relativize(Path)} against the given {@code parent}, optionally
200      * sorting the result.
201      *
202      * @param parent A parent path
203      * @param sort Whether to sort
204      * @param comparator How to sort, null uses default sorting.
205      * @return A new list
206      */
207     public List<Path> relativizeFiles(final Path parent, final boolean sort,
208         final Comparator<? super Path> comparator) {
209         return PathUtils.relativize(getFileList(), parent, sort, comparator);
210     }
211 
212     @Override
213     protected void updateDirCounter(final Path dir, final IOException exc) {
214         super.updateDirCounter(dir, exc);
215         add(dirList, dir);
216     }
217 
218     @Override
219     protected void updateFileCounters(final Path file, final BasicFileAttributes attributes) {
220         super.updateFileCounters(file, attributes);
221         add(fileList, file);
222     }
223 
224 }