All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wicket.protocol.http.MockHttpServletRequest Maven / Gradle / Ivy

Go to download

Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and unloading of Wicket components and pageSources.

There is a newer version: 5.0.0
Show newest version
/*
 * 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.protocol.http;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.IPageMap;
import org.apache.wicket.IRedirectListener;
import org.apache.wicket.IResourceListener;
import org.apache.wicket.Page;
import org.apache.wicket.RequestListenerInterface;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.IFormSubmitListener;
import org.apache.wicket.markup.html.form.IOnChangeListener;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ILinkListener;
import org.apache.wicket.protocol.http.request.WebRequestCodingStrategy;
import org.apache.wicket.util.file.File;
import org.apache.wicket.util.io.IOUtils;
import org.apache.wicket.util.lang.Classes;
import org.apache.wicket.util.upload.FileUploadBase;
import org.apache.wicket.util.value.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Mock servlet request. Implements all of the methods from the standard HttpServletRequest class
 * plus helper methods to aid setting up a request.
 * 
 * @author Chris Turner
 */
public class MockHttpServletRequest implements HttpServletRequest
{
	/**
	 * A holder class for an uploaded file.
	 * 
	 * @author Frank Bille (billen)
	 */
	private class UploadedFile
	{
		private String fieldName;
		private File file;
		private String contentType;

		/**
		 * Construct.
		 * 
		 * @param fieldName
		 * @param file
		 * @param contentType
		 */
		public UploadedFile(String fieldName, File file, String contentType)
		{
			this.fieldName = fieldName;
			this.file = file;
			this.contentType = contentType;
		}

		/**
		 * @return The content type of the file. Mime type.
		 */
		public String getContentType()
		{
			return contentType;
		}

		/**
		 * @param contentType
		 *            The content type.
		 */
		public void setContentType(String contentType)
		{
			this.contentType = contentType;
		}

		/**
		 * @return The field name.
		 */
		public String getFieldName()
		{
			return fieldName;
		}

		/**
		 * @param fieldName
		 */
		public void setFieldName(String fieldName)
		{
			this.fieldName = fieldName;
		}

		/**
		 * @return The uploaded file.
		 */
		public File getFile()
		{
			return file;
		}

		/**
		 * @param file
		 */
		public void setFile(File file)
		{
			this.file = file;
		}
	}

	/** Logging object */
	private static final Logger log = LoggerFactory.getLogger(MockHttpServletRequest.class);

	/** The application */
	private final Application application;

	private final ValueMap attributes = new ValueMap();

	private String authType;

	private String characterEncoding;

	private final ServletContext context;

	private final List cookies = new ArrayList();

	private final ValueMap headers = new ValueMap();

	private String method;

	private final ValueMap parameters = new ValueMap();

	private String path;

	private final HttpSession session;

	private String url;

	private Map uploadedFiles;

	private boolean useMultiPartContentType;

	/**
	 * Create the request using the supplied session object. Note that in order for temporary
	 * sessions to work, the supplied session must be an instance of {@link MockHttpSession}
	 * 
	 * @param application
	 *            The application that this request is for
	 * @param session
	 *            The session object
	 * @param context
	 *            The current servlet context
	 */
	public MockHttpServletRequest(final Application application, final HttpSession session,
		final ServletContext context)
	{
		this.application = application;
		this.session = session;
		this.context = context;
		initialize();
	}

	/**
	 * Add a new cookie.
	 * 
	 * @param cookie
	 *            The cookie
	 */
	public void addCookie(final Cookie cookie)
	{
		cookies.add(cookie);
	}

	public void addCookies(Iterable cookies)
	{
		for (Cookie cookie : cookies)
		{
			addCookie(cookie);
		}
	}


