/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.core.uri; import org.everrest.core.util.UriPatternComparator; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class UriPattern { // TODO: remove static, create comparator when need it public static final Comparator<UriPattern> URIPATTERN_COMPARATOR = new UriPatternComparator(); /** Should be added in URI pattern regular expression. */ private static final String URI_PATTERN_TAIL = "(/.*)?"; // /** List of names for URI template variables. */ private final List<String> parameterNames; /** URI template. */ private final String template; /** Number of characters in URI template NOT resulting from template variable substitution. */ private final int numberOfCharacters; /** Compiled URI pattern. */ private final Pattern pattern; /** Regular expressions for URI pattern. */ private final String regex; /** Regex capturing group indexes. */ private final int[] groupIndexes; // public UriPattern(String template) { if (template.length() > 0 && template.charAt(0) != '/') { template = '/' + template; } UriTemplateParser parser = new UriTemplateParser(template); this.template = parser.getTemplate(); this.parameterNames = Collections.unmodifiableList(parser.getParameterNames()); this.numberOfCharacters = parser.getNumberOfLiteralCharacters(); int[] indexes = parser.getGroupIndexes(); if (indexes != null) { this.groupIndexes = new int[indexes.length + 1]; System.arraycopy(indexes, 0, this.groupIndexes, 0, indexes.length); // Add one more index for URI_PATTERN_TAIL this.groupIndexes[groupIndexes.length - 1] = indexes[indexes.length - 1] + 1; } else { this.groupIndexes = null; } String regex = parser.getRegex(); if (regex.endsWith("/")) { regex = regex.substring(0, regex.length() - 1); } this.regex = regex + URI_PATTERN_TAIL; this.pattern = Pattern.compile(this.regex); } public boolean equals(Object obj) { return obj != null && obj.getClass() == getClass() && getRegex().equals(((UriPattern)obj).getRegex()); } public int hashCode() { int hash = 7; hash = hash * 31 + regex.hashCode(); return hash; } /** * Get the regex pattern. * * @return the regex pattern */ public Pattern getPattern() { return pattern; } /** * Get the URI template as a String. * * @return the URI template */ public String getTemplate() { return template; } /** * Get the regular expression. * * @return the regular expression */ public String getRegex() { return regex; } /** * Get the number of literal characters in the template. * * @return number of literal characters in the template */ public int getNumberOfLiteralCharacters() { return numberOfCharacters; } /** @return list of names */ public List<String> getParameterNames() { return parameterNames; } /** * Check is URI string match to pattern. If it is then fill given list by parameter value. Before coping value list * is cleared. List will be 1 greater then number of keys. It can be used for check is resource is matching to * requested. If resource is match the last element in list must be '/' or null. * * @param uri * the URI string * @param parameters * target list * @return true if URI string is match to pattern, false otherwise */ public boolean match(String uri, List<String> parameters) { if (parameters == null) { throw new IllegalArgumentException("list is null"); } if (uri == null || uri.isEmpty()) { return pattern == null; } if (pattern == null) { return false; } Matcher m = pattern.matcher(uri); if (!m.matches()) { return false; } parameters.clear(); if (groupIndexes == null) { for (int i = 1; i <= m.groupCount(); i++) { parameters.add(m.group(i)); } } else { for (int i = 0; i < groupIndexes.length - 1; i++) { parameters.add(m.group(groupIndexes[i])); } } return true; } public String toString() { return regex; } }