nl.minbzk.dwr.zoeken.enricher.aci.ImportController.java Source code

Java tutorial

Introduction

Here is the source code for nl.minbzk.dwr.zoeken.enricher.aci.ImportController.java

Source

/* Copyright (c) 2010 Ministry of the Interior and Kingdom Relations,
 * the Netherlands. All rights reserved.
 * 
 * This file is part of the MinBZK Search Enricher indexing generator.
 * 
 * Search Enricher is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Search Enricher is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Search Enricher. If not, see <http://www.gnu.org/licenses/>. */

package nl.minbzk.dwr.zoeken.enricher.aci;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import nl.minbzk.dwr.zoeken.enricher.service.EnricherService;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

/**
 * Import controller.
 * 
 * @author Jasper van Veghel <j.veghel@rijksoverheid.nl>
 */
@Controller
public class ImportController extends AbstractController {
    /**
     * The logger.
     */
    private static Logger logger = LoggerFactory.getLogger(ImportController.class);

    /**
     * Constants.
     */
    private static final String PARAM_JOB_NAME = "JobName";
    private static final String PARAM_REFERENCE_ENCODING = "ReferenceEncoding";
    private static final String PARAM_ENVELOPE_XML = "EnvelopeXML";
    private static final String PARAM_ACTION = "action";
    private static final String PARAM_DELETE_TYPE = "DeleteType";
    private static final String PARAM_DOCUMENTS = "Docs";
    private static final String PARAM_FIELD = "Field";

    private static final String ACTION_IMPORT_ENVELOPE = "ImportEnvelope";
    private static final String ACTION_DELETE = "Delete";
    private static final String ACTION_COMMIT = "Commit";

    private static final String DELETE_TYPE_DOCID = "doc";
    private static final String DELETE_TYPE_REFERENCE = "ref";

    private static final int HTTP_STATUS_FAILURE = 500;
    private static final int HTTP_STATUS_NOT_FOUND = 404;

    /**
     * The enricher service.
     */
    @Autowired
    private EnricherService enricherService;

    /**
     * Handle a request.
     * 
     * @param request
     * @param response
     * @return ModelAndView
     */
    @Override
    protected ModelAndView handleRequestInternal(final HttpServletRequest request,
            final HttpServletResponse response) throws Exception {
        // Build a parameter map if the query request incorrectly provided (/name=value instead of /?name=value)

        Map<String, String[]> parameters = null;

        if (request.getRequestURI() != null && request.getRequestURI().indexOf('&') != -1) {
            String query = request.getRequestURI().substring(1);

            if (logger.isDebugEnabled())
                logger.debug(
                        "URL path contains what look like request entities. Actual query string interpreted as "
                                + query);

            parameters = parseQueryString(query);
        }

        // Now resolve all parameters against either the map or the request

        String path = request.getPathInfo().indexOf('&') != -1
                ? request.getPathInfo().substring(0, request.getPathInfo().indexOf('&'))
                : request.getPathInfo();

        if (("/" + PARAM_ACTION + "=" + ACTION_IMPORT_ENVELOPE).equals(path)
                || ACTION_IMPORT_ENVELOPE.equals(request.getParameter(PARAM_ACTION))) {
            processImportEnvelope(parameters, request, response);
        } else if (("/" + PARAM_ACTION + "=" + ACTION_DELETE).equals(path)
                || ACTION_DELETE.equals(request.getParameter(PARAM_ACTION))) {
            processDelete(parameters, request, response);
        } else if (("/" + PARAM_ACTION + "=" + ACTION_COMMIT).equals(path)
                || ACTION_COMMIT.equals(request.getParameter(PARAM_ACTION))) {
            processCommit(parameters, request, response);
        } else {
            response.sendError(HTTP_STATUS_NOT_FOUND, "Request not understood or unknown action given.");

            logger.error("Request " + request.getRequestURI() + " (" + request.getQueryString()
                    + ") was not understood");
        }

        return null;
    }

    /**
     * Process an ImportEnvelope request.
     * 
     * @param parameters
     * @param request
     * @param response
     * @throws IOException
     */
    private void processImportEnvelope(final Map<String, String[]> parameters, final HttpServletRequest request,
            final HttpServletResponse response) throws IOException {
        String jobName = !StringUtils.isEmpty(resolveParameter(request, parameters, PARAM_JOB_NAME))
                ? resolveParameter(request, parameters, PARAM_JOB_NAME)
                : null;
        String referenceEncoding = !StringUtils
                .isEmpty(resolveParameter(request, parameters, PARAM_REFERENCE_ENCODING))
                        ? resolveParameter(request, parameters, PARAM_REFERENCE_ENCODING)
                        : null;
        String envelopeXML = resolveParameter(request, parameters, PARAM_ENVELOPE_XML);

        if (StringUtils.isEmpty(envelopeXML))
            response.sendError(HTTP_STATUS_FAILURE, "No envelope content (" + PARAM_ENVELOPE_XML + ") provided.");
        else {
            if (StringUtils.isEmpty(jobName))
                logger.warn("No job name given, resorting to heuristically deriving it from the envelope XML");
            if (StringUtils.isEmpty(referenceEncoding))
                logger.warn(
                        "No reference encoding given, resorting to heuristically deriving it from the envelope XML");

            // Trace-log the envelope XML content for fine-grained debugging

            if (logger.isTraceEnabled())
                logger.trace("Envelope XML content resolves to: " + envelopeXML);

            if (!enricherService.processImport(new StringReader(envelopeXML), jobName, referenceEncoding))
                response.sendError(HTTP_STATUS_FAILURE, "Please see application log for details.");
            else
                response.getWriter().write("Success\n");
        }
    }

