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 package org.apache.commons.text.lookup;
18
19 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;
26
27 /**
28 * Abstracts guarding Path lookups with fences.
29 */
30 abstract class AbstractPathFencedLookup extends AbstractStringLookup {
31
32 /**
33 * Fences guarding Path resolution.
34 */
35 protected final List<Path> fences;
36
37 /**
38 * Constructs a new instance.
39 *
40 * @param fences The fences guarding Path resolution.
41 */
42 AbstractPathFencedLookup(final Path... fences) {
43 this.fences = fences != null ? Arrays.stream(fences).map(Path::toAbsolutePath).collect(Collectors.toList()) : Collections.emptyList();
44 }
45
46 /**
47 * Gets a Path for the given file name checking that it resolves within our fences.
48 *
49 * @param fileName the file name to resolve.
50 * @return a fenced Path.
51 * @throws IllegalArgumentException if the file name is not without our fences.
52 */
53 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);
64 }
65
66 }