	/**
	 * Add an uploaded file to the request. Use this to simulate a file that has been uploaded to a
	 * field.
	 * 
	 * @param fieldName
	 *            The fieldname of the upload field.
	 * @param file
	 *            The file to upload.
	 * @param contentType
	 *            The content type of the file. Must be a correct mimetype.
	 */
	public void addFile(String fieldName, File file, String contentType)
	{
		if (file == null)
		{
			throw new IllegalArgumentException("File must not be null");
		}

		if (file.exists() == false)
		{
			throw new IllegalArgumentException(
				"File does not exists. You must provide an existing file: " +
					file.getAbsolutePath());
		}

		if (file.isFile() == false)
		{
			throw new IllegalArgumentException(
				"You can only add a File, which is not a directory. Only files can be uploaded.");
		}

		if (uploadedFiles == null)
		{
			uploadedFiles = new HashMap();
		}

		UploadedFile uf = new UploadedFile(fieldName, file, contentType);

		uploadedFiles.put(fieldName, uf);
	}

	/**
	 * Add a header to the request.
	 * 
	 * @param name
	 *            The name of the header to add
	 * @param value
	 *            The value
	 */
	public void addHeader(String name, String value)
	{
		@SuppressWarnings("unchecked")
		List list = (List)headers.get(name);
		if (list == null)
		{
			list = new ArrayList(1);
			headers.put(name, list);
		}
		list.add(value);
	}

	/**
	 * @param name
	 * @param date
	 */
	public void addDateHeader(String name, long date)
	{
		DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
		String dateString = df.format(new Date(date));
		addHeader(name, dateString);
	}

	/**
	 * Get an attribute.
	 * 
	 * @param name
	 *            The attribute name
	 * @return The value, or null
	 */
	public Object getAttribute(final String name)
	{
		return attributes.get(name);
	}

	/**
	 * Get the names of all of the values.
	 * 
	 * @return The names
	 */
	public Enumeration getAttributeNames()
	{
		return Collections.enumeration(attributes.keySet());
	}

	// HttpServletRequest methods

	/**
	 * Get the auth type.
	 * 
	 * @return The auth type
	 */
	public String getAuthType()
	{
		return authType;
	}

	/**
	 * Get the current character encoding.
	 * 
	 * @return The character encoding
	 */
	public String getCharacterEncoding()
	{
		return characterEncoding;
	}

	/**
	 * true will force Request generate multiPart ContentType and ContentLength
	 * 
	 * @param useMultiPartContentType
	 */
	public void setUseMultiPartContentType(boolean useMultiPartContentType)
	{
		this.useMultiPartContentType = useMultiPartContentType;
	}


	/**
	 * Return the length of the content. This is always -1 except if useMultiPartContentType set as
	 * true. Then the length will be the length of the generated request.
	 * 
	 * @return -1 if useMultiPartContentType is false. Else the length of the generated request.
	 */
	public int getContentLength()
	{
		if (useMultiPartContentType)
		{
			byte[] request = buildRequest();
			return request.length;
		}

		return -1;
	}

	/**
	 * If useMultiPartContentType set as true return the correct content-type.
	 * 
	 * @return The correct multipart content-type if useMultiPartContentType is true. Else null.
	 */
	public String getContentType()
	{
		if (useMultiPartContentType)
		{
			return FileUploadBase.MULTIPART_FORM_DATA + "; boundary=abcdefgABCDEFG";
		}

		return null;
	}

	/**
	 * Get the context path. For this mock implementation the name of the application is always
	 * returned.
	 * 
	 * @return The context path
	 */
	public String getContextPath()
	{
		return "/" + application.getName();
	}

	/**
	 * Get all of the cookies for this request.
	 * 
	 * @return The cookies
	 */
	public Cookie[] getCookies()
	{
		if (cookies.size() == 0)
		{
			return null;
		}
		Cookie[] result = new Cookie[cookies.size()];
		return cookies.toArray(result);
	}

