/*
 * Copyright 2002-2008 the original author or authors.
 *
 * Licensed 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.jsecurity.web;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsecurity.util.JavaEnvironment;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;

/**
 * <p>View that redirects to an absolute, context relative, or current request
 * relative URL, exposing all model attributes as HTTP query parameters.
 *
 * <p>A URL for this view is supposed to be a HTTP redirect URL, i.e.
 * suitable for HttpServletResponse's <code>sendRedirect</code> method, which
 * is what actually does the redirect if the HTTP 1.0 flag is on, or via sending
 * back an HTTP 303 code - if the HTTP 1.0 compatibility flag is off.
 *
 * <p>Note that while the default value for the "contextRelative" flag is off,
 * you will probably want to almost always set it to true. With the flag off,
 * URLs starting with "/" are considered relative to the web server root, while
 * with the flag on, they are considered relative to the web application root.
 * Since most web apps will never know or care what their context path actually
 * is, they are much better off setting this flag to true, and submitting paths
 * which are to be considered relative to the web application root.
 *
 * <p>Note that in a Servlet 2.2 environment, i.e. a servlet container which
 * is only compliant to the limits of this spec, this class will probably fail
 * when feeding in URLs which are not fully absolute, or relative to the current
 * request (no leading "/"), as these are the only two types of URL that
 * <code>sendRedirect</code> supports in a Servlet 2.2 environment.
 *
 * <p><em>This class was borrowed from a nearly identical version found in
 * the <a href="http://www.springframework.org/">Spring Framework</a>, with minor modifications to
 * avoid a dependency on Spring itself for a very small amount of code - we couldn't have done it better, and
 * don't want to repeat all of their great effort ;).
 * The original author names and copyright (Apache 2.0) has been left in place.  A special
 * thanks to Rod Johnson, Juergen Hoeller, and Colin Sampaleanu for making this available.</em>
 *
 * @see #setContextRelative
 * @see #setHttp10Compatible
 * @see javax.servlet.http.HttpServletResponse#sendRedirect
 *
 * @since 0.2
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Colin Sampaleanu
 */
public class RedirectView {

	/** The default encoding scheme: UTF-8 */
	public static final String DEFAULT_ENCODING_SCHEME = "UTF-8";

    protected transient final Log log = LogFactory.getLog( getClass() );

    private String url;

    private boolean contextRelative = false;

	private boolean http10Compatible = true;

	private String encodingScheme = DEFAULT_ENCODING_SCHEME;

	/**
	 * Constructor for use as a bean.
	 */
	public RedirectView() {
	}

	/**
	 * Create a new RedirectView with the given URL.
	 * <p>The given URL will be considered as relative to the web server,
	 * not as relative to the current ServletContext.
	 * @param url the URL to redirect to
	 * @see #RedirectView(String, boolean)
	 */
	public RedirectView(String url) {
        setUrl( url );
	}

	/**
	 * Create a new RedirectView with the given URL.
	 * @param url the URL to redirect to
	 * @param contextRelative whether to interpret the given URL as
	 * relative to the current ServletContext
	 */
	public RedirectView(String url, boolean contextRelative) {
		this(url);
		this.contextRelative = contextRelative;
	}

	/**
	 * Create a new RedirectView with the given URL.
	 * @param url the URL to redirect to
	 * @param contextRelative whether to interpret the given URL as
	 * relative to the current ServletContext
	 * @param http10Compatible whether to stay compatible with HTTP 1.0 clients
	 */
	public RedirectView(String url, boolean contextRelative, boolean http10Compatible) {
		this(url);
		this.contextRelative = contextRelative;
		this.http10Compatible = http10Compatible;
	}


    public String getUrl() {
        return url;
    }

    public void setUrl( String url ) {
        this.url = url;
    }

    /**
	 * Set whether to interpret a given URL that starts with a slash ("/")
	 * as relative to the current ServletContext, i.e. as relative to the
	 * web application root.
	 * <p>Default is "false": A URL that starts with a slash will be interpreted
	 * as absolute, i.e. taken as-is. If true, the context path will be
	 * prepended to the URL in such a case.
	 * @see javax.servlet.http.HttpServletRequest#getContextPath
	 */
	public void setContextRelative(boolean contextRelative) {
		this.contextRelative = contextRelative;
	}

	/**
	 * Set whether to stay compatible with HTTP 1.0 clients.
	 * <p>In the default implementation, this will enforce HTTP status code 302
	 * in any case, i.e. delegate to <code>HttpServletResponse.sendRedirect</code>.
	 * Turning this off will send HTTP status code 303, which is the correct
	 * code for HTTP 1.1 clients, but not understood by HTTP 1.0 clients.
	 * <p>Many HTTP 1.1 clients treat 302 just like 303, not making any
	 * difference. However, some clients depend on 303 when redirecting
	 * after a POST request; turn this flag off in such a scenario.
	 * @see javax.servlet.http.HttpServletResponse#sendRedirect
	 */
	public void setHttp10Compatible(boolean http10Compatible) {
		this.http10Compatible = http10Compatible;
	}

