Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java =================================================================== diff -u -re10da332d88104fe61b1f646b8bcac22bbfd15f0 -r2d0422cb41945e1e1b52ad67403354df34fae0aa --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java (.../Assessment.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java (.../Assessment.java) (revision 2d0422cb41945e1e1b52ad67403354df34fae0aa) @@ -242,6 +242,16 @@ } this.setUpdated(new Date(now)); } + + /** + * Checks whether content was modified in monitor and this has happened after attempt was started (and thus this modification can potentially affect attempt results). + * + * @param attemptStartingDate + * @return + */ + public boolean isContentModifiedInMonitor(Date attemptStartingDate) { + return (updated != null) && updated.after(attemptStartingDate); + } // ********************************************************** // get/set methods Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r5fff5c4348abd6cabbe10da89c813e16edec214f -r2d0422cb41945e1e1b52ad67403354df34fae0aa --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 5fff5c4348abd6cabbe10da89c813e16edec214f) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 2d0422cb41945e1e1b52ad67403354df34fae0aa) @@ -23,6 +23,7 @@ package org.lamsfoundation.lams.tool.assessment.service; +import java.lang.reflect.InvocationTargetException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; @@ -40,6 +41,7 @@ import java.util.TreeSet; import java.util.regex.Pattern; +import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -453,7 +455,7 @@ assessmentResultDao.saveObject(lastResult); return; - // mark previous attempt as being not the latest any longer + // mark previous attempt as being not the latest any longer } else { lastResult.setLatest(false); assessmentResultDao.saveObject(lastResult); @@ -478,7 +480,7 @@ } /* - * Auiliary method for setAttemptStarted(). Simply init new AssessmentQuestionResult object and fills it in with + * Auxiliary method for setAttemptStarted(). Simply init new AssessmentQuestionResult object and fills it in with * values. * * @param question @@ -503,7 +505,7 @@ } @Override - public boolean storeUserAnswers(Assessment assessment, Long userId, Long singleMarkHedgingQuestionUid, + public boolean storeUserAnswers(Assessment assessment, Long userId, List> pagedQuestions, Long singleMarkHedgingQuestionUid, boolean isAutosave) { int maximumGrade = 0; @@ -518,44 +520,48 @@ return false; } - // store all answers - for (AssessmentQuestion question : questions) { + // store all answers (in all pages) + for (Set questionsForOnePage : pagedQuestions) { + for (AssessmentQuestion question : questionsForOnePage) { - // in case single MarkHedging question needs to be stored -- search for that question - if ((singleMarkHedgingQuestionUid != null) && !question.getUid().equals(singleMarkHedgingQuestionUid)) { - continue; - } + // in case single MarkHedging question needs to be stored -- search for that question + if ((singleMarkHedgingQuestionUid != null) && !question.getUid().equals(singleMarkHedgingQuestionUid)) { + continue; + } - // In case if assessment was updated after result has been started check question still exists in DB as - // it could be deleted if modified in monitor. - if ((assessment.getUpdated() != null) && assessment.getUpdated().after(result.getStartDate())) { + //TODO possibly move the next if-clause inside of storeUserAnswer() method + // In case if assessment was modified in monitor after result has been started check question still exists in DB as + // it could be deleted + if (assessment.isContentModifiedInMonitor(result.getStartDate())) { - Set references = assessment.getQuestionReferences(); + Set references = assessment.getQuestionReferences(); - boolean isQuestionExists = false; - for (QuestionReference reference : references) { - if (!reference.isRandomQuestion() && reference.getQuestion().getUid().equals(question.getUid())) { - isQuestionExists = true; - break; - } - if (reference.isRandomQuestion()) { - for (AssessmentQuestion questionDb : questions) { - if (questionDb.getUid().equals(question.getUid())) { - isQuestionExists = true; - break; + boolean isQuestionExists = false; + for (QuestionReference reference : references) { + if (!reference.isRandomQuestion() + && reference.getQuestion().getUid().equals(question.getUid())) { + isQuestionExists = true; + break; + } + if (reference.isRandomQuestion()) { + for (AssessmentQuestion questionDb : questions) { + if (questionDb.getUid().equals(question.getUid())) { + isQuestionExists = true; + break; + } } } } + if (!isQuestionExists) { + continue; + } } - if (!isQuestionExists) { - continue; - } - } - float userQeustionGrade = storeUserAnswer(result, question, isAutosave); - grade += userQeustionGrade; + float userQeustionGrade = storeUserAnswer(result, question, isAutosave); + grade += userQeustionGrade; - maximumGrade += question.getGrade(); + maximumGrade += question.getGrade(); + } } // store grades and finished date only on user hitting submit all answers button (and not submit mark hedging @@ -590,9 +596,26 @@ if (assessmentResult.getFinishDate() == null && questionResult == null) { //it should get here only in case teacher edited content in monitor which led to removal of autosave questionResult - questionResult = createQuestionResultObject(question); - questionResult.setAssessmentResult(assessmentResult); - assessmentQuestionResultDao.insert(questionResult); + AssessmentQuestion modifiedQuestion = assessmentQuestionDao.getByUid(question.getUid()); + try { + PropertyUtils.copyProperties(question, modifiedQuestion); +// question.getOptions().clear(); +// question.getOptions().addAll(modifiedQuestion.getOptions()); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchMethodException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return 0; + +// questionResult = createQuestionResultObject(question); +// questionResult.setAssessmentResult(assessmentResult); +// assessmentQuestionResultDao.insert(questionResult); } // store question answer values Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -r5fff5c4348abd6cabbe10da89c813e16edec214f -r2d0422cb41945e1e1b52ad67403354df34fae0aa --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 5fff5c4348abd6cabbe10da89c813e16edec214f) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 2d0422cb41945e1e1b52ad67403354df34fae0aa) @@ -214,14 +214,16 @@ * * @param assessment * @param userId + * @param pagedQuestions * @param singleMarkHedgingQuestionUid * - if provided - means only that current single MarkHedging question needs to be stored * @param isAutosave * indicates whether it's autosave request * * @return whether storing results is allowed, false otherwise */ - boolean storeUserAnswers(Assessment assessment, Long userId, Long singleMarkHedgingQuestionUid, boolean isAutosave); + boolean storeUserAnswers(Assessment assessment, Long userId, List> pagedQuestions, + Long singleMarkHedgingQuestionUid, boolean isAutosave); /** * Return the latest result (it can be unfinished). Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java =================================================================== diff -u -r5fff5c4348abd6cabbe10da89c813e16edec214f -r2d0422cb41945e1e1b52ad67403354df34fae0aa --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java (.../LearningAction.java) (revision 5fff5c4348abd6cabbe10da89c813e16edec214f) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java (.../LearningAction.java) (revision 2d0422cb41945e1e1b52ad67403354df34fae0aa) @@ -52,6 +52,7 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; +import org.apache.struts.action.ActionRedirect; import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.learning.web.bean.ActivityPositionDTO; @@ -475,6 +476,8 @@ String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() .getAttribute(sessionMapID); + List> pagedQuestions = (List>) sessionMap + .get(AssessmentConstants.ATTR_PAGED_QUESTIONS); Long userId = ((AssessmentUser) sessionMap.get(AssessmentConstants.ATTR_USER)).getUserId(); Long toolSessionId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_SESSION_ID); Assessment assessment = service.getAssessmentBySessionId(toolSessionId); @@ -484,7 +487,7 @@ // store results from sessionMap into DB Long singleMarkHedgingQuestionUid = WebUtil.readLongParam(request, "singleMarkHedgingQuestionUid"); - boolean isResultsStored = service.storeUserAnswers(assessment, userId, singleMarkHedgingQuestionUid, false); + boolean isResultsStored = service.storeUserAnswers(assessment, userId, pagedQuestions, singleMarkHedgingQuestionUid, false); // result was not stored in case user was prohibited from submitting (or autosubmitting) answers (e.g. when // using 2 browsers). Then show last stored results if (!isResultsStored) { @@ -493,10 +496,12 @@ //find according question in order to get its mark AssessmentQuestion question = null; - for (AssessmentQuestion questionIter : (Set) assessment.getQuestions()) { - if (questionIter.getUid().equals(singleMarkHedgingQuestionUid)) { - question = questionIter; - question.setResponseSubmitted(true); + for (Set questionsForOnePage : pagedQuestions) { + for (AssessmentQuestion questionIter : questionsForOnePage) { + if (questionIter.getUid().equals(singleMarkHedgingQuestionUid)) { + question = questionIter; + question.setResponseSubmitted(true); + } } } @@ -580,46 +585,45 @@ SessionMap sessionMap = (SessionMap) request.getSession() .getAttribute(sessionMapID); Long toolSessionId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_SESSION_ID); + ToolAccessMode mode = (ToolAccessMode) sessionMap.get(AttributeNames.ATTR_MODE); Assessment assessment = service.getAssessmentBySessionId(toolSessionId); AssessmentUser assessmentUser = (AssessmentUser) sessionMap.get(AssessmentConstants.ATTR_USER); - service.unsetSessionFinished(toolSessionId, assessmentUser.getUserId()); - - //set attempt started: create a new one + mark previous as not being the latest any longer + Long userId = assessmentUser.getUserId(); + service.unsetSessionFinished(toolSessionId, userId); + + Date lastAttemptStartingDate = service.getLastAssessmentResult(assessment.getUid(), userId).getStartDate(); + + // set attempt started: create a new one + mark previous as not being the latest any longer service.setAttemptStarted(assessment, assessmentUser, toolSessionId); - - sessionMap.put(AssessmentConstants.ATTR_FINISHED_LOCK, false); - sessionMap.put(AssessmentConstants.ATTR_PAGE_NUMBER, 1); - sessionMap.put(AssessmentConstants.ATTR_QUESTION_NUMBERING_OFFSET, 1); - request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); - //clear isUserFailed indicator - sessionMap.put(AssessmentConstants.ATTR_IS_USER_FAILED, false); - //time limit feature - sessionMap.put(AssessmentConstants.ATTR_IS_TIME_LIMIT_NOT_LAUNCHED, true); - request.setAttribute(AssessmentConstants.ATTR_SECONDS_LEFT, assessment.getTimeLimit() * 60); + // in case of content was modified in monitor - redirect to start.do in order to refresh info from the DB + if (assessment.isContentModifiedInMonitor(lastAttemptStartingDate)) { + ActionRedirect redirect = new ActionRedirect(mapping.findForwardConfig("startLearning")); + redirect.addParameter(AttributeNames.PARAM_MODE, mode.toString()); + redirect.addParameter(AssessmentConstants.PARAM_TOOL_SESSION_ID, toolSessionId); + return redirect; - //update all questions with DB data in case assessment was edited in monitor - List> pagedQuestions = (List>) sessionMap - .get(AssessmentConstants.ATTR_PAGED_QUESTIONS); - List dbQuestions = service.getAuthoredQuestions(assessment.getUid()); - List> newPagedQuestions = new ArrayList>(); - for (Set questionsForOnePage : pagedQuestions) { - LinkedHashSet newQuestionsForOnePage = new LinkedHashSet(); + //otherwise use data from SessionMap + } else { - for (AssessmentQuestion question : questionsForOnePage) { +// List> pagedQuestions = (List>) sessionMap +// .get(AssessmentConstants.ATTR_PAGED_QUESTIONS); +// service.setAttemptStarted(assessment, pagedQuestions, assessmentUser, toolSessionId); - for (AssessmentQuestion dbQuestion : dbQuestions) { - if (dbQuestion.getUid().equals(question.getUid())) { - newQuestionsForOnePage.add(dbQuestion); - break; - } - } - } - newPagedQuestions.add(newQuestionsForOnePage); + sessionMap.put(AssessmentConstants.ATTR_FINISHED_LOCK, false); + sessionMap.put(AssessmentConstants.ATTR_PAGE_NUMBER, 1); + sessionMap.put(AssessmentConstants.ATTR_QUESTION_NUMBERING_OFFSET, 1); + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); + // clear isUserFailed indicator + sessionMap.put(AssessmentConstants.ATTR_IS_USER_FAILED, false); + + // time limit feature + sessionMap.put(AssessmentConstants.ATTR_IS_TIME_LIMIT_NOT_LAUNCHED, true); + request.setAttribute(AssessmentConstants.ATTR_SECONDS_LEFT, assessment.getTimeLimit() * 60); + + return mapping.findForward(AssessmentConstants.SUCCESS); } - sessionMap.put(AssessmentConstants.ATTR_PAGED_QUESTIONS, newPagedQuestions); - return mapping.findForward(AssessmentConstants.SUCCESS); } /** @@ -1176,13 +1180,16 @@ * Store user answers in DB in last unfinished attempt and notify teachers about it. */ private boolean storeUserAnswersIntoDatabase(SessionMap sessionMap, boolean isAutosave) { + + List> pagedQuestions = (List>) sessionMap + .get(AssessmentConstants.ATTR_PAGED_QUESTIONS); IAssessmentService service = getAssessmentService(); Long toolSessionId = (Long) sessionMap.get(AssessmentConstants.ATTR_TOOL_SESSION_ID); Long userId = ((AssessmentUser) sessionMap.get(AssessmentConstants.ATTR_USER)).getUserId(); ToolAccessMode mode = (ToolAccessMode) sessionMap.get(AttributeNames.ATTR_MODE); Assessment assessment = service.getAssessmentBySessionId(toolSessionId); - boolean isResultsStored = service.storeUserAnswers(assessment, userId, null, isAutosave); + boolean isResultsStored = service.storeUserAnswers(assessment, userId, pagedQuestions, null, isAutosave); // notify teachers if ((mode != null) && !mode.isTeacher() && !isAutosave && isResultsStored Index: lams_tool_assessment/web/WEB-INF/struts-config.xml =================================================================== diff -u -re10da332d88104fe61b1f646b8bcac22bbfd15f0 -r2d0422cb41945e1e1b52ad67403354df34fae0aa --- lams_tool_assessment/web/WEB-INF/struts-config.xml (.../struts-config.xml) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) +++ lams_tool_assessment/web/WEB-INF/struts-config.xml (.../struts-config.xml) (revision 2d0422cb41945e1e1b52ad67403354df34fae0aa) @@ -248,6 +248,7 @@ type="org.lamsfoundation.lams.tool.assessment.web.action.LearningAction" parameter="resubmit" > + :  + + + + + + + + + + + + -  ${result.maximumGrade} (%) +  ${result.maximumGrade} (${resultPercentage}%) Index: lams_tool_assessment/web/pages/learning/parts/multiplechoice.jsp =================================================================== diff -u -r18ef25d68d237fc9f934df0ccad74e5cd2b08ae4 -r2d0422cb41945e1e1b52ad67403354df34fae0aa --- lams_tool_assessment/web/pages/learning/parts/multiplechoice.jsp (.../multiplechoice.jsp) (revision 18ef25d68d237fc9f934df0ccad74e5cd2b08ae4) +++ lams_tool_assessment/web/pages/learning/parts/multiplechoice.jsp (.../multiplechoice.jsp) (revision 2d0422cb41945e1e1b52ad67403354df34fae0aa) @@ -31,13 +31,13 @@ - checked="checked" disabled="disabled" /> - checked="checked" disabled="disabled" /> Index: lams_tool_assessment/web/pages/learning/parts/truefalse.jsp =================================================================== diff -u -r18ef25d68d237fc9f934df0ccad74e5cd2b08ae4 -r2d0422cb41945e1e1b52ad67403354df34fae0aa --- lams_tool_assessment/web/pages/learning/parts/truefalse.jsp (.../truefalse.jsp) (revision 18ef25d68d237fc9f934df0ccad74e5cd2b08ae4) +++ lams_tool_assessment/web/pages/learning/parts/truefalse.jsp (.../truefalse.jsp) (revision 2d0422cb41945e1e1b52ad67403354df34fae0aa) @@ -28,7 +28,7 @@ - checked="checked" disabled="disabled" /> @@ -58,7 +58,7 @@ - checked="checked" disabled="disabled" />