Package org.apache.wicket.protocol.http

Source Code of org.apache.wicket.protocol.http.MockHttpServletRequest$UploadedFile

/*
* 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<Cookie> cookies = new ArrayList<Cookie>();

  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<String, UploadedFile> 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<Cookie> 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<String, UploadedFile>();
    }

    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<String> list = (List<String>)headers.get(name);
    if (list == null)
    {
      list = new ArrayList<String>(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<String> 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<String> l = (List<String>)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<String> 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<String> getHeaders(final String name)
  {
    @SuppressWarnings("unchecked")
    List<String> list = (List<String>)headers.get(name);
    if (list == null)
    {
      list = new ArrayList<String>();
    }
    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()
  {
    final String header = getHeader("Accept-Language");
    if (header == null)
    {
      return Locale.getDefault();
    }

    final String[] firstLocale = header.split(",");
    if (firstLocale.length < 1)
    {
      return Locale.getDefault();
    }

    final String[] bits = firstLocale[0].split("-");
    if (bits.length < 1)
    {
      return Locale.getDefault();
    }

    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<Locale> getLocales()
  {
    List<Locale> list = new ArrayList<Locale>(1);
    list.add(getLocale());
    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<String, Object> getParameterMap()
  {
    return parameters;
  }

  /**
   * Get the names of all of the parameters.
   *
   * @return The parameter names
   */
  public Enumeration<String> 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<String> 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<String, String[]> 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<String, String[]> params = new HashMap<String, String[]>();
      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<String, Object> 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<? extends Page> 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<String, Object> values)
  {
    setRequestToComponent(form);

    final Map<String, Object> valuesApplied = new HashMap<String, Object>();
    form.visitChildren(FormComponent.class, new Component.IVisitor<FormComponent<?>>()
    {
      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<String, Object> diff = new HashMap<String, Object>();
      diff.putAll(values);

      Iterator<String> 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<String> 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<String> 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;
  }
}
TOP

Related Classes of org.apache.wicket.protocol.http.MockHttpServletRequest$UploadedFile

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.