	/**
	 * Set the encoding scheme for this view. Default is UTF-8.
	 */
	public void setEncodingScheme(String encodingScheme) {
		this.encodingScheme = encodingScheme;
	}


	/**
	 * Convert model to request parameters and redirect to the given URL.
	 * @see #appendQueryProperties
	 * @see #sendRedirect
	 */
	public final void renderMergedOutputModel(
			Map model, HttpServletRequest request, HttpServletResponse response) throws IOException {

		// Prepare name URL.
		StringBuffer targetUrl = new StringBuffer();
		if (this.contextRelative && getUrl().startsWith("/")) {
			// Do not apply context path to relative URLs.
			targetUrl.append(request.getContextPath());
		}
		targetUrl.append(getUrl());
		appendQueryProperties(targetUrl, model, this.encodingScheme);

		sendRedirect(request, response, targetUrl.toString(), this.http10Compatible);
	}

	/**
	 * Append query properties to the redirect URL.
	 * Stringifies, URL-encodes and formats model attributes as query properties.
	 * @param targetUrl the StringBuffer to append the properties to
	 * @param model Map that contains model attributes
	 * @param encodingScheme the encoding scheme to use
	 * @throws java.io.UnsupportedEncodingException if string encoding failed
	 * @see #queryProperties
	 */
	protected void appendQueryProperties(StringBuffer targetUrl, Map model, String encodingScheme)
			throws UnsupportedEncodingException {

		// Extract anchor fragment, if any.
		// The following code does not use JDK 1.4's StringBuffer.indexOf(String)
		// method to retain JDK 1.3 compatibility.
		String fragment = null;
		int anchorIndex = targetUrl.toString().indexOf('#');
		if (anchorIndex > -1) {
			fragment = targetUrl.substring(anchorIndex);
			targetUrl.delete(anchorIndex, targetUrl.length());
		}

		// If there aren't already some parameters, we need a "?".
		boolean first = (getUrl().indexOf('?') < 0);
		Iterator entries = queryProperties(model).entrySet().iterator();
		while (entries.hasNext()) {
			if (first) {
				targetUrl.append('?');
				first = false;
			}
			else {
				targetUrl.append('&');
			}
			Map.Entry entry = (Map.Entry) entries.next();
			String encodedKey = urlEncode(entry.getKey().toString(), encodingScheme);
			String encodedValue =
					(entry.getValue() != null ? urlEncode(entry.getValue().toString(), encodingScheme) : "");
			targetUrl.append(encodedKey).append('=').append(encodedValue);
		}

		// Append anchor fragment, if any, to end of URL.
		if (fragment != null) {
			targetUrl.append(fragment);
		}
	}

	/**
	 * URL-encode the given input String with the given encoding scheme.
	 * <p>Default implementation uses <code>URLEncoder.encode(input, enc)</code>
	 * on JDK 1.4+, falling back to <code>URLEncoder.encode(input)</code>
	 * (which uses the platform default encoding) on JDK 1.3.
	 * @param input the unencoded input String
	 * @param encodingScheme the encoding scheme
	 * @return the encoded output String
	 * @throws UnsupportedEncodingException if thrown by the JDK URLEncoder
	 * @see java.net.URLEncoder#encode(String, String)
	 * @see java.net.URLEncoder#encode(String)
	 */
    @SuppressWarnings("deprecated")
    protected String urlEncode(String input, String encodingScheme) throws UnsupportedEncodingException {
        if ( !JavaEnvironment.isAtLeastVersion14() ) {
			if (log.isDebugEnabled()) {
				log.debug("Only JDK 1.3 URLEncoder available: using platform default encoding " +
						"instead of the requested scheme '" + encodingScheme + "'");
			}
            //noinspection deprecation
            return URLEncoder.encode(input);
		}
		return URLEncoder.encode(input, encodingScheme);
	}

	/**
	 * Determine name-value pairs for query strings, which will be stringified,
	 * URL-encoded and formatted by appendQueryProperties.
	 * <p>This implementation returns all model elements as-is.
	 * @see #appendQueryProperties
	 */
	protected Map queryProperties(Map model) {
		return model;
	}

	/**
	 * Send a redirect back to the HTTP client
	 * @param request current HTTP request (allows for reacting to request method)
	 * @param response current HTTP response (for sending response headers)
	 * @param targetUrl the name URL to redirect to
	 * @param http10Compatible whether to stay compatible with HTTP 1.0 clients
	 * @throws IOException if thrown by response methods
	 */
	protected void sendRedirect(
			HttpServletRequest request, HttpServletResponse response, String targetUrl, boolean http10Compatible)
			throws IOException {

		if (http10Compatible) {
			// Always send status code 302.
			response.sendRedirect(response.encodeRedirectURL(targetUrl));
		}
		else {
			// Correct HTTP status code is 303, in particular for POST requests.
			response.setStatus(303);
			response.setHeader("Location", response.encodeRedirectURL(targetUrl));
		}
	}

}
