package cc.blynk.core.http; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class UriTemplate { // Finds parameters in the URL pattern string. private static final String URL_PARAM_REGEX = "\\{(\\w*?)\\}"; // Replaces parameter names in the URL pattern string to match parameters in URLs. private static final String URL_PARAM_MATCH_REGEX = "\\([%\\\\w-.\\\\~!\\$&'\\\\(\\\\)\\\\*\\\\+,;=:\\\\[\\\\]@]+?\\)"; // Pattern to match URL pattern parameter names. private static final Pattern URL_PARAM_PATTERN = Pattern.compile(URL_PARAM_REGEX); // Finds the 'format' portion of the URL pattern string. private static final String URL_FORMAT_REGEX = "(?:\\.\\{format\\})$"; // Replaces the format parameter name in the URL pattern string to match the format specifier in URLs. Appended to the end of the regex string // when a URL pattern contains a format parameter. private static final String URL_FORMAT_MATCH_REGEX = "(?:\\\\.\\([\\\\w%]+?\\))?"; // Finds the query string portion withi private Matcher matcher;n a URL. Appended to the end of the built-up regex string. private static final String URL_QUERY_STRING_REGEX = "(?:\\?.*?)?$"; private String urlPattern; private Matcher matcher; private Pattern compiledUrl; private final List<String> parameterNames = new ArrayList<>(); public UriTemplate(String pattern) { this.urlPattern = pattern; compile(); } public Matcher matcher(String url) { return compiledUrl.matcher(url); } public void compile() { acquireParameterNames(); String parsedPattern = urlPattern.replaceFirst(URL_FORMAT_REGEX, URL_FORMAT_MATCH_REGEX); parsedPattern = parsedPattern.replaceAll(URL_PARAM_REGEX, URL_PARAM_MATCH_REGEX); this.compiledUrl = Pattern.compile(parsedPattern + URL_QUERY_STRING_REGEX); } private void acquireParameterNames() { Matcher m = URL_PARAM_PATTERN.matcher(urlPattern); while (m.find()) { parameterNames.add(m.group(1)); } } public Map<String, String> extractParameters(Matcher matcher) { Map<String, String> values = new HashMap<>(); for (int i = 0; i < matcher.groupCount(); i++) { String value = matcher.group(i + 1); if (value != null) { values.put(parameterNames.get(i), value); } } return values; } }