es.logongas.encuestas.presentacion.controller.EncuestaController.java Source code

Java tutorial

Introduction

Here is the source code for es.logongas.encuestas.presentacion.controller.EncuestaController.java

Source

/*
 * Copyright 2013 Lorenzo Gonzlez.
 *
 * Licensed 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 es.logongas.encuestas.presentacion.controller;

import es.logongas.encuestas.modelo.educacion.Curso;
import es.logongas.encuestas.modelo.encuestas.Encuesta;
import es.logongas.encuestas.modelo.encuestas.Item;
import es.logongas.encuestas.modelo.encuestas.ListaValores;
import es.logongas.encuestas.modelo.encuestas.Pregunta;
import es.logongas.encuestas.modelo.encuestas.Valor;
import es.logongas.encuestas.modelo.respuestas.RespuestaEncuesta;
import es.logongas.encuestas.modelo.respuestas.RespuestaItem;
import es.logongas.encuestas.modelo.respuestas.RespuestaPregunta;
import es.logongas.encuestas.persistencia.services.dao.educacion.CursoDAO;
import es.logongas.encuestas.persistencia.services.dao.respuestas.RespuestaEncuestaDAO;
import es.logongas.ix3.core.BusinessException;
import es.logongas.ix3.core.BusinessMessage;
import es.logongas.ix3.dao.DAOFactory;
import es.logongas.util.seguridad.CodigoVerificacionSeguro;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 *
 * @author Lorenzo Gonzlez
 */
@Controller
public class EncuestaController {

    @Autowired
    DAOFactory daoFactory;

    @Autowired
    private ServletContext servletContext;

    protected final Log log = LogFactory.getLog(getClass());

    @RequestMapping(value = { "/encuesta.html" })
    public ModelAndView encuesta(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        String viewName;

        if (request.getCharacterEncoding() == null) {
            try {
                request.setCharacterEncoding("utf-8");
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(EncuestaController.class.getName()).log(Level.WARNING,
                        "no existe el juego de caracteres utf-8", ex);
            }
        }

        int idEncuesta;
        URI backURI;
        try {
            idEncuesta = Integer.parseInt(request.getParameter("idEncuesta"));
        } catch (NumberFormatException ex) {
            throw new BusinessException(new BusinessMessage(null, "El N de encuesta no es vlido"));
        }

        try {
            if ((request.getParameter("backURI") == null) || (request.getParameter("backURI").trim().equals(""))) {
                backURI = new URI(request.getContextPath() + "/");
            } else {
                backURI = new URI(request.getParameter("backURI"));
            }
        } catch (Exception ex) {
            throw new BusinessException(new BusinessMessage(null, "El backURI no es vlido"));
        }

        Encuesta encuesta = (Encuesta) daoFactory.getDAO(Encuesta.class).read(idEncuesta);
        if (encuesta == null) {
            throw new BusinessException(new BusinessMessage(null, "La encuesta solicitada no existe"));
        }

        if (encuesta.isEncuestaHabilitada() == false) {
            throw new BusinessException(
                    new BusinessMessage(null, "La encuesta solicitada no es posible realizarla actualmente"));
        }

        RespuestaEncuesta respuestaEncuesta = new RespuestaEncuesta(encuesta);
        EncuestaState encuestaState = new EncuestaState(respuestaEncuesta, backURI);
        setEncuestaState(request, encuestaState);

        Pregunta pregunta = respuestaEncuesta.getPrimeraPregunta();
        if (pregunta == null) {
            throw new BusinessException(new BusinessMessage(null, "La encuesta no tiene preguntas"));
        }
        viewName = "redirect:/pregunta.html?idPregunta=" + pregunta.getIdPregunta();

        return new ModelAndView(viewName, model);
    }

