private static ArrayList<SurveyAnswer> convertToSurveyAnswers( String[] answers, SurveyQuestion question) throws SurveyParseException { ArrayList<SurveyAnswer> surveyAnswers = new ArrayList<SurveyAnswer>(); SurveyAnswerFactory answerFactory = new SurveyAnswerFactory(); SurveyAnswer answerObj; for (String answer : answers) { answerObj = answerFactory.getSurveyAnswer(question.getQuestionType(), answer); if (answerObj == null) return null; else surveyAnswers.add(answerObj); } return surveyAnswers; }
/** @return the next url to go to, excluding contextPath */ public static ModelAndView execute( HttpServletRequest request, String documentId, TapestryPHRSurvey currentSurvey, PHRSurvey templateSurvey) throws Exception { ModelAndView m = new ModelAndView(); final String questionId = request.getParameter("questionid"); String direction = request.getParameter("direction"); String observerNotes = request.getParameter("observernote"); if (direction == null) direction = "forward"; if (documentId == null) { logger.error("no selected survey? documentId=" + documentId); m.setViewName("failed"); return m; } String[] answerStrs = request.getParameterValues("answer"); String nextQuestionId = questionId; // if requested survey does not exist if (currentSurvey == null) { logger.error("Cannot find requested survey. documentId=" + documentId); m.setViewName("failed"); return m; } // if requested survey is completed if (currentSurvey.isComplete()) logger.error("trying to complete already completed survey?"); boolean saved = false; // if starting/continuing survey, clear session if (questionId == null) { // if just starting/continuing(from before) the survey, direct to last question String lastQuestionId; if (currentSurvey.getQuestions().size() == 0) { boolean moreQuestions = addNextQuestion(null, currentSurvey, templateSurvey); if (!moreQuestions) { logger.error("Survey has no questions?"); m.setViewName("failed"); return m; } } if (currentSurvey.isComplete()) { // if complete show first question lastQuestionId = currentSurvey.getQuestions().get(0).getId(); m.addObject("hideObservernote", true); } else { // if not complete show next question lastQuestionId = currentSurvey.getQuestions().get(currentSurvey.getQuestions().size() - 1).getId(); // logic for displaying Observer Notes button if (isFirstQuestionId(lastQuestionId, '0')) m.addObject("hideObservernote", true); else m.addObject("hideObservernote", false); } m.addObject("survey", currentSurvey); m.addObject("templateSurvey", templateSurvey); m.addObject("questionid", lastQuestionId); m.addObject("resultid", documentId); m.setViewName("/surveys/show_survey"); return m; } // end of questionId == null; String errMsg = null; // if continuing survey (just submitted an answer) if (questionId != null && direction.equalsIgnoreCase("forward")) { if (currentSurvey .getQuestionById(questionId) .getQuestionType() .equals(SurveyQuestion.ANSWER_CHECK) && answerStrs == null) answerStrs = new String[0]; if (answerStrs != null && (currentSurvey .getQuestionById(questionId) .getQuestionType() .equals(SurveyQuestion.ANSWER_CHECK) || !answerStrs[0].equals(""))) { SurveyQuestion question = currentSurvey.getQuestionById(questionId); SurveyQuestion questionWithoutObserverNotes = currentSurvey.getQuestionById(questionId); // keep answers without obserbernotes for validation // ArrayList<SurveyAnswer> answersWithoutObserverNotes = // convertToSurveyAnswers(answerStrs, questionWithoutObserverNotes); // // //add observernotes into answer when there is no condition or non-number type input // List<SurveyDirectionStatement> logicStatements = question.getNextQuestionLogic(); // String type = question.getQuestionType(); String questionText = question.getQuestionText(); if (!Utils.isNullOrEmpty(questionText)) { String separator = "/observernote/ "; StringBuffer sb = new StringBuffer(); sb.append(questionText); sb.append(separator); sb.append(observerNotes); questionText = sb.toString(); question.setQuestionText(questionText); } // if (!Utils.isNullOrEmpty(type) && (!type.equalsIgnoreCase("number")) && // (logicStatements.size() <= 1)) // { // if (answerStrs.length == 1) // { // String content = answerStrs[0]; // String separator = "/observernote/ "; // StringBuffer sb = new StringBuffer(); // sb.append(content); // sb.append(separator); // sb.append(observerNotes); // answerStrs[0] = sb.toString(); // } // } ArrayList<SurveyAnswer> answers = convertToSurveyAnswers(answerStrs, question); boolean goodAnswerFormat = true; if (answers == null) goodAnswerFormat = false; // check each answer for validation // if answer passes validation // if (goodAnswerFormat && question.validateAnswers(answersWithoutObserverNotes)) if (goodAnswerFormat && question.validateAnswers(answers)) { boolean moreQuestions; // see if the user went back (if current question the last question in user's question // profile) if (!currentSurvey .getQuestions() .get(currentSurvey.getQuestions().size() - 1) .equals(question)) { ArrayList<SurveyAnswer> existingAnswers = currentSurvey.getQuestionById(questionId).getAnswers(); // if user hit back, and then forward, and answer wasn't changed if (StringUtils.join(answerStrs, ", ").equals(StringUtils.join(existingAnswers, ", ")) || currentSurvey.isComplete()) { logger.debug("user hit back and went forward, no answer was changed"); moreQuestions = true; // if the user hit "back" and changed the answer - remove all questions after it } else { ArrayList<SurveyQuestion> tempquestions = new ArrayList< SurveyQuestion>(); // Create a temp array list to transfer answered questions // remove all future answers logger.debug("user hit back and changed an answer"); // clear all questions following it int currentSurveySize = currentSurvey.getQuestions().size(); // stores number of questions int currentQuestionIndex = currentSurvey.getQuestions().indexOf(question); // gets the current question index for (int i = currentQuestionIndex + 1; i < currentSurveySize; i++) { tempquestions.add(currentSurvey.getQuestions().get(currentQuestionIndex + 1)); currentSurvey .getQuestions() .remove( currentQuestionIndex + 1); // goes through quesitons list and removes each question after it } // save answers modified/input by user into question question.setAnswers(answers); saved = true; // add new question moreQuestions = addNextQuestion(questionId, currentSurvey, templateSurvey); // check if old index and new index contain same questions in the same list int sizeofcurrentquestionslist = currentSurvey .getQuestions() .size(); // Size of new getQuestions aftre removing future questions if (currentSurvey .getQuestions() .get(sizeofcurrentquestionslist - 1) .getId() .equals(tempquestions.get(0).getId())) { currentSurvey.getQuestions().remove(sizeofcurrentquestionslist - 1); for (int y = 0; y < tempquestions.size(); y++) currentSurvey.getQuestions().add(tempquestions.get(y)); moreQuestions = addNextQuestion(questionId, currentSurvey, templateSurvey); } // if same then replace temp list with new list // if not then add the one new item. } // if user didn't go back, and requesting the next question } else { logger.debug("user hit forward, and requested the next question"); question.setAnswers(answers); saved = true; moreQuestions = addNextQuestion(questionId, currentSurvey, templateSurvey); } // finished survey if (!moreQuestions) { if (!currentSurvey.isComplete()) { SurveyAction.updateSurveyResult(currentSurvey); m.addObject("survey_completed", true); m.addObject("survey", currentSurvey); m.addObject("templateSurvey", templateSurvey); m.addObject("questionid", questionId); m.addObject("resultid", documentId); m.addObject("message", "SURVEY FINISHED - Please click END SURVEY"); m.addObject("hideObservernote", false); m.setViewName("/surveys/show_survey"); return m; } else { m.addObject("survey", currentSurvey); m.addObject("templateSurvey", templateSurvey); m.addObject("questionid", questionId); m.addObject("resultid", documentId); m.addObject("message", "End of Survey"); m.addObject("hideObservernote", false); m.setViewName("/surveys/show_survey"); return m; } } int questionIndex = currentSurvey.getQuestionIndexbyId(questionId); nextQuestionId = currentSurvey.getQuestions().get(questionIndex + 1).getId(); logger.debug("Next question id: " + nextQuestionId); // save to indivo if (saved && questionIndex % SAVE_INTERVAL == 0 && !currentSurvey.isComplete()) SurveyAction.updateSurveyResult(currentSurvey); // if answer fails validation } // end of validation answers else { m.addObject("survey", currentSurvey); m.addObject("templateSurvey", templateSurvey); m.addObject("questionid", questionId); m.addObject("resultid", documentId); if (question.getRestriction() != null && question.getRestriction().getInstruction() != null) m.addObject("message", question.getRestriction().getInstruction()); m.addObject("hideObservernote", false); m.setViewName("/surveys/show_survey"); return m; } // if answer not specified, and hit forward } else errMsg = "You must supply an answer"; } // end of forward action else if (direction.equalsIgnoreCase("backward")) { int questionIndex = currentSurvey.getQuestionIndexbyId(questionId); if (questionIndex > 0) nextQuestionId = currentSurvey.getQuestions().get(questionIndex - 1).getId(); } // backward to the description page(before the first qustion) if ((questionId != null) && ("backward".equals(direction)) && (isFirstQuestionId(questionId, '0'))) m.addObject("hideObservernote", true); else m.addObject("hideObservernote", false); m.addObject("survey", currentSurvey); m.addObject("templateSurvey", templateSurvey); m.addObject("questionid", nextQuestionId); m.addObject("resultid", documentId); if (errMsg != null) m.addObject("message", errMsg); m.setViewName("/surveys/show_survey"); return m; }