/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.wicket.request; import java.nio.charset.Charset; import java.util.Locale; import org.apache.wicket.request.parameter.CombinedRequestParametersAdapter; import org.apache.wicket.request.parameter.EmptyRequestParameters; import org.apache.wicket.request.parameter.UrlRequestParametersAdapter; /** * Request object. * * @author Matej Knopp */ public abstract class Request { /** * Returns the URL for this request. URL is relative to Wicket filter path. * * @return Url instance */ public abstract Url getUrl(); /** * Returns the url against which the client, usually the browser, will resolve relative urls in * the rendered markup. If the client is a browser this is the url in the browser's address bar. * * <p> * Under normal circumstances the client and request ({@link #getUrl()}) urls are the same. * Handling an Ajax request, however, is a good example of when they may be different. * Technologies such as XHR are free to request whatever url they wish <strong>without * modifying</strong> the client url; however, any produced urls will be evaluated by the client * against the client url - not against the request url. * </p> * <p> * Lets take a simple example: <br> * * Suppose we are on a client detail page. This page contains an Ajax link which opens a list of * client's orders. Each order has a link that goes to the order detail page. * * The client detail page is located at * * <pre> * /detail/customer/15 * </pre> * * and the order detail page is located at * * <pre> * /order/22 * </pre> * * The Ajax link which renders the detail section is located at * * <pre> * /detail/wicket?page 3 * </pre> * * Lets run through the execution and see what happens when the XHR request is processed: * * <pre> * request 1: /details/customer/15 * client url: details/customer/15 (the url in the browser's address bar) * request url: details/customer/15 * Wicket renders relative Ajax details anchor as ../../wicket/page?3 * * ../../wicket/page?3 resolved against current client url details/customer/15 yields: * request 2: /wicket/page?3 * client url: customer/15 (unchanged since XHRs requests dont change it) * request url: wicket/ajax/page?3 * * now Wicket has to render a relative url to /details/order/22. If Wicket renders * it against the request url it will be: ../order/22, and later evaluated on the * client will result in /customer/order/22 which is incorrect. * </pre> * * This is why implementations of {@link Request} must track the client url, so that relative * urls can be rendered against the same url they will be evaluated against on the client - * which is not always the same as the request url. For example, Wicket's Ajax implementation * always sends the current client url in a header along with the XHR request so that Wicket can * correctly render relative urls against it. * </p> * * @return client url */ public abstract Url getClientUrl(); /** * In case this request has been created using {@link #cloneWithUrl(Url)}, this method should * return the original URL. * * @return original URL */ public Url getOriginalUrl() { return getUrl(); } /** * @return POST request parameters for this request. */ public IRequestParameters getPostParameters() { return EmptyRequestParameters.INSTANCE; } /** * @return GET request parameters for this request. */ public IRequestParameters getQueryParameters() { return new UrlRequestParametersAdapter(getUrl()); } /** * @return all request parameters for this request (both POST and GET parameters) */ public IRequestParameters getRequestParameters() { return new CombinedRequestParametersAdapter(getPostParameters(), getQueryParameters()); } /** * Returns locale for this request. * * @return locale */ public abstract Locale getLocale(); /** * Returns request with specified URL and same POST parameters as this request. * * @param url * Url instance * @return request with specified URL. */ public Request cloneWithUrl(final Url url) { return new Request() { @Override public Url getUrl() { return url; } @Override public Url getOriginalUrl() { return Request.this.getOriginalUrl(); } @Override public Locale getLocale() { return Request.this.getLocale(); } @Override public IRequestParameters getPostParameters() { return Request.this.getPostParameters(); } @Override public Charset getCharset() { return Request.this.getCharset(); } @Override public Url getClientUrl() { return Request.this.getClientUrl(); } @Override public Object getContainerRequest() { return Request.this.getContainerRequest(); } }; } /** * Returns prefix from Wicket Filter mapping to context path. This method does not take the * actual URL into account. * <p> * For example if Wicket filter is mapped to hello/* this method should return ../ regardless of * actual URL (after Wicket filter) * * @return prefix to context path for this request. * */ public String getPrefixToContextPath() { return ""; } /** * Returns the context path or an empty string if the application is running under root context. * Returned path, unless an empty string, will always start with a slash and will never end with * a slash. * * @return context path */ public String getContextPath() { return ""; } /** * Returns the path to which wicket Filter is mapped or an empty string if the filter is mapped * to {@code /*}. Returned path, unless an empty string, will always start with a slash and will * never end with a slash. * * @return filter path */ public String getFilterPath() { return ""; } /** * Gets charset of the request * * @return request charset */ public abstract Charset getCharset(); /** * Provides access to the low-level container request object that implementaion of this * {@link Request} delegate to. This allows users to access features provided by the container * requests but not by generalized Wicket {@link Request} objects. * * @return low-level container request object, or {@code null} if none */ public abstract Object getContainerRequest(); }