	/**
	 * Get the given header as a date.
	 * 
	 * @param name
	 *            The header name
	 * @return The date, or -1 if header not found
	 * @throws IllegalArgumentException
	 *             If the header cannot be converted
	 */
	public long getDateHeader(final String name) throws IllegalArgumentException
	{
		String value = getHeader(name);
		if (value == null)
		{
			return -1;
		}

		DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
		try
		{
			return df.parse(value).getTime();
		}
		catch (ParseException e)
		{
			throw new IllegalArgumentException("Can't convert header to date " + name + ": " +
				value);
		}
	}

	/**
	 * Get the given header value.
	 * 
	 * @param name
	 *            The header name
	 * @return The header value or null
	 */
	public String getHeader(final String name)
	{
		@SuppressWarnings("unchecked")
		final List l = (List)headers.get(name);
		if (l == null || l.size() < 1)
		{
			return null;
		}
		else
		{
			return l.get(0);
		}
	}

	/**
	 * Get the names of all of the headers.
	 * 
	 * @return The header names
	 */
	public Enumeration getHeaderNames()
	{
		return Collections.enumeration(headers.keySet());
	}

	/**
	 * Get enumeration of all header values with the given name.
	 * 
	 * @param name
	 *            The name
	 * @return The header values
	 */
	public Enumeration getHeaders(final String name)
	{
		@SuppressWarnings("unchecked")
		List list = (List)headers.get(name);
		if (list == null)
		{
			list = new ArrayList();
		}
		return Collections.enumeration(list);
	}

	/**
	 * Returns an input stream if there has been added some uploaded files. Use
	 * {@link #addFile(String, File, String)} to add some uploaded files.
	 * 
	 * @return The input stream
	 * @throws IOException
	 *             If an I/O related problem occurs
	 */
	public ServletInputStream getInputStream() throws IOException
	{
		byte[] request = buildRequest();

		// Ok lets make an input stream to return
		final ByteArrayInputStream bais = new ByteArrayInputStream(request);

		return new ServletInputStream()
		{
			@Override
			public int read()
			{
				return bais.read();
			}
		};
	}

	/**
	 * Get the given header as an int.
	 * 
	 * @param name
	 *            The header name
	 * @return The header value or -1 if header not found
	 * @throws NumberFormatException
	 *             If the header is not formatted correctly
	 */
	public int getIntHeader(final String name)
	{
		String value = getHeader(name);
		if (value == null)
		{
			return -1;
		}
		return Integer.valueOf(value).intValue();
	}

	/**
	 * Get the locale of the request. Attempts to decode the Accept-Language header and if not found
	 * returns the default locale of the JVM.
	 * 
	 * @return The locale
	 */
	public Locale getLocale()
	{
		return getLocales().nextElement();
	}

	/**
	 * 
	 * @param value
	 * @return locale
	 */
	private Locale getLocale(final String value)
	{
		final String[] bits = value.split("-");
		if (bits.length < 1)
		{
			return null;
		}

		final String language = bits[0].toLowerCase();
		if (bits.length > 1)
		{
			final String country = bits[1].toUpperCase();
			return new Locale(language, country);
		}
		else
		{
			return new Locale(language);
		}
	}

	/**
	 * Return all the accepted locales. This implementation always returns just one.
	 * 
	 * @return The locales
	 */
	public Enumeration getLocales()
	{
		List list = new ArrayList();
		final String header = getHeader("Accept-Language");
		if (header != null)
		{
			final String[] locales = header.split(",");
			for (String value : locales)
			{
				Locale locale = getLocale(value);
				if (locale != null)
				{
					list.add(locale);
				}
			}
		}

		if (list.size() == 0)
		{
			list.add(Locale.getDefault());
		}

		return Collections.enumeration(list);
	}

	/**
	 * Get the method.
	 * 
	 * @return The method
	 */
	public String getMethod()
	{
		return method;
	}

	/**
	 * Get the request parameter with the given name.
	 * 
	 * @param name
	 *            The parameter name
	 * @return The parameter value, or null
	 */
	public String getParameter(final String name)
	{
		return parameters.getString(name);
	}

