/*
 * $Id: MockMultipartRequestHandler.java 471754 2006-11-06 14:55:09Z husted $
 *
 * 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.struts.mock;

import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.upload.FormFile;
import org.apache.struts.upload.MultipartRequestHandler;

/**
 * <p>Mock <strong>MultipartRequestHandler</strong> object for unit tests.</p>
 *
 * @version $Rev: 471754 $
 */
public class MockMultipartRequestHandler implements MultipartRequestHandler {

    /** mock ActionServlet instance. */
    private ActionServlet servlet;

    /** mock ActionMapping instance. */
    private ActionMapping mapping = new ActionMapping();

    /** request elements. */
    private Hashtable<String, String[]> elements;

    /**
     * Convienience method to set a reference to a mock
     * ActionServlet instance.
     * @param val Mock servlet instance.
     */
    @Override
    public void setServlet(final ActionServlet val) {
        this.servlet = val;
    }

    /**
     * Convienience method to set a reference to a mock
     * ActionMapping instance.
     * @param val Mock action mapping instance.
     */
    @Override
    public void setMapping(final ActionMapping val) {
        this.mapping = val;
    }

    /**
     * Get the mock ActionServlet instance.
     * @return The mock servlet instance.
     */
    @Override
    public ActionServlet getServlet() {
        return this.servlet;
    }

    /**
     * Get the ActionMapping instance for this mock request.
     * @return The mock action mapping instance.
     */
    @Override
    public ActionMapping getMapping() {
        return this.mapping;
    }

    /**
      * <p>Mock parsing of the ServletInputStream.</p>
      *
      * <p>Constructs a <code>Hashtable</code> of elements
      *    from the HttpServletRequest's parameters - no
      *    <code>FormFile</code> elements are created.</p>
      * @param request Mock request instance.
      */
    @Override
    public void handleRequest(final HttpServletRequest request) {
        this.elements = new Hashtable<>();
        Enumeration<String> enumer = request.getParameterNames();
        while (enumer.hasMoreElements()) {
            String key = enumer.nextElement();
            this.elements.put(key, request.getParameterValues(key));
        }
    }

    /**
     * This method is called on to retrieve all the text
     * input elements of the request.
     *
     * @return A Hashtable where the keys and values are the names and
     *  values of the request input parameters
     */
    @Override
    public Map<String, String[]> getTextElements() {
        return Collections.unmodifiableMap(this.elements);
    }

    /**
     * <p>This method is called on to retrieve all the FormFile
     * input elements of the request.</p>
     *
     * @return This mock implementation returns an empty
     *    <code>Hashtable</code>
     */
    @Override
    public Map<String, List<FormFile>> getFileElements() {
        return new Hashtable<>();
    }

    /**
     * This method returns all elements of a multipart request.
     * @return This mock implementation returns a Hashtable where
     *   the keys are input names and values are either Strings
     *   (no FormFile elements)
     */
    @Override
    public Map<String, Object> getAllElements() {
        return Collections.unmodifiableMap(this.elements);
    }

    /**
     * Mock <code>rollback()</code> method does nothing.
     */
    @Override
    public void rollback() {
        // ignore
    }

    /**
     * Mock <code>finish()</code> method does nothing.
     */
    @Override
    public void finish() {
        // ignore
    }
}
