/* * The MIT License (MIT) * * Copyright (c) 2014 México 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; } } }