	/**
	 * Get the map of all of the parameters.
	 * 
	 * @return The parameters
	 */
	public Map getParameterMap()
	{
		return parameters;
	}

	/**
	 * Get the names of all of the parameters.
	 * 
	 * @return The parameter names
	 */
	public Enumeration getParameterNames()
	{
		return Collections.enumeration(parameters.keySet());
	}

	/**
	 * Get the values for the given parameter.
	 * 
	 * @param name
	 *            The name of the parameter
	 * @return The return values
	 */
	public String[] getParameterValues(final String name)
	{
		Object value = parameters.get(name);
		if (value == null)
		{
			return new String[0];
		}

		if (value instanceof String[])
		{
			return (String[])value;
		}
		else
		{
			String[] result = new String[1];
			result[0] = value.toString();
			return result;
		}
	}

	/**
	 * Get the path info.
	 * 
	 * @return The path info
	 */
	public String getPathInfo()
	{
		return path;
	}

	/**
	 * Always returns null.
	 * 
	 * @return null
	 */
	public String getPathTranslated()
	{
		return null;
	}

	/**
	 * Get the protocol.
	 * 
	 * @return Always HTTP/1.1
	 */
	public String getProtocol()
	{
		return "HTTP/1.1";
	}

	/**
	 * Get the query string part of the request.
	 * 
	 * @return The query string
	 */
	public String getQueryString()
	{
		if (parameters.size() == 0)
		{
			return null;
		}
		else
		{
			final StringBuffer buf = new StringBuffer();
			for (Iterator iterator = parameters.keySet().iterator(); iterator.hasNext();)
			{
				final String name = iterator.next();
				final String value = parameters.getString(name);
				if (name != null)
				{
					buf.append(WicketURLEncoder.QUERY_INSTANCE.encode(name));
				}
				buf.append('=');
				if (value != null)
				{
					buf.append(WicketURLEncoder.QUERY_INSTANCE.encode(value));
				}
				if (iterator.hasNext())
				{
					buf.append('&');
				}
			}
			return buf.toString();
		}
	}

	/**
	 * This feature is not implemented at this time as we are not supporting binary servlet input.
	 * This functionality may be added in the future.
	 * 
	 * @return The reader
	 * @throws IOException
	 *             If an I/O related problem occurs
	 */
	public BufferedReader getReader() throws IOException
	{
		return new BufferedReader(new CharArrayReader(new char[0]));
	}

	/**
	 * Deprecated method - should not be used.
	 * 
	 * @param name
	 *            The name
	 * @return The path
	 * @deprecated Use ServletContext.getRealPath(String) instead.
	 */
	@Deprecated
	public String getRealPath(String name)
	{
		return context.getRealPath(name);
	}

	/**
	 * Get the remote address of the client.
	 * 
	 * @return Always 127.0.0.1
	 */
	public String getRemoteAddr()
	{
		return "127.0.0.1";
	}

	/**
	 * Get the remote host.
	 * 
	 * @return Always localhost
	 */
	public String getRemoteHost()
	{
		return "localhost";
	}

	/**
	 * Get the name of the remote user from the REMOTE_USER header.
	 * 
	 * @return The name of the remote user
	 */
	public String getRemoteUser()
	{
		return getHeader("REMOTE_USER");
	}

	/**
	 * Return a dummy dispatcher that just records that dispatch has occurred without actually doing
	 * anything.
	 * 
	 * @param name
	 *            The name to dispatch to
	 * @return The dispatcher
	 */
	public RequestDispatcher getRequestDispatcher(String name)
	{
		return context.getRequestDispatcher(name);
	}

	/**
	 * Get the requested session id. Always returns the id of the current session.
	 * 
	 * @return The session id
	 */
	public String getRequestedSessionId()
	{
		if (session instanceof MockHttpSession && ((MockHttpSession)session).isTemporary())
		{
			return null;
		}
		return session.getId();
	}

