
com.airepublic.http.common.pathmatcher.PathMapping Maven / Gradle / Ivy
package com.airepublic.http.common.pathmatcher;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
public class PathMapping {
private final Map configExactMatchMap = new ConcurrentHashMap<>();
private final Map>> configTemplateMatchMap = new ConcurrentHashMap<>();
public void add(final String path, final T mappedObject) {
UriTemplate uriTemplate = null;
try {
uriTemplate = new UriTemplate(path);
} catch (final IOException e) {
// Path is not valid so can't be matched
throw new IllegalArgumentException("URI path not valid: " + path, e);
}
if (uriTemplate.hasParameters()) {
final Integer key = Integer.valueOf(uriTemplate.getSegmentCount());
SortedSet> templateMatches = configTemplateMatchMap.get(key);
if (templateMatches == null) {
// Ensure that if concurrent threads execute this block they
// both end up using the same TreeSet instance
templateMatches = new TreeSet<>(new TemplatePathMatchComparator());
configTemplateMatchMap.putIfAbsent(key, templateMatches);
templateMatches = configTemplateMatchMap.get(key);
}
if (!templateMatches.add(new TemplatePathMatch<>(mappedObject, uriTemplate))) {
// Duplicate uriTemplate;
throw new IllegalArgumentException("Duplicate path mapping: " + path);
}
} else {
// Exact match
final T old = configExactMatchMap.put(path, mappedObject);
if (old != null) {
// Duplicate path mappings
throw new IllegalArgumentException("Duplicate path mapping: " + path);
}
}
}
public MappingResult findMapping(final String path) {
// Check an exact match. Simple case as there are no templates.
T mappedObject = configExactMatchMap.get(path);
if (mappedObject != null) {
return new MappingResult<>(mappedObject, Collections.emptyMap());
}
// No exact match. Need to look for template matches.
UriTemplate pathUriTemplate = null;
try {
pathUriTemplate = new UriTemplate(path);
} catch (final IOException e) {
// Path is not valid so can't be matched
return null;
}
// Number of segments has to match
final Integer key = Integer.valueOf(pathUriTemplate.getSegmentCount());
final SortedSet> templateMatches = configTemplateMatchMap.get(key);
if (templateMatches == null) {
// No templates with an equal number of segments so there will be no matches
return null;
}
// List is in alphabetical order of normalised templates.
// Correct match is the first one that matches.
Map pathParams = null;
for (final TemplatePathMatch templateMatch : templateMatches) {
pathParams = templateMatch.getUriTemplate().match(pathUriTemplate);
if (pathParams != null) {
mappedObject = templateMatch.getConfig();
break;
}
}
if (mappedObject == null) {
// No match
return null;
}
return new MappingResult<>(mappedObject, pathParams);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy