private void verifyIsInstructorOfCourse(String courseId, String email) throws EntityDoesNotExistException { InstructorAttributes instructor = instructorsLogic.getInstructorForEmail(courseId, email); if (instructor == null) { throw new EntityDoesNotExistException( "User " + email + " is not a registered instructor for course " + courseId + "."); } }
/** Handles the logic related to {@link CommentAttributes}. */ public class CommentsLogic { private static CommentsLogic instance; @SuppressWarnings("unused") // used by test private static final Logger log = Utils.getLogger(); private static final CommentsDb commentsDb = new CommentsDb(); private static final CoursesLogic coursesLogic = CoursesLogic.inst(); private static final InstructorsLogic instructorsLogic = InstructorsLogic.inst(); private static final StudentsLogic studentsLogic = StudentsLogic.inst(); private static final FeedbackQuestionsLogic fqLogic = FeedbackQuestionsLogic.inst(); private static final FeedbackResponsesLogic frLogic = FeedbackResponsesLogic.inst(); private static final FeedbackResponseCommentsLogic frcLogic = FeedbackResponseCommentsLogic.inst(); public static CommentsLogic inst() { if (instance == null) { instance = new CommentsLogic(); } return instance; } /** ********** CRUD *********** */ public CommentAttributes createComment(CommentAttributes comment) throws InvalidParametersException, EntityAlreadyExistsException, EntityDoesNotExistException { verifyIsCoursePresent(comment.courseId, "create"); verifyIsInstructorOfCourse(comment.courseId, comment.giverEmail); return commentsDb.createEntity(comment); } public CommentAttributes getComment(Long commentId) { return commentsDb.getComment(commentId); } public List<CommentAttributes> getCommentsForGiver(String courseId, String giverEmail) throws EntityDoesNotExistException { verifyIsCoursePresent(courseId, "get"); return commentsDb.getCommentsForGiver(courseId, giverEmail); } public List<CommentAttributes> getCommentsForReceiver( String courseId, String giverEmail, CommentParticipantType recipientType, String receiverEmail) throws EntityDoesNotExistException { verifyIsCoursePresent(courseId, "get"); List<CommentAttributes> comments = commentsDb.getCommentsForReceiver(courseId, recipientType, receiverEmail); Iterator<CommentAttributes> iterator = comments.iterator(); while (iterator.hasNext()) { CommentAttributes c = iterator.next(); if (!c.giverEmail.equals(giverEmail)) { iterator.remove(); } } return comments; } public List<CommentAttributes> getCommentsForReceiver( String courseId, CommentParticipantType recipientType, String receiverEmail) throws EntityDoesNotExistException { verifyIsCoursePresent(courseId, "get"); return commentsDb.getCommentsForReceiver(courseId, recipientType, receiverEmail); } public List<CommentAttributes> getCommentsForSendingState( String courseId, CommentSendingState sendingState) throws EntityDoesNotExistException { verifyIsCoursePresent(courseId, "get"); return commentsDb.getCommentsForSendingState(courseId, sendingState); } public void updateCommentsSendingState( String courseId, CommentSendingState oldState, CommentSendingState newState) throws EntityDoesNotExistException { verifyIsCoursePresent(courseId, "clear pending"); commentsDb.updateComments(courseId, oldState, newState); } public CommentAttributes updateComment(CommentAttributes comment) throws InvalidParametersException, EntityDoesNotExistException { verifyIsCoursePresent(comment.courseId, "update"); return commentsDb.updateComment(comment); } /** * update comment's giver email (assume to be an instructor) * * @param courseId * @param oldInstrEmail * @param updatedInstrEmail */ public void updateInstructorEmail( String courseId, String oldInstrEmail, String updatedInstrEmail) { commentsDb.updateInstructorEmail(courseId, oldInstrEmail, updatedInstrEmail); } /** * update comment's recipient email (assume to be a student) * * @param courseId * @param oldStudentEmail * @param updatedStudentEmail */ public void updateStudentEmail( String courseId, String oldStudentEmail, String updatedStudentEmail) { commentsDb.updateStudentEmail(courseId, oldStudentEmail, updatedStudentEmail); } public void deleteCommentsForInstructor(String courseId, String instructorEmail) { commentsDb.deleteCommentsByInstructorEmail(courseId, instructorEmail); } public void deleteCommentsForStudent(String courseId, String studentEmail) { commentsDb.deleteCommentsByStudentEmail(courseId, studentEmail); } public void deleteCommentsForTeam(String courseId, String teamName) { commentsDb.deleteCommentsForTeam(courseId, teamName); } public void deleteCommentsForSection(String courseId, String sectionName) { commentsDb.deleteCommentsForSection(courseId, sectionName); } public void deleteCommentsForCourse(String courseId) { commentsDb.deleteCommentsForCourse(courseId); } public void deleteCommentAndDocument(CommentAttributes comment) { this.deleteComment(comment); this.deleteDocument(comment); } public void deleteComment(CommentAttributes comment) { commentsDb.deleteEntity(comment); } public void deleteDocument(CommentAttributes comment) { commentsDb.deleteDocument(comment); } public List<CommentAttributes> getCommentDrafts(String giverEmail) { return commentsDb.getCommentDrafts(giverEmail); } /** * Create or update document for comment * * @param comment */ public void putDocument(CommentAttributes comment) { commentsDb.putDocument(comment); } public CommentSearchResultBundle searchComment( String queryString, List<InstructorAttributes> instructors, String cursorString) { return commentsDb.search(queryString, instructors, cursorString); } private void verifyIsCoursePresent(String courseId, String action) throws EntityDoesNotExistException { if (!coursesLogic.isCoursePresent(courseId)) { throw new EntityDoesNotExistException( "Trying to " + action + " comments for a course that does not exist."); } } private void verifyIsInstructorOfCourse(String courseId, String email) throws EntityDoesNotExistException { InstructorAttributes instructor = instructorsLogic.getInstructorForEmail(courseId, email); if (instructor == null) { throw new EntityDoesNotExistException( "User " + email + " is not a registered instructor for course " + courseId + "."); } } /** ********** Get Comments For an Instructor *********** */ /** * Get comments visible for the given instructor * * @param instructor * @return list of {@link CommentAttributes} * @throws EntityDoesNotExistException when the course doesn't exist */ public List<CommentAttributes> getCommentsForInstructor(InstructorAttributes instructor) throws EntityDoesNotExistException { verifyIsCoursePresent(instructor.courseId, "get"); verifyIsInstructorOfCourse(instructor.courseId, instructor.email); HashSet<String> commentsVisitedSet = new HashSet<String>(); // When the given instructor is the comment giver, List<CommentAttributes> comments = getCommentsForGiverAndStatus(instructor.courseId, instructor.email, CommentStatus.FINAL); for (CommentAttributes c : comments) { preventAppendingThisCommentAgain(commentsVisitedSet, c); } // When other giver's comments are visible to the given instructor List<CommentAttributes> commentsForOtherInstructor = getCommentsForCommentViewer(instructor.courseId, CommentParticipantType.INSTRUCTOR); removeNonVisibleCommentsForInstructor(commentsForOtherInstructor, commentsVisitedSet, comments); java.util.Collections.sort(comments); return comments; } private void removeNonVisibleCommentsForInstructor( List<CommentAttributes> commentsForInstructor, HashSet<String> commentsVisitedSet, List<CommentAttributes> comments) { for (CommentAttributes c : commentsForInstructor) { removeGiverAndRecipientNameByVisibilityOptions(c, CommentParticipantType.INSTRUCTOR); appendComments(c, comments, commentsVisitedSet); } } private List<CommentAttributes> getCommentsForCommentViewer( String courseId, CommentParticipantType commentViewerType) throws EntityDoesNotExistException { verifyIsCoursePresent(courseId, "get"); return commentsDb.getCommentsForCommentViewer(courseId, commentViewerType); } private List<CommentAttributes> getCommentsForGiverAndStatus( String courseId, String giverEmail, CommentStatus status) throws EntityDoesNotExistException { verifyIsCoursePresent(courseId, "get"); return commentsDb.getCommentsForGiverAndStatus(courseId, giverEmail, status); } /** ********** Get Comments For a Student *********** */ /** * Get comments visible to the given student * * @param student * @return list of {@link CommentAttributes} * @throws EntityDoesNotExistException when the course doesn't exist */ public List<CommentAttributes> getCommentsForStudent(StudentAttributes student) throws EntityDoesNotExistException { verifyIsCoursePresent(student.course, "get"); List<StudentAttributes> teammates = studentsLogic.getStudentsForTeam(student.team, student.course); List<StudentAttributes> studentsInTheSameSection = studentsLogic.getStudentsForSection(student.section, student.course); List<String> teammatesEmails = getTeammatesEmails(teammates); List<String> sectionStudentsEmails = getSectionStudentsEmails(studentsInTheSameSection); List<String> teamsInThisSection = getTeamsForSection(studentsInTheSameSection); List<CommentAttributes> comments = new ArrayList<CommentAttributes>(); HashSet<String> commentsVisitedSet = new HashSet<String>(); // Get comments sent to the given student List<CommentAttributes> commentsForStudent = getCommentsForReceiver(student.course, CommentParticipantType.PERSON, student.email); removeNonVisibleCommentsForStudent(commentsForStudent, commentsVisitedSet, comments); // Get comments visible to the given student's teammates List<CommentAttributes> commentsForTeam = getCommentsForCommentViewer(student.course, CommentParticipantType.TEAM); removeNonVisibleCommentsForTeam( commentsForTeam, student, teammatesEmails, commentsVisitedSet, comments); // Get comments visible to the given student's section List<CommentAttributes> commentsForSection = getCommentsForCommentViewer(student.course, CommentParticipantType.SECTION); removeNonVisibleCommentsForSection( commentsForSection, student, teammatesEmails, sectionStudentsEmails, teamsInThisSection, commentsVisitedSet, comments); // Get comments visible to the whole course List<CommentAttributes> commentsForCourse = getCommentsForCommentViewer(student.course, CommentParticipantType.COURSE); removeNonVisibleCommentsForCourse( commentsForCourse, student, teammatesEmails, sectionStudentsEmails, teamsInThisSection, commentsVisitedSet, comments); java.util.Collections.sort(comments); return comments; } private List<String> getTeamsForSection(List<StudentAttributes> studentsInTheSameSection) { List<String> teams = new ArrayList<String>(); for (StudentAttributes stu : studentsInTheSameSection) { teams.add(stu.team); } return teams; } private List<String> getSectionStudentsEmails(List<StudentAttributes> studentsInTheSameSection) { List<String> sectionStudentsEmails = new ArrayList<String>(); for (StudentAttributes stu : studentsInTheSameSection) { sectionStudentsEmails.add(stu.email); } return sectionStudentsEmails; } private List<String> getTeammatesEmails(List<StudentAttributes> teammates) { List<String> teammatesEmails = new ArrayList<String>(); for (StudentAttributes teammate : teammates) { teammatesEmails.add(teammate.email); } return teammatesEmails; } private void removeNonVisibleCommentsForCourse( List<CommentAttributes> commentsForCourse, StudentAttributes student, List<String> teammates, List<String> sectionStudentsEmails, List<String> teamsInThisSection, HashSet<String> commentsVisitedSet, List<CommentAttributes> comments) { removeNonVisibleCommentsForSection( commentsForCourse, student, teammates, sectionStudentsEmails, teamsInThisSection, commentsVisitedSet, comments); for (CommentAttributes c : commentsForCourse) { if (c.courseId.equals(student.course)) { if (c.recipientType == CommentParticipantType.COURSE) { removeGiverNameByVisibilityOptions(c, CommentParticipantType.COURSE); } else { removeGiverAndRecipientNameByVisibilityOptions(c, CommentParticipantType.COURSE); } appendComments(c, comments, commentsVisitedSet); } } } private void removeNonVisibleCommentsForSection( List<CommentAttributes> commentsForSection, StudentAttributes student, List<String> teammatesEmails, List<String> sectionStudentsEmails, List<String> teamsInThisSection, HashSet<String> commentsVisitedSet, List<CommentAttributes> comments) { removeNonVisibleCommentsForTeam( commentsForSection, student, teammatesEmails, commentsVisitedSet, comments); for (CommentAttributes c : commentsForSection) { // for teammates if (c.recipientType == CommentParticipantType.PERSON && isCommentRecipientsWithinGroup(sectionStudentsEmails, c)) { if (c.showCommentTo.contains(CommentParticipantType.SECTION)) { removeGiverAndRecipientNameByVisibilityOptions(c, CommentParticipantType.SECTION); appendComments(c, comments, commentsVisitedSet); } else { preventAppendingThisCommentAgain(commentsVisitedSet, c); } // for team } else if (c.recipientType == CommentParticipantType.TEAM && isCommentRecipientsWithinGroup(teamsInThisSection, c)) { if (c.showCommentTo.contains(CommentParticipantType.SECTION)) { removeGiverNameByVisibilityOptions(c, CommentParticipantType.SECTION); appendComments(c, comments, commentsVisitedSet); } else { preventAppendingThisCommentAgain(commentsVisitedSet, c); } // for section } else if (c.recipientType == CommentParticipantType.SECTION && c.recipients.contains(student.section)) { if (c.showCommentTo.contains(CommentParticipantType.SECTION)) { removeGiverNameByVisibilityOptions(c, CommentParticipantType.SECTION); appendComments(c, comments, commentsVisitedSet); } else { preventAppendingThisCommentAgain(commentsVisitedSet, c); } } } } private void removeNonVisibleCommentsForTeam( List<CommentAttributes> commentsForTeam, StudentAttributes student, List<String> teammates, HashSet<String> commentsVisitedSet, List<CommentAttributes> comments) { for (CommentAttributes c : commentsForTeam) { // for teammates if (c.recipientType == CommentParticipantType.PERSON && isCommentRecipientsWithinGroup(teammates, c)) { if (c.showCommentTo.contains(CommentParticipantType.TEAM)) { removeGiverAndRecipientNameByVisibilityOptions(c, CommentParticipantType.TEAM); appendComments(c, comments, commentsVisitedSet); } else { preventAppendingThisCommentAgain(commentsVisitedSet, c); } // for team } else if (c.recipientType == CommentParticipantType.TEAM && c.recipients.contains(Sanitizer.sanitizeForHtml(student.team))) { if (c.showCommentTo.contains(CommentParticipantType.TEAM)) { removeGiverNameByVisibilityOptions(c, CommentParticipantType.TEAM); appendComments(c, comments, commentsVisitedSet); } else { preventAppendingThisCommentAgain(commentsVisitedSet, c); } } } } private void removeNonVisibleCommentsForStudent( List<CommentAttributes> commentsForStudent, HashSet<String> commentsVisitedSet, List<CommentAttributes> comments) { for (CommentAttributes c : commentsForStudent) { if (c.showCommentTo.contains(CommentParticipantType.PERSON)) { removeGiverNameByVisibilityOptions(c, CommentParticipantType.PERSON); appendComments(c, comments, commentsVisitedSet); } else { preventAppendingThisCommentAgain(commentsVisitedSet, c); } } } private void removeGiverNameByVisibilityOptions( CommentAttributes c, CommentParticipantType viewerType) { if (!c.showGiverNameTo.contains(viewerType)) { c.giverEmail = "Anonymous"; } } private void removeGiverAndRecipientNameByVisibilityOptions( CommentAttributes c, CommentParticipantType viewerType) { removeGiverNameByVisibilityOptions(c, viewerType); if (!c.showRecipientNameTo.contains(viewerType)) { c.recipients = new HashSet<String>(); c.recipients.add("Anonymous"); } } private void appendComments( CommentAttributes c, List<CommentAttributes> toThisCommentList, HashSet<String> commentsVisitedSet) { if (!commentsVisitedSet.contains(c.getCommentId().toString())) { toThisCommentList.add(c); preventAppendingThisCommentAgain(commentsVisitedSet, c); } } private void preventAppendingThisCommentAgain( HashSet<String> commentsVisitedSet, CommentAttributes c) { commentsVisitedSet.add(c.getCommentId().toString()); } private boolean isCommentRecipientsWithinGroup(List<String> group, CommentAttributes c) { for (String recipient : c.recipients) { if (group.contains(recipient)) { return true; } } return false; } /** ********** Send Email For Pending Comments *********** */ /** * Get recipient emails for comments with sending state. When pending comments are cleared, * they'll become sending comments. * * @param courseId * @return set of emails for recipients who can see the sending comments * @throws EntityDoesNotExistException when the course doesn't exist */ public Set<String> getRecipientEmailsForSendingComments(String courseId) throws EntityDoesNotExistException { List<StudentAttributes> allStudents = new StudentsDb().getStudentsForCourse(courseId); CourseRoster roster = new CourseRoster(allStudents, new InstructorsDb().getInstructorsForCourse(courseId)); Map<String, List<StudentAttributes>> teamStudentTable = new HashMap<String, List<StudentAttributes>>(); Map<String, List<StudentAttributes>> sectionStudentTable = new HashMap<String, List<StudentAttributes>>(); populateTeamSectionStudentTables(allStudents, teamStudentTable, sectionStudentTable); Set<String> recipientEmailsList = populateRecipientEmails( courseId, allStudents, roster, teamStudentTable, sectionStudentTable); return recipientEmailsList; } private Set<String> populateRecipientEmails( String courseId, List<StudentAttributes> allStudents, CourseRoster roster, Map<String, List<StudentAttributes>> teamStudentTable, Map<String, List<StudentAttributes>> sectionStudentTable) throws EntityDoesNotExistException { Set<String> recipientEmailsList = new HashSet<String>(); List<CommentAttributes> sendingCommentsList = commentsDb.getCommentsForSendingState(courseId, CommentSendingState.SENDING); populateRecipientEmailsFromPendingComments( sendingCommentsList, allStudents, roster, teamStudentTable, sectionStudentTable, recipientEmailsList); List<FeedbackResponseCommentAttributes> sendingResponseCommentsList = frcLogic.getFeedbackResponseCommentsForSendingState(courseId, CommentSendingState.SENDING); populateRecipientEmailsFromPendingResponseComments( sendingResponseCommentsList, allStudents, roster, teamStudentTable, recipientEmailsList); return recipientEmailsList; } private void populateTeamSectionStudentTables( List<StudentAttributes> allStudents, Map<String, List<StudentAttributes>> teamStudentTable, Map<String, List<StudentAttributes>> sectionStudentTable) { for (StudentAttributes student : allStudents) { List<StudentAttributes> teammates = teamStudentTable.get(student.team); if (teammates == null) { teammates = new ArrayList<StudentAttributes>(); teamStudentTable.put(student.team, teammates); } teammates.add(student); List<StudentAttributes> studentsInTheSameSection = sectionStudentTable.get(student.section); if (studentsInTheSameSection == null) { studentsInTheSameSection = new ArrayList<StudentAttributes>(); sectionStudentTable.put(student.section, studentsInTheSameSection); } studentsInTheSameSection.add(student); } } /** * ********** Send Email For Pending Comments : populate recipients emails from Feedback Response * Comments *********** */ private void populateRecipientEmailsFromPendingResponseComments( List<FeedbackResponseCommentAttributes> sendingResponseCommentsList, List<StudentAttributes> allStudents, CourseRoster roster, Map<String, List<StudentAttributes>> teamStudentTable, Set<String> recipientEmailsList) { Map<String, FeedbackQuestionAttributes> feedbackQuestionsTable = new HashMap<String, FeedbackQuestionAttributes>(); Map<String, FeedbackResponseAttributes> feedbackResponsesTable = new HashMap<String, FeedbackResponseAttributes>(); Map<String, Set<String>> responseCommentsAddedTable = new HashMap<String, Set<String>>(); for (FeedbackResponseCommentAttributes frc : sendingResponseCommentsList) { FeedbackQuestionAttributes relatedQuestion = getRelatedQuestion(feedbackQuestionsTable, frc); FeedbackResponseAttributes relatedResponse = getRelatedResponse(feedbackResponsesTable, frc); if (relatedQuestion != null && relatedResponse != null) { populateRecipientEmailsForGiver( roster, teamStudentTable, recipientEmailsList, responseCommentsAddedTable, frc, relatedQuestion, relatedResponse); populateRecipientEmailsForReceiver( roster, teamStudentTable, recipientEmailsList, responseCommentsAddedTable, frc, relatedResponse); populateRecipientEmailsForTeamMember( roster, teamStudentTable, recipientEmailsList, responseCommentsAddedTable, frc, relatedResponse); populateRecipientEmailsForAllStudents( allStudents, recipientEmailsList, responseCommentsAddedTable, frc); } } } private void populateRecipientEmailsForAllStudents( List<StudentAttributes> allStudents, Set<String> recipientEmailsList, Map<String, Set<String>> responseCommentsAddedTable, FeedbackResponseCommentAttributes frc) { if (frc.isVisibleTo(FeedbackParticipantType.STUDENTS)) { for (StudentAttributes student : allStudents) { addRecipientEmailsToList( responseCommentsAddedTable, recipientEmailsList, frc.getId().toString(), student.email); } } } private void populateRecipientEmailsForTeamMember( CourseRoster roster, Map<String, List<StudentAttributes>> teamStudentTable, Set<String> recipientEmailsList, Map<String, Set<String>> responseCommentsAddedTable, FeedbackResponseCommentAttributes frc, FeedbackResponseAttributes relatedResponse) { if (frc.isVisibleTo(FeedbackParticipantType.RECEIVER_TEAM_MEMBERS)) { StudentAttributes studentOfThisEmail = roster.getStudentForEmail(relatedResponse.recipient); if (studentOfThisEmail == null) { addRecipientEmailsForTeam( teamStudentTable, recipientEmailsList, responseCommentsAddedTable, frc.getId().toString(), relatedResponse.recipient); } else { addRecipientEmailsForTeam( teamStudentTable, recipientEmailsList, responseCommentsAddedTable, frc.getId().toString(), studentOfThisEmail.team); } } } private void populateRecipientEmailsForReceiver( CourseRoster roster, Map<String, List<StudentAttributes>> teamStudentTable, Set<String> recipientEmailsList, Map<String, Set<String>> responseCommentsAddedTable, FeedbackResponseCommentAttributes frc, FeedbackResponseAttributes relatedResponse) { if (frc.isVisibleTo(FeedbackParticipantType.RECEIVER)) { // recipientEmail is email if (roster.getStudentForEmail(relatedResponse.recipient) == null) { addRecipientEmailsForTeam( teamStudentTable, recipientEmailsList, responseCommentsAddedTable, frc.getId().toString(), relatedResponse.recipient); } else { addRecipientEmailsToList( responseCommentsAddedTable, recipientEmailsList, frc.getId().toString(), relatedResponse.recipient); } } } private void populateRecipientEmailsForGiver( CourseRoster roster, Map<String, List<StudentAttributes>> teamStudentTable, Set<String> recipientEmailsList, Map<String, Set<String>> responseCommentsAddedTable, FeedbackResponseCommentAttributes frc, FeedbackQuestionAttributes relatedQuestion, FeedbackResponseAttributes relatedResponse) { StudentAttributes giver = roster.getStudentForEmail(relatedResponse.giver); if (giver == null) { return; } if (frc.isVisibleTo(FeedbackParticipantType.GIVER)) { addRecipientEmailsToList( responseCommentsAddedTable, recipientEmailsList, frc.getId().toString(), relatedResponse.giver); } if (relatedQuestion.giverType == FeedbackParticipantType.TEAMS || frc.isVisibleTo(FeedbackParticipantType.OWN_TEAM_MEMBERS)) { addRecipientEmailsForTeam( teamStudentTable, recipientEmailsList, responseCommentsAddedTable, frc.getId().toString(), giver.team); } } private FeedbackResponseAttributes getRelatedResponse( Map<String, FeedbackResponseAttributes> feedbackResponsesTable, FeedbackResponseCommentAttributes frc) { FeedbackResponseAttributes relatedResponse = feedbackResponsesTable.get(frc.feedbackResponseId); if (relatedResponse == null) { relatedResponse = frLogic.getFeedbackResponse(frc.feedbackResponseId); feedbackResponsesTable.put(frc.feedbackResponseId, relatedResponse); } return relatedResponse; } private FeedbackQuestionAttributes getRelatedQuestion( Map<String, FeedbackQuestionAttributes> feedbackQuestionsTable, FeedbackResponseCommentAttributes frc) { FeedbackQuestionAttributes relatedQuestion = feedbackQuestionsTable.get(frc.feedbackQuestionId); if (relatedQuestion == null) { relatedQuestion = fqLogic.getFeedbackQuestion(frc.feedbackQuestionId); feedbackQuestionsTable.put(frc.feedbackQuestionId, relatedQuestion); } return relatedQuestion; } /** * ********** Send Email For Pending Comments : populate recipients emails from Student Comments * *********** */ private void populateRecipientEmailsFromPendingComments( List<CommentAttributes> sendingCommentsList, List<StudentAttributes> allStudents, CourseRoster roster, Map<String, List<StudentAttributes>> teamStudentTable, Map<String, List<StudentAttributes>> sectionStudentTable, Set<String> recipientEmailList) { Map<String, Set<String>> studentCommentsAddedTable = new HashMap<String, Set<String>>(); for (CommentAttributes pendingComment : sendingCommentsList) { populateRecipientEmailsForPerson( recipientEmailList, studentCommentsAddedTable, pendingComment); populateRecipientEmailsForTeam( recipientEmailList, roster, teamStudentTable, studentCommentsAddedTable, pendingComment); populateRecipientEmailsForSection( recipientEmailList, roster, teamStudentTable, sectionStudentTable, studentCommentsAddedTable, pendingComment); populateRecipientEmailsForCourse( recipientEmailList, allStudents, studentCommentsAddedTable, pendingComment); } } private void populateRecipientEmailsForCourse( Set<String> recipientEmailList, List<StudentAttributes> allStudents, Map<String, Set<String>> studentCommentsAddedTable, CommentAttributes pendingComment) { if (pendingComment.isVisibleTo(CommentParticipantType.COURSE)) { for (StudentAttributes student : allStudents) { addRecipientEmailsToList( studentCommentsAddedTable, recipientEmailList, pendingComment.getCommentId().toString(), student.email); } } } private void populateRecipientEmailsForSection( Set<String> recipientEmailList, CourseRoster roster, Map<String, List<StudentAttributes>> teamStudentTable, Map<String, List<StudentAttributes>> sectionStudentTable, Map<String, Set<String>> studentCommentsAddedTable, CommentAttributes pendingComment) { String commentId = pendingComment.getCommentId().toString(); if (pendingComment.isVisibleTo(CommentParticipantType.SECTION)) { if (pendingComment.recipientType == CommentParticipantType.PERSON) { for (String recipientEmail : pendingComment.recipients) { StudentAttributes student = roster.getStudentForEmail(recipientEmail); if (student == null) { continue; } addRecipientEmailsForSection( sectionStudentTable, recipientEmailList, studentCommentsAddedTable, commentId, student.section); } } else if (pendingComment.recipientType == CommentParticipantType.TEAM) { for (String team : pendingComment.recipients) { List<StudentAttributes> students = teamStudentTable.get(team); if (students == null) { continue; } for (StudentAttributes stu : students) { addRecipientEmailsForSection( sectionStudentTable, recipientEmailList, studentCommentsAddedTable, commentId, stu.section); } } } else if (pendingComment.recipientType == CommentParticipantType.SECTION) { for (String section : pendingComment.recipients) { addRecipientEmailsForSection( sectionStudentTable, recipientEmailList, studentCommentsAddedTable, commentId, section); } } } else { // not visible to SECTION if (pendingComment.recipientType == CommentParticipantType.PERSON) { for (String recipientEmail : pendingComment.recipients) { StudentAttributes student = roster.getStudentForEmail(recipientEmail); if (student == null) { continue; } preventAddRecipientEmailsForSection( teamStudentTable, studentCommentsAddedTable, commentId, student.section); } } else if (pendingComment.recipientType == CommentParticipantType.TEAM) { for (String team : pendingComment.recipients) { List<StudentAttributes> students = teamStudentTable.get(team); if (students == null) { continue; } for (StudentAttributes stu : students) { preventAddRecipientEmailsForSection( teamStudentTable, studentCommentsAddedTable, commentId, stu.section); } } } else if (pendingComment.recipientType == CommentParticipantType.SECTION) { for (String section : pendingComment.recipients) { preventAddRecipientEmailsForSection( teamStudentTable, studentCommentsAddedTable, commentId, section); } } } } private void populateRecipientEmailsForTeam( Set<String> recipientEmailList, CourseRoster roster, Map<String, List<StudentAttributes>> teamStudentTable, Map<String, Set<String>> studentCommentsAddedTable, CommentAttributes pendingComment) { String commentId = pendingComment.getCommentId().toString(); if (pendingComment.isVisibleTo(CommentParticipantType.TEAM)) { if (pendingComment.recipientType == CommentParticipantType.PERSON) { for (String recipientEmail : pendingComment.recipients) { StudentAttributes student = roster.getStudentForEmail(recipientEmail); if (student == null) { continue; } addRecipientEmailsForTeam( teamStudentTable, recipientEmailList, studentCommentsAddedTable, commentId, student.team); } } else if (pendingComment.recipientType == CommentParticipantType.TEAM) { for (String team : pendingComment.recipients) { addRecipientEmailsForTeam( teamStudentTable, recipientEmailList, studentCommentsAddedTable, commentId, team); } } } else { // not visible to TEAM if (pendingComment.recipientType == CommentParticipantType.PERSON) { for (String recipientEmail : pendingComment.recipients) { StudentAttributes student = roster.getStudentForEmail(recipientEmail); if (student == null) { continue; } preventAddRecipientEmailsForTeam( teamStudentTable, studentCommentsAddedTable, commentId, student.team); } } else if (pendingComment.recipientType == CommentParticipantType.TEAM) { for (String team : pendingComment.recipients) { preventAddRecipientEmailsForTeam( teamStudentTable, studentCommentsAddedTable, commentId, team); } } } } private void populateRecipientEmailsForPerson( Set<String> recipientEmailList, Map<String, Set<String>> studentCommentsAddedTable, CommentAttributes pendingComment) { String commentId = pendingComment.getCommentId().toString(); if (pendingComment.isVisibleTo(CommentParticipantType.PERSON)) { for (String recipientEmail : pendingComment.recipients) { addRecipientEmailsToList( studentCommentsAddedTable, recipientEmailList, commentId, recipientEmail); } } else { // not visible to PERSON for (String recipientEmail : pendingComment.recipients) { preventAddRecipientEmailsToList(studentCommentsAddedTable, commentId, recipientEmail); } } } private void addRecipientEmailsToList( Map<String, Set<String>> isAddedTable, Set<String> targetTable, String subKey, String key) { // prevent re-entry Set<String> commentIdsSet = isAddedTable.get(key); if (commentIdsSet == null) { commentIdsSet = new HashSet<String>(); isAddedTable.put(key, commentIdsSet); } if (!commentIdsSet.contains(subKey)) { commentIdsSet.add(subKey); targetTable.add(key); } } private void addRecipientEmailsForSection( Map<String, List<StudentAttributes>> sectionStudentTable, Set<String> recipientEmailsList, Map<String, Set<String>> responseCommentsAddedTable, String commentId, String sectionName) { List<StudentAttributes> students = sectionStudentTable.get(sectionName); if (students == null) { return; } for (StudentAttributes stu : students) { addRecipientEmailsToList( responseCommentsAddedTable, recipientEmailsList, commentId, stu.email); } } private void addRecipientEmailsForTeam( Map<String, List<StudentAttributes>> teamStudentTable, Set<String> recipientEmailsList, Map<String, Set<String>> responseCommentsAddedTable, String commentId, String teamName) { List<StudentAttributes> students = teamStudentTable.get(teamName); if (students == null) { return; } for (StudentAttributes stu : students) { addRecipientEmailsToList( responseCommentsAddedTable, recipientEmailsList, commentId, stu.email); } } private void preventAddRecipientEmailsToList( Map<String, Set<String>> isAddedTable, String subKey, String key) { Set<String> commentIdsSet = isAddedTable.get(key); if (commentIdsSet == null) { commentIdsSet = new HashSet<String>(); isAddedTable.put(key, commentIdsSet); } commentIdsSet.add(subKey); } private void preventAddRecipientEmailsForSection( Map<String, List<StudentAttributes>> sectionStudentTable, Map<String, Set<String>> isAddedTable, String commentId, String section) { List<StudentAttributes> students = sectionStudentTable.get(section); if (students == null) { return; } for (StudentAttributes stu : students) { preventAddRecipientEmailsToList(isAddedTable, commentId, stu.email); } } private void preventAddRecipientEmailsForTeam( Map<String, List<StudentAttributes>> teamStudentTable, Map<String, Set<String>> isAddedTable, String commentId, String team) { List<StudentAttributes> teammates = teamStudentTable.get(team); if (teammates == null) { return; } for (StudentAttributes teamMember : teammates) { preventAddRecipientEmailsToList(isAddedTable, commentId, teamMember.email); } } @SuppressWarnings("deprecation") public List<CommentAttributes> getAllComments() { return commentsDb.getAllComments(); } /** * Sends notifications to students in course {@code courseId} who have received comments and not * yet been notified. */ public void sendCommentNotification(String courseId) { Map<String, String> paramMap = new HashMap<String, String>(); paramMap.put(Const.ParamsNames.EMAIL_COURSE, courseId); paramMap.put(Const.ParamsNames.EMAIL_TYPE, EmailType.PENDING_COMMENT_CLEARED.toString()); TaskQueuesLogic taskQueueLogic = TaskQueuesLogic.inst(); taskQueueLogic.createAndAddTask( Const.SystemParams.EMAIL_TASK_QUEUE, Const.ActionURIs.EMAIL_WORKER, paramMap); } }