	/**
	 * Returns context path and servlet path concatenated, typically
	 * /applicationClassName/applicationClassName
	 * 
	 * @return The path value
	 * @see javax.servlet.http.HttpServletRequest#getRequestURI()
	 */
	public String getRequestURI()
	{
		if (url == null)
		{
			return getContextPath() + getServletPath();
		}
		else
		{
			int index = url.indexOf("?");
			if (index != -1)
			{
				return url.substring(0, index);
			}
		}
		return url;
	}

	/**
	 * Try to build a rough URL.
	 * 
	 * @return The url
	 */
	public StringBuffer getRequestURL()
	{
		final StringBuffer buf = new StringBuffer();
		buf.append("http://localhost");
		buf.append(getContextPath());
		if (getPathInfo() != null)
		{
			buf.append(getPathInfo());
		}

		final String query = getQueryString();
		if (query != null)
		{
			buf.append('?');
			buf.append(query);
		}
		return buf;
	}

	/**
	 * Get the scheme.
	 * 
	 * @return Always http
	 */
	public String getScheme()
	{
		return "http";
	}

	/**
	 * Get the server name.
	 * 
	 * @return Always localhost
	 */
	public String getServerName()
	{
		return "localhost";
	}

	/**
	 * Get the server port.
	 * 
	 * @return Always 80
	 */
	public int getServerPort()
	{
		return 80;
	}

	/**
	 * The servlet path may either be the application name or /. For test purposes we always return
	 * the servlet name.
	 * 
	 * @return The servlet path
	 */
	public String getServletPath()
	{
		return getContextPath();
	}

	/**
	 * Get the sessions.
	 * 
	 * @return The session
	 */
	public HttpSession getSession()
	{
		if (session instanceof MockHttpSession && ((MockHttpSession)session).isTemporary())
		{
			return null;
		}
		return session;
	}

	/**
	 * Get the session.
	 * 
	 * @param b
	 *            Ignored, there is always a session
	 * @return The session
	 */
	public HttpSession getSession(boolean b)
	{
		if (b && session instanceof MockHttpSession)
		{
			((MockHttpSession)session).setTemporary(false);
		}
		return getSession();
	}

	/**
	 * Get the user principal.
	 * 
	 * @return A user principal
	 */
	public Principal getUserPrincipal()
	{
		final String user = getRemoteUser();
		if (user == null)
		{
			return null;
		}
		else
		{
			return new Principal()
			{
				public String getName()
				{
					return user;
				}
			};
		}
	}

	/**
	 * @return True if there has been added files to this request using
	 *         {@link #addFile(String, File, String)}
	 */
	public boolean hasUploadedFiles()
	{
		return uploadedFiles != null;
	}

	/**
	 * Reset the request back to a default state.
	 */
	public void initialize()
	{
		authType = null;
		method = "post";
		cookies.clear();
		setDefaultHeaders();
		path = null;
		url = null;
		characterEncoding = "UTF-8";
		parameters.clear();
		attributes.clear();
	}

	/**
	 * Check whether session id is from a cookie. Always returns true.
	 * 
	 * @return Always true
	 */
	public boolean isRequestedSessionIdFromCookie()
	{
		return true;
	}

	/**
	 * Check whether session id is from a url rewrite. Always returns false.
	 * 
	 * @return Always false
	 */
	public boolean isRequestedSessionIdFromUrl()
	{
		return false;
	}

	/**
	 * Check whether session id is from a url rewrite. Always returns false.
	 * 
	 * @return Always false
	 */
	public boolean isRequestedSessionIdFromURL()
	{
		return false;
	}

	/**
	 * Check whether the session id is valid.
	 * 
	 * @return Always true
	 */
	public boolean isRequestedSessionIdValid()
	{
		return true;
	}

	/**
	 * Always returns false.
	 * 
	 * @return Always false
	 */
	public boolean isSecure()
	{
		return false;
	}

