001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.request;
018
019
020/**
021 * Maps {@link IRequestHandler}(s) into {@link Url}(s) and {@link Request}(s) to
022 * {@link IRequestHandler}(s). For {@link IRequestHandler}s and {@link Request}s the implementation
023 * doesn't recognize, the {@link #mapHandler(IRequestHandler)} and {@link #mapRequest(Request)}
024 * methods must return {@code null}.
025 * 
026 * The workflow is: the Application class collects a set of {@link IRequestMapper}s and for each
027 * request the {@link IRequestCycle request cycle} asks these mappers whether any of them knows how
028 * to handle the current {@link Request}’s {@link Url url}. Wicket pre-configures several mappers
029 * which are used for the basic application functionality like a mapper for the home page, a mapper
030 * for Wicket resources, for bookmarkable pages, etc. The user application can add additional
031 * mappers with the various WebApplication#mountXYZ() methods.
032 * 
033 * The mapper has two main tasks:
034 * 
035 * <ol>
036 * <li>To create {@link IRequestHandler} that will produce the response. When a request comes Wicket
037 * uses {@link #getCompatibilityScore(Request)} to decide which mapper should be asked first to
038 * process the request. If two mappers have the same score then the one added later is asked first.
039 * This way user’s mappers have precedence than the system ones. If a mapper knows how to handle the
040 * request’s url then it should return non-{@code null} {@link IRequestHandler}.</li>
041 * <li>
042 * The second task is to produce {@link Url} for an {@link IRequestHandler}. This is needed at
043 * markup rendering time to create the urls for links, forms' action attribute, etc.</li>
044 * </ol>
045 * 
046 * @author Matej Knopp
047 */
048public interface IRequestMapper
049{
050        /**
051         * Returns {@link IRequestHandler} for the request or <code>null</code> if the {@link Url} is
052         * not recognized.
053         * 
054         * @param request
055         *            provides access to request data (i.e. Url and Parameters)
056         * 
057         * @return RequestHandler instance or <code>null</code>
058         */
059        IRequestHandler mapRequest(Request request);
060
061        /**
062         * Returns the score representing how compatible this request mapper is to processing the given
063         * request. When a request comes in all mappers are scored and are tried in order from highest
064         * score to lowest.
065         * <p>
066         * A good criteria for calculating the score is the number of matched url segments. For example
067         * when there are two mappers for a mounted page, one mapped to <code>/foo</code> another to
068         * <code>/foo/bar</code> and the incoming request URL is </code>/foo/bar/baz</code>, the mapping
069         * to <code>/foo/bar</code> should probably handle the request first as it has matching segments
070         * count of 2 while the first one has only matching segments count of 1.
071         * <p>
072         * Note that the method can return value greater then zero even if the mapper does not recognize
073         * the request.
074         * 
075         * @param request
076         * @return the compatibility score, e.g. count of matching segments
077         */
078        int getCompatibilityScore(Request request);
079
080        /**
081         * Returns the {@link Url} for given {@link IRequestHandler} or <code>null</code> if the request
082         * handler is not recognized.
083         * 
084         * @param requestHandler
085         * @return Url instance or <code>null</code>.
086         */
087        Url mapHandler(IRequestHandler requestHandler);
088}