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.nio.protocol; 029 030import org.apache.http.HttpRequest; 031import org.apache.http.annotation.ThreadingBehavior; 032import org.apache.http.annotation.Contract; 033import org.apache.http.protocol.UriPatternMatcher; 034import org.apache.http.util.Args; 035 036/** 037 * Maintains a map of HTTP request handlers keyed by a request URI pattern. 038 * <br> 039 * Patterns may have three formats: 040 * <ul> 041 * <li>{@code *}</li> 042 * <li>{@code *<uri>}</li> 043 * <li>{@code <uri>*}</li> 044 * </ul> 045 * <br> 046 * This class can be used to map an instance of {@link HttpAsyncRequestHandler} 047 * matching a particular request URI. Usually the mapped request handler 048 * will be used to process the request with the specified request URI. 049 * 050 * @since 4.3 051 */ 052@Contract(threading = ThreadingBehavior.SAFE) 053public class UriHttpAsyncRequestHandlerMapper implements HttpAsyncRequestHandlerMapper { 054 055 private final UriPatternMatcher<HttpAsyncRequestHandler<?>> matcher; 056 057 protected UriHttpAsyncRequestHandlerMapper(final UriPatternMatcher<HttpAsyncRequestHandler<?>> matcher) { 058 super(); 059 this.matcher = Args.notNull(matcher, "Pattern matcher"); 060 } 061 062 public UriHttpAsyncRequestHandlerMapper() { 063 this(new UriPatternMatcher<HttpAsyncRequestHandler<?>>()); 064 } 065 066 /** 067 * Registers the given {@link HttpAsyncRequestHandler} 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 HttpAsyncRequestHandler<?> handler) { 074 matcher.register(pattern, handler); 075 } 076 077 /** 078 * Removes registered handler, if exists, for the given pattern. 079 * 080 * @param pattern the pattern to unregister the handler for. 081 */ 082 public void unregister(final String pattern) { 083 matcher.unregister(pattern); 084 } 085 086 /** 087 * Extracts request path from the given {@link HttpRequest} 088 */ 089 protected String getRequestPath(final HttpRequest request) { 090 String uriPath = request.getRequestLine().getUri(); 091 int index = uriPath.indexOf("?"); 092 if (index != -1) { 093 uriPath = uriPath.substring(0, index); 094 } else { 095 index = uriPath.indexOf("#"); 096 if (index != -1) { 097 uriPath = uriPath.substring(0, index); 098 } 099 } 100 return uriPath; 101 } 102 103 /** 104 * Looks up a handler matching the given request URI. 105 * 106 * @param request the request 107 * @return handler or {@code null} if no match is found. 108 */ 109 @Override 110 public HttpAsyncRequestHandler<?> lookup(final HttpRequest request) { 111 return matcher.lookup(getRequestPath(request)); 112 } 113 114}