Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r6d6bafd58b27e613ae472097129d2fede445ffd9 -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 6d6bafd58b27e613ae472097129d2fede445ffd9) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -128,6 +128,7 @@ import java.nio.charset.StandardCharsets; import java.security.InvalidParameterException; import java.sql.Timestamp; +import java.time.Duration; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; @@ -1411,6 +1412,47 @@ assessmentUserDao.saveObject(user); } + public void finishExpiredAttempts(Long toolContentId) { + Assessment assessment = getAssessmentByContentId(toolContentId); + if (assessment == null) { + throw new IllegalArgumentException("Assessment with tool content ID " + toolContentId + " not found"); + } + LocalDateTime currentLocalDateTime = LocalDateTime.now(); + if (assessment.getRelativeTimeLimit() == 0 && (assessment.getAbsoluteTimeLimitFinish() == null + || Duration.between(assessment.getAbsoluteTimeLimitFinish(), currentLocalDateTime).toSeconds() < 30)) { + // there can be no expired timers or the absolute timer expired less than 30 seconds ago, + // so no need to do anything + return; + } + + Date currentDate = new Date(); + List results = assessmentResultDao.getLastAssessmentResults(assessment.getUid()); + boolean anyResultFinished = false; + for (AssessmentResult result : results) { + if (result.getFinishDate() != null) { + // the result is already finished + continue; + } + AssessmentUser user = result.getUser(); + boolean timeLimitExceeded = checkTimeLimitExceeded(toolContentId, user.getUserId().intValue()); + if (timeLimitExceeded) { + anyResultFinished = true; + // the timer has expired, finish the result + result.setFinishDate(currentDate); + assessmentResultDao.update(result); + if (assessment.getAttemptsAllowed() <= 1) { + // if there are multiple attempts allowed, do not finish the session yet + user.setSessionFinished(true); + assessmentUserDao.update(user); + } + } + } + if (anyResultFinished) { + // update charts + FluxRegistry.emit(AssessmentConstants.LEARNER_TRAVERSED_SINK_NAME, toolContentId); + } + } + @Override public List getSessionDtos(Long contentId, boolean includeStatistics) { List sessionDtos = new ArrayList<>(); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -r27be1eb0b5945027c2c8f95b8a28b1803762c183 -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 27be1eb0b5945027c2c8f95b8a28b1803762c183) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -391,6 +391,11 @@ void unsetSessionFinished(Long toolSessionId, Long userId); /** + * Mark results as finished after time limit is exceeded. + */ + void finishExpiredAttempts(Long toolContentId); + + /** * Returns sessionDtos containing only session ids and session names. * * @param contentId Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java =================================================================== diff -u -r27be1eb0b5945027c2c8f95b8a28b1803762c183 -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 27be1eb0b5945027c2c8f95b8a28b1803762c183) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -151,6 +151,7 @@ List sessionDtos = service.getSessionDtos(contentId, false); Assessment assessment = service.getAssessmentByContentId(contentId); + service.finishExpiredAttempts(contentId); //set SubmissionDeadline, if any if (assessment.getSubmissionDeadline() != null) { Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java =================================================================== diff -u -rf8f156c0f021d60857760ea60579a41e1380288c -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java (.../TblMonitoringController.java) (revision f8f156c0f021d60857760ea60579a41e1380288c) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/TblMonitoringController.java (.../TblMonitoringController.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -1,15 +1,5 @@ package org.lamsfoundation.lams.tool.assessment.web.controller; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.servlet.http.HttpServletRequest; - import org.apache.commons.lang.StringUtils; import org.lamsfoundation.lams.qb.model.QbQuestion; import org.lamsfoundation.lams.tool.assessment.AssessmentConstants; @@ -41,7 +31,14 @@ import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; @Controller @RequestMapping("/tblmonitoring") @@ -68,6 +65,7 @@ public String iraAssessmentStudentChoices(HttpServletRequest request) { Long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); Assessment assessment = assessmentService.getAssessmentByContentId(toolContentId); + assessmentService.finishExpiredAttempts(toolContentId); request.setAttribute(AttributeNames.PARAM_TOOL_CONTENT_ID, toolContentId); request.setAttribute("assessment", assessment); @@ -204,6 +202,8 @@ public String assessment(@RequestParam(name = AttributeNames.PARAM_TOOL_CONTENT_ID) long toolContentId, Model model) { Assessment assessment = assessmentService.getAssessmentByContentId(toolContentId); + assessmentService.finishExpiredAttempts(toolContentId); + model.addAttribute(AttributeNames.PARAM_TOOL_CONTENT_ID, toolContentId); model.addAttribute("allowDiscloseAnswers", assessment.isAllowDiscloseAnswers()); Index: lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/DokumaranService.java =================================================================== diff -u -rd7bfc30e7d7a056b984f35c292a7abed4635c754 -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/DokumaranService.java (.../DokumaranService.java) (revision d7bfc30e7d7a056b984f35c292a7abed4635c754) +++ lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/DokumaranService.java (.../DokumaranService.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -82,6 +82,7 @@ import javax.servlet.http.HttpServletResponse; import java.security.InvalidParameterException; +import java.time.Duration; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; @@ -483,6 +484,47 @@ } @Override + public void finishExpiredSessions(Long toolContentId) { + Dokumaran dokumaran = dokumaranDao.getByContentId(toolContentId); + if (dokumaran == null) { + throw new IllegalArgumentException("Dokumaran with tool content ID " + toolContentId + " not found"); + } + LocalDateTime currentLocalDateTime = LocalDateTime.now(); + if ((dokumaran.isGalleryWalkEnabled() && !dokumaran.isGalleryWalkFinished()) || ( + dokumaran.getRelativeTimeLimit() == 0 && (dokumaran.getAbsoluteTimeLimitFinish() == null + || Duration.between(dokumaran.getAbsoluteTimeLimitFinish(), currentLocalDateTime).toSeconds() + < 30))) { + // there can be no expired timers or the absolute timer expired less than 30 seconds ago, so no need to do anything + return; + } + + Date currentDate = new Date(); + List sessions = dokumaranSessionDao.getByContentId(toolContentId); + for (DokumaranSession session : sessions) { + if (session.getSessionEndDate() != null) { + // the result is already finished + continue; + } + List users = dokumaranUserDao.getBySessionID(session.getSessionId()); + boolean allUsersFinished = true; + for (DokumaranUser user : users) { + boolean timeLimitExceeded = checkTimeLimitExceeded(dokumaran, user.getUserId().intValue()); + if (timeLimitExceeded) { + // the timer has expired, finish the result + user.setSessionFinished(true); + dokumaranUserDao.update(user); + } else { + allUsersFinished = false; + } + } + if (allUsersFinished) { + session.setSessionEndDate(currentDate); + dokumaranSessionDao.update(session); + } + } + } + + @Override public List getSummary(Long contentId, Long ratingUserUid) { // get all sessions in a dokumaran and retrieve all dokumaran items under this session // plus initial dokumaran items by author creating (resItemList) Index: lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/IDokumaranService.java =================================================================== diff -u -r8c6ccd715c5bbd55bacc9a0f112d2ee9a870aa3d -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/IDokumaranService.java (.../IDokumaranService.java) (revision 8c6ccd715c5bbd55bacc9a0f112d2ee9a870aa3d) +++ lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/IDokumaranService.java (.../IDokumaranService.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -185,6 +185,11 @@ String finishToolSession(Long toolSessionId, Long userId) throws DokumaranApplicationException; /** + * Mark session as finished after time limit is exceeded. + */ + void finishExpiredSessions(Long toolContentId); + + /** * Return monitoring summary list. The return value is list of dokumaran summaries for each groups. */ List getSummary(Long contentId, Long ratingUserUid); Index: lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/web/controller/MonitoringController.java =================================================================== diff -u -r8c6ccd715c5bbd55bacc9a0f112d2ee9a870aa3d -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 8c6ccd715c5bbd55bacc9a0f112d2ee9a870aa3d) +++ lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -126,6 +126,7 @@ } Dokumaran dokumaran = dokumaranService.getDokumaranByContentId(contentId); + dokumaranService.finishExpiredSessions(contentId); //set SubmissionDeadline, if any if (dokumaran.getSubmissionDeadline() != null) { Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java =================================================================== diff -u -rf05bad0f63a5e9515f10dc19d40bfdd26195ff9f -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java (.../IScratchieService.java) (revision f05bad0f63a5e9515f10dc19d40bfdd26195ff9f) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java (.../IScratchieService.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -23,13 +23,6 @@ package org.lamsfoundation.lams.tool.scratchie.service; -import java.io.IOException; -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.notebook.model.NotebookEntry; @@ -49,6 +42,13 @@ import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.util.excel.ExcelSheet; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * Interface that defines the contract that all ShareScratchie service provider must follow. * @@ -294,6 +294,11 @@ */ String finishToolSession(Long toolSessionId, Long userId) throws ScratchieApplicationException; + /** + * Mark scratching as finished after time limit is exceeded. + */ + void finishExpiredSessions(Long toolContentId); + ScratchieItem getScratchieItemByUid(Long itemUid); Collection getAllGroupUsers(Long toolSessionId); Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java =================================================================== diff -u -rd7bfc30e7d7a056b984f35c292a7abed4635c754 -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision d7bfc30e7d7a056b984f35c292a7abed4635c754) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -108,6 +108,7 @@ import java.security.InvalidParameterException; import java.sql.Timestamp; import java.text.SimpleDateFormat; +import java.time.Duration; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; @@ -814,6 +815,41 @@ } @Override + public void finishExpiredSessions(Long toolContentId) { + Scratchie scratchie = getScratchieByContentId(toolContentId); + if (scratchie == null) { + throw new IllegalArgumentException("Scratchie with tool content ID " + toolContentId + " not found"); + } + LocalDateTime currentLocalDateTime = LocalDateTime.now(); + if (scratchie.getRelativeTimeLimit() == 0 && (scratchie.getAbsoluteTimeLimitFinish() == null + || Duration.between(scratchie.getAbsoluteTimeLimitFinish(), currentLocalDateTime).toSeconds() < 30)) { + // there can be no expired timers or the absolute timer expired less than 30 seconds ago, so no need to do anything + return; + } + + List sessions = scratchieSessionDao.getByContentId(toolContentId); + for (ScratchieSession session : sessions) { + if (session.isScratchingFinished()) { + // the result is already finished + continue; + } + ScratchieUser user = session.getGroupLeader(); + boolean timeLimitExceeded = checkTimeLimitExceeded(toolContentId, user.getUserId().intValue()); + if (timeLimitExceeded) { + // the timer has expired, finish the result + session.setScratchingFinished(true); + session.setStatus(ScratchieConstants.COMPLETED); + scratchieSessionDao.update(session); + List users = getUsersBySession(session.getSessionId()); + for (ScratchieUser scratchieUser : users) { + scratchieUser.setSessionFinished(true); + scratchieUserDao.update(scratchieUser); + } + } + } + } + + @Override public ScratchieItem getScratchieItemByUid(Long itemUid) { return scratchieItemDao.getByUid(itemUid); } Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java =================================================================== diff -u -reccd6838790a4369b6788e48fb5ae5851622fe35 -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java (.../MonitoringController.java) (revision eccd6838790a4369b6788e48fb5ae5851622fe35) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -23,27 +23,9 @@ package org.lamsfoundation.lams.tool.scratchie.web.controller; -import java.io.IOException; -import java.security.InvalidParameterException; -import java.time.LocalDateTime; -import java.time.OffsetDateTime; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeSet; -import java.util.stream.Collectors; - -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -65,7 +47,14 @@ import org.lamsfoundation.lams.tool.scratchie.service.IScratchieService; import org.lamsfoundation.lams.tool.scratchie.util.ScratchieItemComparator; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; -import org.lamsfoundation.lams.util.*; +import org.lamsfoundation.lams.util.AlphanumComparator; +import org.lamsfoundation.lams.util.CommonConstants; +import org.lamsfoundation.lams.util.Configuration; +import org.lamsfoundation.lams.util.ConfigurationKeys; +import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.FileUtil; +import org.lamsfoundation.lams.util.JsonUtil; +import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.util.excel.ExcelSheet; import org.lamsfoundation.lams.util.excel.ExcelUtil; import org.lamsfoundation.lams.web.session.SessionManager; @@ -82,9 +71,25 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.security.InvalidParameterException; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeSet; +import java.util.stream.Collectors; @Controller @RequestMapping("/monitoring") @@ -109,6 +114,7 @@ Scratchie scratchie = scratchieService.getScratchieByContentId(contentId); Set learners = scratchieService.getAllLeaders(contentId); + scratchieService.finishExpiredSessions(contentId); //set SubmissionDeadline, if any if (scratchie.getSubmissionDeadline() != null) { Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/TblMonitorController.java =================================================================== diff -u -reccd6838790a4369b6788e48fb5ae5851622fe35 -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/TblMonitorController.java (.../TblMonitorController.java) (revision eccd6838790a4369b6788e48fb5ae5851622fe35) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/TblMonitorController.java (.../TblMonitorController.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -23,19 +23,9 @@ package org.lamsfoundation.lams.tool.scratchie.web.controller; -import java.io.IOException; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.log4j.Logger; import org.lamsfoundation.lams.flux.FluxRegistry; import org.lamsfoundation.lams.tool.scratchie.ScratchieConstants; @@ -63,13 +53,20 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; - import reactor.core.publisher.Flux; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + @Controller @RequestMapping("/tblmonitoring") public class TblMonitorController { @@ -85,6 +82,7 @@ public String tra(HttpServletRequest request) throws IOException, ServletException { long toolContentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); Scratchie scratchie = scratchieService.getScratchieByContentId(toolContentId); + scratchieService.finishExpiredSessions(toolContentId); int attemptedLearnersNumber = scratchieService.countUsersByContentId(toolContentId); request.setAttribute("attemptedLearnersNumber", attemptedLearnersNumber); @@ -122,6 +120,7 @@ public String traStudentChoices(@RequestParam(name = AttributeNames.PARAM_TOOL_CONTENT_ID) long toolContentId, Model model) throws IOException, ServletException { Scratchie scratchie = scratchieService.getScratchieByContentId(toolContentId); + scratchieService.finishExpiredSessions(toolContentId); Map modelAttributes = scratchieService.prepareStudentChoicesData(scratchie); model.addAllAttributes(modelAttributes); Index: lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/service/IWhiteboardService.java =================================================================== diff -u -r8c6ccd715c5bbd55bacc9a0f112d2ee9a870aa3d -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/service/IWhiteboardService.java (.../IWhiteboardService.java) (revision 8c6ccd715c5bbd55bacc9a0f112d2ee9a870aa3d) +++ lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/service/IWhiteboardService.java (.../IWhiteboardService.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -103,6 +103,11 @@ String finishToolSession(Long toolSessionId, Long userId) throws WhiteboardApplicationException; /** + * Mark session as finished after time limit is exceeded. + */ + void finishExpiredSessions(Long toolContentId); + + /** * Create refection entry into notebook tool. */ Long createNotebookEntry(Long sessionId, Integer notebookToolType, String toolSignature, Integer userId, Index: lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/service/WhiteboardService.java =================================================================== diff -u -rd7bfc30e7d7a056b984f35c292a7abed4635c754 -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/service/WhiteboardService.java (.../WhiteboardService.java) (revision d7bfc30e7d7a056b984f35c292a7abed4635c754) +++ lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/service/WhiteboardService.java (.../WhiteboardService.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -72,6 +72,7 @@ import java.net.URLEncoder; import java.nio.charset.Charset; import java.security.InvalidParameterException; +import java.time.Duration; import java.time.LocalDateTime; import java.util.*; import java.util.function.Function; @@ -388,6 +389,47 @@ } @Override + public void finishExpiredSessions(Long toolContentId) { + Whiteboard whiteboard = whiteboardDao.getByContentId(toolContentId); + if (whiteboard == null) { + throw new IllegalArgumentException("Whiteboard with tool content ID " + toolContentId + " not found"); + } + LocalDateTime currentLocalDateTime = LocalDateTime.now(); + if ((whiteboard.isGalleryWalkEnabled() && !whiteboard.isGalleryWalkFinished()) || ( + whiteboard.getRelativeTimeLimit() == 0 && (whiteboard.getAbsoluteTimeLimitFinish() == null + || Duration.between(whiteboard.getAbsoluteTimeLimitFinish(), currentLocalDateTime).toSeconds() + < 30))) { + // there can be no expired timers or the absolute timer expired less than 30 seconds ago, so no need to do anything + return; + } + + Date currentDate = new Date(); + List sessions = whiteboardSessionDao.getByContentId(toolContentId); + for (WhiteboardSession session : sessions) { + if (session.getStatus() == WhiteboardConstants.COMPLETED) { + // the result is already finished + continue; + } + List users = whiteboardUserDao.getBySessionID(session.getSessionId()); + boolean allUsersFinished = true; + for (WhiteboardUser user : users) { + boolean timeLimitExceeded = checkTimeLimitExceeded(whiteboard, user.getUserId().intValue()); + if (timeLimitExceeded) { + // the timer has expired, finish the result + user.setSessionFinished(true); + whiteboardUserDao.update(user); + } else { + allUsersFinished = false; + } + } + if (allUsersFinished) { + session.setStatus(WhiteboardConstants.COMPLETED); + whiteboardSessionDao.update(session); + } + } + } + + @Override public List getReflectList(Long contentId) { List reflections = new LinkedList<>(); Index: lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/web/controller/MonitoringController.java =================================================================== diff -u -r8c6ccd715c5bbd55bacc9a0f112d2ee9a870aa3d -r05ed44a065c7620fab4f05e4870d9428f87db685 --- lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 8c6ccd715c5bbd55bacc9a0f112d2ee9a870aa3d) +++ lams_tool_whiteboard/src/java/org/lamsfoundation/lams/tool/whiteboard/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 05ed44a065c7620fab4f05e4870d9428f87db685) @@ -140,6 +140,7 @@ } Whiteboard whiteboard = whiteboardService.getWhiteboardByContentId(contentId); + whiteboardService.finishExpiredSessions(contentId); //set SubmissionDeadline, if any if (whiteboard.getSubmissionDeadline() != null) {