Index: lams_central/src/java/org/lamsfoundation/lams/web/RatingServlet.java =================================================================== diff -u -r33829c670fd8c90447d62ea3300498a103905e7a -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_central/src/java/org/lamsfoundation/lams/web/RatingServlet.java (.../RatingServlet.java) (revision 33829c670fd8c90447d62ea3300498a103905e7a) +++ lams_central/src/java/org/lamsfoundation/lams/web/RatingServlet.java (.../RatingServlet.java) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -49,6 +49,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.support.SpringBeanAutowiringSupport; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -122,10 +123,20 @@ if (criteria.isCommentsEnabled()) { // can have but do not have to have comment String comment = WebUtil.readStrParam(request, "comment", true); + if (comment != null) { ratingService.commentItem(criteria, toolSessionId, userId, itemId, comment); + responseJSON.put("comment", StringEscapeUtils.escapeCsv(comment)); + boolean showAllComments = WebUtil.readBooleanParam(request, "showAllComments", false); + if (showAllComments) { + ArrayNode allCommentsJSON = JsonNodeFactory.instance.arrayNode(); + ratingService.getCommentsByCriteriaAndItem(ratingCriteriaId, null, itemId) + .forEach(c -> allCommentsJSON.add(c.getComment())); + responseJSON.set("allComments", allCommentsJSON); + } } + } String floatString = request.getParameter("rate"); Index: lams_central/web/includes/javascript/rating.js =================================================================== diff -u -rf5d73e30a128c7057badb289646cd9a9ce4b95f5 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_central/web/includes/javascript/rating.js (.../rating.js) (revision f5d73e30a128c7057badb289646cd9a9ce4b95f5) +++ lams_central/web/includes/javascript/rating.js (.../rating.js) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -108,6 +108,7 @@ $(".add-comment-new").click(function() { var itemId = $(this).data("item-id"); var commentsCriteriaId = $(this).data("comment-criteria-id"); + var showAllComments = $(this).data('show-all-comments'); var comment = validComment("comment-textarea-" + itemId, false, false); if ( ! comment ) @@ -124,20 +125,33 @@ hasRatingLimits: HAS_RATING_LIMITS, ratingLimitsByCriteria: ratingLimitsByCriteria, maxRatingsForItem: maxRatingsForItem, + showAllComments : showAllComments, toolSessionId: SESSION_ID }, success: function(data, textStatus) { if ( data.error ) { handleError(); } else { - //add comment to HTML - jQuery('
', { - 'class': "rating-comment", - html: data.comment - }).appendTo('#comments-area-' + itemId); + var commentsArea = $('#comments-area-' + itemId); + + if (data.allComments) { + // add all users' comments to HTML + jQuery.each(data.allComments, function(){ + jQuery('
', { + 'class': "rating-comment", + html: this + }).appendTo(commentsArea); + }); + } else { + //add this user's comment to HTML + jQuery('
', { + 'class': "rating-comment", + html: data.comment + }).appendTo(commentsArea); + } //hide comments textarea and button - $("#add-comment-area-" + itemId).hide(); + $("#add-comment-area-" + itemId, commentsArea).hide(); //handle rating limits if available if (HAS_RATING_LIMITS) { Index: lams_common/src/java/org/lamsfoundation/lams/rating/dao/IRatingDAO.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_common/src/java/org/lamsfoundation/lams/rating/dao/IRatingDAO.java (.../IRatingDAO.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_common/src/java/org/lamsfoundation/lams/rating/dao/IRatingDAO.java (.../IRatingDAO.java) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -21,8 +21,6 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.rating.dao; import java.util.Collection; @@ -35,7 +33,7 @@ public interface IRatingDAO { void saveOrUpdate(Object object); - + void delete(Object object); /** Not limiting by session as the userId is restrictive enough */ @@ -58,6 +56,10 @@ */ ItemRatingCriteriaDTO getRatingAverageDTOByItem(Long ratingCriteriaId, Long toolSessionId, Long itemId); + List getRatingAverageByContentAndItem(Long contentId, Long itemId); + + List getRatingAverageByContentAndItems(Long contentId, Collection itemIds); + List getRatingAverageByContentAndItem(Long contentId, Long toolSessionId, Long itemId); /** @@ -91,8 +93,10 @@ int getCountItemsRatedByUser(final Long toolContentId, final Integer userId); /** - * Returns number of items rated by specified user in a current activity, for a particular criteria. It counts comments as ratings - * iff it is a comment rating. This method is applicable only for RatingCriterias of LEARNER_ITEM_CRITERIA_TYPE type. + * Returns number of items rated by specified user in a current activity, for a particular criteria. It counts + * comments as ratings + * iff it is a comment rating. This method is applicable only for RatingCriterias of LEARNER_ITEM_CRITERIA_TYPE + * type. * * @param toolContentId * @param userId @@ -108,30 +112,29 @@ * @param excludeUserId * @return */ - Map countUsersRatedEachItem(final Long contentId, final Long toolSessionId, final Collection itemIds, - Integer excludeUserId); + Map countUsersRatedEachItem(final Long contentId, final Long toolSessionId, + final Collection itemIds, Integer excludeUserId); /** - * Count how many users rated and commented each item for a particular criteria, + * Count how many users rated and commented each item for a particular criteria, * limiting to a particular session if toolSessionId is not null * * @param contentId * @param itemIds * @param excludeUserId * @return */ - Map countUsersRatedEachItemByCriteria(final Long criteriaId, final Long toolSessionId, final Collection itemIds, - Integer excludeUserId); + Map countUsersRatedEachItemByCriteria(final Long criteriaId, final Long toolSessionId, + final Collection itemIds, Integer excludeUserId); - - /** - * Used by tools to get the ratings and comments relating to their items. To be used within SQL and supply the toolContentId as :toolContentId. - * See Peer Review for example usage. + * Used by tools to get the ratings and comments relating to their items. To be used within SQL and supply the + * toolContentId as :toolContentId. + * See Peer Review for example usage. */ String getRatingSelectJoinSQL(Integer ratingStyle, boolean getByUser); - - /** + + /** * Get all the raw ratings for a combination of criteria and item ids. Used by Peer Review to do SPA analysis. */ List getRatingsByCriteriasAndItems(Collection ratingCriteriaIds, Collection itemIds); Index: lams_common/src/java/org/lamsfoundation/lams/rating/dao/hibernate/RatingCommentDAO.java =================================================================== diff -u -r96068ffc66514c1d25e9adeb96acfa164ab29dd5 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_common/src/java/org/lamsfoundation/lams/rating/dao/hibernate/RatingCommentDAO.java (.../RatingCommentDAO.java) (revision 96068ffc66514c1d25e9adeb96acfa164ab29dd5) +++ lams_common/src/java/org/lamsfoundation/lams/rating/dao/hibernate/RatingCommentDAO.java (.../RatingCommentDAO.java) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -20,14 +20,15 @@ * **************************************************************** */ - package org.lamsfoundation.lams.rating.dao.hibernate; import java.util.Collection; import java.util.Date; import java.util.LinkedList; import java.util.List; +import javax.persistence.Query; + import org.lamsfoundation.lams.dao.hibernate.LAMSBaseDAO; import org.lamsfoundation.lams.rating.dao.IRatingCommentDAO; import org.lamsfoundation.lams.rating.dto.RatingCommentDTO; @@ -39,11 +40,11 @@ private static final String FIND_COMMENTS_BY_CRITERIA_AND_ITEM = "SELECT r.itemId, r.learner.userId, r.comment, CONCAT(r.learner.firstName, ' ', r.learner.lastName), r.postedDate " + "FROM " + RatingComment.class.getName() - + " AS r where r.ratingCriteria.ratingCriteriaId=? AND r.toolSessionId=? AND r.itemId=?"; + + " AS r where r.ratingCriteria.ratingCriteriaId=:ratingCriteriaId AND r.itemId=:itemId"; private static final String FIND_COMMENTS_BY_CRITERIA_AND_ITEMS = "SELECT r.itemId, r.learner.userId, r.comment, CONCAT(r.learner.firstName, ' ', r.learner.lastName), r.postedDate " + "FROM " + RatingComment.class.getName() - + " AS r where r.ratingCriteria.ratingCriteriaId=:ratingCriteriaId AND r.toolSessionId=:toolSessionId AND r.itemId IN (:itemIds)"; + + " AS r where r.ratingCriteria.ratingCriteriaId=:ratingCriteriaId AND r.itemId IN (:itemIds)"; private static final String FIND_COMMENTS_BY_CRITERIA_AND_ITEMS_AND_USER = "SELECT r.itemId, r.learner.userId, r.comment " + "FROM " + RatingComment.class.getName() @@ -52,24 +53,43 @@ private static final String FIND_COMMENTS_BY_CRITERIA = "SELECT r.itemId, r.learner.userId, r.comment " + "FROM " + RatingComment.class.getName() + " AS r where r.ratingCriteria.ratingCriteriaId=? AND r.toolSessionId=?"; - private static final String FIND_RELATED_COMMENT_BY_CRITERIA_AND_USER = "SELECT r.itemId, r.learner.userId, r.comment FROM " + RatingComment.class.getName() + private static final String FIND_RELATED_COMMENT_BY_CRITERIA_AND_USER = "SELECT r.itemId, r.learner.userId, r.comment FROM " + + RatingComment.class.getName() + " AS r where r.ratingCriteria.ratingCriteriaId=:ratingCriteriaId AND r.learner.userId=:userId"; + @SuppressWarnings("unchecked") @Override public List getCommentsByCriteriaAndItem(Long ratingCriteriaId, Long toolSessionId, Long itemId) { - List results = (List) (doFind(FIND_COMMENTS_BY_CRITERIA_AND_ITEM, - new Object[] { ratingCriteriaId, toolSessionId, itemId })); + String queryText = FIND_COMMENTS_BY_CRITERIA_AND_ITEM; + if (toolSessionId != null) { + queryText += " AND r.toolSessionId=:toolSessionId"; + } + Query query = getSession().createQuery(queryText).setParameter("ratingCriteriaId", ratingCriteriaId) + .setParameter("itemId", itemId); + if (toolSessionId != null) { + query.setParameter("toolSessionId", toolSessionId); + } + List results = query.getResultList(); + return convertIntoCommentDtos(results); } + @SuppressWarnings("unchecked") @Override - public List getCommentsByCriteriaAndItems(Long ratingCriteriaId, Long toolSessionId, Collection itemIds) { + public List getCommentsByCriteriaAndItems(Long ratingCriteriaId, Long toolSessionId, + Collection itemIds) { + String queryText = FIND_COMMENTS_BY_CRITERIA_AND_ITEMS; - List results = getSession().createQuery(FIND_COMMENTS_BY_CRITERIA_AND_ITEMS) - .setParameter("ratingCriteriaId", ratingCriteriaId).setParameter("toolSessionId", toolSessionId) - .setParameterList("itemIds", itemIds).list(); - + if (toolSessionId != null) { + queryText += " AND r.toolSessionId=:toolSessionId"; + } + Query query = getSession().createQuery(queryText).setParameter("ratingCriteriaId", ratingCriteriaId) + .setParameterList("itemIds", itemIds); + if (toolSessionId != null) { + query.setParameter("toolSessionId", toolSessionId); + } + List results = query.getResultList(); return convertIntoCommentDtos(results); } @@ -86,31 +106,30 @@ @Override public List getCommentsByCriteria(Long ratingCriteriaId, Long toolSessionId) { - List results = (List) (doFind(FIND_COMMENTS_BY_CRITERIA, - new Object[] { ratingCriteriaId, toolSessionId })); + List results = (doFind(FIND_COMMENTS_BY_CRITERIA, new Object[] { ratingCriteriaId, toolSessionId })); return convertIntoCommentDtos(results); } @Override public List getRelatedCommentByCriteriaAndUser(Long ratingCriteriaId, Integer userId) { List results = getSession().createQuery(FIND_RELATED_COMMENT_BY_CRITERIA_AND_USER) - .setParameter("ratingCriteriaId", ratingCriteriaId) - .setParameter("userId", userId).list(); + .setParameter("ratingCriteriaId", ratingCriteriaId).setParameter("userId", userId).list(); return convertIntoCommentDtos(results); } + /* * Converts DB results presentation into list of RatingCommentDTO. * * @param results - * + * * @return */ private List convertIntoCommentDtos(List results) { //populate RatingCommentDTOs list - List commentDtos = new LinkedList(); + List commentDtos = new LinkedList<>(); for (Object[] result : results) { Long itemId = (Long) result[0]; Long userId = ((Integer) result[1]).longValue(); @@ -133,20 +152,20 @@ @Override public RatingComment getComment(Long ratingCriteriaId, Integer userId, Long itemId) { - List list = (List) doFind(FIND_RATING_BY_CRITERIA_AND_USER_AND_ITEM, + List list = doFind(FIND_RATING_BY_CRITERIA_AND_USER_AND_ITEM, new Object[] { ratingCriteriaId, userId, itemId }); if (list.size() > 0) { return list.get(0); } else { return null; } } - + @Override public List getCommentsByContentAndUser(Long contentId, Integer userId) { final String FIND_RATINGS_BY_USER = "FROM " + RatingComment.class.getName() + " AS r where r.ratingCriteria.toolContentId=? AND r.learner.userId=?"; - return (List) doFind(FIND_RATINGS_BY_USER, new Object[] { contentId, userId }); + return doFind(FIND_RATINGS_BY_USER, new Object[] { contentId, userId }); } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/rating/dao/hibernate/RatingDAO.java =================================================================== diff -u -r96068ffc66514c1d25e9adeb96acfa164ab29dd5 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_common/src/java/org/lamsfoundation/lams/rating/dao/hibernate/RatingDAO.java (.../RatingDAO.java) (revision 96068ffc66514c1d25e9adeb96acfa164ab29dd5) +++ lams_common/src/java/org/lamsfoundation/lams/rating/dao/hibernate/RatingDAO.java (.../RatingDAO.java) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -21,8 +21,6 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.rating.dao.hibernate; import java.util.Collection; @@ -60,30 +58,38 @@ + " AS r where r.ratingCriteria.ratingCriteriaId IN (:ratingCriteriaIds) AND r.itemId IN (:itemIds)"; private static final String FIND_RATING_AVERAGE_BY_ITEM = "SELECT AVG(r.rating), COUNT(*) FROM " - + Rating.class.getName() + " AS r where r.ratingCriteria.ratingCriteriaId=? AND r.toolSessionId=? AND r.itemId=?"; + + Rating.class.getName() + + " AS r where r.ratingCriteria.ratingCriteriaId=? AND r.toolSessionId=? AND r.itemId=?"; private static final String FIND_RATING_AVERAGE_BY_CONTENT_AND_ITEM = "SELECT r.itemId, r.ratingCriteria.ratingCriteriaId, AVG(r.rating), COUNT(*) FROM " + Rating.class.getName() - + " AS r where r.ratingCriteria.toolContentId=? AND r.toolSessionId=? AND r.itemId=? GROUP BY r.ratingCriteria.ratingCriteriaId"; + + " AS r where r.ratingCriteria.toolContentId=? AND r.itemId=? GROUP BY r.ratingCriteria.ratingCriteriaId"; private static final String FIND_RATING_AVERAGE_BY_CONTENT_AND_ITEMS = "SELECT r.itemId, r.ratingCriteria.ratingCriteriaId, AVG(r.rating), COUNT(*) FROM " + Rating.class.getName() + + " AS r where r.ratingCriteria.toolContentId=:contentId AND r.itemId IN (:itemIds) GROUP BY r.itemId, r.ratingCriteria.ratingCriteriaId"; + + private static final String FIND_RATING_AVERAGE_BY_CONTENT_AND_SESSION_AND_ITEM = "SELECT r.itemId, r.ratingCriteria.ratingCriteriaId, AVG(r.rating), COUNT(*) FROM " + + Rating.class.getName() + + " AS r where r.ratingCriteria.toolContentId=? AND r.toolSessionId=? AND r.itemId=? GROUP BY r.ratingCriteria.ratingCriteriaId"; + + private static final String FIND_RATING_AVERAGE_BY_CONTENT_AND_SESSION_AND_ITEMS = "SELECT r.itemId, r.ratingCriteria.ratingCriteriaId, AVG(r.rating), COUNT(*) FROM " + + Rating.class.getName() + " AS r where r.ratingCriteria.toolContentId=:contentId AND r.toolSessionId=:toolSessionId AND r.itemId IN (:itemIds) GROUP BY r.itemId, r.ratingCriteria.ratingCriteriaId"; private static final String FIND_RATING_AVERAGE_BY_CONTENT_ID = "SELECT r.itemId, r.ratingCriteria.ratingCriteriaId, AVG(r.rating), COUNT(*) FROM " + Rating.class.getName() + " AS r where r.ratingCriteria.toolContentId=? GROUP BY r.itemId, r.ratingCriteria.ratingCriteriaId"; - // Used by tools to get the ratings and comments relating to their items, as submitted by a particular user. + // Used by tools to get the ratings and comments relating to their items, as submitted by a particular user. // To be used within SQL and supply the userId as :userId and criteriaId as :ratingCriteriaId // See Peer Review for example usage. Special version for comment style as there is no entry in the lams_rating table for a comment style rating. - private static final String TOOL_SELECT_LEFT_JOIN_BY_USER_STANDARD = "SELECT r.item_id, ANY_VALUE(rc.comment) comment, ANY_VALUE(r2.rating) rating, AVG(r.rating) average_rating, COUNT(r.rating) count_vote " - + " FROM lams_rating r " - + " LEFT JOIN lams_rating r2 ON r2.rating_criteria_id = r.rating_criteria_id AND r.item_id = r2.item_id AND r2.user_id = :userId " - + " LEFT JOIN lams_rating_comment rc ON rc.rating_criteria_id = r.rating_criteria_id AND rc.item_id = r2.item_id AND rc.user_id = :userId " - + " WHERE r.rating_criteria_id = :ratingCriteriaId " - + " GROUP BY r.item_id"; - + private static final String TOOL_SELECT_LEFT_JOIN_BY_USER_STANDARD = "SELECT r.item_id, ANY_VALUE(rc.comment) comment, ANY_VALUE(r2.rating) rating, AVG(r.rating) average_rating, COUNT(r.rating) count_vote " + + " FROM lams_rating r " + + " LEFT JOIN lams_rating r2 ON r2.rating_criteria_id = r.rating_criteria_id AND r.item_id = r2.item_id AND r2.user_id = :userId " + + " LEFT JOIN lams_rating_comment rc ON rc.rating_criteria_id = r.rating_criteria_id AND rc.item_id = r2.item_id AND rc.user_id = :userId " + + " WHERE r.rating_criteria_id = :ratingCriteriaId " + " GROUP BY r.item_id"; + // Used by tools to get the ratings and comments relating to their items. To be used within SQL and supply criteriaId as :ratingCriteriaId // See Peer Review for example usage. private static final String TOOL_SELECT_LEFT_JOIN_BY_USER_COMMENT = "SELECT r.item_id, r.comment " @@ -95,11 +101,10 @@ + " JOIN lams_rating_criteria c ON r.item_id = :userId AND c.tool_content_id = :toolContentId " + " AND c.rating_criteria_id = :ratingCriteriaId AND c.rating_criteria_id = r.rating_criteria_id " + " LEFT JOIN lams_rating_comment rc ON rc.rating_criteria_id = r.rating_criteria_id AND rc.item_id = r.item_id and rc.user_id = r.user_id " - + " LEFT JOIN ( " - + " SELECT r2.item_id, AVG(r2.rating) average_rating, COUNT(*) count_vote " - + " FROM lams_rating r2 WHERE r2.rating_criteria_id = :ratingCriteriaId AND r2.item_id = :userId " - + " GROUP BY r2.item_id " - + " ) calc ON calc.item_id = r.item_id "; + + " LEFT JOIN ( " + + " SELECT r2.item_id, AVG(r2.rating) average_rating, COUNT(*) count_vote " + + " FROM lams_rating r2 WHERE r2.rating_criteria_id = :ratingCriteriaId AND r2.item_id = :userId " + + " GROUP BY r2.item_id " + " ) calc ON calc.item_id = r.item_id "; // Same as TOOL_SELECT_LEFT_JOIN_BY_USER_COMMENT except that it returns all the comments results for a single user (:userId), as left by other users private static final String TOOL_SELECT_LEFT_JOIN_FOR_USER_COMMENT = "SELECT r.item_id, r.comment" @@ -120,14 +125,15 @@ getSession().flush(); } + @Override public void delete(Object object) { getSession().delete(object); getSession().flush(); } @Override public Rating getRating(Long ratingCriteriaId, Integer userId, Long itemId) { - List list = (List) doFind(FIND_RATING_BY_CRITERIA_AND_USER_AND_ITEM, + List list = doFind(FIND_RATING_BY_CRITERIA_AND_USER_AND_ITEM, new Object[] { ratingCriteriaId, userId, itemId }); if (list.size() > 0) { return list.get(0); @@ -143,8 +149,7 @@ // method is not used at the moment private Rating getRating(Long ratingCriteriaId, Integer userId) { - List list = (List) doFind(FIND_RATING_BY_CRITERIA_AND_USER, - new Object[] { ratingCriteriaId, userId }); + List list = doFind(FIND_RATING_BY_CRITERIA_AND_USER, new Object[] { ratingCriteriaId, userId }); if (list.size() > 0) { return list.get(0); } else { @@ -154,44 +159,59 @@ @Override public List getRatingsByUser(Long contentId, Integer userId) { - return (List) doFind(FIND_RATINGS_BY_USER, new Object[] { contentId, userId }); + return doFind(FIND_RATINGS_BY_USER, new Object[] { contentId, userId }); } @Override public List getRatingsByUserCriteria(Long criteriaId, Integer userId) { - return (List) doFind(FIND_RATINGS_BY_USER_CRITERIA, new Object[] { criteriaId, userId }); + return doFind(FIND_RATINGS_BY_USER_CRITERIA, new Object[] { criteriaId, userId }); } @Override public ItemRatingCriteriaDTO getRatingAverageDTOByItem(Long ratingCriteriaId, Long toolSessionId, Long itemId) { - List list = (List) doFind(FIND_RATING_AVERAGE_BY_ITEM, + List list = doFind(FIND_RATING_AVERAGE_BY_ITEM, new Object[] { ratingCriteriaId, toolSessionId, itemId }); Object[] results = list.get(0); Object averageRatingObj = (results[0] == null) ? 0 : results[0]; String numberOfVotes = (results[1] == null) ? "0" : String.valueOf(results[1]); - return new ItemRatingCriteriaDTO((Number)averageRatingObj, numberOfVotes); + return new ItemRatingCriteriaDTO((Number) averageRatingObj, numberOfVotes); } @SuppressWarnings("unchecked") @Override - public List getRatingAverageByContentAndItem(Long contentId, Long toolSessionId, Long itemId) { - return (List) doFind(FIND_RATING_AVERAGE_BY_CONTENT_AND_ITEM, new Object[] { contentId, toolSessionId, itemId }); + public List getRatingAverageByContentAndItem(Long contentId, Long itemId) { + return doFind(FIND_RATING_AVERAGE_BY_CONTENT_AND_ITEM, new Object[] { contentId, itemId }); } @SuppressWarnings("unchecked") @Override - public List getRatingAverageByContentAndItems(Long contentId, Long toolSessionId, Collection itemIds) { + public List getRatingAverageByContentAndItems(Long contentId, Collection itemIds) { return getSession().createQuery(FIND_RATING_AVERAGE_BY_CONTENT_AND_ITEMS).setParameter("contentId", contentId) - .setParameter("toolSessionId", toolSessionId) .setParameterList("itemIds", itemIds).list(); } @SuppressWarnings("unchecked") @Override + public List getRatingAverageByContentAndItem(Long contentId, Long toolSessionId, Long itemId) { + return doFind(FIND_RATING_AVERAGE_BY_CONTENT_AND_SESSION_AND_ITEM, + new Object[] { contentId, toolSessionId, itemId }); + } + + @SuppressWarnings("unchecked") + @Override + public List getRatingAverageByContentAndItems(Long contentId, Long toolSessionId, + Collection itemIds) { + return getSession().createQuery(FIND_RATING_AVERAGE_BY_CONTENT_AND_SESSION_AND_ITEMS) + .setParameter("contentId", contentId).setParameter("toolSessionId", toolSessionId) + .setParameterList("itemIds", itemIds).list(); + } + + @SuppressWarnings("unchecked") + @Override public List getRatingAverageByContent(Long contentId) { - return (List) doFind(FIND_RATING_AVERAGE_BY_CONTENT_ID, new Object[] { contentId }); + return doFind(FIND_RATING_AVERAGE_BY_CONTENT_ID, new Object[] { contentId }); } @Override @@ -222,7 +242,7 @@ List commentedItemIds = this.getSession().createQuery(FIND_ITEM_IDS_COMMENTED_BY_USER) .setParameter("toolContentId", toolContentId).setParameter("userId", userId).list(); - Set unionItemIds = new HashSet(ratedItemIds); + Set unionItemIds = new HashSet<>(ratedItemIds); unionItemIds.addAll(commentedItemIds); return unionItemIds.size(); @@ -246,18 +266,18 @@ List commentedItemIds = this.getSession().createQuery(FIND_ITEM_IDS_COMMENTED_BY_USER) .setParameter("criteriaId", criteriaId).setParameter("userId", userId).list(); - Set unionItemIds = new HashSet(ratedItemIds); + Set unionItemIds = new HashSet<>(ratedItemIds); unionItemIds.addAll(commentedItemIds); return unionItemIds.size(); } @SuppressWarnings("unchecked") @Override - public Map countUsersRatedEachItem(final Long contentId, final Long toolSessionId, final Collection itemIds, - Integer excludeUserId) { + public Map countUsersRatedEachItem(final Long contentId, final Long toolSessionId, + final Collection itemIds, Integer excludeUserId) { - HashMap itemIdToRatedUsersCountMap = new HashMap(); + HashMap itemIdToRatedUsersCountMap = new HashMap<>(); if (itemIds.isEmpty()) { return itemIdToRatedUsersCountMap; } @@ -273,8 +293,9 @@ + " AS r where comment.ratingCriteria.toolContentId=:contentId AND comment.itemId IN (:itemIds) AND comment.ratingCriteria.commentsEnabled IS TRUE" + " AND comment.toolSessionId=:toolSessionId"; - List ratedItemObjs = getSession().createQuery(FIND_ITEMID_USERID_PAIRS_BY_CONTENT_AND_ITEMS) - .setParameter("contentId", contentId).setParameter("toolSessionId", toolSessionId).setParameterList("itemIds", itemIds).list(); + List ratedItemObjs = getSession().createQuery(FIND_ITEMID_USERID_PAIRS_BY_CONTENT_AND_ITEMS) + .setParameter("contentId", contentId).setParameter("toolSessionId", toolSessionId) + .setParameterList("itemIds", itemIds).list(); List commentedItemObjs = getSession() .createQuery(FIND_ITEMID_USERID_COMMENT_PAIRS_BY_CONTENT_AND_ITEMS).setParameter("contentId", contentId) @@ -283,13 +304,13 @@ return createUsersRatedEachItem(itemIds, excludeUserId, itemIdToRatedUsersCountMap, ratedItemObjs, commentedItemObjs); } - + @SuppressWarnings("unchecked") @Override - public Map countUsersRatedEachItemByCriteria(final Long criteriaId, final Long toolSessionId, final Collection itemIds, - Integer excludeUserId) { + public Map countUsersRatedEachItemByCriteria(final Long criteriaId, final Long toolSessionId, + final Collection itemIds, Integer excludeUserId) { - HashMap itemIdToRatedUsersCountMap = new HashMap(); + HashMap itemIdToRatedUsersCountMap = new HashMap<>(); if (itemIds.isEmpty()) { return itemIdToRatedUsersCountMap; } @@ -306,14 +327,14 @@ + " AND comment.itemId IN (:itemIds) AND comment.ratingCriteria.commentsEnabled IS TRUE" + " AND comment.toolSessionId=:toolSessionId"; - List ratedItemObjs = getSession().createQuery(FIND_ITEMID_USERID_PAIRS_BY_CONTENT_AND_ITEMS) .setParameter("criteriaId", criteriaId).setParameter("toolSessionId", toolSessionId) .setParameterList("itemIds", itemIds).list(); List commentedItemObjs = getSession() - .createQuery(FIND_ITEMID_USERID_COMMENT_PAIRS_BY_CONTENT_AND_ITEMS).setParameter("criteriaId", criteriaId) - .setParameterList("itemIds", itemIds).setParameter("toolSessionId", toolSessionId).list(); + .createQuery(FIND_ITEMID_USERID_COMMENT_PAIRS_BY_CONTENT_AND_ITEMS) + .setParameter("criteriaId", criteriaId).setParameterList("itemIds", itemIds) + .setParameter("toolSessionId", toolSessionId).list(); return createUsersRatedEachItem(itemIds, excludeUserId, itemIdToRatedUsersCountMap, ratedItemObjs, commentedItemObjs); @@ -323,7 +344,7 @@ HashMap itemIdToRatedUsersCountMap, List ratedItemObjs, List commentedItemObjs) { for (Long itemId : itemIds) { - HashSet userIds = new HashSet(); + HashSet userIds = new HashSet<>(); //put all corresponding userIds into the userIds set for (Object[] ratedItemObj : ratedItemObjs) { @@ -354,27 +375,29 @@ return itemIdToRatedUsersCountMap; } + /** - * Used by tools to get the ratings and comments relating to their items. To be used within SQL and supply the toolContentId as :toolContentId. - * If getAllValues == true then returns data for all users (monitoring), otherwise just the data for a single user. - * See Peer Review for example usage. + * Used by tools to get the ratings and comments relating to their items. To be used within SQL and supply the + * toolContentId as :toolContentId. + * If getAllValues == true then returns data for all users (monitoring), otherwise just the data for a single user. + * See Peer Review for example usage. */ - public String getRatingSelectJoinSQL(Integer ratingStyle, boolean getByUser){ - if ( ratingStyle == RatingCriteria.RATING_STYLE_COMMENT ) + @Override + public String getRatingSelectJoinSQL(Integer ratingStyle, boolean getByUser) { + if (ratingStyle == RatingCriteria.RATING_STYLE_COMMENT) { return getByUser ? TOOL_SELECT_LEFT_JOIN_BY_USER_COMMENT : TOOL_SELECT_LEFT_JOIN_FOR_USER_COMMENT; - else + } else { return getByUser ? TOOL_SELECT_LEFT_JOIN_BY_USER_STANDARD : TOOL_SELECT_LEFT_JOIN_FOR_USER_STANDARD; + } } - - /** + + /** * Get all the raw ratings for a combination of criteria and item ids. Used by Peer Review to do SPA analysis. */ + @Override public List getRatingsByCriteriasAndItems(Collection ratingCriteriaIds, Collection itemIds) { return getSession().createQuery(FIND_RATINGS_BY_ITEM_CRITERIA) - .setParameterList("ratingCriteriaIds", ratingCriteriaIds) - .setParameterList("itemIds", itemIds) - .list(); + .setParameterList("ratingCriteriaIds", ratingCriteriaIds).setParameterList("itemIds", itemIds).list(); } - - + } Index: lams_common/src/java/org/lamsfoundation/lams/rating/service/IRatingService.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_common/src/java/org/lamsfoundation/lams/rating/service/IRatingService.java (.../IRatingService.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_common/src/java/org/lamsfoundation/lams/rating/service/IRatingService.java (.../IRatingService.java) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -32,6 +32,7 @@ import org.lamsfoundation.lams.rating.RatingException; import org.lamsfoundation.lams.rating.dto.ItemRatingCriteriaDTO; import org.lamsfoundation.lams.rating.dto.ItemRatingDTO; +import org.lamsfoundation.lams.rating.dto.RatingCommentDTO; import org.lamsfoundation.lams.rating.dto.StyledCriteriaRatingDTO; import org.lamsfoundation.lams.rating.model.LearnerItemRatingCriteria; import org.lamsfoundation.lams.rating.model.Rating; @@ -46,7 +47,7 @@ /** * Save a group of ratings as the new ratings for this criteria, marking any existing ratings NULL. * Returns the number of "real" ratings, which should be newRatings.size. - * + * * @return */ public int rateItems(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, @@ -66,7 +67,7 @@ /** * Save an already set up rating criteria. Only used when there will only ever be one anonymous criteria, like in * Share Resources - * + * * @param criteria * @return */ @@ -76,7 +77,7 @@ /** * Delete all the rating criteria linked to a tool content. This allows you to delete criteria created with * saveToolStarRatingCriteria - * + * * @param toolContentId * @return */ @@ -195,7 +196,7 @@ /** * Removes all ratings and comments left by the specified user. - * + * * @param contentId * @param userId * @return @@ -217,9 +218,12 @@ Map countUsersRatedEachItemByCriteria(final Long criteriaId, final Long toolSessionId, final Collection itemIds, Integer excludeUserId); - /** + + /** * Get all the raw ratings for a combination of criteria and item ids. Used by Peer Review to do SPA analysis. */ List getRatingsByCriteriasAndItems(Collection ratingCriteriaIds, Collection itemIds); + List getCommentsByCriteriaAndItem(Long ratingCriteriaId, Long toolSessionId, Long itemId); + } Index: lams_common/src/java/org/lamsfoundation/lams/rating/service/RatingService.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_common/src/java/org/lamsfoundation/lams/rating/service/RatingService.java (.../RatingService.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_common/src/java/org/lamsfoundation/lams/rating/service/RatingService.java (.../RatingService.java) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -149,7 +149,7 @@ && Float.compare(ratingFloat, RatingCriteria.RATING_STYLE_STAR_DEFAULT_MAX_AS_FLOAT) > 0) { ratingFloat = RatingCriteria.RATING_STYLE_STAR_DEFAULT_MAX_AS_FLOAT; } - + rating.setRating(ratingFloat); ratingDAO.saveOrUpdate(rating); @@ -193,7 +193,7 @@ rawRating = RatingCriteria.RATING_STYLE_STAR_DEFAULT_MAX_AS_FLOAT; } rating.setRating(rawRating); - + ratingDAO.saveOrUpdate(rating); numRatings++; } @@ -246,11 +246,14 @@ List userRatings = ratingDAO.getRatingsByUser(contentId, userId.intValue()); List itemsStatistics; if (isSingleItem) { - itemsStatistics = ratingDAO.getRatingAverageByContentAndItem(contentId, toolSessionId, singleItemId); + itemsStatistics = toolSessionId == null + ? ratingDAO.getRatingAverageByContentAndItem(contentId, singleItemId) + : ratingDAO.getRatingAverageByContentAndItem(contentId, toolSessionId, singleItemId); // query DB using itemIds } else { - itemsStatistics = ratingDAO.getRatingAverageByContentAndItems(contentId, toolSessionId, itemIds); + itemsStatistics = toolSessionId == null ? ratingDAO.getRatingAverageByContentAndItems(contentId, itemIds) + : ratingDAO.getRatingAverageByContentAndItems(contentId, itemIds); } //handle all criterias except for comments' one @@ -325,7 +328,7 @@ //handle comments criteria for (RatingCriteria criteria : criterias) { - if (criteria.isCommentRating()) { + if (criteria.isCommentRating() || criteria.isCommentsEnabled()) { Long commentCriteriaId = criteria.getRatingCriteriaId(); List commentDtos; @@ -779,6 +782,11 @@ return ratingDAO.getRatingSelectJoinSQL(ratingStyle, getByUser); } + @Override + public List getCommentsByCriteriaAndItem(Long ratingCriteriaId, Long toolSessionId, Long itemId) { + return ratingCommentDAO.getCommentsByCriteriaAndItem(ratingCriteriaId, toolSessionId, itemId); + } + /** * Get all the raw ratings for a combination of criteria and item ids. Used by Peer Review to do SPA analysis. */ Index: lams_tool_assessment/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -rbcc43af1123a6ca42c3caa1d366507a4dc57c93f -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision bcc43af1123a6ca42c3caa1d366507a4dc57c93f) +++ lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -381,5 +381,10 @@ label.someone.allocated.this.answer =Sorry, someone has allocated this answer already label.monitoring.user.summary.full.name =Full name label.etherpad.discussion = Discussion +label.answer.rating.title = Your rating of this other group's answer +label.average.rating =Average rating {0}/{1} votes +label.your.rating =Your rating {0}, average rating {1}/{2} votes +label.comment.textarea.tip =Type your comment here then click on the green tick +error.resource.image.comment.blank =Comment can not be blank. #======= End labels: Exported 372 labels for en AU ===== Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java =================================================================== diff -u -rce97cec9b77669b1a07fe59949d2bd4d0aa3f901 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java (.../LearningController.java) (revision ce97cec9b77669b1a07fe59949d2bd4d0aa3f901) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java (.../LearningController.java) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -41,6 +41,7 @@ import java.util.SortedSet; import java.util.TimeZone; import java.util.TreeSet; +import java.util.function.Function; import java.util.stream.Collectors; import javax.servlet.ServletException; @@ -53,6 +54,10 @@ import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.qb.model.QbOption; import org.lamsfoundation.lams.qb.model.QbQuestion; +import org.lamsfoundation.lams.rating.dto.ItemRatingDTO; +import org.lamsfoundation.lams.rating.model.RatingCriteria; +import org.lamsfoundation.lams.rating.model.ToolActivityRatingCriteria; +import org.lamsfoundation.lams.rating.service.IRatingService; import org.lamsfoundation.lams.tool.ToolAccessMode; import org.lamsfoundation.lams.tool.assessment.AssessmentConstants; import org.lamsfoundation.lams.tool.assessment.dto.OptionDTO; @@ -73,6 +78,7 @@ 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.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.AlphanumComparator; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; @@ -108,6 +114,12 @@ @Qualifier("laasseAssessmentService") private IAssessmentService service; + @Autowired + private IRatingService ratingService; + + @Autowired + private IUserManagementService userManagementService; + /** * Read assessment data from database and put them into HttpSession. It will redirect to init.do directly after this * method run successfully. @@ -1125,6 +1137,43 @@ Map questionSummaries = service.getQuestionSummaryForExport(assessment); request.setAttribute("questionSummaries", questionSummaries); + + // Assessment currently supports only one place for ratings. + // It is rating other groups' answers on results page. + // Criterion gets automatically created and there must be only one. + List criteria = ratingService.getCriteriasByToolContentId(assessment.getContentId()); + if (criteria.size() > 2) { + throw new IllegalArgumentException("There can be only one criterion for an Assessment activity. " + + "If other criteria are introduced, the criterion for rating other groups' answers needs to become uniquely identifiable."); + } + ToolActivityRatingCriteria criterion = null; + if (criteria.isEmpty()) { + criterion = (ToolActivityRatingCriteria) RatingCriteria + .getRatingCriteriaInstance(RatingCriteria.TOOL_ACTIVITY_CRITERIA_TYPE); + criterion.setTitle(service.getMessage("label.answer.rating.title")); + criterion.setOrderId(1); + criterion.setCommentsEnabled(true); + criterion.setRatingStyle(RatingCriteria.RATING_STYLE_STAR); + criterion.setToolContentId(assessment.getContentId()); + + userManagementService.save(criterion); + } else { + criterion = (ToolActivityRatingCriteria) criteria.get(0); + } + + // Item IDs are AssessmentQuestionResults UIDs, i.e. a user answer for a particular question + // Get all item IDs no matter which session they belong to. + Set itemIds = questionSummaries.values().stream() + .flatMap(s -> s.getQuestionResultsPerSession().stream()) + .collect(Collectors.mapping(l -> l.get(l.size() - 1).getUid(), Collectors.toSet())); + + List itemRatingDtos = ratingService.getRatingCriteriaDtos(assessment.getContentId(), + null, itemIds, true, userId); + // Mapping of Item ID -> DTO + Map itemRatingDtoMap = itemRatingDtos.stream() + .collect(Collectors.toMap(ItemRatingDTO::getItemId, Function.identity())); + + request.setAttribute("itemRatingDtos", itemRatingDtoMap); } } Index: lams_tool_assessment/web/WEB-INF/tags/Rating.tag =================================================================== diff -u -r8e742e0e9689c2f26674a1b43c225694b1a41280 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_tool_assessment/web/WEB-INF/tags/Rating.tag (.../Rating.tag) (revision 8e742e0e9689c2f26674a1b43c225694b1a41280) +++ lams_tool_assessment/web/WEB-INF/tags/Rating.tag (.../Rating.tag) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -24,6 +24,7 @@ <%@ attribute name="averageRatingLabel" required="false" rtexprvalue="true" %> <%@ attribute name="minNumberWordsLabel" required="false" rtexprvalue="true" %> <%@ attribute name="showComments" required="false" rtexprvalue="true" %> +<%@ attribute name="showAllComments" required="false" rtexprvalue="true" %> <%@ attribute name="allowRetries" required="false" rtexprvalue="true" %> <%-- Default value for message key --%> @@ -48,6 +49,9 @@ + + + @@ -153,9 +157,8 @@ <%--Comments area---------------------------------------%>
- - +
@@ -185,10 +188,11 @@
+ data-item-id="${itemRatingDto.itemId}" data-comment-criteria-id="${itemRatingDto.commentsCriteriaId}" + data-show-all-comments="${showAllComments}">
Index: lams_tool_assessment/web/pages/learning/results.jsp =================================================================== diff -u -r6b89d0c84a5695fb1ad02d5525eb240a9f4d3134 -r1307599981af4c3f63c2da571c07e150d4713e8d --- lams_tool_assessment/web/pages/learning/results.jsp (.../results.jsp) (revision 6b89d0c84a5695fb1ad02d5525eb240a9f4d3134) +++ lams_tool_assessment/web/pages/learning/results.jsp (.../results.jsp) (revision 1307599981af4c3f63c2da571c07e150d4713e8d) @@ -6,6 +6,8 @@ <fmt:message key="label.learning.title" /> <%@ include file="/common/header.jsp"%> + + - + @@ -39,7 +41,29 @@ + + + + + +