package com.vtence.molecule.routing;
import com.vtence.molecule.lib.matchers.Matcher;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DynamicPath implements Matcher<String>, WithBoundParameters {
private final Path pattern;
public DynamicPath(String pattern) {
this.pattern = new Path(pattern);
}
public boolean matches(String actual) {
Path path = new Path(actual);
if (!pattern.sameLengthAs(path)) return false;
for (int i = 0; i < pattern.segmentCount(); i++) {
if (!isDynamic(pattern.segment(i)) && !pattern.segment(i).equals(path.segment(i)))
return false;
}
return true;
}
private boolean isDynamic(String segment) {
return segment.startsWith(":");
}
public Map<String, String> parametersBoundTo(String path) {
Path p = new Path(path);
Map<String, String> boundParameters = new HashMap<>();
for (int i = 0; i < pattern.segmentCount(); i++) {
String segment = pattern.segment(i);
if (isDynamic(segment)) {
boundParameters.put(stripLeadingColon(segment), p.segment(i));
}
}
return boundParameters;
}
private String stripLeadingColon(String segment) {
return segment.substring(1);
}
public static class Path {
private final String path;
public Path(String path) {
this.path = path;
}
public String[] segments() {
return removeEmptyParts(path.split("/"));
}
private static String[] removeEmptyParts(String[] parts) {
List<String> segments = new ArrayList<>();
for (String part : parts) {
if (!part.isEmpty()) segments.add(part);
}
return segments.toArray(new String[segments.size()]);
}
public boolean sameLengthAs(Path other) {
return other.segments().length == segments().length;
}
public String segment(int index) {
return segments()[index];
}
public int segmentCount() {
return segments().length;
}
}
}