/**
* Copyright 2005-2014 Restlet
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can
* select the license that you prefer but you may not use this file except in
* compliance with one of these Licenses.
*
* You can obtain a copy of the Apache 2.0 license at
* http://www.opensource.org/licenses/apache-2.0
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://restlet.com/products/restlet-framework
*
* Restlet is a registered trademark of Restlet S.A.S.
*/
package org.restlet.engine.component;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.routing.Route;
import org.restlet.routing.Router;
import org.restlet.routing.VirtualHost;
/**
* Route based on a target VirtualHost.
*
* Concurrency note: instances of this class or its subclasses can be invoked by
* several threads at the same time and therefore must be thread-safe. You
* should be especially careful when storing state in member variables.
*
* @author Jerome Louvel
*/
public class HostRoute extends Route {
/**
* Constructor.
*
* @param router
* The parent router.
* @param target
* The target virtual host.
*/
public HostRoute(Router router, VirtualHost target) {
super(router, target);
}
/**
* Allows filtering before processing by the next Restlet. Set the base
* reference.
*
* @param request
* The request to handle.
* @param response
* The response to update.
* @return The continuation status.
*/
@Override
protected int beforeHandle(Request request, Response response) {
if (request.getHostRef() == null) {
request.getResourceRef().setBaseRef(
request.getResourceRef().getHostIdentifier());
} else {
request.getResourceRef().setBaseRef(request.getHostRef());
}
if (request.isLoggable() && getLogger().isLoggable(Level.FINE)) {
getLogger().fine(
"Base URI: \"" + request.getResourceRef().getBaseRef()
+ "\". Remaining part: \""
+ request.getResourceRef().getRemainingPart()
+ "\"");
}
return CONTINUE;
}
/**
* Returns the target virtual host.
*
* @return The target virtual host.
*/
public VirtualHost getVirtualHost() {
return (VirtualHost) getNext();
}
/**
* Matches a formatted string against a regex pattern, in a case insensitive
* manner.
*
* @param regex
* The pattern to use.
* @param formattedString
* The formatted string to match.
* @return True if the formatted string matched the pattern.
*/
private boolean matches(String regex, String formattedString) {
return Pattern.compile(regex, Pattern.CASE_INSENSITIVE)
.matcher(formattedString).matches();
}
/**
* Returns the score for a given call (between 0 and 1.0).
*
* @param request
* The request to score.
* @param response
* The response to score.
* @return The score for a given call (between 0 and 1.0).
*/
@Override
public float score(Request request, Response response) {
float result = 0F;
// Prepare the value to be matched
String hostDomain = "";
String hostPort = "";
String hostScheme = "";
if (request.getHostRef() != null) {
hostDomain = request.getHostRef().getHostDomain();
if (hostDomain == null) {
hostDomain = "";
}
int basePortValue = request.getHostRef().getHostPort();
if (basePortValue == -1) {
basePortValue = request.getHostRef().getSchemeProtocol()
.getDefaultPort();
}
hostPort = Integer.toString(basePortValue);
hostScheme = request.getHostRef().getScheme();
if (hostScheme == null) {
hostScheme = "";
}
}
if (request.getResourceRef() != null) {
String resourceDomain = request.getResourceRef().getHostDomain();
if (resourceDomain == null) {
resourceDomain = "";
}
int resourcePortValue = request.getResourceRef().getHostPort();
if (resourcePortValue == -1) {
resourcePortValue = request.getResourceRef()
.getSchemeProtocol().getDefaultPort();
}
String resourcePort = Integer.toString(resourcePortValue);
String resourceScheme = request.getResourceRef().getScheme();
if (resourceScheme == null) {
resourceScheme = "";
}
String serverAddress = response.getServerInfo().getAddress();
if (serverAddress == null) {
serverAddress = "";
}
int serverPortValue = response.getServerInfo().getPort();
if (serverPortValue == -1) {
serverPortValue = request.getProtocol().getDefaultPort();
}
String serverPort = Integer.toString(response.getServerInfo()
.getPort());
// Check if all the criteria match
if (matches(getVirtualHost().getHostDomain(), hostDomain)
&& matches(getVirtualHost().getHostPort(), hostPort)
&& matches(getVirtualHost().getHostScheme(), hostScheme)
&& matches(getVirtualHost().getResourceDomain(),
resourceDomain)
&& matches(getVirtualHost().getResourcePort(), resourcePort)
&& matches(getVirtualHost().getResourceScheme(),
resourceScheme)
&& matches(getVirtualHost().getServerAddress(),
serverAddress)
&& matches(getVirtualHost().getServerPort(), serverPort)) {
result = 1F;
}
}
// Log the result of the matching
if (getLogger().isLoggable(Level.FINER)) {
getLogger().finer(
"Call score for the \"" + getVirtualHost().getName()
+ "\" host: " + result);
}
return result;
}
/**
* Sets the next virtual host.
*
* @param next
* The next virtual host.
*/
public void setNext(VirtualHost next) {
super.setNext(next);
}
}