    /**
     * Process a Delete request.
     * 
     * @param parameters
     * @param request
     * @param response
     * @throws IOException
     */
    private void processDelete(final Map<String, String[]> parameters, final HttpServletRequest request,
            final HttpServletResponse response) throws IOException {
        String jobName = !StringUtils.isEmpty(resolveParameter(request, parameters, PARAM_JOB_NAME))
                ? resolveParameter(request, parameters, PARAM_JOB_NAME)
                : null;
        String deleteType = resolveParameter(request, parameters, PARAM_DELETE_TYPE);
        String[] documents = resolveParameterValues(request, parameters, PARAM_DOCUMENTS);

        if (StringUtils.isEmpty(deleteType))
            response.sendError(HTTP_STATUS_FAILURE, "No delete type provided.");
        else {
            if (DELETE_TYPE_DOCID.equals(deleteType)) {
                if (documents == null || documents.length == 0)
                    response.sendError(HTTP_STATUS_FAILURE, "No documents provided for reference-based deletion.");
                else if (!enricherService.processDeleteByDocId(jobName, documents))
                    response.sendError(HTTP_STATUS_FAILURE, "Please see application log for details.");
                else
                    response.getWriter().write("Success\n");
            } else if (DELETE_TYPE_REFERENCE.equals(deleteType)) {
                String field = resolveParameter(request, parameters, PARAM_FIELD);

                if (documents == null || documents.length == 0)
                    response.sendError(HTTP_STATUS_FAILURE, "No documents provided for reference-based deletion.");
                else if (StringUtils.isEmpty(field))
                    response.sendError(HTTP_STATUS_FAILURE, "No field provided for reference-based deletion.");
                else if (!enricherService.processDeleteByReference(jobName, field, documents))
                    response.sendError(HTTP_STATUS_FAILURE, "Please see application log for details.");
                else
                    response.getWriter().write("Success\n");
            } else
                response.sendError(HTTP_STATUS_FAILURE,
                        "The given delete type (" + deleteType + ") is not supported.");
        }
    }

    /**
     * Process a Commit request.
     * 
     * @param parameters
     * @param request
     * @param response
     * @throws IOException
     */
    private void processCommit(final Map<String, String[]> parameters, final HttpServletRequest request,
            final HttpServletResponse response) throws IOException {
        String jobName = !StringUtils.isEmpty(resolveParameter(request, parameters, PARAM_JOB_NAME))
                ? resolveParameter(request, parameters, PARAM_JOB_NAME)
                : null;

        if (StringUtils.isEmpty(jobName))
            response.sendError(HTTP_STATUS_FAILURE, "A job name must be provided.");
        else if (!enricherService.processCommit(jobName))
            response.sendError(HTTP_STATUS_FAILURE, "Please see application log for details.");
        else
            response.getWriter().write("Success\n");
    }

    /**
     * Resolve a given parameter value from either a given map or the request.
     * 
     * @param request
     * @param parameters
     * @param parameter
     * @return String
     */
    private String resolveParameter(final HttpServletRequest request, final Map<String, String[]> parameters,
            final String parameter) {
        if (parameters != null && parameters.containsKey(parameter))
            return parameters.get(parameter)[0];
        else
            return request.getParameter(parameter);
    }

    /**
     * Resolve a given parameter value from either a given map or the request.
     * 
     * @param request
     * @param parameters
     * @param parameter
     * @return String
     */
    private String[] resolveParameterValues(final HttpServletRequest request,
            final Map<String, String[]> parameters, final String parameter) {
        if (parameters != null && parameters.containsKey(parameter))
            return parameters.get(parameter);
        else
            return request.getParameterValues(parameter);
    }

    /**
     * Split up the query map. Note that this is not a particularly exhaustive implementation.
     * 
     * @param query
     * @return Map<String, String>
     * @throws UnsupportedEncodingException
     */
    public static Map<String, String[]> parseQueryString(final String query) throws UnsupportedEncodingException {
        Map<String, String[]> result = new HashMap<String, String[]>();

        for (String param : query.split("&"))
            if (result.containsKey(param.split("=")[0]))
                result.put(param.split("=")[0],
                        (String[]) ArrayUtils.addAll(
                                new String[] { URLDecoder.decode(param.split("=")[1], "UTF-8") },
                                result.get(param.split("=")[0])));
            else
                result.put(param.split("=")[0], new String[] { URLDecoder.decode(param.split("=")[1], "UTF-8") });

        return result;
    }
}