Index: lams_tool_assessment/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -r6622436c9cf078d8ebd3f9ea65d98b6013025e52 -r5c56f99b5c68772f16031bfcadc8ea326e4b1787 --- lams_tool_assessment/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 6622436c9cf078d8ebd3f9ea65d98b6013025e52) +++ lams_tool_assessment/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 5c56f99b5c68772f16031bfcadc8ea326e4b1787) @@ -281,6 +281,7 @@ label.edit =Edit label.submit =Finished label.authoring.advance.numbered.questions =Enable questions' numbering +label.learning.draft.autosaved =Draft autosaved #======= End labels: Exported 275 labels for en AU ===== Index: lams_tool_assessment/conf/xdoclet/struts-actions.xml =================================================================== diff -u -r65e3365a66b2977b268fafdd0b9fe2e5eae732a4 -r5c56f99b5c68772f16031bfcadc8ea326e4b1787 --- lams_tool_assessment/conf/xdoclet/struts-actions.xml (.../struts-actions.xml) (revision 65e3365a66b2977b268fafdd0b9fe2e5eae732a4) +++ lams_tool_assessment/conf/xdoclet/struts-actions.xml (.../struts-actions.xml) (revision 5c56f99b5c68772f16031bfcadc8ea326e4b1787) @@ -251,6 +251,10 @@ parameter="downOption"> + + PROPAGATION_REQUIRED,-java.lang.Exception PROPAGATION_REQUIRED,-java.lang.Exception PROPAGATION_REQUIRED,-java.lang.Exception + PROPAGATION_REQUIRED,-java.lang.Exception PROPAGATION_REQUIRED,-java.lang.Exception PROPAGATION_REQUIRED,-java.lang.Exception PROPAGATION_REQUIRED,-java.lang.Exception Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentOutputFactory.java =================================================================== diff -u -r61e7bbf20d65e2ecb5e50f3154e52264003defa1 -r5c56f99b5c68772f16031bfcadc8ea326e4b1787 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentOutputFactory.java (.../AssessmentOutputFactory.java) (revision 61e7bbf20d65e2ecb5e50f3154e52264003defa1) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentOutputFactory.java (.../AssessmentOutputFactory.java) (revision 5c56f99b5c68772f16031bfcadc8ea326e4b1787) @@ -141,7 +141,7 @@ * Get total score for a user. Will always return a ToolOutput object. */ private ToolOutput getTotalScore(IAssessmentService assessmentService, Long learnerId, Assessment assessment) { - AssessmentResult assessmentResult = assessmentService.getLastAssessmentResult(assessment.getUid(), learnerId); + AssessmentResult assessmentResult = assessmentService.getLastFinishedAssessmentResult(assessment.getUid(), learnerId); float totalScore = (assessmentResult == null) ? 0 : assessmentResult.getGrade(); @@ -153,7 +153,7 @@ * Get time taken for a specific user to accomplish this assessment. Will always return a ToolOutput object. */ private ToolOutput getTimeTaken(IAssessmentService assessmentService, Long learnerId, Assessment assessment) { - AssessmentResult assessmentResult = assessmentService.getLastAssessmentResult(assessment.getUid(), learnerId); + AssessmentResult assessmentResult = assessmentService.getLastFinishedAssessmentResult(assessment.getUid(), learnerId); long timeTaken = 0; if ((assessmentResult != null) && (assessmentResult.getFinishDate() != null)) { @@ -179,7 +179,7 @@ */ private ToolOutput getQuestionScore(IAssessmentService assessmentService, Long learnerId, Assessment assessment, int questionSequenceId) { - AssessmentResult assessmentResult = assessmentService.getLastAssessmentResult(assessment.getUid(), learnerId); + AssessmentResult assessmentResult = assessmentService.getLastFinishedAssessmentResult(assessment.getUid(), learnerId); float questionScore = 0; for (AssessmentQuestionResult questionResult : assessmentResult.getQuestionResults()) { Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -rb749eaf5465cf318976a6e036293ed9fded85434 -r5c56f99b5c68772f16031bfcadc8ea326e4b1787 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision b749eaf5465cf318976a6e036293ed9fded85434) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 5c56f99b5c68772f16031bfcadc8ea326e4b1787) @@ -355,6 +355,12 @@ @Override public void setAttemptStarted(Assessment assessment, AssessmentUser assessmentUser, Long toolSessionId) { + AssessmentResult lastResult = this.getLastAssessmentResult(assessment.getUid(), assessmentUser.getUserId()); + //don't instantiate new attempt if the previous one wasn't finished and thus continue working with it + if ((lastResult != null) && (lastResult.getFinishDate() == null)) { + return; + } + AssessmentResult result = new AssessmentResult(); result.setAssessment(assessment); result.setUser(assessmentUser); @@ -364,32 +370,38 @@ } @Override - public void processUserAnswers(Long assessmentUid, Long userId, - ArrayList> pagedQuestions) { + public void storeUserAnswers(Long assessmentUid, Long userId, + ArrayList> pagedQuestions, boolean isAutosave) { + SortedSet questionResultList = new TreeSet( new AssessmentQuestionResultComparator()); int maximumGrade = 0; float grade = 0; + for (LinkedHashSet questionsForOnePage : pagedQuestions) { for (AssessmentQuestion question : questionsForOnePage) { int numberWrongAnswers = assessmentQuestionResultDao.getNumberWrongAnswersDoneBefore(assessmentUid, userId, question.getUid()); - AssessmentQuestionResult processedAnswer = this.processUserAnswer(question, numberWrongAnswers); + AssessmentQuestionResult processedAnswer = this.storeUserAnswer(question, numberWrongAnswers); questionResultList.add(processedAnswer); maximumGrade += question.getGrade(); grade += processedAnswer.getMark(); } } + AssessmentResult result = assessmentResultDao.getLastAssessmentResult(assessmentUid, userId); result.setQuestionResults(questionResultList); - result.setMaximumGrade(maximumGrade); - result.setGrade(grade); - result.setFinishDate(new Timestamp(new Date().getTime())); + //store grades and finished date only on user hitting submit all answers button + if (!isAutosave) { + result.setMaximumGrade(maximumGrade); + result.setGrade(grade); + result.setFinishDate(new Timestamp(new Date().getTime())); + } assessmentResultDao.saveObject(result); } - private AssessmentQuestionResult processUserAnswer(AssessmentQuestion question, int numberWrongAnswers) { + private AssessmentQuestionResult storeUserAnswer(AssessmentQuestion question, int numberWrongAnswers) { AssessmentQuestionResult questionResult = new AssessmentQuestionResult(); Set optionAnswers = questionResult.getOptionAnswers(); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -rb749eaf5465cf318976a6e036293ed9fded85434 -r5c56f99b5c68772f16031bfcadc8ea326e4b1787 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision b749eaf5465cf318976a6e036293ed9fded85434) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 5c56f99b5c68772f16031bfcadc8ea326e4b1787) @@ -179,7 +179,16 @@ */ void setAttemptStarted(Assessment assessment, AssessmentUser assessmentUser, Long toolSessionId); - void processUserAnswers(Long assessmentUid, Long userId, ArrayList> pagedQuestions); + /** + * Store user answers into DB. It can be autosave and non-autosave requests. + * + * @param assessmentUid + * @param userId + * @param pagedQuestions + * @param isAutosave indicates whether it's autosave request + */ + void storeUserAnswers(Long assessmentUid, Long userId, ArrayList> pagedQuestions, + boolean isAutosave); AssessmentResult getLastAssessmentResult(Long assessmentUid, Long userId); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java =================================================================== diff -u -rb749eaf5465cf318976a6e036293ed9fded85434 -r5c56f99b5c68772f16031bfcadc8ea326e4b1787 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java (.../LearningAction.java) (revision b749eaf5465cf318976a6e036293ed9fded85434) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java (.../LearningAction.java) (revision 5c56f99b5c68772f16031bfcadc8ea326e4b1787) @@ -51,7 +51,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.lamsfoundation.lams.events.DeliveryMethodMail; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.learning.web.bean.ActivityPositionDTO; import org.lamsfoundation.lams.learning.web.util.LearningWebUtil; @@ -116,6 +115,9 @@ if (param.equals("downOption")) { return downOption(mapping, form, request, response); } + if (param.equals("autoSaveAnswers")) { + return autoSaveAnswers(mapping, form, request, response); + } // ================ Reflection ======================= if (param.equals("newReflection")) { return newReflection(mapping, form, request, response); @@ -195,11 +197,13 @@ int dbResultCount = service.getAssessmentResultCount(assessment.getUid(), assessmentUser.getUserId()); int attemptsAllowed = assessment.getAttemptsAllowed(); - AssessmentResult lastResult = service.getLastAssessmentResult(assessment.getUid(), assessmentUser.getUserId()); - boolean finishedLockForMonitor = (mode != null) && mode.isTeacher() && (lastResult != null) && (lastResult.getFinishDate() != null); - boolean finishedLock = (assessmentUser.isSessionFinished() && (attemptsAllowed != 0)) - || finishedLockForMonitor - || ((attemptsAllowed <= dbResultCount) && (attemptsAllowed != 0)); + boolean isResubmitAllowed = ((attemptsAllowed > dbResultCount) | (attemptsAllowed == 0)); + + AssessmentResult lastResult = service.getLastAssessmentResult(assessment.getUid(), assessmentUser.getUserId()); + boolean isLastResultFinished = (lastResult != null) && (lastResult.getFinishDate() != null); + //finishedLockForMonitor is a lock for displaying results page for teacher only if user see it, and displaying learner page if user see it accordingly + boolean finishedLockForMonitor = (mode != null) && mode.isTeacher() && isLastResultFinished; + boolean finishedLock = assessmentUser.isSessionFinished() || finishedLockForMonitor || isLastResultFinished; // get notebook entry String entryText = new String(); @@ -211,7 +215,7 @@ // basic information sessionMap.put(AssessmentConstants.ATTR_TITLE, assessment.getTitle()); sessionMap.put(AssessmentConstants.ATTR_INSTRUCTIONS, assessment.getInstructions()); - sessionMap.put(AssessmentConstants.ATTR_IS_RESUBMIT_ALLOWED, false); + sessionMap.put(AssessmentConstants.ATTR_IS_RESUBMIT_ALLOWED, isResubmitAllowed); sessionMap.put(AssessmentConstants.ATTR_FINISHED_LOCK, finishedLock); sessionMap.put(AssessmentConstants.ATTR_USER_FINISHED, assessmentUser.isSessionFinished()); sessionMap.put(AssessmentConstants.PARAM_RUN_OFFLINE, assessment.getRunOffline()); @@ -322,11 +326,12 @@ sessionMap.put(AssessmentConstants.ATTR_ASSESSMENT, assessment); // loadupLastAttempt for display purpose - if (dbResultCount > 0) { - loadupLastAttempt(sessionMap); - if (finishedLock) { - loadupResultMarks(sessionMap); - } + loadupLastAttempt(sessionMap); + + //check if need to display results page + if ((dbResultCount > 0) && finishedLock) { + // display results page + populateResultsPage(sessionMap); } return mapping.findForward(AssessmentConstants.SUCCESS); @@ -339,9 +344,14 @@ HttpServletResponse response) throws ServletException { String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + boolean finishedLock = (Boolean) sessionMap.get(AssessmentConstants.ATTR_FINISHED_LOCK); if (! finishedLock) { - preserveUserAnswers(request); + //get user answers from request and store them into sessionMap + storeUserAnswersIntoSessionMap(request); + // store results from sessionMap into DB + storeUserAnswersIntoDatabase(sessionMap, true); + request.setAttribute(AssessmentConstants.PARAM_SECONDS_LEFT, request.getParameter(AssessmentConstants.PARAM_SECONDS_LEFT)); } @@ -367,10 +377,14 @@ HttpServletResponse response) throws ServletException { String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); - preserveUserAnswers(request); - processUserAnswers(sessionMap); - loadupResultMarks(sessionMap); + //get user answers from request and store them into sessionMap + storeUserAnswersIntoSessionMap(request); + //store results from sessionMap into DB + storeUserAnswersIntoDatabase(sessionMap, false); + // populate info for displaying results page + populateResultsPage(sessionMap); + Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); //calculate whether isResubmitAllowed IAssessmentService service = getAssessmentService(); @@ -386,7 +400,7 @@ AssessmentResult result = (AssessmentResult) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT_RESULT); int passingMark = assessment.getPassingMark(); boolean isUserFailed = ((passingMark != 0) && (passingMark > result.getGrade())); - request.setAttribute(AssessmentConstants.ATTR_IS_USER_FAILED, isUserFailed); + sessionMap.put(AssessmentConstants.ATTR_IS_USER_FAILED, isUserFailed); sessionMap.put(AssessmentConstants.ATTR_FINISHED_LOCK, true); request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); @@ -498,6 +512,23 @@ } /** + * auto saves responses + */ + private ActionForward autoSaveAnswers(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + IAssessmentService service = getAssessmentService(); + String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + //get user answers from request and store them into sessionMap + storeUserAnswersIntoSessionMap(request); + //store results from sessionMap into DB + storeUserAnswersIntoDatabase(sessionMap, true); + + return null; + } + + /** * Display empty reflection form. */ private ActionForward newReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, @@ -561,7 +592,12 @@ // Private method // ************************************************************************************* - private void preserveUserAnswers(HttpServletRequest request){ + /** + * Get back user answers from request and store it into sessionMap. + * + * @param request + */ + private void storeUserAnswersIntoSessionMap(HttpServletRequest request){ String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); int pageNumber = (Integer) sessionMap.get(AssessmentConstants.ATTR_PAGE_NUMBER); @@ -622,13 +658,13 @@ } } - private void loadupResultMarks(SessionMap sessionMap){ + private void populateResultsPage(SessionMap sessionMap){ ArrayList> pagedQuestions = (ArrayList>) sessionMap .get(AssessmentConstants.ATTR_PAGED_QUESTIONS); Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); Long userId = ((AssessmentUser) sessionMap.get(AssessmentConstants.ATTR_USER)).getUserId(); IAssessmentService service = getAssessmentService(); - AssessmentResult result = service.getLastAssessmentResult(assessment.getUid(), userId); + AssessmentResult result = service.getLastFinishedAssessmentResult(assessment.getUid(), userId); for (LinkedHashSet questionsForOnePage : pagedQuestions) { for (AssessmentQuestion question : questionsForOnePage) { @@ -677,7 +713,7 @@ Long assessmentUid = ((Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT)).getUid(); Long userId = ((AssessmentUser) sessionMap.get(AssessmentConstants.ATTR_USER)).getUserId(); IAssessmentService service = getAssessmentService(); - AssessmentResult result = service.getLastFinishedAssessmentResult(assessmentUid,userId); + AssessmentResult result = service.getLastAssessmentResult(assessmentUid,userId); for(LinkedHashSet questionsForOnePage : pagedQuestions) { for (AssessmentQuestion question : questionsForOnePage) { @@ -719,24 +755,25 @@ } /** - * Get answer options from HttpRequest + * Store user answers in DB in last unfinished attempt and notify teachers about it. */ - private void processUserAnswers(SessionMap sessionMap) { + private void storeUserAnswersIntoDatabase(SessionMap sessionMap, boolean isAutosave) { ArrayList> pagedQuestions = (ArrayList>) sessionMap .get(AssessmentConstants.ATTR_PAGED_QUESTIONS); Long assessmentUid = ((Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT)).getUid(); Long userId = ((AssessmentUser) sessionMap.get(AssessmentConstants.ATTR_USER)).getUserId(); IAssessmentService service = getAssessmentService(); - service.processUserAnswers(assessmentUid, userId, pagedQuestions); + service.storeUserAnswers(assessmentUid, userId, pagedQuestions, isAutosave); // notify teachers ToolAccessMode mode = (ToolAccessMode) sessionMap.get(AttributeNames.ATTR_MODE); - if ((mode != null) && !mode.isTeacher()) { - Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); - Long toolSessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - final boolean isHtmlFormat = false; + if ((mode != null) && !mode.isTeacher() && !isAutosave) { + Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); if (assessment.isNotifyTeachersOnAttemptCompletion()) { + + Long toolSessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + final boolean isHtmlFormat = false; List monitoringUsers = service.getMonitorsByToolSessionId(toolSessionId); if (monitoringUsers != null && !monitoringUsers.isEmpty()) { Integer[] monitoringUsersIds = new Integer[monitoringUsers.size()]; @@ -751,6 +788,7 @@ service.getLocalisedMessage("event.learner.completes.attempt.body", new Object[] { fullName }), isHtmlFormat); } + } } } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/MonitoringAction.java =================================================================== diff -u -r5a5f3640c4d5fdf0c302347e7d6b502a972fd9cc -r5c56f99b5c68772f16031bfcadc8ea326e4b1787 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 5a5f3640c4d5fdf0c302347e7d6b502a972fd9cc) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 5c56f99b5c68772f16031bfcadc8ea326e4b1787) @@ -408,7 +408,7 @@ data.add(userTitleRow); } - AssessmentResult assessmentResult = service.getLastAssessmentResult(assessment.getUid(), + AssessmentResult assessmentResult = service.getLastFinishedAssessmentResult(assessment.getUid(), assessmentUser.getUserId()); if (assessmentResult != null) { Index: lams_tool_assessment/web/pages/learning/learning.jsp =================================================================== diff -u -r8aded0b18a5a7712622ae56f38923fa297449977 -r5c56f99b5c68772f16031bfcadc8ea326e4b1787 --- lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision 8aded0b18a5a7712622ae56f38923fa297449977) +++ lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision 5c56f99b5c68772f16031bfcadc8ea326e4b1787) @@ -8,8 +8,7 @@ - <fmt:message key="label.learning.title" /> - + <fmt:message key="label.learning.title" /> <%@ include file="/common/header.jsp"%> <%-- param has higher level for request attribute --%> @@ -34,8 +33,15 @@ + - + +