    @RequestMapping(value = { "/pregunta.html" })
    public ModelAndView pregunta(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        String viewName;

        if (request.getCharacterEncoding() == null) {
            try {
                request.setCharacterEncoding("utf-8");
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(EncuestaController.class.getName()).log(Level.WARNING,
                        "no existe el juego de caracteres utf-8", ex);
            }
        }

        int idPregunta;
        try {
            idPregunta = Integer.parseInt(request.getParameter("idPregunta"));
        } catch (NumberFormatException ex) {
            throw new BusinessException(
                    new BusinessMessage(null, "El N de pregunta no es vlido.No es un nmero"));
        }

        Pregunta pregunta = (Pregunta) daoFactory.getDAO(Pregunta.class).read(idPregunta);
        if (pregunta == null) {
            throw new BusinessException(new BusinessMessage(null, "La pregunta solicitada no existe"));
        }

        if (getEncuestaState(request).getRespuestaEncuesta().isPreguntaValida(pregunta) == false) {
            throw new BusinessException(
                    new BusinessMessage(null, "La pregunta solicitada no es vlida en esta encuesta"));
        }

        RespuestaPregunta respuestaPregunta = getEncuestaState(request).getRespuestaEncuesta()
                .getRespuestaPregunta(pregunta);
        model.put("respuestaPregunta", respuestaPregunta);
        viewName = "encuestas/pregunta";

        return new ModelAndView(viewName, model);
    }

    @RequestMapping(value = { "/siguiente.html" })
    public ModelAndView siguiente(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        String viewName;

        try {
            request.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException ex) {
            throw new RuntimeException("no existe el juego de caracteres utf-8", ex);
        }

        int idPregunta;
        try {
            idPregunta = Integer.parseInt(request.getParameter("idPregunta"));
        } catch (NumberFormatException ex) {
            throw new BusinessException(new BusinessMessage(null, "El N de pregunta no es vlido"));
        }

        Pregunta pregunta = (Pregunta) daoFactory.getDAO(Pregunta.class).read(idPregunta);
        if (pregunta == null) {
            throw new BusinessException(new BusinessMessage(null, "La pregunta solicitada no existe"));
        }

        RespuestaEncuesta respuestaEncuesta = getEncuestaState(request).getRespuestaEncuesta();
        if (respuestaEncuesta.isPreguntaValida(pregunta) == false) {
            throw new BusinessException(
                    new BusinessMessage(null, "La pregunta solicitada no es vlida en esta encuesta"));
        }

        RespuestaPregunta respuestaPregunta = respuestaEncuesta.getRespuestaPregunta(pregunta);
        populateRespuestaFromRequest(request, respuestaPregunta);
        List<BusinessMessage> businessMessages = respuestaPregunta.validate();
        if ((businessMessages != null) && (businessMessages.size() > 0)) {
            model.put("businessMessages", businessMessages);
            model.put("respuestaPregunta", respuestaPregunta);
            viewName = "encuestas/pregunta";
        } else {

            Pregunta siguientePregunta = respuestaEncuesta.getRespuestaPregunta(pregunta).siguiente();

            if (siguientePregunta != null) {
                viewName = "redirect:/pregunta.html?idPregunta=" + siguientePregunta.getIdPregunta();
            } else {
                //Era la ltima pregunta.Vamos a la pgina de finalizar
                viewName = "redirect:/finalizar.html";
            }
        }

        return new ModelAndView(viewName, model);
    }

    @RequestMapping(value = { "/anterior.html" })
    public ModelAndView anterior(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        String viewName;

        if (request.getCharacterEncoding() == null) {
            try {
                request.setCharacterEncoding("utf-8");
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(EncuestaController.class.getName()).log(Level.WARNING,
                        "no existe el juego de caracteres utf-8", ex);
            }
        }

        int idPregunta;
        try {
            idPregunta = Integer.parseInt(request.getParameter("idPregunta"));
        } catch (NumberFormatException ex) {
            throw new BusinessException(new BusinessMessage(null, "El N de pregunta no es vlido"));
        }

        Pregunta pregunta = (Pregunta) daoFactory.getDAO(Pregunta.class).read(idPregunta);
        if (pregunta == null) {
            throw new BusinessException(new BusinessMessage(null, "La pregunta solicitada no existe"));
        }

        RespuestaEncuesta respuestaEncuesta = getEncuestaState(request).getRespuestaEncuesta();
        if (respuestaEncuesta.isPreguntaValida(pregunta) == false) {
            throw new BusinessException(
                    new BusinessMessage(null, "La pregunta solicitada no es vlida en esta encuesta"));
        }

        RespuestaPregunta respuestaPregunta = respuestaEncuesta.getRespuestaPregunta(pregunta);
        populateRespuestaFromRequest(request, respuestaPregunta);

        Pregunta anteriorPregunta = respuestaEncuesta.getRespuestaPregunta(pregunta).anterior();

        if (anteriorPregunta != null) {
            viewName = "redirect:/pregunta.html?idPregunta=" + anteriorPregunta.getIdPregunta();
        } else {
            //Era la primera pregunta
            //As que vamos al BackURL
            viewName = "redirect:" + getEncuestaState(request).getBackURI().toASCIIString();
        }

        return new ModelAndView(viewName, model);
    }