	/**
	 * NOT IMPLEMENTED.
	 * 
	 * @param name
	 *            The role name
	 * @return Always false
	 */
	public boolean isUserInRole(String name)
	{
		return false;
	}

	/**
	 * Remove the given attribute.
	 * 
	 * @param name
	 *            The name of the attribute
	 */
	public void removeAttribute(final String name)
	{
		attributes.remove(name);
	}

	/**
	 * Set the given attribute.
	 * 
	 * @param name
	 *            The attribute name
	 * @param o
	 *            The value to set
	 */
	public void setAttribute(final String name, final Object o)
	{
		attributes.put(name, o);
	}

	/**
	 * Set the auth type.
	 * 
	 * @param authType
	 *            The auth type
	 */
	public void setAuthType(final String authType)
	{
		this.authType = authType;
	}

	/**
	 * Set the character encoding.
	 * 
	 * @param encoding
	 *            The character encoding
	 * @throws UnsupportedEncodingException
	 *             If encoding not supported
	 */
	public void setCharacterEncoding(final String encoding) throws UnsupportedEncodingException
	{
		characterEncoding = encoding;
	}

	/**
	 * Set the cookies.
	 * 
	 * @param theCookies
	 *            The cookies
	 */
	public void setCookies(final Cookie[] theCookies)
	{
		cookies.clear();
		for (int i = 0; i < theCookies.length; i++)
		{
			cookies.add(theCookies[i]);
		}
	}

	/**
	 * Set the method.
	 * 
	 * @param method
	 *            The method
	 */
	public void setMethod(final String method)
	{
		this.method = method;
	}

	/**
	 * Set a parameter.
	 * 
	 * @param name
	 *            The name
	 * @param value
	 *            The value
	 */
	public void setParameter(final String name, final String value)
	{
		parameters.put(name, value);
	}

	/**
	 * Sets a map of parameters.
	 * 
	 * @param parameters
	 *            the parameters to set
	 */
	public void setParameters(final Map parameters)
	{
		this.parameters.putAll(parameters);
	}

	/**
	 * Set the path that this request is supposed to be serving. The path is relative to the web
	 * application root and should start with a / character
	 * 
	 * @param path
	 */
	public void setPath(final String path)
	{
		this.path = WicketURLDecoder.PATH_INSTANCE.decode(path);
	}

	/**
	 * Set the complete url for this request. The url will be analyzed.
	 * 
	 * @param url
	 */
	public void setURL(String url)
	{
		if (url.startsWith("http://"))
		{
			int index = url.indexOf("/", 7);
			url = url.substring(index);
		}
		if (!url.startsWith("/"))
		{
			url = getContextPath() + getServletPath() + "/" + url;
		}
		this.url = url;
		if (url.startsWith(getContextPath()))
		{
			url = url.substring(getContextPath().length());
		}
		if (url.startsWith(getServletPath()))
		{
			url = url.substring(getServletPath().length());
		}

		int index = url.indexOf("?");
		if (index == -1)
		{
			setPath(url);
		}
		else
		{
			setPath(url.substring(0, index));

			String queryString = url.substring(index + 1);
			Map params = new HashMap();
			RequestUtils.decodeUrlParameters(queryString, params);
			parameters.putAll(params);
		}
	}

	/**
	 * Initialize the request parameters to point to the given bookmarkable page.
	 * 
	 * @param page
	 *            The page to point to
	 * @param params
	 *            Additional parameters
	 */
	public void setRequestToBookmarkablePage(final Page page, final Map params)
	{
		parameters.putAll(params);
		parameters.put(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME, page.getClass()
			.getName());
	}

