0
# Path and Filter Utilities
1
2
Path and filter utilities provide comprehensive support for archive path manipulation, content filtering, and selective archive operations.
3
4
## Path Management
5
6
### BasicPath
7
8
Core implementation of the ArchivePath interface for representing archive entry paths.
9
10
```java { .api }
11
public class BasicPath implements ArchivePath, Comparable<ArchivePath>
12
```
13
14
**Constructors:**
15
```java { .api }
16
public BasicPath() // Root path "/"
17
public BasicPath(String context) // Path from string
18
public BasicPath(ArchivePath basePath, String context) // Path from base + context
19
```
20
21
**Key Methods:**
22
```java { .api }
23
public String get() // Get full path string
24
public ArchivePath getParent() // Get parent path
25
public Set<ArchivePath> getChildPaths() // Get child paths
26
public boolean isRoot() // Check if root path
27
public int compareTo(ArchivePath other) // Path comparison
28
```
29
30
**Usage Examples:**
31
```java
32
// Create paths
33
ArchivePath root = new BasicPath(); // "/"
34
ArchivePath webInf = new BasicPath("/WEB-INF"); // "/WEB-INF"
35
ArchivePath classes = new BasicPath(webInf, "classes"); // "/WEB-INF/classes"
36
37
// Path operations
38
String pathString = classes.get(); // "/WEB-INF/classes"
39
ArchivePath parent = classes.getParent(); // "/WEB-INF"
40
boolean isRoot = root.isRoot(); // true
41
```
42
43
### PathUtil
44
45
Utility class for path manipulation and normalization.
46
47
```java { .api }
48
public class PathUtil
49
```
50
51
**Key Methods:**
52
```java { .api }
53
public static String normalize(String path)
54
public static boolean isValid(String path)
55
public static String getParent(String path)
56
public static String getName(String path)
57
public static String getExtension(String path)
58
```
59
60
**Usage:**
61
```java
62
// Path normalization
63
String normalized = PathUtil.normalize("//META-INF/../classes/./MyClass.class");
64
// Result: "/classes/MyClass.class"
65
66
// Path validation
67
boolean valid = PathUtil.isValid("/META-INF/MANIFEST.MF"); // true
68
69
// Path components
70
String parent = PathUtil.getParent("/WEB-INF/classes/MyClass.class"); // "/WEB-INF/classes"
71
String name = PathUtil.getName("/WEB-INF/classes/MyClass.class"); // "MyClass.class"
72
String ext = PathUtil.getExtension("/WEB-INF/classes/MyClass.class"); // "class"
73
```
74
75
## Filter Implementations
76
77
### Path Filters
78
79
#### IncludeAllPaths
80
81
Filter that includes all archive paths without restriction.
82
83
```java { .api }
84
public class IncludeAllPaths implements Filter<ArchivePath>
85
```
86
87
**Methods:**
88
```java { .api }
89
public boolean include(ArchivePath object) // Always returns true
90
```
91
92
#### IncludePaths
93
94
Filter that includes only specified paths.
95
96
```java { .api }
97
public class IncludePaths implements Filter<ArchivePath>
98
```
99
100
**Constructors:**
101
```java { .api }
102
public IncludePaths(String... paths)
103
public IncludePaths(ArchivePath... paths)
104
```
105
106
**Usage:**
107
```java
108
Filter<ArchivePath> filter = new IncludePaths(
109
"/META-INF/MANIFEST.MF",
110
"/WEB-INF/web.xml"
111
);
112
```
113
114
#### ExcludePaths
115
116
Filter that excludes specified paths.
117
118
```java { .api }
119
public class ExcludePaths implements Filter<ArchivePath>
120
```
121
122
**Constructors:**
123
```java { .api }
124
public ExcludePaths(String... paths)
125
public ExcludePaths(ArchivePath... paths)
126
```
127
128
**Usage:**
129
```java
130
Filter<ArchivePath> filter = new ExcludePaths(
131
"/temp",
132
"/logs",
133
"/backup"
134
);
135
```
136
137
#### IncludeRegExpPaths
138
139
Filter using regular expressions for path inclusion.
140
141
```java { .api }
142
public class IncludeRegExpPaths implements Filter<ArchivePath>
143
```
144
145
**Constructors:**
146
```java { .api }
147
public IncludeRegExpPaths(String... expressions)
148
public IncludeRegExpPaths(Pattern... patterns)
149
```
150
151
**Usage:**
152
```java
153
// Include only Java class files and XML files
154
Filter<ArchivePath> filter = new IncludeRegExpPaths(
155
".*\\.class$",
156
".*\\.xml$"
157
);
158
159
// Include files in specific directories
160
Filter<ArchivePath> filter = new IncludeRegExpPaths(
161
"/WEB-INF/.*",
162
"/META-INF/.*"
163
);
164
```
165
166
#### ExcludeRegExpPaths
167
168
Filter using regular expressions for path exclusion.
169
170
```java { .api }
171
public class ExcludeRegExpPaths implements Filter<ArchivePath>
172
```
173
174
**Constructors:**
175
```java { .api }
176
public ExcludeRegExpPaths(String... expressions)
177
public ExcludeRegExpPaths(Pattern... patterns)
178
```
179
180
**Usage:**
181
```java
182
// Exclude test files and temporary files
183
Filter<ArchivePath> filter = new ExcludeRegExpPaths(
184
".*Test\\.class$",
185
".*\\.tmp$",
186
".*\\.bak$"
187
);
188
189
// Exclude specific directories
190
Filter<ArchivePath> filter = new ExcludeRegExpPaths(
191
"/test/.*",
192
"/temp/.*"
193
);
194
```
195
196
### Class Filters
197
198
#### IncludeAllClasses
199
200
Filter that includes all classes without restriction.
201
202
```java { .api }
203
public class IncludeAllClasses implements Filter<Class<?>>
204
```
205
206
**Methods:**
207
```java { .api }
208
public boolean include(Class<?> clazz) // Always returns true
209
```
210
211
## Filter Composition
212
213
Filters can be combined for complex filtering logic:
214
215
```java
216
// Combine filters with logical operations
217
Filter<ArchivePath> webResources = new IncludeRegExpPaths("/web/.*");
218
Filter<ArchivePath> noTemp = new ExcludeRegExpPaths(".*\\.tmp$");
219
220
// Composite filter (include web resources but exclude temp files)
221
Filter<ArchivePath> composite = Filters.and(webResources, noTemp);
222
223
// Use in archive operations
224
archive.merge(sourceArchive, composite);
225
```
226
227
## Advanced Path Operations
228
229
### Path Traversal
230
231
Safe path traversal with validation:
232
233
```java
234
public class PathTraversal {
235
public static void walkPaths(Archive<?> archive, PathVisitor visitor) {
236
for (ArchivePath path : archive.getContent().keySet()) {
237
if (PathUtil.isValid(path.get())) {
238
visitor.visit(path, archive.get(path));
239
}
240
}
241
}
242
}
243
244
// Usage
245
PathTraversal.walkPaths(archive, (path, node) -> {
246
System.out.println("Found: " + path.get());
247
if (node.getAsset() != null) {
248
System.out.println(" Size: " + node.getAsset().getSize());
249
}
250
});
251
```
252
253
### Path Pattern Matching
254
255
Advanced pattern matching for complex path selection:
256
257
```java
258
// Utility for complex path matching
259
public class PathMatcher {
260
public static boolean matches(ArchivePath path, String pattern) {
261
return path.get().matches(pattern);
262
}
263
264
public static List<ArchivePath> findMatching(Archive<?> archive, String pattern) {
265
return archive.getContent().keySet().stream()
266
.filter(path -> matches(path, pattern))
267
.collect(Collectors.toList());
268
}
269
}
270
271
// Find all JSP files in web application
272
List<ArchivePath> jspFiles = PathMatcher.findMatching(warArchive, ".*\\.jsp$");
273
274
// Find all configuration files
275
List<ArchivePath> configFiles = PathMatcher.findMatching(archive,
276
".*(config|properties|xml)$");
277
```
278
279
## Utility Integration
280
281
### Archive Content Analysis
282
283
Utilities for analyzing archive contents:
284
285
```java
286
public class ArchiveAnalyzer {
287
public static Map<String, Integer> getFileTypeCounts(Archive<?> archive) {
288
Map<String, Integer> counts = new HashMap<>();
289
290
for (ArchivePath path : archive.getContent().keySet()) {
291
String extension = PathUtil.getExtension(path.get());
292
counts.merge(extension, 1, Integer::sum);
293
}
294
295
return counts;
296
}
297
298
public static long getTotalSize(Archive<?> archive) {
299
return archive.getContent().values().stream()
300
.filter(node -> node.getAsset() != null)
301
.mapToLong(node -> node.getAsset().getSize())
302
.sum();
303
}
304
}
305
306
// Usage
307
Map<String, Integer> types = ArchiveAnalyzer.getFileTypeCounts(archive);
308
long totalSize = ArchiveAnalyzer.getTotalSize(archive);
309
```
310
311
### Path Validation
312
313
Comprehensive path validation utilities:
314
315
```java
316
public class PathValidator {
317
public static boolean isValidArchivePath(String path) {
318
return PathUtil.isValid(path) &&
319
!path.contains("..") && // No parent directory traversal
320
!path.startsWith("../") && // No relative parent access
321
path.length() <= 260; // Path length limit
322
}
323
324
public static void validateArchivePaths(Archive<?> archive) {
325
for (ArchivePath path : archive.getContent().keySet()) {
326
if (!isValidArchivePath(path.get())) {
327
throw new IllegalArchivePathException(
328
"Invalid path: " + path.get());
329
}
330
}
331
}
332
}
333
```
334
335
## Performance Optimizations
336
337
### Filter Caching
338
339
Optimized filter implementations with caching:
340
341
```java
342
public class CachedRegExpFilter implements Filter<ArchivePath> {
343
private final Pattern pattern;
344
private final Map<String, Boolean> cache = new ConcurrentHashMap<>();
345
346
public CachedRegExpFilter(String regex) {
347
this.pattern = Pattern.compile(regex);
348
}
349
350
@Override
351
public boolean include(ArchivePath path) {
352
return cache.computeIfAbsent(path.get(),
353
pathString -> pattern.matcher(pathString).matches());
354
}
355
}
356
```
357
358
### Batch Path Operations
359
360
Efficient batch operations on paths:
361
362
```java
363
// Batch path creation
364
List<ArchivePath> createPaths(List<String> pathStrings) {
365
return pathStrings.parallelStream()
366
.map(BasicPath::new)
367
.collect(Collectors.toList());
368
}
369
370
// Batch filtering
371
List<ArchivePath> filterPaths(Collection<ArchivePath> paths, Filter<ArchivePath> filter) {
372
return paths.parallelStream()
373
.filter(filter::include)
374
.collect(Collectors.toList());
375
}
376
```