src/main/java/de/uapcore/lightpit/PathPattern.java

Mon, 04 Jan 2021 17:30:10 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 04 Jan 2021 17:30:10 +0100
changeset 178
88207b860cba
parent 130
7ef369744fd1
permissions
-rw-r--r--

automatically select version/component when creating new issues under active filters

universe@130 1 package de.uapcore.lightpit;
universe@130 2
universe@130 3 import java.util.ArrayList;
universe@130 4 import java.util.List;
universe@130 5
universe@130 6 public final class PathPattern {
universe@130 7
universe@130 8 private final List<String> nodePatterns;
universe@130 9 private final boolean collection;
universe@130 10
universe@130 11 /**
universe@130 12 * Constructs a new path pattern.
universe@130 13 * The special directories . and .. are disallowed in the pattern.
universe@130 14 *
universe@130 15 * @param pattern
universe@130 16 */
universe@130 17 public PathPattern(String pattern) {
universe@130 18 nodePatterns = parse(pattern);
universe@130 19 collection = pattern.endsWith("/");
universe@130 20 }
universe@130 21
universe@130 22 private List<String> parse(String pattern) {
universe@130 23
universe@130 24 var nodes = new ArrayList<String>();
universe@130 25 var parts = pattern.split("/");
universe@130 26
universe@130 27 for (var part : parts) {
universe@130 28 if (part.isBlank()) continue;
universe@130 29 if (part.equals(".") || part.equals(".."))
universe@130 30 throw new IllegalArgumentException("Path must not contain '.' or '..' nodes.");
universe@130 31 nodes.add(part);
universe@130 32 }
universe@130 33
universe@130 34 return nodes;
universe@130 35 }
universe@130 36
universe@130 37 /**
universe@130 38 * Matches a path against this pattern.
universe@130 39 * The path must be canonical in the sense that no . or .. parts occur.
universe@130 40 *
universe@130 41 * @param path the path to match
universe@130 42 * @return true if the path matches the pattern, false otherwise
universe@130 43 */
universe@130 44 public boolean matches(String path) {
universe@130 45 if (collection ^ path.endsWith("/"))
universe@130 46 return false;
universe@130 47
universe@130 48 var nodes = parse(path);
universe@130 49 if (nodePatterns.size() != nodes.size())
universe@130 50 return false;
universe@130 51
universe@130 52 for (int i = 0 ; i < nodePatterns.size() ; i++) {
universe@130 53 var pattern = nodePatterns.get(i);
universe@130 54 var node = nodes.get(i);
universe@130 55 if (pattern.startsWith("$"))
universe@130 56 continue;
universe@130 57 if (!pattern.equals(node))
universe@130 58 return false;
universe@130 59 }
universe@130 60
universe@130 61 return true;
universe@130 62 }
universe@130 63
universe@130 64 /**
universe@130 65 * Returns the path parameters found in the specified path using this pattern.
universe@130 66 * The return value of this method is undefined, if the patter does not match.
universe@130 67 *
universe@130 68 * @param path the path
universe@130 69 * @return the path parameters, if any, or an empty map
universe@130 70 * @see #matches(String)
universe@130 71 */
universe@130 72 public PathParameters obtainPathParameters(String path) {
universe@130 73 var params = new PathParameters();
universe@130 74
universe@130 75 var nodes = parse(path);
universe@130 76
universe@130 77 for (int i = 0 ; i < Math.min(nodes.size(), nodePatterns.size()) ; i++) {
universe@130 78 var pattern = nodePatterns.get(i);
universe@130 79 var node = nodes.get(i);
universe@130 80 if (pattern.startsWith("$")) {
universe@130 81 params.put(pattern.substring(1), node);
universe@130 82 }
universe@130 83 }
universe@130 84
universe@130 85 return params;
universe@130 86 }
universe@130 87
universe@130 88 @Override
universe@130 89 public int hashCode() {
universe@130 90 var str = new StringBuilder();
universe@130 91 for (var node : nodePatterns) {
universe@130 92 if (node.startsWith("$")) {
universe@130 93 str.append("/$");
universe@130 94 } else {
universe@130 95 str.append('/');
universe@130 96 str.append(node);
universe@130 97 }
universe@130 98 }
universe@130 99 if (collection)
universe@130 100 str.append('/');
universe@130 101
universe@130 102 return str.toString().hashCode();
universe@130 103 }
universe@130 104
universe@130 105 @Override
universe@130 106 public boolean equals(Object obj) {
universe@130 107 if (!obj.getClass().equals(PathPattern.class))
universe@130 108 return false;
universe@130 109
universe@130 110 var other = (PathPattern) obj;
universe@130 111 if (collection ^ other.collection || nodePatterns.size() != other.nodePatterns.size())
universe@130 112 return false;
universe@130 113
universe@130 114 for (int i = 0 ; i < nodePatterns.size() ; i++) {
universe@130 115 var left = nodePatterns.get(i);
universe@130 116 var right = other.nodePatterns.get(i);
universe@130 117 if (left.startsWith("$") && right.startsWith("$"))
universe@130 118 continue;
universe@130 119 if (!left.equals(right))
universe@130 120 return false;
universe@130 121 }
universe@130 122
universe@130 123 return true;
universe@130 124 }
universe@130 125 }

mercurial