Index: lams_tool_assessment/conf/hibernate/mappings/org/lamsfoundation/lams/tool/assessment/model/AssessmentResult.hbm.xml =================================================================== diff -u -r65efb0abb529cafc1977e284e2c9a4ed33722334 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/conf/hibernate/mappings/org/lamsfoundation/lams/tool/assessment/model/AssessmentResult.hbm.xml (.../AssessmentResult.hbm.xml) (revision 65efb0abb529cafc1977e284e2c9a4ed33722334) +++ lams_tool_assessment/conf/hibernate/mappings/org/lamsfoundation/lams/tool/assessment/model/AssessmentResult.hbm.xml (.../AssessmentResult.hbm.xml) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -53,6 +53,14 @@ insert="true" column="start_date" /> + + 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/dbupdates/patch20161130.sql =================================================================== diff -u --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20161130.sql (revision 0) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20161130.sql (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -0,0 +1,14 @@ +-- 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-3801 keep the time limit start time in DB +ALTER TABLE tl_laasse10_assessment_result ADD COLUMN time_limit_launched_date datetime; + +----------------------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 Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java (.../Assessment.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.java (.../Assessment.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -37,9 +37,6 @@ * Assessment * * @author Andrey Balan - * - * - * */ public class Assessment implements Cloneable { @@ -308,9 +305,6 @@ /** * @return Returns the userid of the user who created the Share assessment. - * - * - * */ public AssessmentUser getCreatedBy() { return createdBy; @@ -337,9 +331,6 @@ /** * @return Returns the title. - * - * - * */ public String getTitle() { return title; @@ -355,9 +346,6 @@ /** * If the tool utilizes leaders from Select Leader tool. - * - * @return - * */ public boolean isUseSelectLeaderToolOuput() { return useSelectLeaderToolOuput; @@ -369,9 +357,6 @@ /** * @return Returns the time limitation, that students have to complete an attempt. - * - * - * */ public int getTimeLimit() { return timeLimit; Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentOptionAnswer.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentOptionAnswer.java (.../AssessmentOptionAnswer.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentOptionAnswer.java (.../AssessmentOptionAnswer.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -29,8 +29,6 @@ * AssessmentOptionAnswer * * @author Andrey Balan - * - * */ public class AssessmentOptionAnswer implements Cloneable { private static final Logger log = Logger.getLogger(AssessmentOptionAnswer.class); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentOverallFeedback.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentOverallFeedback.java (.../AssessmentOverallFeedback.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentOverallFeedback.java (.../AssessmentOverallFeedback.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -29,8 +29,6 @@ * AssessmentOverallFeedback * * @author Andrey Balan - * - * */ public class AssessmentOverallFeedback implements Cloneable, Sequencable { private static final Logger log = Logger.getLogger(AssessmentOverallFeedback.class); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestion.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestion.java (.../AssessmentQuestion.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestion.java (.../AssessmentQuestion.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -39,8 +39,6 @@ * Assessment Question * * @author Andrey Balan - * - * */ public class AssessmentQuestion implements Cloneable, Sequencable, Comparable { private static final Logger log = Logger.getLogger(AssessmentQuestion.class); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionOption.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionOption.java (.../AssessmentQuestionOption.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionOption.java (.../AssessmentQuestionOption.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -29,8 +29,6 @@ * AssessmentQuestionOption * * @author Andrey Balan - * - * */ public class AssessmentQuestionOption implements Cloneable, Sequencable { private static final Logger log = Logger.getLogger(AssessmentQuestionOption.class); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java (.../AssessmentQuestionResult.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java (.../AssessmentQuestionResult.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -35,9 +35,6 @@ * Assessment Question Result * * @author Andrey Balan - * - * - * */ public class AssessmentQuestionResult { Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentResult.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentResult.java (.../AssessmentResult.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentResult.java (.../AssessmentResult.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -33,15 +33,14 @@ * Assessment Result * * @author Andrey Balan - * - * - * */ public class AssessmentResult { private Long uid; private Assessment assessment; private Date startDate; + //date when user has started activity (pressed start button) that has time limitation + private Date timeLimitLaunchedDate; //indicates the latest retry private boolean isLatest; private Date finishDate; @@ -106,7 +105,19 @@ public void setStartDate(Date startDate) { this.startDate = startDate; } + + /** + * + * @return + */ + public Date getTimeLimitLaunchedDate() { + return timeLimitLaunchedDate; + } + public void setTimeLimitLaunchedDate(Date timeLimitLaunchedDate) { + this.timeLimitLaunchedDate = timeLimitLaunchedDate; + } + /** * * @return Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentSession.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentSession.java (.../AssessmentSession.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentSession.java (.../AssessmentSession.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -32,9 +32,6 @@ * Assessment session * * @author Andrey Balan - * - * - * */ public class AssessmentSession { @@ -138,7 +135,6 @@ } /** - * * @param sessionName * The session name to set. */ @@ -147,12 +143,6 @@ } /** - * - * - * - * - * - * * @return */ public Set getAssessmentQuestions() { @@ -164,10 +154,6 @@ } /** - * - * - * - * * @return */ public Set getAssessmentUsers() { Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUnit.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUnit.java (.../AssessmentUnit.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUnit.java (.../AssessmentUnit.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -29,8 +29,6 @@ * AssessmentUnit * * @author Andrey Balan - * - * */ public class AssessmentUnit implements Cloneable, Sequencable { private static final Logger log = Logger.getLogger(AssessmentUnit.class); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUser.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUser.java (.../AssessmentUser.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUser.java (.../AssessmentUser.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -34,9 +34,6 @@ * Assessment User * * @author Andrey Balan - * - * - * */ public class AssessmentUser implements Cloneable { private static final long serialVersionUID = -7043502180037866257L; Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/QuestionReference.java =================================================================== diff -u -r3399163940c61c9132223c758d274486e57ff9b7 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/QuestionReference.java (.../QuestionReference.java) (revision 3399163940c61c9132223c758d274486e57ff9b7) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/QuestionReference.java (.../QuestionReference.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -29,9 +29,6 @@ * Reference to the Question * * @author Andrey Balan - * - * - * */ public class QuestionReference implements Cloneable, Sequencable { private static final Logger log = Logger.getLogger(QuestionReference.class); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -rb6f4f2ff2da4913b0c65c482b77c56c661a19375 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision b6f4f2ff2da4913b0c65c482b77c56c661a19375) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -281,6 +281,45 @@ assessmentResultDao.saveObject(userResult); } + + @Override + public void launchTimeLimit(Long assessmentUid, Long userId) { + AssessmentResult lastResult = getLastAssessmentResult(assessmentUid, userId); + lastResult.setTimeLimitLaunchedDate(new Date()); + assessmentResultDao.saveObject(lastResult); + } + + @Override + public long getSecondsLeft(Assessment assessment, AssessmentUser user) { + AssessmentResult lastResult = getLastAssessmentResult(assessment.getUid(), user.getUserId()); + + long secondsLeft = 1; + if (assessment.getTimeLimit() != 0) { + // if user has pressed OK button already - calculate remaining time, and full time otherwise + boolean isTimeLimitNotLaunched = (lastResult == null) || (lastResult.getTimeLimitLaunchedDate() == null); + secondsLeft = isTimeLimitNotLaunched ? assessment.getTimeLimit() * 60 + : assessment.getTimeLimit() * 60 - (System.currentTimeMillis() - lastResult.getTimeLimitLaunchedDate().getTime()) / 1000; + // change negative or zero number to 1 + secondsLeft = Math.max(1, secondsLeft); + } + + return secondsLeft; + } + + @Override + public boolean checkTimeLimitExceeded(Assessment assessment, AssessmentUser groupLeader) { + int timeLimit = assessment.getTimeLimit(); + if (timeLimit == 0) { + return false; + } + + AssessmentResult lastLeaderResult = getLastAssessmentResult(assessment.getUid(), groupLeader.getUserId()); + + //check if the time limit is exceeded + return (lastLeaderResult != null) && (lastLeaderResult.getTimeLimitLaunchedDate() != null) + && lastLeaderResult.getTimeLimitLaunchedDate().getTime() + timeLimit * 60000 < System.currentTimeMillis(); + } + @Override public List getUsersBySession(Long toolSessionID) { Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -r176ee597a35dd2bdf71e49889e6291051e260a29 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 176ee597a35dd2bdf71e49889e6291051e260a29) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -79,6 +79,31 @@ */ void copyAnswersFromLeader(AssessmentUser user, AssessmentUser leader) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException; + + /** + * Stores date when user has started activity with time limit. + * + * @param assessmentUid + * @param userId + */ + void launchTimeLimit(Long assessmentUid, Long userId); + + /** + * Calculates how many seconds left till the time limit will expire. If it's expired already - returns 1 in order to + * show learning.jsp and autosubmit results. + * + * @param assessment + * @param user + * @return + */ + long getSecondsLeft(Assessment assessment, AssessmentUser user); + + /** + * @param assessment + * @param groupLeader + * @return whether the time limit is exceeded already + */ + boolean checkTimeLimitExceeded(Assessment assessment, AssessmentUser groupLeader); /** * Get users by given toolSessionID. Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java =================================================================== diff -u -rd01ecb3fa180d6aed8745c1a6ebf23b11ec95c27 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java (.../LearningAction.java) (revision d01ecb3fa180d6aed8745c1a6ebf23b11ec95c27) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java (.../LearningAction.java) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -85,7 +85,6 @@ import org.springframework.web.context.support.WebApplicationContextUtils; /** - * * @author Andrey Balan */ public class LearningAction extends Action { @@ -125,6 +124,9 @@ if (param.equals("autoSaveAnswers")) { return autoSaveAnswers(mapping, form, request, response); } + if (param.equals("launchTimeLimit")) { + return launchTimeLimit(mapping, form, request, response); + } if (param.equals("checkLeaderProgress")) { return checkLeaderProgress(mapping, form, request, response); } @@ -165,45 +167,63 @@ // get back the assessment and question list and display them on page IAssessmentService service = getAssessmentService(); - AssessmentUser assessmentUser = null; + AssessmentUser user = null; if ((mode != null) && mode.isTeacher()) { // monitoring mode - user is specified in URL // assessmentUser may be null if the user was force completed. - assessmentUser = getSpecifiedUser(service, toolSessionId, + user = getSpecifiedUser(service, toolSessionId, WebUtil.readIntParam(request, AttributeNames.PARAM_USER_ID, false)); } else { - assessmentUser = getCurrentUser(toolSessionId); + user = getCurrentUser(toolSessionId); } Assessment assessment = service.getAssessmentBySessionId(toolSessionId); - //support for leader select feature - AssessmentUser groupLeader = null; - if (assessment.isUseSelectLeaderToolOuput()) { - groupLeader = service.checkLeaderSelectToolForSessionLeader(assessmentUser, - new Long(toolSessionId).longValue()); + // support for leader select feature + AssessmentUser groupLeader = assessment.isUseSelectLeaderToolOuput() + ? service.checkLeaderSelectToolForSessionLeader(user, new Long(toolSessionId).longValue()) + : null; + if (assessment.isUseSelectLeaderToolOuput() && !mode.isTeacher()) { // forwards to the leaderSelection page - if (groupLeader == null && !mode.isTeacher()) { - + if (groupLeader == null) { List groupUsers = service.getUsersBySession(new Long(toolSessionId).longValue()); request.setAttribute(AssessmentConstants.ATTR_GROUP_USERS, groupUsers); request.setAttribute(AssessmentConstants.ATTR_ASSESSMENT, assessment); return mapping.findForward(AssessmentConstants.WAIT_FOR_LEADER); } + + // forwards to the waitForLeader pages + boolean isNonLeader = !user.getUserId().equals(groupLeader.getUserId()); + if (assessment.getTimeLimit() != 0 && isNonLeader && !user.isSessionFinished()) { + AssessmentResult lastLeaderResult = service.getLastAssessmentResult(assessment.getUid(), groupLeader.getUserId()); + //show waitForLeaderLaunchTimeLimit page if the leader hasn't started activity or hasn't pressed OK button to launch time limit + if (lastLeaderResult == null || lastLeaderResult.getTimeLimitLaunchedDate() == null) { + request.setAttribute(AssessmentConstants.PARAM_WAITING_MESSAGE_KEY, "label.waiting.for.leader.launch.time.limit"); + return mapping.findForward(AssessmentConstants.WAIT_FOR_LEADER_TIME_LIMIT); + } + + //if the time is up and leader hasn't submitted response - show waitForLeaderFinish page + boolean isTimeLimitExceeded = service.checkTimeLimitExceeded(assessment, groupLeader); + if (isTimeLimitExceeded && !groupLeader.isSessionFinished()) { + request.setAttribute(AssessmentConstants.PARAM_WAITING_MESSAGE_KEY, "label.waiting.for.leader.finish"); + return mapping.findForward(AssessmentConstants.WAIT_FOR_LEADER_TIME_LIMIT); + } + } + // check if leader has submitted all answers - if (groupLeader.isSessionFinished() && !mode.equals(ToolAccessMode.TEACHER.toString())) { + if (groupLeader.isSessionFinished()) { // 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 - service.copyAnswersFromLeader(assessmentUser, groupLeader); + service.copyAnswersFromLeader(user, groupLeader); } } sessionMap.put(AssessmentConstants.ATTR_GROUP_LEADER, groupLeader); - boolean isUserLeader = service.isUserGroupLeader(assessmentUser, new Long(toolSessionId)); + boolean isUserLeader = service.isUserGroupLeader(user, new Long(toolSessionId)); sessionMap.put(AssessmentConstants.ATTR_IS_USER_LEADER, isUserLeader); Set questionReferences = new TreeSet(new SequencableComparator()); @@ -235,21 +255,21 @@ } } - int dbResultCount = service.getAssessmentResultCount(assessment.getUid(), assessmentUser.getUserId()); + int dbResultCount = service.getAssessmentResultCount(assessment.getUid(), user.getUserId()); int attemptsAllowed = assessment.getAttemptsAllowed(); boolean isResubmitAllowed = ((attemptsAllowed > dbResultCount) | (attemptsAllowed == 0)); - AssessmentResult lastResult = service.getLastAssessmentResult(assessment.getUid(), assessmentUser.getUserId()); + AssessmentResult lastResult = service.getLastAssessmentResult(assessment.getUid(), user.getUserId()); boolean hasEditRight = !assessment.isUseSelectLeaderToolOuput() || assessment.isUseSelectLeaderToolOuput() && isUserLeader; 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; + boolean finishedLock = user.isSessionFinished() || finishedLockForMonitor || isLastResultFinished; // get notebook entry String entryText = new String(); - AssessmentUser notebookCreator = (groupLeader == null) ? assessmentUser : groupLeader; + AssessmentUser notebookCreator = (groupLeader == null) ? user : groupLeader; NotebookEntry notebookEntry = service.getEntry(toolSessionId, notebookCreator.getUserId().intValue()); if (notebookEntry != null) { entryText = notebookEntry.getEntry(); @@ -260,16 +280,24 @@ sessionMap.put(AssessmentConstants.ATTR_INSTRUCTIONS, assessment.getInstructions()); 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.ATTR_HAS_EDIT_RIGHT, hasEditRight); + sessionMap.put(AssessmentConstants.ATTR_USER_FINISHED, user.isSessionFinished()); sessionMap.put(AttributeNames.ATTR_LEARNER_CONTENT_FOLDER, - service.getLearnerContentFolder(toolSessionId, assessmentUser.getUserId())); + service.getLearnerContentFolder(toolSessionId, user.getUserId())); sessionMap.put(AttributeNames.PARAM_TOOL_SESSION_ID, toolSessionId); - sessionMap.put(AssessmentConstants.ATTR_USER, assessmentUser); + sessionMap.put(AssessmentConstants.ATTR_USER, user); sessionMap.put(AttributeNames.ATTR_MODE, mode); // reflection information sessionMap.put(AssessmentConstants.ATTR_REFLECTION_ON, assessment.isReflectOnActivity()); sessionMap.put(AssessmentConstants.ATTR_REFLECTION_INSTRUCTION, assessment.getReflectInstructions()); sessionMap.put(AssessmentConstants.ATTR_REFLECTION_ENTRY, entryText); + + //time limit + boolean isTimeLimitEnabled = hasEditRight && !finishedLock && assessment.getTimeLimit() != 0; + long secondsLeft = isTimeLimitEnabled ? service.getSecondsLeft(assessment, user) : 0; + request.setAttribute(AssessmentConstants.ATTR_SECONDS_LEFT, secondsLeft); + boolean isTimeLimitNotLaunched = (lastResult == null) || (lastResult.getTimeLimitLaunchedDate() == null); + sessionMap.put(AssessmentConstants.ATTR_IS_TIME_LIMIT_NOT_LAUNCHED, isTimeLimitNotLaunched); ActivityPositionDTO activityPosition = LearningWebUtil .putActivityPositionInRequestByToolSessionId(toolSessionId, request, getServlet().getServletContext()); @@ -355,7 +383,7 @@ //set attempt started if (!finishedLock && hasEditRight) { - service.setAttemptStarted(assessment, pagedQuestions, assessmentUser, toolSessionId); + service.setAttemptStarted(assessment, pagedQuestions, user, toolSessionId); } // loadupLastAttempt for display purpose @@ -382,23 +410,28 @@ AssessmentSession session = service.getAssessmentSessionBySessionId(toolSessionId); AssessmentUser leader = session.getGroupLeader(); + //in case of time limit - prevent user from seeing questions page longer than time limit allows + boolean isTimeLimitExceeded = service.checkTimeLimitExceeded(session.getAssessment(), leader); boolean isLeaderResponseFinalized = leader.isSessionFinished(); JSONObject JSONObject = new JSONObject(); - JSONObject.put("isLeaderResponseFinalized", isLeaderResponseFinalized); + JSONObject.put("isPageRefreshRequested", isLeaderResponseFinalized || isTimeLimitExceeded); response.setContentType("application/x-json;charset=utf-8"); response.getWriter().print(JSONObject); return null; } /** - * Display same entire authoring page content from HttpSession variable. + * Shows next page. It's available only to leaders as non-leaders see all questions on one page. */ private ActionForward nextPage(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException { + IAssessmentService service = getAssessmentService(); String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() .getAttribute(sessionMapID); + Assessment assessment = (Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT); + AssessmentUser user = (AssessmentUser) sessionMap.get(AssessmentConstants.ATTR_USER); boolean finishedLock = (Boolean) sessionMap.get(AssessmentConstants.ATTR_FINISHED_LOCK); if (!finishedLock) { @@ -407,8 +440,8 @@ // store results from sessionMap into DB storeUserAnswersIntoDatabase(sessionMap, true); - request.setAttribute(AssessmentConstants.PARAM_SECONDS_LEFT, - request.getParameter(AssessmentConstants.PARAM_SECONDS_LEFT)); + long secondsLeft = service.getSecondsLeft(assessment, user); + request.setAttribute(AssessmentConstants.ATTR_SECONDS_LEFT, secondsLeft); } //get pageNumber as request parameter in normal case and as attribute in case of submitAll returned it back @@ -566,6 +599,10 @@ 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); } @@ -673,7 +710,26 @@ return null; } + + /** + * Stores date when user has started activity with time limit + */ + private ActionForward launchTimeLimit(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); + + Long assessmentUid = ((Assessment) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT)).getUid(); + Long userId = ((AssessmentUser) sessionMap.get(AssessmentConstants.ATTR_USER)).getUserId(); + sessionMap.put(AssessmentConstants.ATTR_IS_TIME_LIMIT_NOT_LAUNCHED, false); + + service.launchTimeLimit(assessmentUid, userId); + return null; + } + /** * Display empty reflection form. */ Index: lams_tool_assessment/web/WEB-INF/struts-config.xml =================================================================== diff -u -r65efb0abb529cafc1977e284e2c9a4ed33722334 -re10da332d88104fe61b1f646b8bcac22bbfd15f0 --- lams_tool_assessment/web/WEB-INF/struts-config.xml (.../struts-config.xml) (revision 65efb0abb529cafc1977e284e2c9a4ed33722334) +++ lams_tool_assessment/web/WEB-INF/struts-config.xml (.../struts-config.xml) (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -222,6 +222,7 @@ + + + <%@ include file="/common/taglibs.jsp"%> + - - - - <fmt:message key="label.learning.title" /> @@ -22,18 +19,11 @@ + + - - - - - - - - - @@ -126,12 +116,14 @@ } //boolean to indicate whether ok dialog is still ON so that autosave can't be run - var isWaitingForConfirmation = ${not finishedLock && assessment.timeLimit > 0 && empty param.secondsLeft}; + var isWaitingForConfirmation = ${isTimeLimitEnabled && sessionMap.isTimeLimitNotLaunched}; - + //timelimit feature + $(document).ready(function(){ - if (${empty param.secondsLeft}) { - //show confirmation dialog + //show timelimit-start-dialog in order to start countdown + if (${sessionMap.isTimeLimitNotLaunched}) { + $.blockUI({ message: $('#timelimit-start-dialog'), css: { width: '325px', height: '120px'}, @@ -140,6 +132,15 @@ //once OK button pressed start countdown $('#timelimit-start-ok').click(function() { + + //store date when user has started activity with time limit + $.ajax({ + async: true, + url: '', + data: 'sessionMapID=${sessionMapID}', + type: 'post' + }); + $.unblockUI(); displayCountdown(); isWaitingForConfirmation = false; @@ -168,7 +169,7 @@ }); $('#countdown').countdown({ - until: '+${secondsLeft}S', + until: '+${secondsLeft}S', format: 'hMS', compact: true, onTick: function(periods) { @@ -254,36 +255,23 @@ if (!validateAnswers()) { return; } - - var secondsLeft = 0; - if (${not finishedLock && assessment.timeLimit > 0}) { - var times = $("#countdown").countdown('getTimes'); - secondsLeft = times[4]*3600 + times[5]*60 + times[6]; - } + var myForm = $("#answers"); - myForm.attr("action", "" + pageNumber + "&secondsLeft=" + secondsLeft); + myForm.attr("action", "" + pageNumber); myForm.submit(); } function submitAll(isTimelimitExpired){ - var secondsLeft = 0; - //only if time limit is not expired if (!isTimelimitExpired) { - if (!validateAnswers()) { return; } - - if (${not finishedLock && assessment.timeLimit > 0}) { - var times = $("#countdown").countdown('getTimes'); - secondsLeft = times[4]*3600 + times[5]*60 + times[6]; - } } var myForm = $("#answers"); - myForm.attr("action", "&secondsLeft=" + secondsLeft + "&isTimelimitExpired=" + isTimelimitExpired); + myForm.attr("action", "&isTimelimitExpired=" + isTimelimitExpired); myForm.submit(); } @@ -325,12 +313,12 @@ var orderingArea = "#orderingArea" + questionUid; var url = ""; $(orderingArea).load( - url, - { - questionUid: questionUid, - optionIndex: idx, - sessionMapID: "${sessionMapID}" - } + url, + { + questionUid: questionUid, + optionIndex: idx, + sessionMapID: "${sessionMapID}" + } ); } @@ -339,15 +327,14 @@ } function checkLeaderProgress() { - $.ajax({ async: false, url: '', data: 'toolSessionID=${toolSessionID}', dataType: 'json', type: 'post', success: function (json) { - if (json.isLeaderResponseFinalized) { + if (json.isPageRefreshRequested) { location.reload(); } } @@ -654,10 +641,9 @@ - + - + Fisheye: Tag e10da332d88104fe61b1f646b8bcac22bbfd15f0 refers to a dead (removed) revision in file `lams_tool_assessment/web/pages/learning/start.jsp'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_assessment/web/pages/learning/waitForLeaderTimeLimit.jsp =================================================================== diff -u --- lams_tool_assessment/web/pages/learning/waitForLeaderTimeLimit.jsp (revision 0) +++ lams_tool_assessment/web/pages/learning/waitForLeaderTimeLimit.jsp (revision e10da332d88104fe61b1f646b8bcac22bbfd15f0) @@ -0,0 +1,35 @@ + +<%@ include file="/common/taglibs.jsp"%> + + + + <fmt:message key="activity.title" /> + + + + + + + + + + +

+ +

+ + + + + +
+ + +