Skip to content

Commit f3b64e7

Browse files
committed
Internal refactoring
Extract a package-private PathFence class from AbstractPathFencedLookup
1 parent 1df1c0c commit f3b64e7

File tree

2 files changed

+115
-22
lines changed

2 files changed

+115
-22
lines changed

src/main/java/org/apache/commons/text/lookup/AbstractPathFencedLookup.java

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,28 @@
1414
* See the license for the specific language governing permissions and
1515
* limitations under the license.
1616
*/
17+
1718
package org.apache.commons.text.lookup;
1819

1920
import java.nio.file.Path;
20-
import java.nio.file.Paths;
21-
import java.util.Arrays;
22-
import java.util.Collections;
23-
import java.util.List;
24-
import java.util.Optional;
25-
import java.util.stream.Collectors;
2621

2722
/**
28-
* Abstracts guarding Path lookups with fences.
23+
* Abstracts string lookup that guards Path lookups with a fence.
2924
*/
3025
abstract class AbstractPathFencedLookup extends AbstractStringLookup {
3126

3227
/**
3328
* A fence is made of Paths guarding Path resolution.
3429
*/
35-
protected final List<Path> fences;
30+
protected final PathFence fence;
3631

3732
/**
3833
* Constructs a new instance.
3934
*
40-
* @param fences The fences guarding Path resolution.
35+
* @param paths The fences guarding Path resolution.
4136
*/
42-
AbstractPathFencedLookup(final Path... fences) {
43-
this.fences = fences != null ? Arrays.stream(fences).map(Path::toAbsolutePath).collect(Collectors.toList()) : Collections.emptyList();
37+
AbstractPathFencedLookup(final Path... paths) {
38+
this.fence = PathFence.builder().setPaths(paths).get();
4439
}
4540

4641
/**
@@ -51,16 +46,6 @@ abstract class AbstractPathFencedLookup extends AbstractStringLookup {
5146
* @throws IllegalArgumentException if the file name is not without our fence.
5247
*/
5348
protected Path getPath(final String fileName) {
54-
final Path path = Paths.get(fileName);
55-
if (fences.isEmpty()) {
56-
return path;
57-
}
58-
final Path pathAbs = path.normalize().toAbsolutePath();
59-
final Optional<Path> first = fences.stream().filter(pathAbs::startsWith).findFirst();
60-
if (first.isPresent()) {
61-
return path;
62-
}
63-
throw IllegalArgumentExceptions.format("[%s] -> [%s] not in %s", fileName, pathAbs, fences);
49+
return fence.getPath(fileName);
6450
}
65-
6651
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
* https://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.text.lookup;
19+
20+
import java.nio.file.Path;
21+
import java.nio.file.Paths;
22+
import java.util.Arrays;
23+
import java.util.List;
24+
import java.util.Optional;
25+
import java.util.function.Supplier;
26+
import java.util.stream.Collectors;
27+
28+
/**
29+
* A Path fence guards Path resolution.
30+
*
31+
* Keep package-private.
32+
*/
33+
final class PathFence {
34+
35+
/**
36+
* Builds {@link PathFence} instances.
37+
*/
38+
static final class Builder implements Supplier<PathFence> {
39+
40+
/** The empty Path array. */
41+
private static final Path[] EMPTY = {};
42+
43+
/**
44+
* A fence is made of Paths guarding Path resolution.
45+
*/
46+
private Path[] paths = EMPTY;
47+
48+
/**
49+
* Sets the paths that delineate this fence.
50+
*
51+
* @param paths the paths that delineate this fence.
52+
* @return {@code this} instance.
53+
*/
54+
Builder setPaths(final Path... paths) {
55+
this.paths = paths != null ? paths.clone() : EMPTY;
56+
return this;
57+
}
58+
59+
@Override
60+
public PathFence get() {
61+
return new PathFence(this);
62+
}
63+
}
64+
65+
/**
66+
* Creates a new builder.
67+
*
68+
* @return a new builder.
69+
*/
70+
static Builder builder() {
71+
return new Builder();
72+
}
73+
74+
/**
75+
* A fence is made of Paths guarding Path resolution.
76+
*/
77+
private final List<Path> paths;
78+
79+
/**
80+
* Constructs a new instance.
81+
*
82+
* @param builder A builder.
83+
*/
84+
private PathFence(final Builder builder) {
85+
this.paths = Arrays.stream(builder.paths).map(Path::toAbsolutePath).collect(Collectors.toList());
86+
}
87+
88+
/**
89+
* Gets a Path for the given file name checking that it resolves within our fence.
90+
*
91+
* @param fileName the file name to resolve.
92+
* @return a fenced Path.
93+
* @throws IllegalArgumentException if the file name is not without our fence.
94+
*/
95+
Path getPath(final String fileName) {
96+
final Path path = Paths.get(fileName);
97+
if (paths.isEmpty()) {
98+
return path;
99+
}
100+
final Path pathAbs = path.normalize().toAbsolutePath();
101+
final Optional<Path> first = paths.stream().filter(pathAbs::startsWith).findFirst();
102+
if (first.isPresent()) {
103+
return path;
104+
}
105+
throw new IllegalArgumentException(String.format("[%s] -> [%s] not in the fence %s", fileName, pathAbs, paths));
106+
}
107+
108+
}

0 commit comments

Comments
 (0)