Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dbupdates/patch20180724.sql =================================================================== diff -u --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dbupdates/patch20180724.sql (revision 0) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dbupdates/patch20180724.sql (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -0,0 +1,23 @@ +-- Turn off autocommit, so nothing is committed if there is an error +SET AUTOCOMMIT = 0; +SET FOREIGN_KEY_CHECKS=0; +----------------------Put all sql statements below here------------------------- + +-- LDEV-4440 Change tool access URLs after migration to Spring MVC +UPDATE lams_tool SET + author_url = 'tool/lamc11/authoring/authoring.do', + learner_url = 'tool/lamc11/learning/learner.do', + learner_preview_url = 'tool/lamc11/learning/author.do', + learner_progress_url = 'tool/lamc11/learning/teacher.do', + monitor_url = 'tool/lamc11/monitoring/monitoring.do', + pedagogical_planner_url = 'tool/lamc11/pedagogicalPlanner/initPedagogicalPlannerForm.do' +WHERE tool_signature = 'lamc11'; + +UPDATE lams_tool SET tool_version='20180724' WHERE tool_signature='lamc11'; + +----------------------Put all sql statements above here------------------------- + +-- If there were no errors, commit and restore autocommit to on +COMMIT; +SET AUTOCOMMIT = 1; +SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/ClearSessionAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McLearningAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McLearningStarterAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McMonitoringAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McMonitoringStarterAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McPedagogicalPlannerAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McStarterAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/TblMonitoringAction.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/ClearSessionController.java =================================================================== diff -u --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/ClearSessionController.java (revision 0) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/ClearSessionController.java (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -0,0 +1,65 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.mc.web.controller; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.authoring.web.AuthoringConstants; +import org.lamsfoundation.lams.authoring.web.LamsAuthoringFinishController; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.mc.McAppConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.WebApplicationContext; + +/** + * This class give a chance to clear HttpSession when user save/close authoring page. + */ +@Controller +public class ClearSessionController extends LamsAuthoringFinishController implements McAppConstants { + private static Logger logger = Logger.getLogger(ClearSessionController.class.getName()); + + @Autowired + private WebApplicationContext applicationContext; + + @RequestMapping("/clearsession") + public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException { + super.execute(request, response, applicationContext); + } + + @Override + public void clearSession(String customiseSessionID, HttpSession session, ToolAccessMode mode) { + session.removeAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG); + if (mode.isAuthor()) { + ClearSessionController.logger.debug("In Author mode"); + session.removeAttribute(customiseSessionID); + } + } +} Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McController.java =================================================================== diff -u --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McController.java (revision 0) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McController.java (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -0,0 +1,826 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.mc.web.controller; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.authoring.web.AuthoringConstants; +import org.lamsfoundation.lams.questions.Answer; +import org.lamsfoundation.lams.questions.Question; +import org.lamsfoundation.lams.questions.QuestionExporter; +import org.lamsfoundation.lams.questions.QuestionParser; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.mc.McAppConstants; +import org.lamsfoundation.lams.tool.mc.dto.McOptionDTO; +import org.lamsfoundation.lams.tool.mc.dto.McQuestionDTO; +import org.lamsfoundation.lams.tool.mc.pojos.McContent; +import org.lamsfoundation.lams.tool.mc.pojos.McQueContent; +import org.lamsfoundation.lams.tool.mc.service.IMcService; +import org.lamsfoundation.lams.tool.mc.util.AuthoringUtil; +import org.lamsfoundation.lams.tool.mc.web.form.McAuthoringForm; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Action class that controls the logic of tool behavior. + * + * @author Ozgur Demirtas + */ +@Controller +@RequestMapping("/authoring") +public class McController { + + private static Logger logger = Logger.getLogger(McController.class.getName()); + + @Autowired + @Qualifier("mcService") + private IMcService mcService; + + @Autowired + @Qualifier("lamcMessageService") + private static MessageService messageService; + + @RequestMapping("/authoring") + public String execute(@ModelAttribute McAuthoringForm mcAuthoringForm, HttpServletRequest request) { + + SessionMap sessionMap = new SessionMap<>(); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + String sessionMapId = sessionMap.getSessionID(); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + sessionMap.put(AttributeNames.PARAM_CONTENT_FOLDER_ID, contentFolderID); + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + sessionMap.put(AttributeNames.PARAM_TOOL_CONTENT_ID, strToolContentID); + ToolAccessMode mode = WebUtil.readToolAccessModeAuthorDefaulted(request); + sessionMap.put(AttributeNames.ATTR_MODE, mode); + + // request is from monitoring module + if (mode.isTeacher()) { + mcService.setDefineLater(strToolContentID, true); + } + + if ((strToolContentID == null) || (strToolContentID.equals(""))) { + return "McErrorBox"; + } + + McContent mcContent = mcService.getMcContent(new Long(strToolContentID)); + + // if mcContent does not exist, try to use default content instead. + if (mcContent == null) { + long defaultContentID = mcService.getToolDefaultContentIdBySignature(McAppConstants.TOOL_SIGNATURE); + mcContent = mcService.getMcContent(new Long(defaultContentID)); + mcContent = McContent.newInstance(mcContent, new Long(strToolContentID)); + } + + // prepare form + mcAuthoringForm.setSln(mcContent.isShowReport() ? "1" : "0"); + mcAuthoringForm.setQuestionsSequenced(mcContent.isQuestionsSequenced() ? "1" : "0"); + mcAuthoringForm.setRandomize(mcContent.isRandomize() ? "1" : "0"); + mcAuthoringForm.setDisplayAnswersFeedback( + mcContent.isDisplayAnswers() ? "answers" : mcContent.isDisplayFeedbackOnly() ? "feedback" : "none"); + mcAuthoringForm.setShowMarks(mcContent.isShowMarks() ? "1" : "0"); + mcAuthoringForm.setUseSelectLeaderToolOuput(mcContent.isUseSelectLeaderToolOuput() ? "1" : "0"); + mcAuthoringForm.setPrefixAnswersWithLetters(mcContent.isPrefixAnswersWithLetters() ? "1" : "0"); + mcAuthoringForm.setRetries(mcContent.isRetries() ? "1" : "0"); + mcAuthoringForm.setPassmark("" + mcContent.getPassMark()); + mcAuthoringForm.setReflect(mcContent.isReflect() ? "1" : "0"); + mcAuthoringForm.setReflectionSubject(mcContent.getReflectionSubject()); + mcAuthoringForm.setTitle(mcContent.getTitle()); + mcAuthoringForm.setInstructions(mcContent.getInstructions()); + mcAuthoringForm.setEnableConfidenceLevels(mcContent.isEnableConfidenceLevels()); + + List questionDtos = AuthoringUtil.buildDefaultQuestions(mcContent); + sessionMap.put(McAppConstants.QUESTION_DTOS, questionDtos); + + List listDeletedQuestionDTOs = new ArrayList<>(); + sessionMap.put(McAppConstants.LIST_DELETED_QUESTION_DTOS, listDeletedQuestionDTOs); + + return "authoring/AuthoringTabsHolder"; + } + + /** + * submits content into the tool database + */ + @RequestMapping("/submitAllContent") + public String submitAllContent(@ModelAttribute McAuthoringForm mcAuthoringForm, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + + String sessionMapId = mcAuthoringForm.getHttpSessionID(); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + String strToolContentID = (String) sessionMap.get(AttributeNames.PARAM_TOOL_CONTENT_ID); + List questionDTOs = (List) sessionMap.get(McAppConstants.QUESTION_DTOS); + McContent mcContent = mcService.getMcContent(new Long(strToolContentID)); + ToolAccessMode mode = (ToolAccessMode) sessionMap.get(AttributeNames.ATTR_MODE); + List deletedQuestionDTOs = (List) sessionMap + .get(McAppConstants.LIST_DELETED_QUESTION_DTOS); + + if (questionDTOs.isEmpty()) { + MultiValueMap errorMap = new LinkedMultiValueMap<>(); + errorMap.add("GLOBAL", messageService.getMessage("questions.none.submitted")); + request.setAttribute("errorMap", errorMap); +// McController.logger.debug("errors saved: " + errors); + return "authoring/AuthoringTabsHolder"; + } + + // in case request is from monitoring module - prepare for recalculate User Answers + if (mode.isTeacher()) { + Set oldQuestions = mcContent.getMcQueContents(); + mcService.releaseQuestionsFromCache(mcContent); + mcService.setDefineLater(strToolContentID, false); + + // audit log the teacher has started editing activity in monitor + mcService.auditLogStartEditingActivityInMonitor(new Long(strToolContentID)); + + // recalculate User Answers + mcService.recalculateUserAnswers(mcContent, oldQuestions, questionDTOs, deletedQuestionDTOs); + } + + // remove deleted questions + for (McQuestionDTO deletedQuestionDTO : deletedQuestionDTOs) { + McQueContent removeableQuestion = mcService.getQuestionByUid(deletedQuestionDTO.getUid()); + if (removeableQuestion != null) { + // Set attempts = removeableQuestion.getMcUsrAttempts(); + // Iterator iter = attempts.iterator(); + // while (iter.hasNext()) { + // McUsrAttempt attempt = iter.next(); + // iter.remove(); + // } + // mcService.updateQuestion(removeableQuestion); + mcContent.getMcQueContents().remove(removeableQuestion); + mcService.removeMcQueContent(removeableQuestion); + } + } + + // store content + mcContent = AuthoringUtil.saveOrUpdateMcContent(mcService, request, mcContent, strToolContentID, questionDTOs); + + // store questions + mcContent = mcService.createQuestions(questionDTOs, mcContent); + + if (mcContent != null) { + // sorts the questions by the display order + List sortedQuestions = mcService.getAllQuestionsSorted(mcContent.getUid().longValue()); + int displayOrder = 1; + for (McQueContent question : sortedQuestions) { + McQueContent existingQuestion = mcService.getQuestionByUid(question.getUid()); + existingQuestion.setDisplayOrder(new Integer(displayOrder)); + mcService.saveOrUpdateMcQueContent(existingQuestion); + displayOrder++; + } + } + + request.setAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG, Boolean.TRUE); + return "authoring/AuthoringTabsHolder"; + } + + /** + * opens up an new screen within the current page for editing a question + */ + @RequestMapping("/editQuestionBox") + public String editQuestionBox(@ModelAttribute McAuthoringForm mcAuthoringForm, HttpServletRequest request) { + + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + List questionDtos = (List) sessionMap.get(McAppConstants.QUESTION_DTOS); + + Integer questionIndex = WebUtil.readIntParam(request, "questionIndex", true); + + McQuestionDTO questionDto = null; + //editing existing question + if (questionIndex != null) { + mcAuthoringForm.setQuestionIndex(questionIndex); + + //find according questionDto + for (McQuestionDTO questionDtoIter : questionDtos) { + Integer displayOrder = questionDtoIter.getDisplayOrder(); + + if ((displayOrder != null) && displayOrder.equals(questionIndex)) { + questionDto = questionDtoIter; + break; + } + } + + //adding new question + } else { + // prepare question for adding new question page + questionDto = new McQuestionDTO(); + List newOptions = new ArrayList<>(); + McOptionDTO newOption1 = new McOptionDTO(); + newOption1.setCorrect("Correct"); + McOptionDTO newOption2 = new McOptionDTO(); + newOptions.add(newOption1); + newOptions.add(newOption2); + questionDto.setOptionDtos(newOptions); + } + sessionMap.put(McAppConstants.QUESTION_DTO, questionDto); + + return "authoring/editQuestionBox"; + } + + /** + * removes a question from the questions map + */ + @RequestMapping("/removeQuestion") + public String removeQuestion(@ModelAttribute McAuthoringForm mcAuthoringForm, HttpServletRequest request) { + + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + Integer questionIndexToDelete = WebUtil.readIntParam(request, "questionIndex"); + mcAuthoringForm.setQuestionIndex(questionIndexToDelete); + + List questionDTOs = (List) sessionMap.get(McAppConstants.QUESTION_DTOS); + + //exclude Question with questionIndex From List + List tempQuestionDtos = new LinkedList<>(); + int queIndex = 0; + for (McQuestionDTO questionDTO : questionDTOs) { + + String questionText = questionDTO.getQuestion(); + Integer displayOrder = questionDTO.getDisplayOrder(); + if ((questionText != null) && !questionText.isEmpty()) { + + if (!displayOrder.equals(questionIndexToDelete)) { + ++queIndex; + questionDTO.setDisplayOrder(queIndex); + tempQuestionDtos.add(questionDTO); + + } else { + List deletedQuestionDTOs = (List) sessionMap + .get(McAppConstants.LIST_DELETED_QUESTION_DTOS); + deletedQuestionDTOs.add(questionDTO); + sessionMap.put(McAppConstants.LIST_DELETED_QUESTION_DTOS, deletedQuestionDTOs); + } + } + } + questionDTOs = tempQuestionDtos; + sessionMap.put(McAppConstants.QUESTION_DTOS, questionDTOs); + + return "authoring/itemlist"; + } + + /** + * moves a question down in the list + */ + @RequestMapping("/moveQuestionDown") + public String moveQuestionDown(@ModelAttribute McAuthoringForm mcAuthoringForm, HttpServletRequest request) { + + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + Integer questionIndex = WebUtil.readIntParam(request, "questionIndex"); + mcAuthoringForm.setQuestionIndex(questionIndex); + + List questionDTOs = (List) sessionMap.get(McAppConstants.QUESTION_DTOS); + questionDTOs = McController.swapQuestions(questionDTOs, questionIndex, "down"); + questionDTOs = McController.reorderQuestionDtos(questionDTOs); + sessionMap.put(McAppConstants.QUESTION_DTOS, questionDTOs); + + return "authoring/itemlist"; + } + + @RequestMapping("/moveQuestionUp") + public String moveQuestionUp(@ModelAttribute McAuthoringForm mcAuthoringForm, HttpServletRequest request) { + + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + Integer questionIndex = WebUtil.readIntParam(request, "questionIndex"); + mcAuthoringForm.setQuestionIndex(questionIndex); + + List questionDTOs = (List) sessionMap.get(McAppConstants.QUESTION_DTOS); + questionDTOs = McController.swapQuestions(questionDTOs, questionIndex, "up"); + questionDTOs = McController.reorderQuestionDtos(questionDTOs); + sessionMap.put(McAppConstants.QUESTION_DTOS, questionDTOs); + + return "authoring/itemlist"; + } + + /* + * swappes McQuestionDTO questions in the list. Auxiliary method for moveQuestionDown() and moveQuestionUp() + */ + private static List swapQuestions(List questionDTOs, Integer originalQuestionIndex, + String direction) { + + int replacedQuestionIndex = direction.equals("down") ? originalQuestionIndex + 1 : originalQuestionIndex - 1; + + McQuestionDTO mainQuestion = questionDTOs.get(originalQuestionIndex - 1); + McQuestionDTO replacedQuestion = questionDTOs.get(replacedQuestionIndex - 1); + if ((mainQuestion == null) || (replacedQuestion == null)) { + return questionDTOs; + } + + List questionDtos = new LinkedList<>(); + + Iterator iter = questionDTOs.iterator(); + while (iter.hasNext()) { + McQuestionDTO questionDto = iter.next(); + McQuestionDTO tempQuestion = new McQuestionDTO(); + + if ((!questionDto.getDisplayOrder().equals(originalQuestionIndex)) + && !questionDto.getDisplayOrder().equals(replacedQuestionIndex)) { + // normal copy + tempQuestion = questionDto; + + } else if (questionDto.getDisplayOrder().equals(originalQuestionIndex)) { + // move type 1 + tempQuestion = replacedQuestion; + + } else if (questionDto.getDisplayOrder().equals(replacedQuestionIndex)) { + // move type 2 + tempQuestion = mainQuestion; + } + + questionDtos.add(tempQuestion); + } + + return questionDtos; + } + + /* + * Auxiliary method for moveQuestionDown() and moveQuestionUp() + */ + private static List reorderQuestionDtos(List questionDTOs) { + List tempQuestionDtos = new LinkedList<>(); + + int queIndex = 0; + Iterator iter = questionDTOs.iterator(); + while (iter.hasNext()) { + McQuestionDTO questionDto = iter.next(); + + String question = questionDto.getQuestion(); + String feedback = questionDto.getFeedback(); + String mark = questionDto.getMark(); + + List optionDtos = questionDto.getOptionDtos(); + if ((question != null) && (!question.equals(""))) { + ++queIndex; + + questionDto.setQuestion(question); + questionDto.setDisplayOrder(queIndex); + questionDto.setFeedback(feedback); + questionDto.setOptionDtos(optionDtos); + questionDto.setMark(mark); + tempQuestionDtos.add(questionDto); + } + } + + return tempQuestionDtos; + } + + @RequestMapping("/saveQuestion") + public String saveQuestion(@ModelAttribute McAuthoringForm mcAuthoringForm, HttpServletRequest request) { + + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + String mark = request.getParameter("mark"); + + List options = McController.repopulateOptionDTOs(request, false); + + //remove blank options + List optionsWithoutEmptyOnes = new LinkedList<>(); + for (McOptionDTO optionDTO : options) { + String optionText = optionDTO.getCandidateAnswer(); + if ((optionText != null) && (optionText.length() > 0)) { + optionsWithoutEmptyOnes.add(optionDTO); + } + } + options = optionsWithoutEmptyOnes; + + List questionDTOs = (List) sessionMap.get(McAppConstants.QUESTION_DTOS); + + String newQuestion = request.getParameter("newQuestion"); + String feedback = request.getParameter("feedback"); + Integer questionIndex = WebUtil.readIntParam(request, "questionIndex", true); + mcAuthoringForm.setQuestionIndex(questionIndex); + + if ((newQuestion != null) && (newQuestion.length() > 0)) { + // adding new question + if (questionIndex == null) { + + //finding max displayOrder + int maxDisplayOrder = 0; + for (McQuestionDTO questionDTO : questionDTOs) { + int displayOrder = new Integer(questionDTO.getDisplayOrder()); + if (displayOrder > maxDisplayOrder) { + maxDisplayOrder = displayOrder; + } + } + + McQuestionDTO questionDTO = new McQuestionDTO(); + questionDTO.setQuestion(newQuestion); + questionDTO.setFeedback(feedback); + questionDTO.setDisplayOrder(maxDisplayOrder + 1); + questionDTO.setOptionDtos(options); + questionDTO.setMark(mark); + + questionDTOs.add(questionDTO); + + // updating existing question + } else { + McQuestionDTO questionDto = null; + for (McQuestionDTO questionDtoIter : questionDTOs) { + Integer displayOrder = questionDtoIter.getDisplayOrder(); + + if ((displayOrder != null) && displayOrder.equals(questionIndex)) { + questionDto = questionDtoIter; + break; + } + } + + questionDto.setQuestion(newQuestion); + questionDto.setFeedback(feedback); + questionDto.setDisplayOrder(questionIndex); + questionDto.setOptionDtos(options); + questionDto.setMark(mark); + } + } else { + // entry blank, not adding + } + + request.setAttribute(McAppConstants.QUESTION_DTOS, questionDTOs); + sessionMap.put(McAppConstants.QUESTION_DTOS, questionDTOs); + + return "authoring/itemlist"; + } + + /** + * Parses questions extracted from IMS QTI file and adds them to currently edited question. + */ + @RequestMapping("/saveQTI") + @SuppressWarnings({ "unchecked", "rawtypes" }) + public String saveQTI(HttpServletRequest request) throws IOException, ServletException { + + // big part of code was taken from addSingleQuestion() and saveQuestion() methods + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + String contentFolderID = (String) sessionMap.get(AttributeNames.PARAM_CONTENT_FOLDER_ID); + + List questionDtos = (List) sessionMap.get(McAppConstants.QUESTION_DTOS); + // proper parsing + Question[] questions = QuestionParser.parseQuestionChoiceForm(request); + + for (Question question : questions) { + // quietly do same verification as in other question-adding methods + String questionText = question.getText(); + if (StringUtils.isBlank(questionText)) { + logger.warn("Skipping a blank question."); + continue; + } + + questionText = QuestionParser.processHTMLField(questionText, false, contentFolderID, + question.getResourcesFolderPath()); + + List optionDtos = new ArrayList<>(); + String correctAnswer = null; + Integer correctAnswerScore = 1; + + if (question.getAnswers() != null) { + for (Answer answer : question.getAnswers()) { + McOptionDTO optionDto = new McOptionDTO(); + String answerText = QuestionParser.processHTMLField(answer.getText(), false, contentFolderID, + question.getResourcesFolderPath()); + if (answerText == null) { + logger.warn("Skipping a blank answer"); + continue; + } + if ((correctAnswer != null) && correctAnswer.equals(answerText)) { + logger.warn("Skipping an answer with same text as the correct answer: " + answerText); + + continue; + } + + optionDto.setCandidateAnswer(answerText); + + if ((answer.getScore() != null) && (answer.getScore() > 0)) { + if (correctAnswer == null) { + optionDto.setCorrect("Correct"); + correctAnswer = optionDto.getCandidateAnswer(); + // marks are integer numbers + correctAnswerScore = Math.min(new Double(Math.ceil(answer.getScore())).intValue(), 10); + } else { + // there can be only one correct answer in a MCQ question + logger.warn( + "Choosing only first correct answer, despite another one was found: " + answerText); + optionDto.setCorrect("Incorrect"); + } + } else { + optionDto.setCorrect("Incorrect"); + } + + optionDtos.add(optionDto); + } + } + + if (correctAnswer == null) { + logger.warn("No correct answer found for question: " + questionText); + continue; + } + + McQuestionDTO questionDto = new McQuestionDTO(); + questionDto.setDisplayOrder(questionDtos.size() + 1); + questionDto.setQuestion(questionText); + questionDto.setFeedback(QuestionParser.processHTMLField(question.getFeedback(), true, null, null)); + questionDto.setOptionDtos(optionDtos); + questionDto.setMark(correctAnswerScore.toString()); + + questionDtos.add(questionDto); + + if (logger.isDebugEnabled()) { + logger.debug("Added question: " + questionText); + } + } + + sessionMap.put(McAppConstants.QUESTION_DTOS, questionDtos); + + return "authoring/itemlist"; + } + + /** + * Prepares MC questions for QTI packing + */ + @RequestMapping("/exportQTI") + @SuppressWarnings({ "unchecked", "rawtypes" }) + public String exportQTI(HttpServletRequest request, HttpServletResponse response) { + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + List questionDtos = (List) sessionMap.get(McAppConstants.QUESTION_DTOS); + List questions = new LinkedList<>(); + + for (McQuestionDTO mcQuestion : questionDtos) { + Question question = new Question(); + + question.setType(Question.QUESTION_TYPE_MULTIPLE_CHOICE); + question.setTitle("Question " + mcQuestion.getDisplayOrder()); + question.setText(mcQuestion.getQuestion()); + question.setFeedback(mcQuestion.getFeedback()); + List answers = new ArrayList<>(); + + for (McOptionDTO mcAnswer : mcQuestion.getOptionDtos()) { + Answer answer = new Answer(); + answer.setText(mcAnswer.getCandidateAnswer()); + answer.setScore( + "Correct".equalsIgnoreCase(mcAnswer.getCorrect()) ? Float.parseFloat(mcQuestion.getMark()) : 0); + + answers.add(answer); + question.setAnswers(answers); + } + + // put the question in the right place + questions.add(mcQuestion.getDisplayOrder() - 1, question); + } + + String title = request.getParameter("title"); + QuestionExporter exporter = new QuestionExporter(title, questions.toArray(Question.QUESTION_ARRAY_TYPE)); + exporter.exportQTIPackage(request, response); + + return null; + } + + @RequestMapping("/moveCandidateUp") + public String moveCandidateUp(HttpServletRequest request) { + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + String candidateIndex = request.getParameter("candidateIndex"); + request.setAttribute("candidateIndex", candidateIndex); + + List optionDtos = McController.repopulateOptionDTOs(request, false); + + //moveAddedCandidateUp + McQuestionDTO questionDto = (McQuestionDTO) sessionMap.get(McAppConstants.QUESTION_DTO); + List listCandidates = new LinkedList<>(); + listCandidates = McController.swapOptions(optionDtos, candidateIndex, "up"); + questionDto.setOptionDtos(listCandidates); + sessionMap.put(McAppConstants.QUESTION_DTO, questionDto); + + return "authoring/candidateAnswersList"; + } + + @RequestMapping("/moveCandidateDown") + public String moveCandidateDown(HttpServletRequest request) { + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + String candidateIndex = request.getParameter("candidateIndex"); + request.setAttribute("candidateIndex", candidateIndex); + + List optionDtos = McController.repopulateOptionDTOs(request, false); + + //moveAddedCandidateDown + McQuestionDTO questionDto = (McQuestionDTO) sessionMap.get(McAppConstants.QUESTION_DTO); + List swapedOptions = new LinkedList<>(); + swapedOptions = McController.swapOptions(optionDtos, candidateIndex, "down"); + questionDto.setOptionDtos(swapedOptions); + sessionMap.put(McAppConstants.QUESTION_DTO, questionDto); + + return "authoring/candidateAnswersList"; + } + + /* + * swaps options in the list + */ + private static List swapOptions(List optionDtos, String optionIndex, String direction) { + + int intOptionIndex = new Integer(optionIndex).intValue(); + int intOriginalOptionIndex = intOptionIndex; + + int replacedOptionIndex = 0; + if (direction.equals("down")) { + replacedOptionIndex = ++intOptionIndex; + } else { + replacedOptionIndex = --intOptionIndex; + } + + McOptionDTO mainOption = AuthoringUtil.getOptionAtDisplayOrder(optionDtos, intOriginalOptionIndex); + McOptionDTO replacedOption = AuthoringUtil.getOptionAtDisplayOrder(optionDtos, replacedOptionIndex); + if ((mainOption == null) || (replacedOption == null)) { + return optionDtos; + } + + List newOptionDtos = new LinkedList<>(); + + int queIndex = 1; + for (McOptionDTO option : optionDtos) { + + McOptionDTO tempOption = new McOptionDTO(); + if ((!new Integer(queIndex).toString().equals(new Integer(intOriginalOptionIndex).toString())) + && !new Integer(queIndex).toString().equals(new Integer(replacedOptionIndex).toString())) { + // normal copy + tempOption = option; + } else if (new Integer(queIndex).toString().equals(new Integer(intOriginalOptionIndex).toString())) { + // move type 1 + tempOption = replacedOption; + } else if (new Integer(queIndex).toString().equals(new Integer(replacedOptionIndex).toString())) { + // move type 2 + tempOption = mainOption; + } + + newOptionDtos.add(tempOption); + queIndex++; + } + + return newOptionDtos; + } + + @RequestMapping("/removeCandidate") + public String removeCandidate(HttpServletRequest request) { + + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + String candidateIndexToRemove = request.getParameter("candidateIndex"); + request.setAttribute("candidateIndex", candidateIndexToRemove); + + // removeAddedCandidate + McQuestionDTO questionDto = (McQuestionDTO) sessionMap.get(McAppConstants.QUESTION_DTO); + + List optionDtos = McController.repopulateOptionDTOs(request, false); + List listFinalCandidatesDTO = new LinkedList<>(); + int caIndex = 0; + for (McOptionDTO mcOptionDTO : optionDtos) { + caIndex++; + + if (caIndex != new Integer(candidateIndexToRemove).intValue()) { + listFinalCandidatesDTO.add(mcOptionDTO); + } + } + + questionDto.setOptionDtos(listFinalCandidatesDTO); + sessionMap.put(McAppConstants.QUESTION_DTO, questionDto); + + return "authoring/candidateAnswersList"; + } + + @RequestMapping("/newCandidateBox") + public String newCandidateBox(HttpServletRequest request) { + + String sessionMapId = request.getParameter(McAppConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(sessionMapId); + request.setAttribute(McAppConstants.ATTR_SESSION_MAP_ID, sessionMapId); + + String candidateIndex = request.getParameter("candidateIndex"); + request.setAttribute("candidateIndex", candidateIndex); + + List optionDtos = McController.repopulateOptionDTOs(request, true); + + //newAddedCandidateBox + McQuestionDTO questionDto = (McQuestionDTO) sessionMap.get(McAppConstants.QUESTION_DTO); + questionDto.setOptionDtos(optionDtos); + sessionMap.put(McAppConstants.QUESTION_DTO, questionDto); + + return "authoring/candidateAnswersList"; + } + + /** + * repopulateOptionsBox + */ + private static List repopulateOptionDTOs(HttpServletRequest request, boolean isAddBlankOptions) { + + String correct = request.getParameter("correct"); + + /* check this logic again */ + int intCorrect = 0; + if (correct != null) { + intCorrect = new Integer(correct).intValue(); + } + + List optionDtos = new LinkedList<>(); + for (int i = 0; i < McAppConstants.MAX_OPTION_COUNT; i++) { + String optionText = request.getParameter("ca" + i); + Long optionUid = WebUtil.readLongParam(request, "caUid" + i, true); + + String isCorrect = "Incorrect"; + + if (i == intCorrect) { + isCorrect = "Correct"; + } + + if (optionText != null) { + McOptionDTO optionDTO = new McOptionDTO(); + optionDTO.setUid(optionUid); + optionDTO.setCandidateAnswer(optionText); + optionDTO.setCorrect(isCorrect); + optionDtos.add(optionDTO); + } + } + + if (isAddBlankOptions) { + McOptionDTO optionDTO = new McOptionDTO(); + optionDTO.setCandidateAnswer(""); + optionDTO.setCorrect("Incorrect"); + optionDtos.add(optionDTO); + } + + return optionDtos; + } + +} Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McLearningController.java =================================================================== diff -u --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McLearningController.java (revision 0) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McLearningController.java (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -0,0 +1,851 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ***********************************************************************/ + +package org.lamsfoundation.lams.tool.mc.web.controller; + +import java.io.IOException; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeMap; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.learning.web.util.LearningWebUtil; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.exception.DataMissingException; +import org.lamsfoundation.lams.tool.exception.ToolException; +import org.lamsfoundation.lams.tool.mc.McAppConstants; +import org.lamsfoundation.lams.tool.mc.dto.AnswerDTO; +import org.lamsfoundation.lams.tool.mc.dto.McGeneralLearnerFlowDTO; +import org.lamsfoundation.lams.tool.mc.pojos.McContent; +import org.lamsfoundation.lams.tool.mc.pojos.McOptsContent; +import org.lamsfoundation.lams.tool.mc.pojos.McQueContent; +import org.lamsfoundation.lams.tool.mc.pojos.McQueUsr; +import org.lamsfoundation.lams.tool.mc.pojos.McSession; +import org.lamsfoundation.lams.tool.mc.pojos.McUsrAttempt; +import org.lamsfoundation.lams.tool.mc.service.IMcService; +import org.lamsfoundation.lams.tool.mc.util.LearningUtil; +import org.lamsfoundation.lams.tool.mc.util.McComparator; +import org.lamsfoundation.lams.tool.mc.web.form.McLearningForm; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.WebApplicationContext; + +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * @author Ozgur Demirtas + */ +@Controller +@RequestMapping("/learning") +public class McLearningController { + + private static Logger logger = Logger.getLogger(McLearningController.class.getName()); + + @Autowired + @Qualifier("mcService") + private IMcService mcService; + + @Autowired + @Qualifier("lamcMessageService") + private static MessageService messageService; + + @Autowired + private WebApplicationContext applicationContext; + + @RequestMapping("/learner") + public String execute(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request) { + + mcLearningForm.setMcService(mcService); + mcLearningForm.setPassMarkApplicable(new Boolean(false).toString()); + mcLearningForm.setUserOverPassMark(new Boolean(false).toString()); + + SessionMap sessionMap = new SessionMap<>(); + List sequentialCheckedCa = new LinkedList<>(); + sessionMap.put(McAppConstants.QUESTION_AND_CANDIDATE_ANSWERS_KEY, sequentialCheckedCa); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + mcLearningForm.setHttpSessionID(sessionMap.getSessionID()); + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + mcLearningForm.setToolSessionID(new Long(toolSessionID).toString()); + + /* + * by now, we made sure that the passed tool session id exists in the db as a new record Make sure we can + * retrieve it and the relavent content + */ + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionID)); + if (mcSession == null) { + return "McErrorBox"; + } + + /* + * find out what content this tool session is referring to get the content for this tool session Each passed + * tool session id points to a particular content. Many to one mapping. + */ + McContent mcContent = mcSession.getMcContent(); + if (mcContent == null) { + MultiValueMap errorMap = new LinkedMultiValueMap<>(); + errorMap.add("GLOBAL", messageService.getMessage("error.content.doesNotExist")); + request.setAttribute("errorMap", errorMap); + return "McErrorBox"; + } + + String mode = request.getParameter(McAppConstants.MODE); + McQueUsr user = null; + if ((mode != null) && mode.equals(ToolAccessMode.TEACHER.toString())) { + // monitoring mode - user is specified in URL + // user may be null if the user was force completed. + user = getSpecifiedUser(toolSessionID, WebUtil.readIntParam(request, AttributeNames.PARAM_USER_ID, false)); + } else { + user = getCurrentUser(toolSessionID); + } + Long userID = user.getQueUsrId(); + mcLearningForm.setUserID(userID); + + /* + * Is there a deadline set? + */ + Date submissionDeadline = mcContent.getSubmissionDeadline(); + if (submissionDeadline != null) { + + HttpSession ss = SessionManager.getSession(); + UserDTO learnerDto = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone learnerTimeZone = learnerDto.getTimeZone(); + Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, submissionDeadline); + Date currentLearnerDate = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, new Date()); + request.setAttribute("submissionDeadline", submissionDeadline); + + // calculate whether submission deadline has passed, and if so forward to "submissionDeadline" + if (currentLearnerDate.after(tzSubmissionDeadline)) { + return "learning/submissionDeadline"; + } + } + + mcLearningForm.setToolContentID(mcContent.getMcContentId().toString()); + + McGeneralLearnerFlowDTO mcGeneralLearnerFlowDTO = LearningUtil.buildMcGeneralLearnerFlowDTO(mcContent); + mcGeneralLearnerFlowDTO.setTotalCountReached(new Boolean(false).toString()); + mcGeneralLearnerFlowDTO.setQuestionIndex(new Integer(1)); + + Boolean displayAnswers = mcContent.isDisplayAnswers(); + mcGeneralLearnerFlowDTO.setDisplayAnswers(displayAnswers.toString()); + mcGeneralLearnerFlowDTO.setDisplayFeedbackOnly(((Boolean) mcContent.isDisplayFeedbackOnly()).toString()); + mcGeneralLearnerFlowDTO.setReflection(new Boolean(mcContent.isReflect()).toString()); + // String reflectionSubject = McUtils.replaceNewLines(mcContent.getReflectionSubject()); + mcGeneralLearnerFlowDTO.setReflectionSubject(mcContent.getReflectionSubject()); + + NotebookEntry notebookEntry = mcService.getEntry(new Long(toolSessionID), CoreNotebookConstants.NOTEBOOK_TOOL, + McAppConstants.TOOL_SIGNATURE, userID.intValue()); + + if (notebookEntry != null) { + // String notebookEntryPresentable = McUtils.replaceNewLines(notebookEntry.getEntry()); + mcGeneralLearnerFlowDTO.setNotebookEntry(notebookEntry.getEntry()); + } + request.setAttribute(McAppConstants.MC_GENERAL_LEARNER_FLOW_DTO, mcGeneralLearnerFlowDTO); + + List learnerAnswersDTOList = mcService.getAnswersFromDatabase(mcContent, user); + request.setAttribute(McAppConstants.LEARNER_ANSWERS_DTO_LIST, learnerAnswersDTOList); + // should we show the marks for each question - we show the marks if any of the questions + // have a mark > 1. + Boolean showMarks = LearningUtil.isShowMarksOnQuestion(learnerAnswersDTOList); + mcGeneralLearnerFlowDTO.setShowMarks(showMarks.toString()); + + /* find out if the content is being modified at the moment. */ + boolean isDefineLater = mcContent.isDefineLater(); + if (isDefineLater == true) { + return "learning/defineLater"; + } + + McQueUsr groupLeader = null; + if (mcContent.isUseSelectLeaderToolOuput()) { + groupLeader = mcService.checkLeaderSelectToolForSessionLeader(user, new Long(toolSessionID)); + + // forwards to the leaderSelection page + if (groupLeader == null && !mode.equals(ToolAccessMode.TEACHER.toString())) { + + Set groupUsers = mcSession.getMcQueUsers();// mcService.getUsersBySession(new + // Long(toolSessionID).longValue()); + request.setAttribute(McAppConstants.ATTR_GROUP_USERS, groupUsers); + request.setAttribute(McAppConstants.TOOL_SESSION_ID, toolSessionID); + request.setAttribute(McAppConstants.ATTR_CONTENT, mcContent); + + return "learning/WaitForLeader"; + } + + // check if leader has submitted all answers + if (groupLeader.isResponseFinalised() && !mode.equals(ToolAccessMode.TEACHER.toString())) { + + // in case user joins the lesson after leader has answers some answers already - we need to make sure + // he has the same scratches as leader + mcService.copyAnswersFromLeader(user, groupLeader); + + user.setResponseFinalised(true); + mcService.updateMcQueUsr(user); + } + } + + sessionMap.put(McAppConstants.ATTR_GROUP_LEADER, groupLeader); + boolean isUserLeader = mcSession.isUserGroupLeader(user); + sessionMap.put(McAppConstants.ATTR_IS_USER_LEADER, isUserLeader); + sessionMap.put(AttributeNames.ATTR_MODE, mode); + sessionMap.put(McAppConstants.ATTR_CONTENT, mcContent); + request.setAttribute("sessionMapID", sessionMap.getSessionID()); + + /* user has already submitted response once OR it's a monitor - go to viewAnswers page. */ + if (user.isResponseFinalised() || mode.equals("teacher")) { + + String redirect = "redirect:/learning/viewAnswers.do"; + redirect = WebUtil.appendParameterToURL(redirect, AttributeNames.PARAM_TOOL_SESSION_ID, toolSessionID); + redirect = WebUtil.appendParameterToURL(redirect, "userID", userID.toString()); + redirect = WebUtil.appendParameterToURL(redirect, McAppConstants.MODE, mode); + redirect = WebUtil.appendParameterToURL(redirect, "httpSessionID", sessionMap.getSessionID()); + return redirect; + } + + return "learning/AnswersContent"; + } + + /** + * main content/question content management and workflow logic + * + * if the passed toolContentId exists in the db, we need to get the relevant data into the Map if not, create the + * default Map + */ + public String unspecified(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request) { + LearningUtil.saveFormRequestData(request, mcLearningForm); + return null; + } + + /** + * responds to learner activity in learner mode. + */ + @RequestMapping("/displayMc") + public String displayMc(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request, + HttpServletResponse response) throws IOException { + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + mcLearningForm.setToolSessionID(toolSessionID); + + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionID)); + + String toolContentId = mcSession.getMcContent().getMcContentId().toString(); + mcLearningForm.setToolContentID(toolContentId); + + LearningUtil.saveFormRequestData(request, mcLearningForm); + + if (mcLearningForm.getNextQuestionSelected() != null && !mcLearningForm.getNextQuestionSelected().equals("")) { + mcLearningForm.resetParameters(); + return getNextOptions(mcLearningForm, request); + } + if (mcLearningForm.getContinueOptionsCombined() != null) { + return continueOptionsCombined(mcLearningForm, request); + } else if (mcLearningForm.getNextOptions() != null) { + return getNextOptions(mcLearningForm, request); + } else if (mcLearningForm.getRedoQuestions() != null) { + return redoQuestions(mcLearningForm, request); + } else if (mcLearningForm.getViewAnswers() != null) { + return viewAnswers(mcLearningForm, request); + } else if (mcLearningForm.getSubmitReflection() != null) { + return submitReflection(mcLearningForm, request, response); + } else if (mcLearningForm.getForwardtoReflection() != null) { + return forwardtoReflection(mcLearningForm, request); + } else if (mcLearningForm.getLearnerFinished() != null) { + return endLearning(mcLearningForm, request, response); + } + + return "learning/AnswersContent"; + } + + /** + * ActionForward endLearning(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse + * response) + */ + @ModelAttribute("/endLearning") + public String endLearning(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request, + HttpServletResponse response) throws IOException { + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + mcLearningForm.setToolSessionID(toolSessionID); + + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionID)); + + String toolContentId = mcSession.getMcContent().getMcContentId().toString(); + mcLearningForm.setToolContentID(toolContentId); + + LearningUtil.saveFormRequestData(request, mcLearningForm); + // requested learner finished, the learner should be directed to next activity + + HttpSession ss = SessionManager.getSession(); + UserDTO userDto = (UserDTO) ss.getAttribute(AttributeNames.USER); + + String nextUrl = null; + try { + nextUrl = mcService.leaveToolSession(new Long(toolSessionID), userDto.getUserID().longValue()); + } catch (DataMissingException e) { + McLearningController.logger.error("failure getting nextUrl: " + e); + return "learningIndex"; + } catch (ToolException e) { + McLearningController.logger.error("failure getting nextUrl: " + e); + return "learningIndex"; + } catch (Exception e) { + McLearningController.logger.error("unknown exception getting nextUrl: " + e); + return "learningIndex"; + } + + response.sendRedirect(nextUrl); + + return null; + } + + protected List buildAnswerDtos(List answers, McContent content, HttpServletRequest request) { + + List answerDtos = new LinkedList<>(); + + for (McQueContent question : (Set) content.getMcQueContents()) { + String questionUid = question.getUid().toString(); + int questionMark = question.getMark().intValue(); + + AnswerDTO answerDto = new AnswerDTO(); + answerDto.setQuestion(question.getQuestion()); + answerDto.setDisplayOrder(question.getDisplayOrder().toString()); + answerDto.setQuestionUid(question.getUid()); + answerDto.setFeedback(question.getFeedback() != null ? question.getFeedback() : ""); + + //search for according answer + McOptsContent answerOption = null; + for (String answer : answers) { + int hyphenPosition = answer.indexOf("-"); + String answeredQuestionUid = answer.substring(0, hyphenPosition); + + if (questionUid.equals(answeredQuestionUid)) { + String answeredOptionUid = answer.substring(hyphenPosition + 1); + answerOption = question.getOptionsContentByUID(new Long(answeredOptionUid)); + answerDto.setAnswerOption(answerOption); + break; + } + } + + boolean isCorrect = (answerOption != null) && answerOption.isCorrectOption(); + answerDto.setAttemptCorrect(isCorrect); + if (isCorrect) { + answerDto.setFeedbackCorrect(question.getFeedback()); + answerDto.setMark(questionMark); + } else { + answerDto.setFeedbackIncorrect(question.getFeedback()); + answerDto.setMark(0); + } + + //handle confidence levels + if (content.isEnableConfidenceLevels()) { + int confidenceLevel = WebUtil.readIntParam(request, "confidenceLevel" + question.getUid()); + answerDto.setConfidenceLevel(confidenceLevel); + } + + answerDtos.add(answerDto); + } + + return answerDtos; + } + + /** + * responses to learner when they answer all the questions on a single page + */ + @RequestMapping("/continueOptionsCombined") + public String continueOptionsCombined(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request) { + + String httpSessionID = mcLearningForm.getHttpSessionID(); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(httpSessionID); + request.getSession().setAttribute(httpSessionID, sessionMap); + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + McSession session = mcService.getMcSessionById(new Long(toolSessionID)); + String toolContentId = session.getMcContent().getMcContentId().toString(); + McContent mcContent = mcService.getMcContent(new Long(toolContentId)); + + List answers = McLearningController.parseLearnerAnswers(mcLearningForm, request, + mcContent.isQuestionsSequenced()); + if (mcContent.isQuestionsSequenced()) { + sessionMap.put(McAppConstants.QUESTION_AND_CANDIDATE_ANSWERS_KEY, answers); + } + + mcLearningForm.resetCa(request); + + McQueUsr user = getCurrentUser(toolSessionID); + + //prohibit users from submitting answers after response is finalized but Resubmit button is not pressed (e.g. using 2 browsers) + if (user.isResponseFinalised()) { + return viewAnswers(mcLearningForm, request); + } + + /* process the answers */ + List answerDtos = buildAnswerDtos(answers, mcContent, request); + mcService.saveUserAttempt(user, answerDtos); + + //calculate total learner mark + int learnerMark = 0; + for (AnswerDTO answerDto : answerDtos) { + learnerMark += answerDto.getMark(); + } + + Integer numberOfAttempts = user.getNumberOfAttempts() + 1; + user.setNumberOfAttempts(numberOfAttempts); + user.setLastAttemptTotalMark(learnerMark); + user.setResponseFinalised(true); + mcService.updateMcQueUsr(user); + + return viewAnswers(mcLearningForm, request); + } + + /** + * takes the learner to the next set of questions + */ + @RequestMapping("/getNextOptions") + public String getNextOptions(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request) { + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionID)); + String toolContentId = mcSession.getMcContent().getMcContentId().toString(); + McContent mcContent = mcService.getMcContent(new Long(toolContentId)); + + McQueUsr user = getCurrentUser(toolSessionID); + + String httpSessionID = mcLearningForm.getHttpSessionID(); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + //prohibit users from submitting answers after response is finalized but Resubmit button is not pressed (e.g. using 2 browsers) + if (user.isResponseFinalised()) { + return viewAnswers(mcLearningForm, request); + } + + //parse learner input + List answers = McLearningController.parseLearnerAnswers(mcLearningForm, request, + mcContent.isQuestionsSequenced()); + sessionMap.put(McAppConstants.QUESTION_AND_CANDIDATE_ANSWERS_KEY, answers); + + //save user attempt + List answerDtos = buildAnswerDtos(answers, mcContent, request); + mcService.saveUserAttempt(user, answerDtos); + + List learnerAnswersDTOList = mcService.getAnswersFromDatabase(mcContent, user); + request.setAttribute(McAppConstants.LEARNER_ANSWERS_DTO_LIST, learnerAnswersDTOList); + + McGeneralLearnerFlowDTO mcGeneralLearnerFlowDTO = LearningUtil.buildMcGeneralLearnerFlowDTO(mcContent); + + Integer totalQuestionCount = mcGeneralLearnerFlowDTO.getTotalQuestionCount(); + Integer questionIndex = mcLearningForm.getQuestionIndex(); + if (totalQuestionCount.equals(questionIndex)) { + mcGeneralLearnerFlowDTO.setTotalCountReached(new Boolean(true).toString()); + } + + mcGeneralLearnerFlowDTO.setReflection(new Boolean(mcContent.isReflect()).toString()); + mcGeneralLearnerFlowDTO.setReflectionSubject(mcContent.getReflectionSubject()); + mcGeneralLearnerFlowDTO.setRetries(new Boolean(mcContent.isRetries()).toString()); + mcGeneralLearnerFlowDTO.setTotalMarksPossible(mcContent.getTotalMarksPossible()); + mcGeneralLearnerFlowDTO.setQuestionIndex(questionIndex); + request.setAttribute(McAppConstants.MC_GENERAL_LEARNER_FLOW_DTO, mcGeneralLearnerFlowDTO); + + LearningWebUtil.putActivityPositionInRequestByToolSessionId(new Long(toolSessionID), request, + applicationContext.getServletContext()); + + request.setAttribute("sessionMapID", sessionMap.getSessionID()); + + return "learning/AnswersContent"; + } + + /** + * allows the learner to view their answer history + */ + @RequestMapping("/viewAnswers") + public String viewAnswers(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request) { + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionID)); + + String toolContentId = mcSession.getMcContent().getMcContentId().toString(); + McContent mcContent = mcService.getMcContent(new Long(toolContentId)); + + String sessionMapID = mcLearningForm.getHttpSessionID(); + request.setAttribute("sessionMapID", sessionMapID); + + McGeneralLearnerFlowDTO mcGeneralLearnerFlowDTO = LearningUtil.buildMcGeneralLearnerFlowDTO(mcContent); + + Map mapQuestionsUidContent = new TreeMap(new McComparator()); + if (mcContent != null) { + List list = mcService.refreshQuestionContent(mcContent.getUid()); + + Iterator listIterator = list.iterator(); + Long mapIndex = new Long(1); + while (listIterator.hasNext()) { + McQueContent mcQueContent = (McQueContent) listIterator.next(); + mapQuestionsUidContent.put(mapIndex.toString(), mcQueContent.getUid()); + mapIndex = new Long(mapIndex.longValue() + 1); + } + } + + //builds a map to hold all the candidate answers for all the questions by accessing the db + Map mapStartupGeneralOptionsContent = new TreeMap(new McComparator()); + Iterator itMap = mapQuestionsUidContent.entrySet().iterator(); + Long mapIndex = new Long(1); + while (itMap.hasNext()) { + Map.Entry pairs = (Map.Entry) itMap.next(); + String currentQuestionUid = pairs.getValue().toString(); + List listQuestionOptions = mcService.findOptionsByQuestionUid(new Long(currentQuestionUid)); + + //builds a questions map from questions list + Map mapOptsContent = new TreeMap<>(); + Iterator iter = listQuestionOptions.iterator(); + int mapIndex2 = 0; + while (iter.hasNext()) { + McOptsContent option = iter.next(); + String stringIndex = mcContent.isPrefixAnswersWithLetters() ? option.formatPrefixLetter(mapIndex2++) + : Integer.toString(++mapIndex2); + mapOptsContent.put(stringIndex, option.getMcQueOptionText()); + } + + mapStartupGeneralOptionsContent.put(mapIndex.toString(), mapOptsContent); + mapIndex = new Long(mapIndex.longValue() + 1); + } + mcGeneralLearnerFlowDTO.setMapGeneralOptionsContent(mapStartupGeneralOptionsContent); + + //builds a map to hold question texts + Map mapQuestionsContent = new TreeMap(new McComparator()); + List list = mcService.refreshQuestionContent(mcContent.getUid()); + Iterator iter = list.iterator(); + Long mapIndex3 = new Long(1); + while (iter.hasNext()) { + McQueContent question = (McQueContent) iter.next(); + mapQuestionsContent.put(mapIndex3.toString(), question.getQuestion()); + mapIndex3 = new Long(mapIndex3.longValue() + 1); + } + mcGeneralLearnerFlowDTO.setMapQuestionsContent(mapQuestionsContent); + + //rebuildFeedbackMapfromDB + Map mapFeedbackContent = new TreeMap(new McComparator()); + List list2 = mcService.refreshQuestionContent(mcContent.getUid()); + Iterator iter2 = list2.iterator(); + Long mapIndex4 = new Long(1); + while (iter2.hasNext()) { + McQueContent question = (McQueContent) iter2.next(); + + String feedback = question.getFeedback(); + + mapFeedbackContent.put(mapIndex4.toString(), feedback); + mapIndex4 = new Long(mapIndex4.longValue() + 1); + } + mcGeneralLearnerFlowDTO.setMapFeedbackContent(mapFeedbackContent); + + McQueUsr user = getCurrentUser(toolSessionID); + + Long toolContentUID = mcContent.getUid(); + + //create attemptMap for displaying on jsp + Map attemptMap = new TreeMap(new McComparator()); + for (int i = 1; i <= mcContent.getMcQueContents().size(); i++) { + McQueContent question = mcService.getQuestionByDisplayOrder(new Long(i), toolContentUID); + + McUsrAttempt userAttempt = mcService.getUserAttemptByQuestion(user.getUid(), question.getUid()); + + if (userAttempt != null) { + attemptMap.put(new Integer(i).toString(), userAttempt); + } + } + mcGeneralLearnerFlowDTO.setAttemptMap(attemptMap); + mcGeneralLearnerFlowDTO.setReflection(new Boolean(mcContent.isReflect()).toString()); + mcGeneralLearnerFlowDTO.setReflectionSubject(mcContent.getReflectionSubject()); + + NotebookEntry notebookEntry = mcService.getEntry(new Long(toolSessionID), CoreNotebookConstants.NOTEBOOK_TOOL, + McAppConstants.TOOL_SIGNATURE, new Integer(user.getQueUsrId().intValue())); + request.setAttribute("notebookEntry", notebookEntry); + if (notebookEntry != null) { + mcGeneralLearnerFlowDTO.setNotebookEntry(notebookEntry.getEntry()); + } + + mcGeneralLearnerFlowDTO.setRetries(new Boolean(mcContent.isRetries()).toString()); + mcGeneralLearnerFlowDTO.setPassMarkApplicable(new Boolean(mcContent.isPassMarkApplicable()).toString()); + mcGeneralLearnerFlowDTO.setUserOverPassMark(new Boolean(user.isLastAttemptMarkPassed()).toString()); + mcGeneralLearnerFlowDTO.setTotalMarksPossible(mcContent.getTotalMarksPossible()); + mcGeneralLearnerFlowDTO.setShowMarks(new Boolean(mcContent.isShowMarks()).toString()); + mcGeneralLearnerFlowDTO.setDisplayAnswers(new Boolean(mcContent.isDisplayAnswers()).toString()); + mcGeneralLearnerFlowDTO.setDisplayFeedbackOnly(((Boolean) mcContent.isDisplayFeedbackOnly()).toString()); + mcGeneralLearnerFlowDTO.setLearnerMark(user.getLastAttemptTotalMark()); + + Object[] markStatistics = null; + if (mcContent.isShowMarks()) { + markStatistics = mcService.getMarkStatistics(mcSession); + } + if (markStatistics != null) { + mcGeneralLearnerFlowDTO + .setLowestMark(markStatistics[0] != null ? ((Float) markStatistics[0]).intValue() : 0); + mcGeneralLearnerFlowDTO + .setAverageMark(markStatistics[1] != null ? ((Float) markStatistics[1]).intValue() : 0); + mcGeneralLearnerFlowDTO.setTopMark(markStatistics[2] != null ? ((Float) markStatistics[2]).intValue() : 0); + } else { + mcGeneralLearnerFlowDTO.setLowestMark(0); + mcGeneralLearnerFlowDTO.setAverageMark(0); + mcGeneralLearnerFlowDTO.setTopMark(0); + } + + request.setAttribute(McAppConstants.MC_GENERAL_LEARNER_FLOW_DTO, mcGeneralLearnerFlowDTO); + + LearningWebUtil.putActivityPositionInRequestByToolSessionId(new Long(toolSessionID), request, + applicationContext.getServletContext()); + + return "learning/ViewAnswers"; + } + + @RequestMapping("/redoQuestions") + public String redoQuestions(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request) { + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionID)); + String toolContentId = mcSession.getMcContent().getMcContentId().toString(); + McContent mcContent = mcService.getMcContent(new Long(toolContentId)); + McQueUsr mcQueUsr = getCurrentUser(toolSessionID); + + //in order to track whether redo button is pressed store this info + mcQueUsr.setResponseFinalised(false); + mcService.updateMcQueUsr(mcQueUsr); + + //clear sessionMap + String httpSessionID = mcLearningForm.getHttpSessionID(); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(httpSessionID); + List sequentialCheckedCa = new LinkedList<>(); + sessionMap.put(McAppConstants.QUESTION_AND_CANDIDATE_ANSWERS_KEY, sequentialCheckedCa); + + List learnerAnswersDTOList = mcService.getAnswersFromDatabase(mcContent, mcQueUsr); + request.setAttribute(McAppConstants.LEARNER_ANSWERS_DTO_LIST, learnerAnswersDTOList); + + McGeneralLearnerFlowDTO mcGeneralLearnerFlowDTO = LearningUtil.buildMcGeneralLearnerFlowDTO(mcContent); + mcGeneralLearnerFlowDTO.setQuestionIndex(new Integer(1)); + mcGeneralLearnerFlowDTO.setReflection(new Boolean(mcContent.isReflect()).toString()); + mcGeneralLearnerFlowDTO.setReflectionSubject(mcContent.getReflectionSubject()); + mcGeneralLearnerFlowDTO.setRetries(new Boolean(mcContent.isRetries()).toString()); + + String passMarkApplicable = new Boolean(mcContent.isPassMarkApplicable()).toString(); + mcGeneralLearnerFlowDTO.setPassMarkApplicable(passMarkApplicable); + mcLearningForm.setPassMarkApplicable(passMarkApplicable); + + String userOverPassMark = Boolean.FALSE.toString(); + mcGeneralLearnerFlowDTO.setUserOverPassMark(userOverPassMark); + mcLearningForm.setUserOverPassMark(userOverPassMark); + + mcGeneralLearnerFlowDTO.setTotalMarksPossible(mcContent.getTotalMarksPossible()); + + // should we show the marks for each question - we show the marks if any of the questions + // have a mark > 1. + Boolean showMarks = LearningUtil.isShowMarksOnQuestion(learnerAnswersDTOList); + mcGeneralLearnerFlowDTO.setShowMarks(showMarks.toString()); + + request.setAttribute("sessionMapID", mcLearningForm.getHttpSessionID()); + + request.setAttribute(McAppConstants.MC_GENERAL_LEARNER_FLOW_DTO, mcGeneralLearnerFlowDTO); + return "learning/AnswersContent"; + } + + /** + * checks Leader Progress + */ + @RequestMapping("/checkLeaderProgress") + @ResponseBody + public String checkLeaderProgress(HttpServletRequest request, HttpServletResponse response) throws IOException { + + Long toolSessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + + McSession session = mcService.getMcSessionById(toolSessionId); + McQueUsr leader = session.getGroupLeader(); + + boolean isLeaderResponseFinalized = leader.isResponseFinalised(); + + ObjectNode ObjectNode = JsonNodeFactory.instance.objectNode(); + ObjectNode.put("isLeaderResponseFinalized", isLeaderResponseFinalized); + response.setContentType("application/x-json;charset=utf-8"); + response.getWriter().print(ObjectNode); + return null; + } + + @RequestMapping("/submitReflection") + public String submitReflection(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request, + HttpServletResponse response) throws IOException { + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + mcLearningForm.setToolSessionID(toolSessionID); + + Long userID = mcLearningForm.getUserID(); + + String reflectionEntry = request.getParameter(McAppConstants.ENTRY_TEXT); + NotebookEntry notebookEntry = mcService.getEntry(new Long(toolSessionID), CoreNotebookConstants.NOTEBOOK_TOOL, + McAppConstants.TOOL_SIGNATURE, userID.intValue()); + + if (notebookEntry != null) { + notebookEntry.setEntry(reflectionEntry); + notebookEntry.setLastModified(new Date()); + mcService.updateEntry(notebookEntry); + } else { + mcService.createNotebookEntry(new Long(toolSessionID), CoreNotebookConstants.NOTEBOOK_TOOL, + McAppConstants.TOOL_SIGNATURE, userID.intValue(), reflectionEntry); + } + + return endLearning(mcLearningForm, request, response); + } + + @RequestMapping("/forwardtoReflection") + public String forwardtoReflection(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request) { + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionID)); + + McContent mcContent = mcSession.getMcContent(); + + McGeneralLearnerFlowDTO mcGeneralLearnerFlowDTO = new McGeneralLearnerFlowDTO(); + mcGeneralLearnerFlowDTO.setActivityTitle(mcContent.getTitle()); + mcGeneralLearnerFlowDTO.setReflectionSubject(mcContent.getReflectionSubject()); + + Long userID = mcLearningForm.getUserID(); + + // attempt getting notebookEntry + NotebookEntry notebookEntry = mcService.getEntry(new Long(toolSessionID), CoreNotebookConstants.NOTEBOOK_TOOL, + McAppConstants.TOOL_SIGNATURE, userID.intValue()); + + if (notebookEntry != null) { + String notebookEntryPresentable = notebookEntry.getEntry(); + mcLearningForm.setEntryText(notebookEntryPresentable); + + } + + request.setAttribute(McAppConstants.MC_GENERAL_LEARNER_FLOW_DTO, mcGeneralLearnerFlowDTO); + + return "learning/Notebook"; + } + + /** + * auto saves responses + */ + @RequestMapping("/autoSaveAnswers") + public String autoSaveAnswers(@ModelAttribute McLearningForm mcLearningForm, HttpServletRequest request) { + + String toolSessionID = request.getParameter(AttributeNames.PARAM_TOOL_SESSION_ID); + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionID)); + McContent mcContent = mcSession.getMcContent(); + + Long userID = mcLearningForm.getUserID(); + McQueUsr user = mcService.getMcUserBySession(userID, mcSession.getUid()); + + //prohibit users from autosaving answers after response is finalized but Resubmit button is not pressed (e.g. using 2 browsers) + if (user.isResponseFinalised()) { + return null; + } + + List answers = McLearningController.parseLearnerAnswers(mcLearningForm, request, + mcContent.isQuestionsSequenced()); + + List answerDtos = buildAnswerDtos(answers, mcContent, request); + mcService.saveUserAttempt(user, answerDtos); + + return null; + } + + private static List parseLearnerAnswers(McLearningForm mcLearningForm, HttpServletRequest request, + boolean isQuestionsSequenced) { + String httpSessionID = mcLearningForm.getHttpSessionID(); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(httpSessionID); + + List answers = new LinkedList<>(); + if (isQuestionsSequenced) { + + List previousAnswers = (List) sessionMap + .get(McAppConstants.QUESTION_AND_CANDIDATE_ANSWERS_KEY); + answers.addAll(previousAnswers); + + /* checkedCa refers to candidate answers */ + String[] checkedCa = mcLearningForm.getCheckedCa(); + + if (checkedCa != null) { + for (int i = 0; i < checkedCa.length; i++) { + String currentCa = checkedCa[i]; + answers.add(currentCa); + } + } + + } else { + Map parameters = request.getParameterMap(); + Iterator iter = parameters.keySet().iterator(); + while (iter.hasNext()) { + String key = iter.next(); + if (key.startsWith("checkedCa")) { + String currentCheckedCa = request.getParameter(key); + if (currentCheckedCa != null) { + answers.add(currentCheckedCa); + } + } + } + } + + return answers; + } + + private McQueUsr getCurrentUser(String toolSessionId) { + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionId)); + + // get back login user DTO + HttpSession ss = SessionManager.getSession(); + UserDTO toolUser = (UserDTO) ss.getAttribute(AttributeNames.USER); + Long userId = new Long(toolUser.getUserID().longValue()); + + return mcService.getMcUserBySession(userId, mcSession.getUid()); + } + + private McQueUsr getSpecifiedUser(String toolSessionId, Integer userId) { + McSession mcSession = mcService.getMcSessionById(new Long(toolSessionId)); + McQueUsr qaUser = mcService.getMcUserBySession(new Long(userId.intValue()), mcSession.getUid()); + if (qaUser == null) { + logger.error("Unable to find specified user for Q&A activity. Screens are likely to fail. SessionId=" + + new Long(toolSessionId) + " UserId=" + userId); + } + return qaUser; + } +} Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McMonitoringController.java =================================================================== diff -u --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McMonitoringController.java (revision 0) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McMonitoringController.java (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -0,0 +1,555 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ***********************************************************************/ + +package org.lamsfoundation.lams.tool.mc.web.controller; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeSet; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionMapping; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.tool.mc.McAppConstants; +import org.lamsfoundation.lams.tool.mc.dto.LeaderResultsDTO; +import org.lamsfoundation.lams.tool.mc.dto.McGeneralLearnerFlowDTO; +import org.lamsfoundation.lams.tool.mc.dto.McGeneralMonitoringDTO; +import org.lamsfoundation.lams.tool.mc.dto.McUserMarkDTO; +import org.lamsfoundation.lams.tool.mc.dto.ReflectionDTO; +import org.lamsfoundation.lams.tool.mc.dto.SessionDTO; +import org.lamsfoundation.lams.tool.mc.pojos.McContent; +import org.lamsfoundation.lams.tool.mc.pojos.McOptsContent; +import org.lamsfoundation.lams.tool.mc.pojos.McQueContent; +import org.lamsfoundation.lams.tool.mc.pojos.McQueUsr; +import org.lamsfoundation.lams.tool.mc.pojos.McSession; +import org.lamsfoundation.lams.tool.mc.pojos.McUsrAttempt; +import org.lamsfoundation.lams.tool.mc.service.IMcService; +import org.lamsfoundation.lams.tool.mc.util.McSessionComparator; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.JsonUtil; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.util.HtmlUtils; + +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * * @author Ozgur Demirtas + */ +@Controller +@RequestMapping("/monitoring") +public class McMonitoringController { + + private static Logger logger = Logger.getLogger(McMonitoringController.class.getName()); + + @Autowired + @Qualifier("mcService") + private IMcService mcService; + + @Autowired + @Qualifier("lamcMessageService") + private static MessageService messageService; + + @Autowired + private WebApplicationContext applicationContext; + + @RequestMapping("/monitoring") + @SuppressWarnings("unchecked") + public String execute(HttpServletRequest request) { + + McGeneralMonitoringDTO mcGeneralMonitoringDTO = new McGeneralMonitoringDTO(); + + String toolContentID = null; + try { + Long toolContentIDLong = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID, false); + toolContentID = toolContentIDLong.toString(); + } catch (IllegalArgumentException e) { + logger.error("Unable to start monitoring as tool content id is missing"); + throw (e); + } + + McContent mcContent = mcService.getMcContent(new Long(toolContentID)); + mcGeneralMonitoringDTO.setToolContentID(toolContentID); + mcGeneralMonitoringDTO.setActivityTitle(mcContent.getTitle()); + mcGeneralMonitoringDTO.setActivityInstructions(mcContent.getInstructions()); + + //set up sessionDTOs list + Set sessions = new TreeSet<>(new McSessionComparator()); + sessions.addAll(mcContent.getMcSessions()); + List sessionDtos = new LinkedList<>(); + for (McSession session : sessions) { + SessionDTO sessionDto = new SessionDTO(); + sessionDto.setSessionId(session.getMcSessionId()); + sessionDto.setSessionName(session.getSession_name()); + + sessionDtos.add(sessionDto); + } + request.setAttribute(McAppConstants.SESSION_DTOS, sessionDtos); + + // setting up the advanced summary + + request.setAttribute(McAppConstants.ATTR_CONTENT, mcContent); + request.setAttribute("questionsSequenced", mcContent.isQuestionsSequenced()); + request.setAttribute("enableConfidenceLevels", mcContent.isEnableConfidenceLevels()); + request.setAttribute("showMarks", mcContent.isShowMarks()); + request.setAttribute("useSelectLeaderToolOuput", mcContent.isUseSelectLeaderToolOuput()); + request.setAttribute("prefixAnswersWithLetters", mcContent.isPrefixAnswersWithLetters()); + request.setAttribute("randomize", mcContent.isRandomize()); + request.setAttribute("displayAnswers", mcContent.isDisplayAnswers()); + request.setAttribute("displayFeedbackOnly", mcContent.isDisplayFeedbackOnly()); + request.setAttribute("retries", mcContent.isRetries()); + request.setAttribute("reflect", mcContent.isReflect()); + request.setAttribute("reflectionSubject", mcContent.getReflectionSubject()); + request.setAttribute("passMark", mcContent.getPassMark()); + request.setAttribute("toolContentID", mcContent.getMcContentId()); + request.setAttribute(AttributeNames.PARAM_CONTENT_FOLDER_ID, + WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID)); + + // setting up Date and time restriction in activities + HttpSession ss = SessionManager.getSession(); + Date submissionDeadline = mcContent.getSubmissionDeadline(); + if (submissionDeadline != null) { + UserDTO learnerDto = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone learnerTimeZone = learnerDto.getTimeZone(); + Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, submissionDeadline); + request.setAttribute(McAppConstants.ATTR_SUBMISSION_DEADLINE, tzSubmissionDeadline.getTime()); + // use the unconverted time, as convertToStringForJSON() does the timezone conversion if needed + request.setAttribute(McAppConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, + DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); + } + + boolean isGroupedActivity = mcService.isGroupedActivity(new Long(mcContent.getMcContentId())); + request.setAttribute("isGroupedActivity", isGroupedActivity); + + /* this section is needed for Edit Activity screen, from here... */ + + mcGeneralMonitoringDTO.setDisplayAnswers(new Boolean(mcContent.isDisplayAnswers()).toString()); + mcGeneralMonitoringDTO.setDisplayFeedbackOnly(new Boolean(mcContent.isDisplayFeedbackOnly()).toString()); + + List reflectionsContainerDTO = mcService.getReflectionList(mcContent, null); + request.setAttribute(McAppConstants.REFLECTIONS_CONTAINER_DTO, reflectionsContainerDTO); + + request.setAttribute(McAppConstants.MC_GENERAL_MONITORING_DTO, mcGeneralMonitoringDTO); + + //count users + int countSessionComplete = 0; + int countAllUsers = 0; + Iterator iteratorSession = mcContent.getMcSessions().iterator(); + while (iteratorSession.hasNext()) { + McSession mcSession = (McSession) iteratorSession.next(); + + if (mcSession != null) { + + if (mcSession.getSessionStatus().equals(McAppConstants.COMPLETED)) { + countSessionComplete++; + } + countAllUsers += mcSession.getMcQueUsers().size(); + } + } + mcGeneralMonitoringDTO.setCountAllUsers(new Integer(countAllUsers)); + mcGeneralMonitoringDTO.setCountSessionComplete(new Integer(countSessionComplete)); + + return "monitoring/MonitoringMaincontent"; + } + + /** + * Turn on displayAnswers + */ + @RequestMapping("/displayAnswers") + public String displayAnswers(HttpServletRequest request) { + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + + McContent mcContent = mcService.getMcContent(new Long(strToolContentID)); + mcContent.setDisplayAnswers(new Boolean(true)); + mcContent.setDisplayFeedbackOnly(new Boolean(false)); + mcService.updateMc(mcContent); + + // use redirect to prevent resubmition of the same request + String redirect = "redirect:/monitoring/monitoring.do"; + redirect = WebUtil.appendParameterToURL(redirect, McAppConstants.TOOL_CONTENT_ID, strToolContentID); + redirect = WebUtil.appendParameterToURL(redirect, AttributeNames.PARAM_CONTENT_FOLDER_ID, contentFolderID); + return redirect; + } + + /** + * Turn on displayFeedbackOnly + */ + @RequestMapping("/displayFeedbackOnly") + public String displayFeedbackOnly(HttpServletRequest request) { + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + + McContent mcContent = mcService.getMcContent(new Long(strToolContentID)); + mcContent.setDisplayFeedbackOnly(new Boolean(true)); + mcService.updateMc(mcContent); + + // use redirect to prevent resubmition of the same request + String redirect = "redirect:/monitoring/monitoring.do"; + redirect = WebUtil.appendParameterToURL(redirect, McAppConstants.TOOL_CONTENT_ID, strToolContentID); + redirect = WebUtil.appendParameterToURL(redirect, AttributeNames.PARAM_CONTENT_FOLDER_ID, contentFolderID); + return redirect; + } + + /** + * allows viewing users reflection data + */ + @RequestMapping("/openNotebook") + public String openNotebook(HttpServletRequest request) { + + String userId = request.getParameter("userId"); + String userName = request.getParameter("userName"); + String sessionId = request.getParameter("sessionId"); + NotebookEntry notebookEntry = mcService.getEntry(new Long(sessionId), CoreNotebookConstants.NOTEBOOK_TOOL, + McAppConstants.TOOL_SIGNATURE, new Integer(userId)); + + McGeneralLearnerFlowDTO mcGeneralLearnerFlowDTO = new McGeneralLearnerFlowDTO(); + if (notebookEntry != null) { + // String notebookEntryPresentable = McUtils.replaceNewLines(notebookEntry.getEntry()); + mcGeneralLearnerFlowDTO.setNotebookEntry(notebookEntry.getEntry()); + mcGeneralLearnerFlowDTO.setUserName(userName); + } + + request.setAttribute(McAppConstants.MC_GENERAL_LEARNER_FLOW_DTO, mcGeneralLearnerFlowDTO); + + return "monitoring/LearnerNotebook"; + } + + /** + * downloadMarks + */ + @RequestMapping("/downloadMarks") + public String downloadMarks(HttpServletRequest request, HttpServletResponse response) throws IOException { + + Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID, false); + + McContent mcContent = mcService.getMcContent(new Long(toolContentID)); + + byte[] spreadsheet = null; + + try { + spreadsheet = mcService.prepareSessionDataSpreadsheet(mcContent); + } catch (Exception e) { + logger.error("Error preparing spreadsheet: ", e); + request.setAttribute("errorName", messageService.getMessage("error.monitoring.spreadsheet.download")); + request.setAttribute("errorMessage", e); + return "error"; + } + + // set cookie that will tell JS script that export has been finished + String downloadTokenValue = WebUtil.readStrParam(request, "downloadTokenValue"); + Cookie fileDownloadTokenCookie = new Cookie("fileDownloadToken", downloadTokenValue); + fileDownloadTokenCookie.setPath("/"); + response.addCookie(fileDownloadTokenCookie); + + // construct download file response header + OutputStream out = response.getOutputStream(); + String fileName = "lams_mcq.xls"; + String mineType = "application/vnd.ms-excel"; + String header = "attachment; filename=\"" + fileName + "\";"; + response.setContentType(mineType); + response.setHeader("Content-Disposition", header); + + // write response + try { + out.write(spreadsheet); + out.flush(); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException e) { + } + } + + return null; + } + + /** + * Set Submission Deadline + */ + @RequestMapping(path = "setSubmissionDeadline", produces = MediaType.TEXT_PLAIN_VALUE) + @ResponseBody + public String setSubmissionDeadline(HttpServletRequest request) { + + Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + McContent mcContent = mcService.getMcContent(contentID); + + Long dateParameter = WebUtil.readLongParam(request, McAppConstants.ATTR_SUBMISSION_DEADLINE, true); + Date tzSubmissionDeadline = null; + String formattedDate = ""; + if (dateParameter != null) { + Date submissionDeadline = new Date(dateParameter); + HttpSession ss = SessionManager.getSession(); + org.lamsfoundation.lams.usermanagement.dto.UserDTO teacher = (org.lamsfoundation.lams.usermanagement.dto.UserDTO) ss + .getAttribute(AttributeNames.USER); + TimeZone teacherTimeZone = teacher.getTimeZone(); + tzSubmissionDeadline = DateUtil.convertFromTimeZoneToDefault(teacherTimeZone, submissionDeadline); + formattedDate = DateUtil.convertToStringForJSON(tzSubmissionDeadline, request.getLocale()); + } + mcContent.setSubmissionDeadline(tzSubmissionDeadline); + mcService.updateMc(mcContent); + return formattedDate; + } + + /** + * Set tool's activityEvaluation + */ + @RequestMapping(path = "/setActivityEvaluation", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @ResponseBody + public String setActivityEvaluation(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException { + + Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + String activityEvaluation = WebUtil.readStrParam(request, McAppConstants.ATTR_ACTIVITY_EVALUATION); + mcService.setActivityEvaluation(contentID, activityEvaluation); + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + responseJSON.put("success", "true"); + return responseJSON.toString(); + } + + /** + * Populate user jqgrid table on summary page. + */ + @RequestMapping("/userMasterDetail") + public String userMasterDetail(HttpServletRequest request) { + + Long userUid = WebUtil.readLongParam(request, McAppConstants.USER_UID); + McQueUsr user = mcService.getMcUserByUID(userUid); + List userAttempts = mcService.getFinalizedUserAttempts(user); + + // Escapes all characters that may brake JS code on assigning Java value to JS String variable (particularly + // escapes all quotes in the following way \"). + if (userAttempts != null) { + for (McUsrAttempt userAttempt : userAttempts) { + McQueContent question = userAttempt.getMcQueContent(); + McOptsContent option = userAttempt.getMcOptionsContent(); + + String questionText = question.getQuestion(); + if (questionText != null) { + String escapedQuestion = StringEscapeUtils.escapeJavaScript(questionText); + question.setEscapedQuestion(escapedQuestion); + } + + String optionText = option.getMcQueOptionText(); + if (optionText != null) { + String escapedOptionText = StringEscapeUtils.escapeJavaScript(optionText); + option.setEscapedOptionText(escapedOptionText); + } + } + } + + request.setAttribute(McAppConstants.ATTR_CONTENT, user.getMcSession().getMcContent()); + request.setAttribute(McAppConstants.USER_ATTEMPTS, userAttempts); + request.setAttribute(McAppConstants.TOOL_SESSION_ID, user.getMcSession().getMcSessionId()); + return (userAttempts == null || userAttempts.isEmpty()) ? null : "monitoring/masterDetailLoadUp"; + } + + /** + * Return paged users for jqGrid. + */ + @RequestMapping(path = "/getPagedUsers", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @ResponseBody + public String getPagedUsers(HttpServletRequest request) { + + Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + McSession session = mcService.getMcSessionById(sessionId); + //find group leader, if any + McQueUsr groupLeader = session.getGroupLeader(); + + // Getting the params passed in from the jqGrid + int page = WebUtil.readIntParam(request, AttributeNames.PARAM_PAGE); + int rowLimit = WebUtil.readIntParam(request, AttributeNames.PARAM_ROWS); + String sortOrder = WebUtil.readStrParam(request, AttributeNames.PARAM_SORD); + String sortBy = WebUtil.readStrParam(request, AttributeNames.PARAM_SIDX, true); + if (StringUtils.isEmpty(sortBy)) { + sortBy = "userName"; + } + String searchString = WebUtil.readStrParam(request, "userName", true); + + List userDtos = new ArrayList<>(); + int countVisitLogs = 0; + //in case of UseSelectLeaderToolOuput - display only one user + if (groupLeader != null) { + + Integer totalMark = groupLeader.getLastAttemptTotalMark(); + Long portraitId = mcService.getPortraitId(groupLeader.getQueUsrId()); + + McUserMarkDTO userDto = new McUserMarkDTO(); + userDto.setQueUsrId(groupLeader.getUid().toString()); + userDto.setUserId(groupLeader.getQueUsrId().toString()); + userDto.setFullName(groupLeader.getFullname()); + userDto.setTotalMark(totalMark != null ? totalMark.longValue() : null); + userDto.setPortraitId(portraitId == null ? null : portraitId.toString()); + userDtos.add(userDto); + countVisitLogs = 1; + + } else { + userDtos = mcService.getPagedUsersBySession(sessionId, page - 1, rowLimit, sortBy, sortOrder, searchString); + countVisitLogs = mcService.getCountPagedUsersBySession(sessionId, searchString); + } + + int totalPages = new Double( + Math.ceil(new Integer(countVisitLogs).doubleValue() / new Integer(rowLimit).doubleValue())).intValue(); + + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + int i = 1; + for (McUserMarkDTO userDto : userDtos) { + + ArrayNode visitLogData = JsonNodeFactory.instance.arrayNode(); + Long userUid = Long.parseLong(userDto.getQueUsrId()); + visitLogData.add(userUid); + visitLogData.add(userDto.getUserId()); + + String fullName = HtmlUtils.htmlEscape(userDto.getFullName()); + if (groupLeader != null && groupLeader.getUid().equals(userUid)) { + fullName += " (" + mcService.getLocalizedMessage("label.monitoring.group.leader") + ")"; + } + + visitLogData.add(fullName); + Long totalMark = (userDto.getTotalMark() == null) ? 0 : userDto.getTotalMark(); + visitLogData.add(totalMark); + + visitLogData.add(userDto.getPortraitId()); + + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); + userRow.put("id", i++); + userRow.set("cell", visitLogData); + + rows.add(userRow); + } + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + responseJSON.put("total", totalPages); + responseJSON.put("page", page); + responseJSON.put("records", countVisitLogs); + responseJSON.set("rows", rows); + + return responseJSON.toString(); + } + + @RequestMapping("/saveUserMark") + public String saveUserMark(HttpServletRequest request) { + + if ((request.getParameter(McAppConstants.PARAM_NOT_A_NUMBER) == null) + && !StringUtils.isEmpty(request.getParameter(McAppConstants.PARAM_USER_ATTEMPT_UID))) { + + Long userAttemptUid = WebUtil.readLongParam(request, McAppConstants.PARAM_USER_ATTEMPT_UID); + Integer newGrade = Integer.valueOf(request.getParameter(McAppConstants.PARAM_GRADE)); + mcService.changeUserAttemptMark(userAttemptUid, newGrade); + } + + return null; + } + + /** + * Get the mark summary with data arranged in bands. Can be displayed graphically or in a table. + */ + @RequestMapping(path = "/getMarkChartData", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @ResponseBody + public String getMarkChartData(HttpServletRequest request) throws IOException { + + Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + McContent mcContent = mcService.getMcContent(contentID); + List results = null; + + if (mcContent != null) { + if (mcContent.isUseSelectLeaderToolOuput()) { + results = mcService.getMarksArrayForLeaders(contentID); + } else { + Long sessionID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + results = mcService.getMarksArray(sessionID); + } + } + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + if (results != null) { + responseJSON.set("data", JsonUtil.readArray(results)); + } else { + responseJSON.set("data", JsonUtil.readArray(new Float[0])); + } + + return responseJSON.toString(); + + } + + @RequestMapping("/statistic") + public String statistic(HttpServletRequest request) { + + Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + request.setAttribute(AttributeNames.PARAM_TOOL_CONTENT_ID, contentID); + McContent mcContent = mcService.getMcContent(contentID); + if (mcContent != null) { + if (mcContent.isUseSelectLeaderToolOuput()) { + LeaderResultsDTO leaderDto = mcService.getLeaderResultsDTOForLeaders(contentID); + request.setAttribute("leaderDto", leaderDto); + } else { + List sessionDtos = mcService.getSessionDtos(contentID, true); + request.setAttribute("sessionDtos", sessionDtos); + } + request.setAttribute("useSelectLeaderToolOutput", mcContent.isUseSelectLeaderToolOuput()); + } + + // prepare toolOutputDefinitions and activityEvaluation + List toolOutputDefinitions = new ArrayList<>(); + toolOutputDefinitions.add(McAppConstants.OUTPUT_NAME_LEARNER_MARK); + toolOutputDefinitions.add(McAppConstants.OUTPUT_NAME_LEARNER_ALL_CORRECT); + String activityEvaluation = mcService.getActivityEvaluation(contentID); + request.setAttribute(McAppConstants.ATTR_TOOL_OUTPUT_DEFINITIONS, toolOutputDefinitions); + request.setAttribute(McAppConstants.ATTR_ACTIVITY_EVALUATION, activityEvaluation); + + return "monitoring/parts/statsPart"; + } + +} Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McPedagogicalPlannerController.java =================================================================== diff -u --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McPedagogicalPlannerController.java (revision 0) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McPedagogicalPlannerController.java (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -0,0 +1,183 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.mc.web.controller; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.lamsfoundation.lams.tool.mc.McAppConstants; +import org.lamsfoundation.lams.tool.mc.dto.McOptionDTO; +import org.lamsfoundation.lams.tool.mc.pojos.McContent; +import org.lamsfoundation.lams.tool.mc.pojos.McOptsContent; +import org.lamsfoundation.lams.tool.mc.pojos.McQueContent; +import org.lamsfoundation.lams.tool.mc.service.IMcService; +import org.lamsfoundation.lams.tool.mc.web.form.McPedagogicalPlannerForm; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/pedagogicalPlanner") +public class McPedagogicalPlannerController { + + @Autowired + @Qualifier("mcService") + private IMcService mcService; + + @Autowired + @Qualifier("lamcMessageService") + private static MessageService messageService; + + protected String unspecified(@ModelAttribute McPedagogicalPlannerForm plannerForm, HttpServletRequest request) { + return initPedagogicalPlannerForm(plannerForm, request); + } + + @RequestMapping("/initPedagogicalPlannerForm") + public String initPedagogicalPlannerForm(@ModelAttribute McPedagogicalPlannerForm plannerForm, + HttpServletRequest request) { + + Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + McContent mcContent = mcService.getMcContent(toolContentID); + plannerForm.fillForm(mcContent, mcService); + return "authoring/pedagogicalPlannerForm"; + } + + @RequestMapping("/saveOrUpdatePedagogicalPlannerForm") + public String saveOrUpdatePedagogicalPlannerForm(@ModelAttribute McPedagogicalPlannerForm plannerForm, + HttpServletRequest request) throws IOException { + + MultiValueMap errorMap = plannerForm.validate(request); + + if (errorMap.isEmpty()) { + McContent mcContent = mcService.getMcContent(plannerForm.getToolContentID()); + int questionIndex = 1; + String question = null; + + do { + question = plannerForm.getQuestion(questionIndex - 1); + List candidateAnswerDTOList = plannerForm.extractCandidateAnswers(request, questionIndex); + boolean removeQuestion = true; + if (!StringUtils.isEmpty(question)) { + if (candidateAnswerDTOList != null) { + for (McOptionDTO answer : candidateAnswerDTOList) { + if (answer != null && !StringUtils.isEmpty(answer.getCandidateAnswer())) { + removeQuestion = false; + break; + } + } + } + } + if (removeQuestion) { + plannerForm.removeQuestion(questionIndex - 1); + } else { + if (questionIndex <= mcContent.getMcQueContents().size()) { + McQueContent mcQueContent = mcService.getQuestionByDisplayOrder((long) questionIndex, + mcContent.getUid()); + mcQueContent.setQuestion(question); + int candidateAnswerDTOIndex = 0; + Set candidateAnswers = mcQueContent.getMcOptionsContents(); + Iterator candidateAnswerIter = candidateAnswers.iterator(); + while (candidateAnswerIter.hasNext()) { + McOptsContent candidateAnswer = candidateAnswerIter.next(); + if (candidateAnswerDTOIndex >= candidateAnswerDTOList.size()) { + candidateAnswerIter.remove(); + } else { + McOptionDTO answerDTO = candidateAnswerDTOList.get(candidateAnswerDTOIndex); + candidateAnswer.setCorrectOption(McAppConstants.CORRECT.equals(answerDTO.getCorrect())); + candidateAnswer.setMcQueOptionText(answerDTO.getCandidateAnswer()); + mcService.updateMcOptionsContent(candidateAnswer); + } + candidateAnswerDTOIndex++; + } + mcService.saveOrUpdateMcQueContent(mcQueContent); + } else { + McQueContent mcQueContent = new McQueContent(); + mcQueContent.setDisplayOrder(questionIndex); + mcQueContent.setMcContent(mcContent); + mcQueContent.setMcContentId(mcContent.getMcContentId()); + mcQueContent.setQuestion(question); + mcQueContent.setMark(McAppConstants.QUESTION_DEFAULT_MARK); + Set candidateAnswers = mcQueContent.getMcOptionsContents(); + for (int candidateAnswerDTOIndex = 0; candidateAnswerDTOIndex < candidateAnswerDTOList + .size(); candidateAnswerDTOIndex++) { + McOptionDTO answerDTO = candidateAnswerDTOList.get(candidateAnswerDTOIndex); + McOptsContent candidateAnswer = new McOptsContent(candidateAnswerDTOIndex + 1, + McAppConstants.CORRECT.equals(answerDTO.getCorrect()), + answerDTO.getCandidateAnswer(), mcQueContent); + candidateAnswer.setMcQueContentId(mcQueContent.getMcContentId()); + candidateAnswers.add(candidateAnswer); + } + mcService.saveOrUpdateMcQueContent(mcQueContent); + mcContent.getMcQueContents().add(mcQueContent); + } + questionIndex++; + } + } while (questionIndex <= plannerForm.getQuestionCount()); + for (; questionIndex <= mcContent.getMcQueContents().size(); questionIndex++) { + McQueContent mcQueContent = mcService.getQuestionByDisplayOrder((long) questionIndex, + mcContent.getUid()); + mcContent.getMcQueContents().remove(mcQueContent); + mcService.removeMcQueContent(mcQueContent); + } + plannerForm.fillForm(mcContent, mcService); + } else { + request.setAttribute("errorMap", errorMap); + } + return "authoring/pedagogicalPlannerForm"; + } + + @RequestMapping("/createPedagogicalPlannerQuestion") + public String createPedagogicalPlannerQuestion(@ModelAttribute McPedagogicalPlannerForm plannerForm, + HttpServletRequest request) { + + int questionDisplayOrder = plannerForm.getQuestionCount().intValue() + 1; + plannerForm.setCandidateAnswerCount(new ArrayList(plannerForm.getQuestionCount())); + Map paramMap = request.getParameterMap(); + for (int questionIndex = 1; questionIndex < questionDisplayOrder; questionIndex++) { + String[] param = paramMap.get(McAppConstants.CANDIDATE_ANSWER_COUNT + questionIndex); + int count = NumberUtils.toInt(param[0]); + plannerForm.getCandidateAnswerCount().add(count); + } + plannerForm.setQuestion(questionDisplayOrder - 1, ""); + plannerForm.getCandidateAnswerCount().add(McAppConstants.CANDIDATE_ANSWER_DEFAULT_COUNT); + plannerForm.setCorrect(questionDisplayOrder - 1, "1"); + + return "authoring/pedagogicalPlannerForm"; + } + +} \ No newline at end of file Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/TblMonitoringController.java =================================================================== diff -u --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/TblMonitoringController.java (revision 0) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/TblMonitoringController.java (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -0,0 +1,127 @@ +package org.lamsfoundation.lams.tool.mc.web.controller; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.tool.mc.dto.McOptionDTO; +import org.lamsfoundation.lams.tool.mc.dto.McQuestionDTO; +import org.lamsfoundation.lams.tool.mc.pojos.McContent; +import org.lamsfoundation.lams.tool.mc.pojos.McOptsContent; +import org.lamsfoundation.lams.tool.mc.pojos.McQueContent; +import org.lamsfoundation.lams.tool.mc.pojos.McQueUsr; +import org.lamsfoundation.lams.tool.mc.pojos.McSession; +import org.lamsfoundation.lams.tool.mc.pojos.McUsrAttempt; +import org.lamsfoundation.lams.tool.mc.service.IMcService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/tblmonitoring") +public class TblMonitoringController { + + private static Logger logger = Logger.getLogger(TblMonitoringController.class.getName()); + + @Autowired + @Qualifier("mcService") + private IMcService mcService; + + /** + * Shows iRA page in case of MCQ activity + */ + @RequestMapping("/iraMcq") + public String iraMcq(HttpServletRequest request) { + + long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + McContent mcContent = mcService.getMcContent(toolContentId); + + int attemptedLearnersNumber = 0; + for (McSession session : (Set) mcContent.getMcSessions()) { + attemptedLearnersNumber += session.getMcQueUsers().size(); + } + request.setAttribute("attemptedLearnersNumber", attemptedLearnersNumber); + + request.setAttribute("questions", mcContent.getMcQueContents()); + return "tblmonitoring/mcq"; + } + + /** + * Shows ira StudentChoices page + */ + @RequestMapping("/mcqStudentChoices") + public String mcqStudentChoices(HttpServletRequest request) { + + long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + McContent mcContent = mcService.getMcContent(toolContentId); + + // ======================================================= Report by question IRA page + // ======================================= + + Set questions = mcContent.getMcQueContents(); + int maxOptionsInQuestion = 0; + for (McQueContent question : questions) { + if (question.getMcOptionsContents().size() > maxOptionsInQuestion) { + maxOptionsInQuestion = question.getMcOptionsContents().size(); + } + } + request.setAttribute("maxOptionsInQuestion", maxOptionsInQuestion); + + int totalNumberOfUsers = 0; + for (McSession session : (Set) mcContent.getMcSessions()) { + totalNumberOfUsers += session.getMcQueUsers().size(); + } + + ArrayList questionDtos = new ArrayList<>(); + for (McQueContent question : questions) { + + // build candidate dtos + List optionDtos = new LinkedList<>(); + for (McOptsContent option : (Set) question.getMcOptionsContents()) { + int optionAttemptCount = mcService.getAttemptsCountPerOption(option.getUid()); + + float percentage = (float) (optionAttemptCount * 100) / totalNumberOfUsers; + + McOptionDTO optionDTO = new McOptionDTO(option); + optionDTO.setPercentage(percentage); + optionDtos.add(optionDTO); + } + + McQuestionDTO questionDto = new McQuestionDTO(); + questionDto.setUid(question.getUid()); + questionDto.setQuestion(question.getQuestion()); + questionDto.setOptionDtos(optionDtos); + + questionDtos.add(questionDto); + } + request.setAttribute("questionDtos", questionDtos); + + request.setAttribute(AttributeNames.PARAM_TOOL_CONTENT_ID, toolContentId); + return "tblmonitoring/mcqStudentChoices"; + } + + /** + * Get ModalDialog for Teams tab. + */ + @RequestMapping("/getModalDialogForTeamsTab") + public String getModalDialogForTeamsTab(HttpServletRequest request) { + + long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + Long userId = WebUtil.readLongParam(request, AttributeNames.PARAM_USER_ID); + + McQueUsr user = mcService.getMcUserByContentId(userId, toolContentId); + List finalizedUserAttempts = user == null ? new LinkedList<>() + : mcService.getFinalizedUserAttempts(user); + request.setAttribute("userAttempts", finalizedUserAttempts); + + return "tblmonitoring/teams"; + } + +} Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/form/McLearningForm.java =================================================================== diff -u -re4c72d9ff29d298b32927e0e1c0970b653acb86e -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/form/McLearningForm.java (.../McLearningForm.java) (revision e4c72d9ff29d298b32927e0e1c0970b653acb86e) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/form/McLearningForm.java (.../McLearningForm.java) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -33,7 +33,7 @@ * * ActionForm for the Learning environment */ -public class McLearningForm extends ActionForm { +public class McLearningForm { protected String continueOptions; protected String nextOptions; protected String continueOptionsCombined; @@ -68,7 +68,7 @@ public IMcService mcService; - public void resetCa(ActionMapping mapping, HttpServletRequest request) { + public void resetCa(HttpServletRequest request) { checkedCa = new String[0]; } Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/form/McPedagogicalPlannerForm.java =================================================================== diff -u -r4170df8bc66e658ef4dcd47e99eceddec3c2673a -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/form/McPedagogicalPlannerForm.java (.../McPedagogicalPlannerForm.java) (revision 4170df8bc66e658ef4dcd47e99eceddec3c2673a) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/form/McPedagogicalPlannerForm.java (.../McPedagogicalPlannerForm.java) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -20,7 +20,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.mc.web.form; import java.io.UnsupportedEncodingException; @@ -33,26 +32,35 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; -import org.apache.struts.action.ActionMessage; -import org.apache.struts.action.ActionMessages; import org.lamsfoundation.lams.tool.mc.McAppConstants; import org.lamsfoundation.lams.tool.mc.dto.McOptionDTO; import org.lamsfoundation.lams.tool.mc.dto.McQuestionDTO; import org.lamsfoundation.lams.tool.mc.pojos.McContent; import org.lamsfoundation.lams.tool.mc.service.IMcService; import org.lamsfoundation.lams.tool.mc.util.AuthoringUtil; -import org.lamsfoundation.lams.web.planner.PedagogicalPlannerActivityForm; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.web.planner.PedagogicalPlannerActivitySpringForm; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; -public class McPedagogicalPlannerForm extends PedagogicalPlannerActivityForm { +public class McPedagogicalPlannerForm extends PedagogicalPlannerActivitySpringForm { + private static Logger logger = Logger.getLogger(McPedagogicalPlannerForm.class); + @Autowired + @Qualifier("lamcMessageService") + private static MessageService messageService; + private List question; private List candidateAnswerCount; private String candidateAnswersString; private List correct; - public ActionMessages validate(HttpServletRequest request) { - ActionMessages errors = new ActionMessages(); + public MultiValueMap validate(HttpServletRequest request) { + + MultiValueMap errorMap = new LinkedMultiValueMap<>(); boolean allEmpty = true; if (question != null && !question.isEmpty()) { @@ -63,35 +71,34 @@ List candidateAnswerList = extractCandidateAnswers(request, questionIndex); if (candidateAnswerList != null) { boolean answersEmpty = true; - ActionMessage correctAnswerBlankError = null; + String correctAnswerBlankError = null; for (McOptionDTO answer : candidateAnswerList) { if (answer != null && !StringUtils.isEmpty(answer.getCandidateAnswer())) { allEmpty = false; answersEmpty = false; } else if (McAppConstants.CORRECT.equals(answer.getCorrect())) { - correctAnswerBlankError = new ActionMessage( - "error.pedagogical.planner.empty.answer.selected", questionIndex); + correctAnswerBlankError = "error.pedagogical.planner.empty.answer.selected"; } } if (!answersEmpty && correctAnswerBlankError != null) { - errors.add(ActionMessages.GLOBAL_MESSAGE, correctAnswerBlankError); + errorMap.add("GLOBAL", + messageService.getMessage("error.pedagogical.planner.empty.answer.selected")); } } } catch (UnsupportedEncodingException e) { McPedagogicalPlannerForm.logger.error(e.getMessage()); - return errors; + return errorMap; } questionIndex++; } } } if (allEmpty) { - ActionMessage error = new ActionMessage("questions.none.submitted"); - errors.clear(); - errors.add(ActionMessages.GLOBAL_MESSAGE, error); + errorMap.clear(); + errorMap.add("GLOBAL", messageService.getMessage("questions.none.submitted")); question = null; setCandidateAnswersString(""); - } else if (!errors.isEmpty()) { + } else if (!errorMap.isEmpty()) { StringBuilder candidateAnswersBuilder = new StringBuilder(); Map paramMap = request.getParameterMap(); setCandidateAnswerCount(new ArrayList(getQuestionCount())); @@ -110,8 +117,8 @@ } } - setValid(errors.isEmpty()); - return errors; + setValid(errorMap.isEmpty()); + return errorMap; } public void fillForm(McContent mcContent, IMcService mcService) { @@ -147,7 +154,7 @@ public void setQuestion(int number, String Questions) { if (question == null) { - question = new ArrayList(); + question = new ArrayList<>(); } while (number >= question.size()) { question.add(null); @@ -189,7 +196,7 @@ int count = NumberUtils.toInt(param[0]); int correct = Integer.parseInt(getCorrect(questionIndex - 1)); - List candidateAnswerList = new ArrayList(); + List candidateAnswerList = new ArrayList<>(); for (int index = 1; index <= count; index++) { param = paramMap.get(McAppConstants.CANDIDATE_ANSWER_PREFIX + questionIndex + "-" + index); String answer = param[0]; @@ -214,7 +221,7 @@ public void setCorrect(int number, String correct) { if (this.correct == null) { - this.correct = new ArrayList(); + this.correct = new ArrayList<>(); } while (number >= this.correct.size()) { this.correct.add(null); Index: lams_tool_lamc/web/WEB-INF/spring-servlet.xml =================================================================== diff -u --- lams_tool_lamc/web/WEB-INF/spring-servlet.xml (revision 0) +++ lams_tool_lamc/web/WEB-INF/spring-servlet.xml (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -0,0 +1,17 @@ + + + + + + + + + + + \ No newline at end of file Index: lams_tool_lamc/web/WEB-INF/tags/AuthoringButton.tag =================================================================== diff -u -rc90250258ad030c59157aa61c61e47583e26df5e -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/AuthoringButton.tag (.../AuthoringButton.tag) (revision c90250258ad030c59157aa61c61e47583e26df5e) +++ lams_tool_lamc/web/WEB-INF/tags/AuthoringButton.tag (.../AuthoringButton.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -32,7 +32,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ attribute name="formID" required="true" rtexprvalue="true" %> @@ -123,11 +122,11 @@ } \ No newline at end of file Index: lams_tool_lamc/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag =================================================================== diff -u -r540199b8a30f643c2ca5960c007e5bef74acd397 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag (.../AuthoringRatingAllStyleCriteria.tag) (revision 540199b8a30f643c2ca5960c007e5bef74acd397) +++ lams_tool_lamc/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag (.../AuthoringRatingAllStyleCriteria.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -8,7 +8,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> Index: lams_tool_lamc/web/WEB-INF/tags/AuthoringRatingCriteria.tag =================================================================== diff -u -r5bdde98b1e94d44d239a50549987293714a5bef1 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/AuthoringRatingCriteria.tag (.../AuthoringRatingCriteria.tag) (revision 5bdde98b1e94d44d239a50549987293714a5bef1) +++ lams_tool_lamc/web/WEB-INF/tags/AuthoringRatingCriteria.tag (.../AuthoringRatingCriteria.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -8,7 +8,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> @@ -284,42 +283,42 @@ - - + + - - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + - - + + - - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + Index: lams_tool_lamc/web/WEB-INF/tags/CommentsAuthor.tag =================================================================== diff -u -r500ae45f4243aa718eac7436bc903b4f137a3aa7 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/CommentsAuthor.tag (.../CommentsAuthor.tag) (revision 500ae45f4243aa718eac7436bc903b4f137a3aa7) +++ lams_tool_lamc/web/WEB-INF/tags/CommentsAuthor.tag (.../CommentsAuthor.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -1,5 +1,4 @@ <%@ taglib uri="tags-core" prefix="c"%> -<%@ taglib uri="tags-html" prefix="html"%> <%@ taglib uri="tags-fmt" prefix="fmt"%> <%@ taglib uri="tags-lams" prefix="lams"%> @@ -42,23 +41,21 @@
-     -   +     +  
Index: lams_tool_lamc/web/WEB-INF/tags/Page.tag =================================================================== diff -u -rb32cbfc76a3cd150823b3696160d5fd4fa6cde84 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/Page.tag (.../Page.tag) (revision b32cbfc76a3cd150823b3696160d5fd4fa6cde84) +++ lams_tool_lamc/web/WEB-INF/tags/Page.tag (.../Page.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -4,6 +4,7 @@ <%@ taglib uri="tags-lams" prefix="lams"%> <%@ attribute name="type" required="true" rtexprvalue="true"%> +<%@ attribute name="formID" required="false" rtexprvalue="true"%> <%@ attribute name="style" required="false" rtexprvalue="true"%> <%@ attribute name="title" required="false" rtexprvalue="true"%> <%@ attribute name="titleHelpURL" required="false" rtexprvalue="true"%> @@ -88,8 +89,8 @@ - - + + ${toolForm.toolSessionID} @@ -434,4 +435,4 @@
- + \ No newline at end of file Index: lams_tool_lamc/web/WEB-INF/tags/Rating.tag =================================================================== diff -u -r35a96de80ddf8f88a34d7f75eaf71748db934044 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/Rating.tag (.../Rating.tag) (revision 35a96de80ddf8f88a34d7f75eaf71748db934044) +++ lams_tool_lamc/web/WEB-INF/tags/Rating.tag (.../Rating.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -8,7 +8,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> Index: lams_tool_lamc/web/WEB-INF/tags/StyledRating.tag =================================================================== diff -u -refa51a5d0464d96fada4e5a70f1fb86c2d726717 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/StyledRating.tag (.../StyledRating.tag) (revision efa51a5d0464d96fada4e5a70f1fb86c2d726717) +++ lams_tool_lamc/web/WEB-INF/tags/StyledRating.tag (.../StyledRating.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -8,7 +8,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> Index: lams_tool_lamc/web/WEB-INF/tags/TabBody.tag =================================================================== diff -u -r36e474218e1201198ba926e57e56c7a885db1a9f -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/TabBody.tag (.../TabBody.tag) (revision 36e474218e1201198ba926e57e56c7a885db1a9f) +++ lams_tool_lamc/web/WEB-INF/tags/TabBody.tag (.../TabBody.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -34,7 +34,6 @@ <%@ attribute name="titleKey" required="false" rtexprvalue="true"%> <%@ attribute name="page" required="false" rtexprvalue="true"%> <%@ taglib uri="tags-core" prefix="c"%> -<%@ taglib uri="tags-bean" prefix="bean"%> Index: lams_tool_lamc/web/WEB-INF/tags/TabBodyArea.tag =================================================================== diff -u -r00937d78dacc0993260d5ed7b39e4376e432cf45 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/TabBodyArea.tag (.../TabBodyArea.tag) (revision 00937d78dacc0993260d5ed7b39e4376e432cf45) +++ lams_tool_lamc/web/WEB-INF/tags/TabBodyArea.tag (.../TabBodyArea.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -30,7 +30,6 @@ %> <%@ taglib uri="tags-core" prefix="c"%> -<%@ taglib uri="tags-bean" prefix="bean"%>
Index: lams_tool_lamc/web/WEB-INF/tags/TextSearch.tag =================================================================== diff -u -rd56929f06ad90a63082d514e6521adc175f3de27 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/tags/TextSearch.tag (.../TextSearch.tag) (revision d56929f06ad90a63082d514e6521adc175f3de27) +++ lams_tool_lamc/web/WEB-INF/tags/TextSearch.tag (.../TextSearch.tag) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -32,12 +32,11 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <%@ taglib uri="tags-lams" prefix="lams" %> <%-- Required attributes --%> <%@ attribute name="sessionMapID" required="true" rtexprvalue="true" %> -<%@ attribute name="wrapInFormTag" required="true" rtexprvalue="true" %> <%-- Optional attributes --%> <%@ attribute name="action" required="false" rtexprvalue="true" %> @@ -53,10 +52,10 @@ <%-- Default value for message key --%> - + - + @@ -85,52 +84,40 @@ - -
- - -

- - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - -
- - - - - - - - - + +

+ + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
\ No newline at end of file Fisheye: Tag 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d refers to a dead (removed) revision in file `lams_tool_lamc/web/WEB-INF/validation.xml'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_lamc/web/WEB-INF/web.xml =================================================================== diff -u -rad8707a3e0b0501d651993f3da9dd0ba975f39fc -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/WEB-INF/web.xml (.../web.xml) (revision ad8707a3e0b0501d651993f3da9dd0ba975f39fc) +++ lams_tool_lamc/web/WEB-INF/web.xml (.../web.xml) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -61,35 +61,21 @@ /* + + spring + + org.springframework.web.servlet.DispatcherServlet + + 1 + + org.springframework.web.context.ContextLoaderListener - action - org.apache.struts.action.ActionServlet - - config - /WEB-INF/struts-config.xml - - - debug - 999 - - - detail - 2 - - - validate - true - - 1 - - - download org.lamsfoundation.lams.contentrepository.client.ToolDownload @@ -115,7 +101,7 @@ - action + spring *.do Index: lams_tool_lamc/web/authoring/AdvancedContent.jsp =================================================================== diff -u -r2dca74ca01cdce55ea691b9784f19ac9f528f104 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/authoring/AdvancedContent.jsp (.../AdvancedContent.jsp) (revision 2dca74ca01cdce55ea691b9784f19ac9f528f104) +++ lams_tool_lamc/web/authoring/AdvancedContent.jsp (.../AdvancedContent.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -1,10 +1,9 @@ <%@ include file="/common/taglibs.jsp"%> -
@@ -13,46 +12,46 @@
style="display:none;"> + style="display:none;"> @@ -62,29 +61,29 @@
@@ -95,12 +94,12 @@
- +
Index: lams_tool_lamc/web/authoring/AuthoringTabsHolder.jsp =================================================================== diff -u -r289926a27bdbc9bd2519e3064a85f489fc1845ec -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/authoring/AuthoringTabsHolder.jsp (.../AuthoringTabsHolder.jsp) (revision 289926a27bdbc9bd2519e3064a85f489fc1845ec) +++ lams_tool_lamc/web/authoring/AuthoringTabsHolder.jsp (.../AuthoringTabsHolder.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -24,6 +24,7 @@ document.McAuthoringForm.dispatch.value=actionMethod; document.McAuthoringForm.submit(); } + function submitModifyAuthoringQuestion(questionIndexValue, actionMethod) { document.McAuthoringForm.questionIndex.value=questionIndexValue; @@ -74,12 +75,11 @@ - - - + + - + @@ -95,14 +95,14 @@ - - + \ No newline at end of file Index: lams_tool_lamc/web/authoring/BasicContent.jsp =================================================================== diff -u -r289926a27bdbc9bd2519e3064a85f489fc1845ec -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/authoring/BasicContent.jsp (.../BasicContent.jsp) (revision 289926a27bdbc9bd2519e3064a85f489fc1845ec) +++ lams_tool_lamc/web/authoring/BasicContent.jsp (.../BasicContent.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -1,5 +1,4 @@ <%@ include file="/common/taglibs.jsp"%> - - +
- +
- +
<%@ include file="/authoring/itemlist.jsp"%>

- ?dispatch=editQuestionBox&sessionMapId=${sessionMapId}&KeepThis=true&TB_iframe=true&modal=true" +   Index: lams_tool_lamc/web/authoring/candidateAnswersList.jsp =================================================================== diff -u -r289926a27bdbc9bd2519e3064a85f489fc1845ec -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/authoring/candidateAnswersList.jsp (.../candidateAnswersList.jsp) (revision 289926a27bdbc9bd2519e3064a85f489fc1845ec) +++ lams_tool_lamc/web/authoring/candidateAnswersList.jsp (.../candidateAnswersList.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -9,7 +9,7 @@ ${candidateIndex} - ${formBean.candidateIndex} + ${mcAuthoringForm.candidateIndex} Index: lams_tool_lamc/web/authoring/editQuestionBox.jsp =================================================================== diff -u -r4e39db7121b2be70c34a77f7e53982cf9a5c4b04 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/authoring/editQuestionBox.jsp (.../editQuestionBox.jsp) (revision 4e39db7121b2be70c34a77f7e53982cf9a5c4b04) +++ lams_tool_lamc/web/authoring/editQuestionBox.jsp (.../editQuestionBox.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -29,6 +29,11 @@ target: $('#candidateArea') }); } + + function submitForm(methodName) { + var f = document.getElementById('mcAuthoringForm'); + f.action = methodName + ".do"; + f.submit(); function saveQuestion() { $("#newQuestion").val(CKEDITOR.instances.newQuestion.getData()); @@ -55,7 +60,7 @@ function submitModifyCandidate(candidateIndexValue, actionMethod) { document.McAuthoringForm.candidateIndex.value=candidateIndexValue; - submitMethod(actionMethod); + submitForm(actionMethod); } function removeCandidate(candidateIndexValue) { @@ -146,11 +151,11 @@ - - + + - +

- +
@@ -203,6 +208,6 @@
- + Index: lams_tool_lamc/web/authoring/itemlist.jsp =================================================================== diff -u -r289926a27bdbc9bd2519e3064a85f489fc1845ec -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/authoring/itemlist.jsp (.../itemlist.jsp) (revision 289926a27bdbc9bd2519e3064a85f489fc1845ec) +++ lams_tool_lamc/web/authoring/itemlist.jsp (.../itemlist.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -75,7 +75,7 @@ - ?dispatch=editQuestionBox&questionIndex=${queIndex}&sessionMapId=${sessionMapId}&KeepThis=true&TB_iframe=true&modal=true + authoring/editQuestionBox.do?questionIndex=${queIndex}&sessionMapId=${sessionMapId}&KeepThis=true&TB_iframe=true&modal=true Index: lams_tool_lamc/web/authoring/pedagogicalPlannerForm.jsp =================================================================== diff -u -r463f7b3dbb88ee41210f7170dc19dc25360cd26f -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/authoring/pedagogicalPlannerForm.jsp (.../pedagogicalPlannerForm.jsp) (revision 463f7b3dbb88ee41210f7170dc19dc25360cd26f) +++ lams_tool_lamc/web/authoring/pedagogicalPlannerForm.jsp (.../pedagogicalPlannerForm.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -40,7 +40,7 @@ function createQuestion(){ prepareFormData(); $('#pedagogicalPlannerForm').ajaxSubmit({ - url: "", + url: "", data: { sessionMapId: '${sessionMapId}' }, @@ -99,22 +99,20 @@ <%@ include file="/common/messages.jsp"%>

- - - + - - - - - + + + + +
@@ -128,18 +126,18 @@
- + ${candidateAnswerIndex}. - +
- +
-
+
\ No newline at end of file Index: lams_tool_lamc/web/common/messages.jsp =================================================================== diff -u -r00937d78dacc0993260d5ed7b39e4376e432cf45 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/common/messages.jsp (.../messages.jsp) (revision 00937d78dacc0993260d5ed7b39e4376e432cf45) +++ lams_tool_lamc/web/common/messages.jsp (.../messages.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -1,14 +1,15 @@ -<%-- Error Messages --%> - -
- - -
-
-
-
-
+<%@include file="/common/taglibs.jsp"%> +<%-- Error Messages --%> + + + + + + + + + <%-- Success Messages --%>
Index: lams_tool_lamc/web/common/taglibs.jsp =================================================================== diff -u -r5d1d1bc2d08ed13455ca34ceb5ab94e5f918855d -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/common/taglibs.jsp (.../taglibs.jsp) (revision 5d1d1bc2d08ed13455ca34ceb5ab94e5f918855d) +++ lams_tool_lamc/web/common/taglibs.jsp (.../taglibs.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -7,6 +7,7 @@ <%@ taglib uri="tags-fmt" prefix="fmt" %> <%@ taglib uri="tags-xml" prefix="x" %> <%@ taglib uri="tags-lams" prefix="lams" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> Index: lams_tool_lamc/web/learning/AnswersContent.jsp =================================================================== diff -u -r78b448706a4b92d425c6d68add1c40d82759a6c7 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/learning/AnswersContent.jsp (.../AnswersContent.jsp) (revision 78b448706a4b92d425c6d68add1c40d82759a6c7) +++ lams_tool_lamc/web/learning/AnswersContent.jsp (.../AnswersContent.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -41,7 +41,7 @@ function(){ //ajax form submit $('#learningForm').ajaxSubmit({ - url: "" + new Date().getTime(), + url: "" + new Date().getTime(), success: function() { $.growlUI(' '); } @@ -102,8 +102,8 @@ $.ajax({ async: false, - url: '', - data: 'method=checkLeaderProgress&toolSessionID=' + $("#tool-session-id").val(), + url: '', + data: 'toolSessionID=' + $("#tool-session-id").val(), dataType: 'json', type: 'post', success: function (json) { @@ -119,7 +119,7 @@ - +
@@ -144,14 +144,14 @@
- - - - - - - + + + + + + <%@ include file="/common/messages.jsp"%> @@ -171,7 +171,7 @@ - +
Index: lams_tool_lamc/web/learning/CombinedAnswersContent.jsp =================================================================== diff -u -rcc784a8f6f9919f02bce473b1909e919bc175604 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/learning/CombinedAnswersContent.jsp (.../CombinedAnswersContent.jsp) (revision cc784a8f6f9919f02bce473b1909e919bc175604) +++ lams_tool_lamc/web/learning/CombinedAnswersContent.jsp (.../CombinedAnswersContent.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -81,12 +81,12 @@
- + - + Index: lams_tool_lamc/web/learning/Notebook.jsp =================================================================== diff -u -rf78c13d077554f43a098b67854182c258b6323db -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/learning/Notebook.jsp (.../Notebook.jsp) (revision f78c13d077554f43a098b67854182c258b6323db) +++ lams_tool_lamc/web/learning/Notebook.jsp (.../Notebook.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -9,32 +9,32 @@ - +
- - - - - - - + + + + + + + - - + - + - + - +

@@ -295,26 +295,26 @@
- - - - - - + + + + + + - + - +
- + - @@ -324,19 +324,19 @@ - + - + - +
- + Index: lams_tool_lamc/web/learning/WaitForLeader.jsp =================================================================== diff -u -rf78c13d077554f43a098b67854182c258b6323db -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/learning/WaitForLeader.jsp (.../WaitForLeader.jsp) (revision f78c13d077554f43a098b67854182c258b6323db) +++ lams_tool_lamc/web/learning/WaitForLeader.jsp (.../WaitForLeader.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -32,9 +32,9 @@ - + Index: lams_tool_lamc/web/learning/submissionDeadline.jsp =================================================================== diff -u -rf78c13d077554f43a098b67854182c258b6323db -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/learning/submissionDeadline.jsp (.../submissionDeadline.jsp) (revision f78c13d077554f43a098b67854182c258b6323db) +++ lams_tool_lamc/web/learning/submissionDeadline.jsp (.../submissionDeadline.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -30,12 +30,12 @@ - - - - - + + + + + @@ -46,9 +46,9 @@ - + - @@ -58,17 +58,17 @@ - + - + - +

- +
Index: lams_tool_lamc/web/monitoring/Edit.jsp =================================================================== diff -u -r556d465d0c2dba467f2acef7d29c0f8261ecf84b -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/monitoring/Edit.jsp (.../Edit.jsp) (revision 556d465d0c2dba467f2acef7d29c0f8261ecf84b) +++ lams_tool_lamc/web/monitoring/Edit.jsp (.../Edit.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -21,6 +21,6 @@
- + - + Index: lams_tool_lamc/web/monitoring/MonitoringMaincontent.jsp =================================================================== diff -u -rb4f6a6c35d72f0cf2d10144f3700f0e29a527edc -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/monitoring/MonitoringMaincontent.jsp (.../MonitoringMaincontent.jsp) (revision b4f6a6c35d72f0cf2d10144f3700f0e29a527edc) +++ lams_tool_lamc/web/monitoring/MonitoringMaincontent.jsp (.../MonitoringMaincontent.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -25,7 +25,7 @@ } function doStatistic(){ - var url = ''; + var url = ''; $.ajaxSetup({ cache: true }); $("#statisticArea").load( url, @@ -37,20 +37,20 @@ } function downloadMarks() { - var url = ""; + var url = ""; var reqIDVar = new Date(); - var param = "?validate=false&dispatch=downloadMarks&toolContentID=${mcGeneralMonitoringDTO.toolContentID}&reqID="+reqIDVar.getTime(); + var param = "?validate=false&toolContentID=${mcGeneralMonitoringDTO.toolContentID}&reqID="+reqIDVar.getTime(); url = url + param; return downloadFile(url, 'message-area-busy', '', 'message-area', 'btn-disable-on-submit'); } function turnOnDisplayAnswers() { - window.open("?dispatch=displayAnswers&toolContentID=${mcGeneralMonitoringDTO.toolContentID}&contentFolderID=${contentFolderID}","_self") + window.open("?toolContentID=${mcGeneralMonitoringDTO.toolContentID}&contentFolderID=${contentFolderID}","_self") } function turnOnDisplayFeedbackOnly() { - window.open("?dispatch=displayFeedbackOnly&toolContentID=${mcGeneralMonitoringDTO.toolContentID}&contentFolderID=${contentFolderID}","_self") + window.open("?toolContentID=${mcGeneralMonitoringDTO.toolContentID}&contentFolderID=${contentFolderID}","_self") } Index: lams_tool_lamc/web/monitoring/Reflections.jsp =================================================================== diff -u -r729f1d10a1efd78ec420b373a7af23ee66ec3454 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/monitoring/Reflections.jsp (.../Reflections.jsp) (revision 729f1d10a1efd78ec420b373a7af23ee66ec3454) +++ lams_tool_lamc/web/monitoring/Reflections.jsp (.../Reflections.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -27,9 +27,9 @@ - + -   +   Index: lams_tool_lamc/web/monitoring/SummaryContent.jsp =================================================================== diff -u -r10afbb9a2d6f910c0f9131e82ebf2d3cb6ee359f -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/monitoring/SummaryContent.jsp (.../SummaryContent.jsp) (revision 10afbb9a2d6f910c0f9131e82ebf2d3cb6ee359f) +++ lams_tool_lamc/web/monitoring/SummaryContent.jsp (.../SummaryContent.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -27,7 +27,7 @@ lams: '${lams}', submissionDeadline: '${submissionDeadline}', submissionDateString: '${submissionDateString}', - setSubmissionDeadlineUrl: '', + setSubmissionDeadlineUrl: '', toolContentID: '${toolContentID}', messageNotification: '', messageRestrictionSet: '', @@ -45,7 +45,7 @@ jQuery("#group${sessionDto.sessionId}").jqGrid({ datatype: "json", - url: "?dispatch=getPagedUsers&toolSessionID=${sessionDto.sessionId}", + url: "?toolSessionID=${sessionDto.sessionId}", height: 'auto', autowidth: true, shrinkToFit: true, @@ -127,7 +127,7 @@ {name:'grade', index:'grade', width:80, sorttype:"int", editable:true, editoptions: {size:4, maxlength: 4}, align:"right" } ], multiselect: false, - cellurl: '', + cellurl: '', cellEdit: true, afterEditCell: function (rowid,name,val,iRow,iCol){ oldValue = eval(val); Index: lams_tool_lamc/web/monitoring/parts/dateRestriction.jsp =================================================================== diff -u -r00937d78dacc0993260d5ed7b39e4376e432cf45 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/monitoring/parts/dateRestriction.jsp (.../dateRestriction.jsp) (revision 00937d78dacc0993260d5ed7b39e4376e432cf45) +++ lams_tool_lamc/web/monitoring/parts/dateRestriction.jsp (.../dateRestriction.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -10,9 +10,9 @@ - + - +
@@ -21,9 +21,9 @@ - + - +
Index: lams_tool_lamc/web/monitoring/parts/statsPart.jsp =================================================================== diff -u -r6fa531a730e4c685bcec3569ae46c98ea9f51571 -r424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d --- lams_tool_lamc/web/monitoring/parts/statsPart.jsp (.../statsPart.jsp) (revision 6fa531a730e4c685bcec3569ae46c98ea9f51571) +++ lams_tool_lamc/web/monitoring/parts/statsPart.jsp (.../statsPart.jsp) (revision 424f8d213bbff9badfb9b913fd7c68d5cc1d5c3d) @@ -36,13 +36,13 @@ drawHistogram('chartDivLeader${sessionMap.toolContentID}', - '', + '', '', ''); drawHistogram('chartDivSession${sessionDto.sessionId}', - '', + '', '', '');