|
| 1 | +package com.retailsvc.http.spec; |
| 2 | + |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.LinkedHashMap; |
| 5 | +import java.util.List; |
| 6 | +import java.util.Map; |
| 7 | +import java.util.Optional; |
| 8 | +import java.util.regex.Matcher; |
| 9 | +import java.util.regex.Pattern; |
| 10 | + |
| 11 | +public record PathTemplate(String raw, Pattern compiled, List<String> parameterNames) { |
| 12 | + |
| 13 | + private static final Pattern TOKEN = Pattern.compile("\\{([^/}]+)}"); |
| 14 | + |
| 15 | + public static PathTemplate compile(String template) { |
| 16 | + StringBuilder regex = new StringBuilder("^"); |
| 17 | + List<String> names = new ArrayList<>(); |
| 18 | + Matcher m = TOKEN.matcher(template); |
| 19 | + int last = 0; |
| 20 | + while (m.find()) { |
| 21 | + regex.append(Pattern.quote(template.substring(last, m.start()))); |
| 22 | + regex.append("([^/]+)"); |
| 23 | + names.add(m.group(1)); |
| 24 | + last = m.end(); |
| 25 | + } |
| 26 | + regex.append(Pattern.quote(template.substring(last))); |
| 27 | + regex.append("$"); |
| 28 | + return new PathTemplate(template, Pattern.compile(regex.toString()), List.copyOf(names)); |
| 29 | + } |
| 30 | + |
| 31 | + public Optional<Map<String, String>> match(String path) { |
| 32 | + Matcher m = compiled.matcher(path); |
| 33 | + if (!m.matches()) return Optional.empty(); |
| 34 | + Map<String, String> out = new LinkedHashMap<>(); |
| 35 | + for (int i = 0; i < parameterNames.size(); i++) { |
| 36 | + out.put(parameterNames.get(i), m.group(i + 1)); |
| 37 | + } |
| 38 | + return Optional.of(Map.copyOf(out)); |
| 39 | + } |
| 40 | +} |
0 commit comments