1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.logging.log4j.core.appender.rolling.action;
19
20 import java.io.IOException;
21 import java.nio.file.FileVisitOption;
22 import java.nio.file.FileVisitor;
23 import java.nio.file.Files;
24 import java.nio.file.Path;
25 import java.nio.file.Paths;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.EnumSet;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.concurrent.TimeUnit;
32
33 import org.apache.logging.log4j.core.lookup.StrSubstitutor;
34
35
36
37
38 public abstract class AbstractPathAction extends AbstractAction {
39
40 private final String basePathString;
41 private final Set<FileVisitOption> options;
42 private final int maxDepth;
43 private final List<PathCondition> pathConditions;
44 private final StrSubstitutor subst;
45
46
47
48
49
50
51
52
53
54
55
56
57 protected AbstractPathAction(final String basePath, final boolean followSymbolicLinks, final int maxDepth,
58 final PathCondition[] pathFilters, final StrSubstitutor subst) {
59 this.basePathString = basePath;
60 this.options = followSymbolicLinks ? EnumSet.of(FileVisitOption.FOLLOW_LINKS)
61 : Collections.<FileVisitOption> emptySet();
62 this.maxDepth = maxDepth;
63 this.pathConditions = Arrays.asList(Arrays.copyOf(pathFilters, pathFilters.length));
64 this.subst = subst;
65 }
66
67 @Override
68 public boolean execute() throws IOException {
69 return execute(createFileVisitor(getBasePath(), pathConditions));
70 }
71
72 public boolean execute(final FileVisitor<Path> visitor) throws IOException {
73 final long start = System.nanoTime();
74 LOGGER.debug("Starting {}", this);
75
76 Files.walkFileTree(getBasePath(), options, maxDepth, visitor);
77
78 final double duration = System.nanoTime() - start;
79 LOGGER.debug("{} complete in {} seconds", getClass().getSimpleName(), duration / TimeUnit.SECONDS.toNanos(1));
80
81
82 return true;
83 }
84
85
86
87
88
89
90
91
92
93
94
95 protected abstract FileVisitor<Path> createFileVisitor(final Path visitorBaseDir,
96 final List<PathCondition> conditions);
97
98
99
100
101
102
103
104
105 public Path getBasePath() {
106 return Paths.get(subst.replace(getBasePathString()));
107 }
108
109
110
111
112
113
114 public String getBasePathString() {
115 return basePathString;
116 }
117
118 public StrSubstitutor getStrSubstitutor() {
119 return subst;
120 }
121
122
123
124
125
126
127 public Set<FileVisitOption> getOptions() {
128 return Collections.unmodifiableSet(options);
129 }
130
131
132
133
134
135
136 public boolean isFollowSymbolicLinks() {
137 return options.contains(FileVisitOption.FOLLOW_LINKS);
138 }
139
140
141
142
143
144
145 public int getMaxDepth() {
146 return maxDepth;
147 }
148
149
150
151
152
153
154 public List<PathCondition> getPathConditions() {
155 return Collections.unmodifiableList(pathConditions);
156 }
157
158 @Override
159 public String toString() {
160 return getClass().getSimpleName() + "[basePath=" + getBasePath() + ", options=" + options + ", maxDepth="
161 + maxDepth + ", conditions=" + pathConditions + "]";
162 }
163 }