    @RequestMapping(value = { "/ultima.html" })
    public ModelAndView ultima(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        String viewName;

        if (request.getCharacterEncoding() == null) {
            try {
                request.setCharacterEncoding("utf-8");
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(EncuestaController.class.getName()).log(Level.WARNING,
                        "no existe el juego de caracteres utf-8", ex);
            }
        }

        Pregunta ultimaPregunta;
        ultimaPregunta = getEncuestaState(request).getRespuestaEncuesta().getUltimaPregunta();
        if (ultimaPregunta == null) {
            throw new BusinessException(new BusinessMessage(null, "La encuesta no tiene preguntas"));
        }

        viewName = "redirect:/pregunta.html?idPregunta=" + ultimaPregunta.getIdPregunta();

        return new ModelAndView(viewName, model);
    }

    @RequestMapping(value = { "/finalizar.html" })
    public ModelAndView finalizar(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();
        String viewName;

        if (request.getCharacterEncoding() == null) {
            try {
                request.setCharacterEncoding("utf-8");
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(EncuestaController.class.getName()).log(Level.WARNING,
                        "no existe el juego de caracteres utf-8", ex);
            }
        }

        RespuestaEncuesta respuestaEncuesta = getEncuestaState(request).getRespuestaEncuesta();

        List<BusinessMessage> businessMessages = respuestaEncuesta.validate();
        if ((businessMessages != null) && (businessMessages.size() > 0)) {
            Encuesta encuesta = respuestaEncuesta.getEncuesta();
            model.put("encuesta", encuesta);
            model.put("businessMessages", businessMessages);
            viewName = "encuestas/error_encuesta";
        } else {
            Date fechaRespuesta = new Date();
            respuestaEncuesta.setFechaRespuesta(fechaRespuesta);
            respuestaEncuesta.setCurso(getCursoFromDate(fechaRespuesta));

            daoFactory.getDAO(RespuestaEncuesta.class).insert(respuestaEncuesta);
            CodigoVerificacionSeguro codigoVerificacionSeguro = CodigoVerificacionSeguro
                    .getInstance(respuestaEncuesta.getIdRespuestaEncuesta());
            respuestaEncuesta.setCodigoVerificacionSeguro(codigoVerificacionSeguro);
            daoFactory.getDAO(RespuestaEncuesta.class).update(respuestaEncuesta);

            URI backURI = getEncuestaState(request).getBackURI();

            clearEncuestaState(request);

            model.put("codigoVerificacionSeguro", codigoVerificacionSeguro);
            model.put("backURI", backURI);
            viewName = "encuestas/finalizar";
        }

        return new ModelAndView(viewName, model);
    }

    @RequestMapping(value = { "/secure_qrcode.png" }, method = RequestMethod.GET, produces = "image/png")
    public @ResponseBody byte[] qrcode(HttpServletRequest request, HttpServletResponse response) {

        String valorCVC = request.getParameter("cvc");
        int tamanyo;
        try {
            tamanyo = Integer.parseInt(request.getParameter("tamanyo"));
        } catch (Exception ex) {
            tamanyo = 200;
        }

        CodigoVerificacionSeguro codigoVerificacionSeguro = CodigoVerificacionSeguro.getInstance(valorCVC);

        if (codigoVerificacionSeguro.isValido() == false) {
            log.error("Se solicit un CodigoVerificacionSeguro invlido:" + valorCVC);
            try {
                InputStream is = new BufferedInputStream(
                        new FileInputStream(servletContext.getRealPath("/img/error_qrcode.png")));
                return toByteArray(is);
            } catch (FileNotFoundException ex) {
                throw new RuntimeException(ex);
            }

        } else {
            RespuestaEncuestaDAO respuestaEncuestaDAO = (RespuestaEncuestaDAO) daoFactory
                    .getDAO(RespuestaEncuesta.class);
            RespuestaEncuesta respuestaEncuesta = respuestaEncuestaDAO
                    .getByCodigoVerificacionSeguro(codigoVerificacionSeguro);
            if (respuestaEncuesta == null) {
                log.error("Se solicit un CodigoVerificacionSeguro que no existe:" + valorCVC);
            }
            return codigoVerificacionSeguro.getQRCode(tamanyo);
        }

    }

