Index: lams_tool_assessment/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -rebe7b8f43ffb5c0a69b930b307ff9eaf9baf8dc2 -ra8bfd33aa6963608e01ba5f7015031686ab113ae --- lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision ebe7b8f43ffb5c0a69b930b307ff9eaf9baf8dc2) +++ lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision a8bfd33aa6963608e01ba5f7015031686ab113ae) @@ -99,6 +99,7 @@ label.authoring.advance.grade.boundary =Grade boundary label.authoring.advance.feedback =Feedback label.authoring.advance.add.feedback.field =Add feedback +label.authoring.advance.question.etherpad = Show a discussion Etherpad after each question label.authoring.cancel.button =Cancel label.authoring.basic.answer.options =Answer options label.authoring.basic.instruction =Instructions @@ -372,6 +373,6 @@ admin.return =Return to maintain LAMS admin.button.save =Save admin.hide.titles =Hide question titles for learners +label.etherpad.discussion = Discussion - #======= End labels: Exported 365 labels for en AU ===== Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java =================================================================== diff -u -r51d4ec0a2ce479984ec5daf54c9a29029309428f -ra8bfd33aa6963608e01ba5f7015031686ab113ae --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java (.../AssessmentConstants.java) (revision 51d4ec0a2ce479984ec5daf54c9a29029309428f) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java (.../AssessmentConstants.java) (revision a8bfd33aa6963608e01ba5f7015031686ab113ae) @@ -265,4 +265,8 @@ public static final String ALLOW_PROTOCOL_REFIX = new String("[http://|https://|ftp://|nntp://]"); public static final String EVENT_NAME_NOTIFY_TEACHERS_ON_ASSIGMENT_SUBMIT = "notify_teachers_on_assigment_submit"; + + public static final String ATTR_IS_QUESTION_ETHERPAD_ENABLED = "isQuestionEtherpadEnabled"; + + public static final String ATTR_ALL_GROUP_USERS = "allGroupUsers"; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r8ea1e40c1667699690a4f1047e31dfaa0f372c76 -ra8bfd33aa6963608e01ba5f7015031686ab113ae --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 8ea1e40c1667699690a4f1047e31dfaa0f372c76) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision a8bfd33aa6963608e01ba5f7015031686ab113ae) @@ -418,7 +418,7 @@ @Override public void saveOrUpdateAssessment(Assessment assessment) { //update questions' hashes in case questions' titles or descriptions got changed - for (AssessmentQuestion question : (Set) assessment.getQuestions()) { + for (AssessmentQuestion question : assessment.getQuestions()) { String newHash = question.getQuestion() == null ? null : HashUtil.sha1(question.getQuestion()); question.setQuestionHash(newHash); } @@ -569,8 +569,7 @@ return questionResult; } - - + @Override public void storeSingleMarkHedgingQuestion(Assessment assessment, Long userId, List> pagedQuestions, Long singleMarkHedgingQuestionUid) @@ -592,10 +591,10 @@ } } } - + AssessmentQuestionResult questionResult = storeUserAnswer(result, questionDto); questionResult.setFinishDate(new Date()); - + float mark = 0; for (OptionDTO optionDto : questionDto.getOptionDtos()) { if (optionDto.isCorrect()) { @@ -608,7 +607,7 @@ questionResult.setMark(mark); questionResult.setMaxMark((float) questionDto.getGrade()); assessmentResultDao.saveObject(questionResult); - + //for displaying purposes calculate mark and set it to questionDto questionDto.setMark(mark); } @@ -716,10 +715,10 @@ if (assessment.isEnableConfidenceLevels()) { questionResult.setConfidenceLevel(questionDto.getConfidenceLevel()); } - + return questionResult; } - + /** * * @return grade that user scored by answering that question @@ -870,21 +869,21 @@ } } } - + //total mark can't be more than maxMark if (mark > maxMark) { mark = maxMark; - // in case options have negative grades (<0), their total mark can't be less than -maxMark + // in case options have negative grades (<0), their total mark can't be less than -maxMark } else if (mark < -maxMark) { mark = -maxMark; } // calculate penalty if (mark > 0) { // calculate number of wrong answers - int numberWrongAnswers = assessmentQuestionResultDao.getNumberWrongAnswersDoneBefore(assessmentUid, - userId, questionDto.getUid()); + int numberWrongAnswers = assessmentQuestionResultDao.getNumberWrongAnswersDoneBefore(assessmentUid, userId, + questionDto.getUid()); // calculate penalty itself float penalty = questionDto.getPenaltyFactor() * numberWrongAnswers; @@ -903,7 +902,7 @@ questionResult.setMark(mark); questionResult.setMaxMark(maxMark); } - + @Override public void loadupLastAttempt(Long assessmentUid, Long userId, List> pagedQuestionDtos) { //get the latest result (it can be unfinished one) @@ -938,7 +937,7 @@ } } } - + /** * Loads up all information from questionResult into questionDto. */ @@ -1078,7 +1077,7 @@ public int getAssessmentResultCount(Long assessmentUid, Long userId) { return assessmentResultDao.getAssessmentResultCount(assessmentUid, userId); } - + @Override public boolean isAssessmentAttempted(Long assessmentUid) { return assessmentResultDao.isAssessmentAttempted(assessmentUid); @@ -1163,7 +1162,7 @@ //finish non-leader sessionUser.setSessionFinished(true); assessmentUserDao.saveObject(user); - + //copy answers from leader to non-leaders copyAnswersFromLeader(sessionUser, session.getGroupLeader()); }); @@ -1307,7 +1306,7 @@ //otherwise show only questions from the question list } else { - for (QuestionReference reference : (Set) assessment.getQuestionReferences()) { + for (QuestionReference reference : assessment.getQuestionReferences()) { questions.add(reference.getQuestion()); } } @@ -1388,7 +1387,7 @@ sessionIdToUsersMap.put(sessionId, users); } - for (AssessmentQuestion question : (Set) assessment.getQuestions()) { + for (AssessmentQuestion question : assessment.getQuestions()) { Long questionUid = question.getUid(); QuestionSummary questionSummary = new QuestionSummary(); questionSummary.setQuestion(question); @@ -1448,7 +1447,7 @@ @Override public List exportSummary(Assessment assessment, List sessionDtos) { - List sheets = new LinkedList(); + List sheets = new LinkedList<>(); // -------------- First tab: Summary ---------------------------------------------------- ExcelSheet summarySheet = new ExcelSheet(getMessage("label.export.summary")); @@ -1599,8 +1598,8 @@ for (AssessmentQuestion question : questions) { ExcelRow questionTitle = questionSummarySheet.initRow(); - questionTitle.addCell( - getMessage("label.monitoring.question.summary.question") + " " + questionNumber++, true); + questionTitle.addCell(getMessage("label.monitoring.question.summary.question") + " " + questionNumber++, + true); // set up the summary table data for the top of the question area. boolean doSummaryTable = question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE @@ -1872,8 +1871,8 @@ return sheets; } - private ExcelRow startSummaryTable(AssessmentQuestion question, Map summaryOfAnswers, - Long trueKey, Long falseKey) { + private ExcelRow startSummaryTable(AssessmentQuestion question, Map summaryOfAnswers, Long trueKey, + Long falseKey) { ExcelRow summaryTableRow; int i = 0; if (question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE @@ -1978,16 +1977,16 @@ optionCell.setColor(IndexedColors.GREEN); } } - + } else { Double correctPercentage = total == 0 || summaryOfAnswers.get(trueKey) == null ? 0 : (double) summaryOfAnswers.get(trueKey) / total; ExcelCell correctCell = summaryTableRow.addPercentageCell(correctPercentage); - + Double wrongPercentage = total == 0 || summaryOfAnswers.get(falseKey) == null ? 0 : (double) summaryOfAnswers.get(falseKey) / total; ExcelCell wrongCell = summaryTableRow.addPercentageCell(wrongPercentage); - + if (question.getCorrectAnswer()) { correctCell.setColor(IndexedColors.GREEN); } else { @@ -1997,7 +1996,7 @@ Double summaryNAPercentage = total == 0 ? 0 : (double) summaryNACount / total; summaryTableRow.addPercentageCell(summaryNAPercentage); - + return summaryTableRow; } @@ -2091,7 +2090,7 @@ // create list of modified questions List modifiedQuestions = new ArrayList<>(); for (AssessmentQuestion oldQuestion : oldQuestions) { - + if (AssessmentConstants.QUESTION_TYPE_ESSAY == oldQuestion.getType() || AssessmentConstants.QUESTION_TYPE_MATCHING_PAIRS == oldQuestion.getType()) { continue; @@ -2103,7 +2102,7 @@ boolean isQuestionModified = false; // title or question is different - do nothing. Also question grade can't be changed - + //AssessmentConstants.QUESTION_TYPE_TRUE_FALSE if (oldQuestion.getCorrectAnswer() != newQuestion.getCorrectAnswer()) { isQuestionModified = true; @@ -2182,7 +2181,7 @@ float assessmentMark = assessmentResult.getGrade(); int assessmentMaxMark = assessmentResult.getMaximumGrade(); Set questionResults = assessmentResult.getQuestionResults(); - + // [+] if the question is modified for (AssessmentQuestionResult questionResult : questionResults) { AssessmentQuestion question = questionResult.getAssessmentQuestion(); @@ -2198,18 +2197,18 @@ loadupQuestionResultIntoQuestionDto(questionDto, questionResult); calculateAnswerMark(assessmentUid, user.getUserId(), questionResult, questionDto); assessmentQuestionResultDao.saveObject(questionResult); - + float newQuestionAnswerMark = questionResult.getMark(); assessmentMark += newQuestionAnswerMark - oldQuestionAnswerMark; break; } } } - + // [+] if the question reference mark is modified - for (AssessmentQuestionResult questionResult:questionResults) { + for (AssessmentQuestionResult questionResult : questionResults) { Long questionUid = questionResult.getAssessmentQuestion().getUid(); - + for (QuestionReference modifiedReference : modifiedReferences.keySet()) { if (!modifiedReference.isRandomQuestion() && questionUid.equals(modifiedReference.getQuestion().getUid())) { @@ -2316,7 +2315,7 @@ public void auditLogStartEditingActivityInMonitor(long toolContentID) { toolService.auditLogStartEditingActivityInMonitor(toolContentID); } - + @Override public boolean isLastActivity(Long toolSessionId) { return toolService.isLastActivity(toolSessionId); @@ -2532,8 +2531,7 @@ // reset it to new toolContentId toolContentObj.setContentId(toolContentId); - AssessmentUser user = assessmentUserDao.getUserCreatedAssessment(newUserUid.longValue(), - toolContentId); + AssessmentUser user = assessmentUserDao.getUserCreatedAssessment(newUserUid.longValue(), toolContentId); if (user == null) { user = new AssessmentUser(); UserDTO sysUser = ((User) userManagementService.findById(User.class, newUserUid)).getUserDTO(); @@ -2716,7 +2714,7 @@ @Override public List getConfidenceLevels(Long toolSessionId) { - List confidenceLevelDtos = new ArrayList(); + List confidenceLevelDtos = new ArrayList<>(); if (toolSessionId == null) { return confidenceLevelDtos; } @@ -2737,7 +2735,7 @@ for (AssessmentQuestionResult questionResult : assessmentResult.getQuestionResults()) { AssessmentQuestion question = questionResult.getAssessmentQuestion(); - List answers = new LinkedList(); + List answers = new LinkedList<>(); if (question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE) { @@ -2802,16 +2800,16 @@ return; } Assessment assessment = session.getAssessment(); - + AssessmentUser assessmentUser = getUserByIDAndSession(userId, toolSessionId); // create user if he hasn't accessed this activity yet if (assessmentUser == null) { assessmentUser = new AssessmentUser(user.getUserDTO(), session); createUser(assessmentUser); - + setAttemptStarted(assessment, assessmentUser, toolSessionId); } - + //finalize the latest result, if it's still active AssessmentResult lastAssessmentResult = getLastAssessmentResult(assessment.getUid(), userId); if (lastAssessmentResult != null && lastAssessmentResult.getFinishDate() == null) { @@ -2832,7 +2830,7 @@ //copy answers from leader to non-leaders copyAnswersFromLeader(sessionUser, groupLeader); }); - + } else { assessmentUser.setSessionFinished(true); assessmentUserDao.saveObject(user); @@ -3131,7 +3129,7 @@ @Override public void notifyLearnersOnAnswerDisclose(long toolContentId) { List sessions = assessmentSessionDao.getByContentId(toolContentId); - Set userIds = new HashSet(); + Set userIds = new HashSet<>(); for (AssessmentSession session : sessions) { for (AssessmentUser user : session.getAssessmentUsers()) { userIds.add(user.getUserId().intValue()); @@ -3142,4 +3140,9 @@ jsonCommand.put("hookTrigger", "assessment-results-refresh-" + toolContentId); learnerService.createCommandForLearners(toolContentId, userIds, jsonCommand.toString()); } + + @Override + public Collection getAllGroupUsers(Long toolSessionId) { + return toolService.getToolSession(toolSessionId).getLearners(); + } } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -r8ea1e40c1667699690a4f1047e31dfaa0f372c76 -ra8bfd33aa6963608e01ba5f7015031686ab113ae --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 8ea1e40c1667699690a4f1047e31dfaa0f372c76) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision a8bfd33aa6963608e01ba5f7015031686ab113ae) @@ -24,7 +24,7 @@ package org.lamsfoundation.lams.tool.assessment.service; import java.lang.reflect.InvocationTargetException; -import java.util.LinkedHashMap; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; @@ -47,7 +47,7 @@ import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; import org.lamsfoundation.lams.tool.assessment.model.QuestionReference; import org.lamsfoundation.lams.tool.service.ICommonToolService; -import org.lamsfoundation.lams.util.excel.ExcelCell; +import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.util.excel.ExcelSheet; /** @@ -230,7 +230,7 @@ * @param assessmentResult */ void setAttemptStarted(Assessment assessment, AssessmentUser assessmentUser, Long toolSessionId); - + void storeSingleMarkHedgingQuestion(Assessment assessment, Long userId, List> pagedQuestions, Long singleMarkHedgingQuestionUid) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException; @@ -248,7 +248,7 @@ */ boolean storeUserAnswers(Assessment assessment, Long userId, List> pagedQuestions, boolean isAutosave) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException; - + void loadupLastAttempt(Long assessmentUid, Long userId, List> pagedQuestionDtos); /** @@ -353,7 +353,7 @@ * @return */ int getAssessmentResultCount(Long assessmentUid, Long userId); - + /** * Checks whether anyone has attempted this assessment. */ @@ -529,4 +529,5 @@ */ void notifyLearnersOnAnswerDisclose(long toolContentId); + Collection getAllGroupUsers(Long toolSessionId); } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java =================================================================== diff -u -r20aa6cbca9fc96d341080e6ad39f82593443f792 -ra8bfd33aa6963608e01ba5f7015031686ab113ae --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java (.../LearningController.java) (revision 20aa6cbca9fc96d341080e6ad39f82593443f792) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java (.../LearningController.java) (revision a8bfd33aa6963608e01ba5f7015031686ab113ae) @@ -40,6 +40,7 @@ import java.util.SortedSet; import java.util.TimeZone; import java.util.TreeSet; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -48,7 +49,6 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.tool.ToolAccessMode; @@ -69,8 +69,11 @@ import org.lamsfoundation.lams.tool.assessment.util.AssessmentSessionComparator; import org.lamsfoundation.lams.tool.assessment.util.SequencableComparator; import org.lamsfoundation.lams.tool.assessment.web.form.ReflectionForm; +import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.util.AlphanumComparator; +import org.lamsfoundation.lams.util.Configuration; +import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.DateUtil; import org.lamsfoundation.lams.util.ValidationUtil; import org.lamsfoundation.lams.util.WebUtil; @@ -323,11 +326,11 @@ } //paging - List> pagedQuestionDtos = new ArrayList>(); + List> pagedQuestionDtos = new ArrayList<>(); int maxQuestionsPerPage = ((assessment.getQuestionsPerPage() != 0) && hasEditRight) ? assessment.getQuestionsPerPage() : questionDtos.size(); - LinkedHashSet questionsForOnePage = new LinkedHashSet(); + LinkedHashSet questionsForOnePage = new LinkedHashSet<>(); pagedQuestionDtos.add(questionsForOnePage); int count = 0; for (QuestionDTO questionDto : questionDtos) { @@ -359,6 +362,18 @@ service.setAttemptStarted(assessment, user, toolSessionId); } + boolean questionEtherpadEnabled = assessment.isUseSelectLeaderToolOuput() + && StringUtils.isNotBlank(Configuration.get(ConfigurationKeys.ETHERPAD_API_KEY)); + request.setAttribute(AssessmentConstants.ATTR_IS_QUESTION_ETHERPAD_ENABLED, questionEtherpadEnabled); + if (questionEtherpadEnabled) { + // get all users from the group, even if they did not reach the Scratchie yet + // order them by first and last name + Collection allGroupUsers = service.getAllGroupUsers(toolSessionId).stream() + .sorted(Comparator.comparing(u -> u.getFirstName() + u.getLastName())) + .collect(Collectors.toList()); + request.setAttribute(AssessmentConstants.ATTR_ALL_GROUP_USERS, allGroupUsers); + } + return "pages/learning/learning"; } } @@ -765,12 +780,13 @@ for (OptionDTO optionDto : questionDto.getOptionDtos()) { boolean answerBoolean = false; if (questionDto.isMultipleAnswersAllowed()) { - String answerString = request.getParameter( - AssessmentConstants.ATTR_QUESTION_PREFIX + i + "_" + optionDto.getUid()); + String answerString = request + .getParameter(AssessmentConstants.ATTR_QUESTION_PREFIX + i + "_" + optionDto.getUid()); answerBoolean = !StringUtils.isBlank(answerString); - + } else { - String optionUidSelectedStr = request.getParameter(AssessmentConstants.ATTR_QUESTION_PREFIX + i); + String optionUidSelectedStr = request + .getParameter(AssessmentConstants.ATTR_QUESTION_PREFIX + i); if (optionUidSelectedStr != null) { Long optionUidSelected = Long.parseLong(optionUidSelectedStr); answerBoolean = optionDto.getUid().equals(optionUidSelected); @@ -1010,7 +1026,7 @@ result.setTimeTaken(timeTaken); if (assessment.isAllowOverallFeedbackAfterQuestion()) { int percentageCorrectAnswers = (int) (result.getGrade() * 100 / result.getMaximumGrade()); - ArrayList overallFeedbacks = new ArrayList( + ArrayList overallFeedbacks = new ArrayList<>( assessment.getOverallFeedbacks()); int lastBorder = 0; for (int i = overallFeedbacks.size() - 1; i >= 0; i--) { @@ -1035,7 +1051,7 @@ // if answers are going to be disclosed, prepare data for the table in results page if (assessment.isAllowDiscloseAnswers()) { // such entities should not go into session map, but as request attributes instead - SortedSet sessions = new TreeSet( + SortedSet sessions = new TreeSet<>( new AssessmentSessionComparator()); sessions.addAll(service.getSessionsByContentId(assessment.getContentId())); request.setAttribute("sessions", sessions); Index: lams_tool_assessment/web/pages/learning/learning.jsp =================================================================== diff -u -r673e64304c12d78aa1b4ba819a39ae14f394ca42 -ra8bfd33aa6963608e01ba5f7015031686ab113ae --- lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision 673e64304c12d78aa1b4ba819a39ae14f394ca42) +++ lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision a8bfd33aa6963608e01ba5f7015031686ab113ae) @@ -29,6 +29,15 @@ + Index: lams_tool_assessment/web/pages/learning/parts/allquestions.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -ra8bfd33aa6963608e01ba5f7015031686ab113ae --- lams_tool_assessment/web/pages/learning/parts/allquestions.jsp (.../allquestions.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_assessment/web/pages/learning/parts/allquestions.jsp (.../allquestions.jsp) (revision a8bfd33aa6963608e01ba5f7015031686ab113ae) @@ -1,4 +1,14 @@ <%@ include file="/common/taglibs.jsp"%> + + + <%-- Prepare same content for each question Etherpad. Each group participant's first and last name --%> + +  :
+
+
+
+
+
@@ -71,5 +81,24 @@ + + <%--Display Etherpad for each question --%> + +
+ + +
+
+ ${questionEtherpadContent} +
+
+
+