	/**
	 * Initialize the request parameters to point to the given component.
	 * 
	 * @param component
	 *            The component
	 */
	public void setRequestToComponent(final Component component)
	{
		final IPageMap pageMap = component.getPage().getPageMap();
		final String pageMapName = pageMap.isDefault() ? "" : pageMap.getName();
		if (component instanceof BookmarkablePageLink)
		{
			final Class clazz = ((BookmarkablePageLink)component).getPageClass();
			parameters.put(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME, pageMapName +
				':' + clazz.getName());
		}
		else
		{
			int version = component.getPage().getCurrentVersionNumber();
			Class clazz = null;
			if (component instanceof IRedirectListener)
			{
				clazz = IRedirectListener.class;
			}
			else if (component instanceof IResourceListener)
			{
				clazz = IResourceListener.class;
			}
			else if (component instanceof IFormSubmitListener)
			{
				clazz = IFormSubmitListener.class;
			}
			else if (component instanceof ILinkListener)
			{
				clazz = ILinkListener.class;
			}
			else if (component instanceof IOnChangeListener)
			{
				clazz = IOnChangeListener.class;
			}
			else
			{
				throw new IllegalArgumentException(
					"The component class doesn't seem to implement any of the known *Listener interfaces: " +
						component.getClass());
			}

			// manually create the url using default strategy and format
			parameters.put(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME, pageMapName + ':' +
				component.getPath() + ':' + (version == 0 ? "" : "" + version) + ':' +
				Classes.simpleName(clazz) + "::");

			// see if we can replace our manual listener url with a properly generated one...

			try
			{
				RequestListenerInterface rli = (RequestListenerInterface)clazz.getField("INTERFACE")
					.get(clazz);

				String auto = component.getRequestCycle().urlFor(component, rli).toString();

				// check for crypted strategy
				if (auto.startsWith("?x="))
				{
					auto = auto.substring(3);
					parameters.put("x", auto);
					parameters.remove(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME);
				}
				else
				{
					int idx = auto.indexOf(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME);
					if (idx >= 0)
					{
						auto = auto.substring(idx +
							WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME.length() + 1);
					}
					else
					{
						idx = auto.indexOf("&");
						if (idx >= 0)
						{
							auto = auto.substring(0, idx);
						}
					}
					parameters.put(WebRequestCodingStrategy.INTERFACE_PARAMETER_NAME, auto);
				}
			}
			catch (Exception e)
			{
				// noop
			}

			if (component.isStateless() && component.getPage().isBookmarkable())
			{
				parameters.put(WebRequestCodingStrategy.BOOKMARKABLE_PAGE_PARAMETER_NAME,
					pageMapName + ':' + component.getPage().getClass().getName());
			}
		}
	}

	/**
	 * Initialize the request parameters to point to the given form component. The additional map
	 * should contain mappings between individual components that appear in the form and the string
	 * value that should be submitted for each of these components.
	 * 
	 * @param form
	 *            The for to send the request to
	 * @param values
	 *            The values for each of the form components
	 */
	public void setRequestToFormComponent(final Form form, final Map values)
	{
		setRequestToComponent(form);

		final Map valuesApplied = new HashMap();
		form.visitChildren(FormComponent.class, new Component.IVisitor>()
		{
			public Object component(final FormComponent component)
			{
				String value = (String)values.get(component);
				if (value != null)
				{
					parameters.put(component.getInputName(), values.get(component));
					valuesApplied.put(component.getId(), component);
				}
				return CONTINUE_TRAVERSAL;
			}
		});

		if (values.size() != valuesApplied.size())
		{
			Map diff = new HashMap();
			diff.putAll(values);

			Iterator iter = valuesApplied.keySet().iterator();
			while (iter.hasNext())
			{
				diff.remove(iter.next());
			}

			log.error("Parameter mismatch: didn't find all components referenced in parameter 'values': " +
				diff.keySet());
		}
	}

