mx.org.cedn.avisosconagua.engine.Controler.java Source code

Java tutorial

Introduction

Here is the source code for mx.org.cedn.avisosconagua.engine.Controler.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Mxico Abierto
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * For more information visit https://github.com/mxabierto/avisos.
*/
package mx.org.cedn.avisosconagua.engine;

import com.mongodb.BasicDBObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import mx.org.cedn.avisosconagua.exceptions.AvisosException;
import mx.org.cedn.avisosconagua.mongo.MongoInterface;

/**
 * Controller servlet.
 * Manages the requests in the defined workflows for the web application, taking as input the {@link types.properties} config file.
 * @author serch
 */
@WebServlet(name = "Controler", urlPatterns = { "/ctrl/*" })
public class Controler extends HttpServlet {

    private static final HashMap<String, List<String>> control = new HashMap<>();
    private static final HashMap<String, Processor> processors = new HashMap<>();
    private static final String ADVICE_ID = "internalId";

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        try (BufferedReader input = new BufferedReader(
                new InputStreamReader(Controler.class.getResourceAsStream("/types.properties")))) {
            String linea;
            while ((linea = input.readLine()) != null) {
                if (!linea.startsWith("#")) {
                    String[] kv = linea.split("=");
                    if (kv.length == 2) {
                        String[] val = kv[1].split(",");
                        List<String> list = Arrays.asList(val);
                        control.put(kv[0], list);
                        for (String proc : list) {
                            if (!processors.containsKey(proc)) {
                                String clazzName = "mx.org.cedn.avisosconagua.engine.processors."
                                        + proc.substring(0, 1).toUpperCase() + proc.substring(1);
                                Class clazz = Class.forName(clazzName);
                                Processor procObj = (Processor) clazz.newInstance();
                                processors.put(proc, procObj);
                            }
                        }
                    }
                }
            }
        } catch (IOException | ReflectiveOperationException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String currentId = (String) request.getSession(true).getAttribute(ADVICE_ID);
        String[] parts = request.getRequestURI().split("/");
        if (parts.length > 3 && control.containsKey(parts[2])) {
            List<String> flujo = control.get(parts[2]);
            BasicDBObject datos = null;
            if (flujo.contains(parts[3])) {
                if ("capgen".equals(parts[2])) {
                    processors.get(parts[3]).invokeForm(request, response, null, parts);
                    return;
                }
                if (parts.length > 4 && !"new".equals(parts[4])) {
                    datos = MongoInterface.getInstance().getAdvice(parts[4]);
                    if (null != datos) {
                        currentId = parts[4];
                        request.getSession(true).setAttribute(ADVICE_ID, currentId);
                        response.sendRedirect("/" + parts[1] + "/" + parts[2] + "/" + parts[3]);
                        return;
                    }
                }
                if ((null == currentId && parts[3].equals(flujo.get(0)))
                        || (parts.length > 4 && "new".equals(parts[4]))) {
                    currentId = UUID.randomUUID().toString();
                    request.getSession(true).setAttribute(ADVICE_ID, currentId);
                    MongoInterface.getInstance().createNewAdvice(currentId, parts[2]);
                    response.sendRedirect("/" + parts[1] + "/" + parts[2] + "/" + parts[3]);
                    return;
                }
                if (null == datos) {
                    datos = MongoInterface.getInstance().getAdvice(currentId);
                }

                cleanAttributes(request);
                processors.get(parts[3]).invokeForm(request, response, (BasicDBObject) datos.get(parts[3]), parts);

            }
        }

    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String currentId = (String) request.getSession(true).getAttribute(ADVICE_ID);
        if (null == currentId) {
            response.sendError(500, "Call outside the flow");
        }
        String[] parts = request.getRequestURI().split("/");
        if (parts.length > 3 && control.containsKey(parts[2]) && control.get(parts[2]).contains(parts[3])) {
            try {
                processors.get(parts[3]).processForm(request, parts, currentId);
            } catch (AvisosException aex) {
                PrintWriter pw = response.getWriter();
                pw.println(
                        "<html><body><script>alert('Error: " + aex.getMessage() + "'); window.location.href='/ctrl/"
                                + parts[2] + "/" + parts[3] + "';</script></body></html>");
                pw.flush();
                System.out.println("tuve error, listo para return");
                return;
            }
            System.out.println("redirect a nextPart");
            response.sendRedirect("/ctrl/" + parts[2] + "/" + getNext(parts));
        } else {
            System.out.println("not found");
            response.sendError(404);
        }
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    /**
     * Cleans the attributes from the servlet request.
     * @param request servlet request.
     */
    private void cleanAttributes(HttpServletRequest request) {
        Enumeration<String> en = request.getAttributeNames();
        while (en.hasMoreElements()) {
            String act = en.nextElement();
            request.removeAttribute(act);
        }
    }

    /**
     * Gets the next step from the workflows configured in the controller.
     * @param parts parts of the request URI.
     * @return next step in the configured workflow.
     */
    private String getNext(String[] parts) {
        List<String> flujo = control.get(parts[2]);
        int idx = flujo.indexOf(parts[3]) + 1;
        if (idx < flujo.size()) {
            return flujo.get(idx);
        } else {
            return null;
        }
    }

}