UriMapping.java
/*
* Licensed 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.esigate.impl;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.esigate.ConfigurationException;
/**
* UriMapping holds provider mapping definition.
*
* <p>
* Mappings are based on (all optional) :
* <ul>
* <li>A Scheme, host and port</li>
* <li>a starting path</li>
* <li>an extension</li>
* </ul>
* <p>
* Default (all values set to null) mappings are allowed.
*
* @author Francois-Xavier Bonnet
* @author Nicolas Richeton
*
*/
public final class UriMapping {
private static final Pattern MAPPING_PATTERN = Pattern
.compile("((http://|https://)[^/:]*(:([0-9]*))?)?(/[^*]*)?(\\*?)([^*]*)");
private final String host;
private final String path;
private final String extension;
private final int weight;
/**
* Creates UriMapping object and compute its weight.
*
* @param host
* @param path
* @param extension
*/
private UriMapping(String host, String path, String extension) {
this.host = host;
this.path = path;
this.extension = extension;
int targetWeight = 0;
if (this.host != null) {
targetWeight += 1000;
}
if (this.path != null) {
targetWeight += this.path.length() * 10;
}
if (this.extension != null) {
targetWeight += this.extension.length();
}
this.weight = targetWeight;
}
/**
* Creates a UriMapping instance based on the mapping definition given as parameter.
* <p>
* Mapping is split in 3 parts :
* <ul>
* <li>Host, including the scheme and port : http://www.example:8080</li>
* <li>path, left part before the wildcard caracter *</li>
* <li>extension, right part after the wildcard caracter *</li>
* </ul>
*
* @param mapping
* the mapping expression as string
* @return the uri mapping object
* @throws ConfigurationException
*/
public static UriMapping create(String mapping) {
Matcher matcher = MAPPING_PATTERN.matcher(mapping);
if (!matcher.matches()) {
throw new ConfigurationException("Unrecognized URI pattern: " + mapping);
}
String host = StringUtils.trimToNull(matcher.group(1));
String path = StringUtils.trimToNull(matcher.group(5));
if (path != null && !path.startsWith("/")) {
throw new ConfigurationException("Unrecognized URI pattern: " + mapping
+ " Mapping path should start with / was: " + path);
}
String extension = StringUtils.trimToNull(matcher.group(7));
if (extension != null && !extension.startsWith(".")) {
throw new ConfigurationException("Unrecognized URI pattern: " + mapping
+ " Mapping extension should start with . was: " + extension);
}
return new UriMapping(host, path, extension);
}
/**
* Check this matching rule against a request.
*
* @param schemeParam
* @param hostParam
* @param uriParam
* @return true if the rule matches the request
*/
public boolean matches(String schemeParam, String hostParam, String uriParam) {
// If URI mapping enforce a host, ensure it is the one used.
if (this.host != null && !this.host.equalsIgnoreCase(schemeParam + "://" + hostParam)) {
return false;
}
if (this.extension != null && !uriParam.endsWith(this.extension)) {
return false;
}
if (this.path != null && !uriParam.startsWith(this.path)) {
return false;
}
return true;
}
/**
* The weight of this URI matching. Larger weights must be evaluated first.
*
* @return the weight
*/
public int getWeight() {
return this.weight;
}
/**
* Get the extension of this URI matching.
*
* @return the extension
*/
public String getExtension() {
return this.extension;
}
/**
* Get the path of this URI matching.
*
* @return the path
*/
public String getPath() {
return this.path;
}
/**
* Get the host of this URI matching.
*
* @return the host
*/
public String getHost() {
return this.host;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}