    private EncuestaState getEncuestaState(HttpServletRequest request) throws Exception {
        EncuestaState encuestaState = (EncuestaState) request.getSession().getAttribute("encuestaState");
        if (encuestaState == null) {
            throw new BusinessException(new BusinessMessage(null, "No hay ninguna encuesta en la sesin"));
        }

        return encuestaState;
    }

    private EncuestaState setEncuestaState(HttpServletRequest request, EncuestaState encuestaState)
            throws Exception {
        if (encuestaState == null) {
            throw new IllegalArgumentException("El argumento 'encuestaState' no puede ser null");
        }

        request.getSession().setAttribute("encuestaState", encuestaState);

        return encuestaState;
    }

    private void clearEncuestaState(HttpServletRequest request) throws Exception {
        request.getSession().setAttribute("encuestaState", null);
    }

    private void populateRespuestaFromRequest(HttpServletRequest request, RespuestaPregunta respuestaPregunta) {

        for (RespuestaItem respuestaItem : respuestaPregunta.getRespuestaItems()) {
            Item item = respuestaItem.getItem();

            respuestaItem.setValor(parameterDecode(request.getParameter("valor" + item.getIdItem())));
            ListaValores listaValores = respuestaItem.getItem().getListaValores();
            if ((listaValores != null) && (listaValores.isContieneValoresNumericos() == true)) {
                Valor valor = listaValores.getValorByNombre(respuestaItem.getValor());
                if ((valor != null) && (valor.getValorNumerico() != null)) {
                    respuestaItem.setValorNumerico(valor.getValorNumerico());
                }
            }

            switch (respuestaPregunta.getPregunta().getTipoPregunta()) {
            case Radio:
                if (("" + item.getIdItem()).equals(request.getParameter("check1"))) {
                    respuestaItem.setCheck(true);
                } else {
                    respuestaItem.setCheck(false);
                }
                break;
            case Check:
            case EspecificoPorItem:
                if (("" + item.getIdItem()).equals(request.getParameter("check" + item.getIdItem()))) {
                    respuestaItem.setCheck(true);
                } else {
                    respuestaItem.setCheck(false);
                }
                break;
            default:
                throw new RuntimeException(
                        "El tipo de pregunta es desconocido:" + respuestaPregunta.getPregunta().getTipoPregunta());
            }
        }

    }

    private String parameterDecode(String s) {
        if (s == null) {
            return null;
        }

        try {
            s = new String(s.getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            throw new RuntimeException(ex);
        }

        //Cambiar los &nbsp; por " " espacios normales
        s = s.replace("\u00a0", " ");

        if (s.trim().equals("")) {
            return null;
        }

        return s.trim();
    }

    private Curso getCursoFromDate(Date date) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);

        int anyoInicioCurso;
        int anyoActual = gc.get(GregorianCalendar.YEAR);
        int mesActual = gc.get(GregorianCalendar.MONTH);
        //A partir de Mayo estamos en el nuevo curso a efectos de las encuestas de matricula
        if (mesActual >= Calendar.MAY) {
            anyoInicioCurso = anyoActual;
        } else {
            anyoInicioCurso = anyoActual - 1;
        }

        CursoDAO cursoDAO = (CursoDAO) daoFactory.getDAO(Curso.class);
        Curso curso = cursoDAO.getByAnyoInicio(anyoInicioCurso);
        if (curso == null) {
            //Creamos un nuevo curso para este ao
            throw new RuntimeException("No existe el curso que empieza en el ao:" + anyoInicioCurso);
        }

        return curso;
    }

    private static byte[] toByteArray(InputStream is) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int reads = is.read();

            while (reads != -1) {
                baos.write(reads);
                reads = is.read();
            }

            return baos.toByteArray();
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }

    }
}