001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027 028package org.apache.http.protocol; 029 030import org.apache.http.HttpRequest; 031import org.apache.http.annotation.ThreadingBehavior; 032import org.apache.http.annotation.Contract; 033import org.apache.http.util.Args; 034 035/** 036 * Maintains a map of HTTP request handlers keyed by a request URI pattern. 037 * <br> 038 * Patterns may have three formats: 039 * <ul> 040 * <li>{@code *}</li> 041 * <li>{@code *<uri>}</li> 042 * <li>{@code <uri>*}</li> 043 * </ul> 044 * <br> 045 * This class can be used to map an instance of 046 * {@link HttpRequestHandler} matching a particular request URI. Usually the 047 * mapped request handler will be used to process the request with the 048 * specified request URI. 049 * 050 * @since 4.3 051 */ 052@Contract(threading = ThreadingBehavior.SAFE) 053public class UriHttpRequestHandlerMapper implements HttpRequestHandlerMapper { 054 055 private final UriPatternMatcher<HttpRequestHandler> matcher; 056 057 protected UriHttpRequestHandlerMapper(final UriPatternMatcher<HttpRequestHandler> matcher) { 058 super(); 059 this.matcher = Args.notNull(matcher, "Pattern matcher"); 060 } 061 062 public UriHttpRequestHandlerMapper() { 063 this(new UriPatternMatcher<HttpRequestHandler>()); 064 } 065 066 /** 067 * Registers the given {@link HttpRequestHandler} as a handler for URIs 068 * matching the given pattern. 069 * 070 * @param pattern the pattern to register the handler for. 071 * @param handler the handler. 072 */ 073 public void register(final String pattern, final HttpRequestHandler handler) { 074 Args.notNull(pattern, "Pattern"); 075 Args.notNull(handler, "Handler"); 076 matcher.register(pattern, handler); 077 } 078 079 /** 080 * Removes registered handler, if exists, for the given pattern. 081 * 082 * @param pattern the pattern to unregister the handler for. 083 */ 084 public void unregister(final String pattern) { 085 matcher.unregister(pattern); 086 } 087 088 /** 089 * Extracts request path from the given {@link HttpRequest} 090 */ 091 protected String getRequestPath(final HttpRequest request) { 092 String uriPath = request.getRequestLine().getUri(); 093 int index = uriPath.indexOf("?"); 094 if (index != -1) { 095 uriPath = uriPath.substring(0, index); 096 } else { 097 index = uriPath.indexOf("#"); 098 if (index != -1) { 099 uriPath = uriPath.substring(0, index); 100 } 101 } 102 return uriPath; 103 } 104 105 /** 106 * Looks up a handler matching the given request URI. 107 * 108 * @param request the request 109 * @return handler or {@code null} if no match is found. 110 */ 111 @Override 112 public HttpRequestHandler lookup(final HttpRequest request) { 113 Args.notNull(request, "HTTP request"); 114 return matcher.lookup(getRequestPath(request)); 115 } 116 117}