Java tutorial
/* 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; } }