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 */ 017 018package org.apache.commons.io.file; 019 020import java.io.IOException; 021import java.nio.file.FileVisitResult; 022import java.nio.file.Files; 023import java.nio.file.Path; 024import java.nio.file.attribute.BasicFileAttributes; 025import java.util.ArrayList; 026import java.util.Comparator; 027import java.util.List; 028import java.util.Objects; 029 030import org.apache.commons.io.file.Counters.PathCounters; 031 032/** 033 * Accumulates normalized paths during visitation. 034 * <p> 035 * Use with care on large file trees as each visited Path element is remembered. 036 * </p> 037 * 038 * @since 2.7 039 */ 040public class AccumulatorPathVisitor extends CountingPathVisitor { 041 042 /** 043 * Creates a new instance configured with a BigInteger {@link PathCounters}. 044 * 045 * @return a new instance configured with a BigInteger {@link PathCounters}. 046 */ 047 public static AccumulatorPathVisitor withBigIntegerCounters() { 048 return new AccumulatorPathVisitor(Counters.bigIntegerPathCounters()); 049 } 050 051 /** 052 * Creates a new instance configured with a long {@link PathCounters}. 053 * 054 * @return a new instance configured with a long {@link PathCounters}. 055 */ 056 public static AccumulatorPathVisitor withLongCounters() { 057 return new AccumulatorPathVisitor(Counters.longPathCounters()); 058 } 059 060 private final List<Path> dirList = new ArrayList<>(); 061 062 private final List<Path> fileList = new ArrayList<>(); 063 064 /** 065 * Constructs a new instance. 066 * 067 * @param pathCounter How to count path visits. 068 */ 069 public AccumulatorPathVisitor(PathCounters pathCounter) { 070 super(pathCounter); 071 } 072 073 @Override 074 public boolean equals(Object obj) { 075 if (this == obj) { 076 return true; 077 } 078 if (!super.equals(obj)) { 079 return false; 080 } 081 if (!(obj instanceof AccumulatorPathVisitor)) { 082 return false; 083 } 084 AccumulatorPathVisitor other = (AccumulatorPathVisitor) obj; 085 return Objects.equals(dirList, other.dirList) && Objects.equals(fileList, other.fileList); 086 } 087 088 /** 089 * Gets the list of visited directories. 090 * 091 * @return the list of visited directories. 092 */ 093 public List<Path> getDirList() { 094 return dirList; 095 } 096 097 /** 098 * Gets the list of visited files. 099 * 100 * @return the list of visited files. 101 */ 102 public List<Path> getFileList() { 103 return fileList; 104 } 105 106 @Override 107 public int hashCode() { 108 final int prime = 31; 109 int result = super.hashCode(); 110 result = prime * result + Objects.hash(dirList, fileList); 111 return result; 112 } 113 114 /** 115 * Relativizes each directory path with {@link Path#relativize(Path)} against the given {@code parent}, optionally 116 * sorting the result. 117 * 118 * @param parent A parent path 119 * @param sort Whether to sort 120 * @param comparator How to sort, null uses default sorting. 121 * @return A new list 122 */ 123 public List<Path> relativizeDirectories(final Path parent, boolean sort, Comparator<? super Path> comparator) { 124 return PathUtils.relativize(getDirList(), parent, sort, comparator); 125 } 126 127 /** 128 * Relativizes each file path with {@link Path#relativize(Path)} against the given {@code parent}, optionally 129 * sorting the result. 130 * 131 * @param parent A parent path 132 * @param sort Whether to sort 133 * @param comparator How to sort, null uses default sorting. 134 * @return A new list 135 */ 136 public List<Path> relativizeFiles(final Path parent, boolean sort, Comparator<? super Path> comparator) { 137 return PathUtils.relativize(getFileList(), parent, sort, comparator); 138 } 139 140 @Override 141 public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException { 142 ((Files.isDirectory(file)) ? dirList : fileList).add(file.normalize()); 143 return super.visitFile(file, attributes); 144 } 145 146}