blob: ae2f6fec00c3a819104ce7a4fb76f9f920d08bd0 [file] [log] [blame]
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
// * with the License. You may obtain a copy of the License at *
// * *
// * http://www.apache.org/licenses/LICENSE-2.0 *
// * *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
// * specific language governing permissions and limitations under the License. *
// ***************************************************************************************************************************
package org.apache.juneau.rest.util;
import static org.apache.juneau.internal.StringUtils.*;
import java.util.*;
import org.apache.juneau.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.marshall.*;
/**
* Represents a URL path pattern match.
*
* For example, given the pattern <js>"/foo/{bar}/*"</js> and the path <js>"/foo/123/baz/qux"</js>, this match gives
* you a map containing <js>"{bar:123}"</js> and a remainder string containing <js>"baz/qux"</js>.
*/
public class UrlPathPatternMatch {
private final int matchedParts;
private final String path;
private final Map<String,String> vars;
/**
* Constructor.
*
* @param path The path being matched against. Can be <jk>null</jk>.
* @param matchedParts The number of parts that were matched against the path.
* @param keys The variable keys. Can be <jk>null</jk>.
* @param values The variable values. Can be <jk>null</jk>.
*/
protected UrlPathPatternMatch(String path, int matchedParts, String[] keys, String[] values) {
this.path = path;
this.matchedParts = matchedParts;
this.vars = keys == null ? Collections.emptyMap() : new SimpleMap<>(keys, values);
}
/**
* Returns a map of the path variables and values.
*
* @return
* An unmodifiable map of variable keys/values.
* <br>Returns an empty map if no variables were found in the path.
*/
public Map<String,String> getVars() {
return vars;
}
/**
* Returns <jk>true</jk> if this match contains one or more variables.
*
* @return <jk>true</jk> if this match contains one or more variables.
*/
public boolean hasVars() {
return ! vars.isEmpty();
}
/**
* Returns <jk>true</jk> if any of the variable values are blank.
*
* @return <jk>true</jk> if any of the variable values are blank.
*/
public boolean hasEmptyVars() {
for (String v : vars.values())
if (isEmpty(v))
return true;
return false;
}
/**
* Returns the remainder of the path after the pattern match has been made.
*
* @return The remainder of the path after the pattern match has been made.
*/
public String getRemainder() {
String suffix = getSuffix();
if (isNotEmpty(suffix) && suffix.charAt(0) == '/')
suffix = suffix.substring(1);
return suffix;
}
/**
* Returns the remainder of the URL after the pattern was matched.
*
* @return
* The remainder of the URL after the pattern was matched.
* <br>Can be <jk>null</jk> if nothing remains to be matched.
* <br>Otherwise, always starts with <js>'/'</js>.
*/
public String getSuffix() {
String s = path;
for (int j = 0; j < matchedParts; j++) {
int k = s.indexOf('/', 1);
if (k == -1)
return null;
s = s.substring(k);
}
return s;
}
/**
* Returns the part of the URL that the pattern matched against.
*
* @return
* The part of the URL that the pattern matched against.
* <br>Can be <jk>null</jk> if nothing matched.
* <br>Otherwise, always starts with <js>'/'</js>.
*/
public String getPrefix() {
int c = 0;
for (int j = 0; j < matchedParts; j++) {
c = path.indexOf('/', c+1);
if (c == -1)
c = path.length();
}
return nullIfEmpty(path.substring(0, c));
}
/**
* Converts this object to a map.
*
* @return This object converted to a map.
*/
public ObjectMap toMap() {
return new DefaultFilteringObjectMap().append("v", getVars()).append("r", getRemainder());
}
@Override /* Object */
public String toString() {
return SimpleJson.DEFAULT.toString(toMap());
}
}