	/**
	 * Initialize the request parameters from the given redirect string that redirects back to a
	 * particular component for display.
	 * 
	 * @param redirect
	 *            The redirect string to display from
	 */
	public void setRequestToRedirectString(final String redirect)
	{
		parameters.clear();

		int queryStringPos = redirect.indexOf('?');

		// Decode the parameters
		if (queryStringPos != -1)
		{
			final String queryString = redirect.substring(queryStringPos + 1);
			RequestUtils.decodeParameters(queryString, parameters);
		}

		// We need to absolutize the redirect URL as we are not as smart as a web-browser
		// (WICKET-702)
		url = redirect;
		if ((url.length() == 0) || (url.charAt(0) != '/'))
		{
			url = getContextPath() + getServletPath() + "/" + redirect;
		}

		// Remove occurrences of ".." from the path
		url = RequestUtils.removeDoubleDots(url);
		log.info("Redirecting to " + url);
	}

	/**
	 * Helper method to create some default headers for the request
	 */
	private void setDefaultHeaders()
	{
		headers.clear();
		addHeader("Accept", "text/xml,application/xml,application/xhtml+xml,"
			+ "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
		addHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
		Locale l = Locale.getDefault();
		addHeader("Accept-Language", l.getLanguage().toLowerCase() + "-" +
			l.getCountry().toLowerCase() + "," + l.getLanguage().toLowerCase() + ";q=0.5");
		addHeader("User-Agent",
			"Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040707 Firefox/0.9.2");
	}

	private static final String crlf = "\r\n";
	private static final String boundary = "--abcdefgABCDEFG";

	private void newAttachment(OutputStream out) throws IOException
	{
		out.write(boundary.getBytes());
		out.write(crlf.getBytes());
		out.write("Content-Disposition: form-data".getBytes());
	}

	/**
	 * Build the request based on the uploaded files and the parameters.
	 * 
	 * @return The request as a string.
	 */
	private byte[] buildRequest()
	{
		try
		{
			// Build up the input stream based on the files and parameters
			ByteArrayOutputStream out = new ByteArrayOutputStream();

			// Add parameters
			for (Iterator iterator = parameters.keySet().iterator(); iterator.hasNext();)
			{
				final String name = iterator.next();
				newAttachment(out);
				out.write("; name=\"".getBytes());
				out.write(name.getBytes());
				out.write("\"".getBytes());
				out.write(crlf.getBytes());
				out.write(crlf.getBytes());
				out.write(parameters.get(name).toString().getBytes());
				out.write(crlf.getBytes());
			}

			// Add files
			if (uploadedFiles != null)
			{
				for (Iterator iterator = uploadedFiles.keySet().iterator(); iterator.hasNext();)
				{
					String fieldName = iterator.next();

					UploadedFile uf = uploadedFiles.get(fieldName);

					newAttachment(out);
					out.write("; name=\"".getBytes());
					out.write(fieldName.getBytes());
					out.write("\"; filename=\"".getBytes());
					out.write(uf.getFile().getName().getBytes());
					out.write("\"".getBytes());
					out.write(crlf.getBytes());
					out.write("Content-Type: ".getBytes());
					out.write(uf.getContentType().getBytes());
					out.write(crlf.getBytes());
					out.write(crlf.getBytes());

					// Load the file and put it into the the inputstream
					FileInputStream fis = new FileInputStream(uf.getFile());
					IOUtils.copy(fis, out);
					fis.close();
					out.write(crlf.getBytes());
				}
			}

			out.write(boundary.getBytes());
			out.write("--".getBytes());
			out.write(crlf.getBytes());
			return out.toByteArray();
		}
		catch (IOException e)
		{
			// NOTE: IllegalStateException(Throwable) only exists since Java 1.5
			throw new WicketRuntimeException(e);
		}
	}

	/**
	 * @return local address
	 */
	public String getLocalAddr()
	{
		return "127.0.0.1";
	}

	/**
	 * @return local host name
	 */
	public String getLocalName()
	{
		return "127.0.0.1";
	}

	/**
	 * @return local port
	 */
	public int getLocalPort()
	{
		return 80;
	}

	/**
	 * @return remote port
	 */
	public int getRemotePort()
	{
		return 80;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy