Index: lams_common/src/java/org/lamsfoundation/lams/comments/dao/ICommentDAO.java =================================================================== diff -u -r46bcb6ea758a272250071d1a571d008c6745e593 -r54921c2609f8b6eed36ab972d246bc9094489ebf --- lams_common/src/java/org/lamsfoundation/lams/comments/dao/ICommentDAO.java (.../ICommentDAO.java) (revision 46bcb6ea758a272250071d1a571d008c6745e593) +++ lams_common/src/java/org/lamsfoundation/lams/comments/dao/ICommentDAO.java (.../ICommentDAO.java) (revision 54921c2609f8b6eed36ab972d246bc9094489ebf) @@ -22,8 +22,9 @@ */ public abstract Comment getRootTopic(Long externalId, Integer externalIdType, String externalSignature); - public abstract SortedSet getThreadByThreadId(Long threadCommentId, Integer userId); + public abstract SortedSet getThreadByThreadId(Long threadCommentId, Integer sortBy, Integer userId); - public abstract SortedSet getNextThreadByThreadId(final Long rootTopicId, final Long previousThreadMessageId, Integer numberOfThreads, Integer userId); + public abstract SortedSet getNextThreadByThreadId(final Long rootTopicId, final Long previousThreadMessageId, + Integer numberOfThreads, Integer sortBy, String extraSortParam, Integer userId); } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/comments/dao/hibernate/CommentDAO.java =================================================================== diff -u -rf65bf8d775c89d19993d672813a4af9f95266267 -r54921c2609f8b6eed36ab972d246bc9094489ebf --- lams_common/src/java/org/lamsfoundation/lams/comments/dao/hibernate/CommentDAO.java (.../CommentDAO.java) (revision f65bf8d775c89d19993d672813a4af9f95266267) +++ lams_common/src/java/org/lamsfoundation/lams/comments/dao/hibernate/CommentDAO.java (.../CommentDAO.java) (revision 54921c2609f8b6eed36ab972d246bc9094489ebf) @@ -25,6 +25,8 @@ package org.lamsfoundation.lams.comments.dao.hibernate; +import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; @@ -33,8 +35,9 @@ import org.hibernate.SQLQuery; import org.lamsfoundation.lams.comments.Comment; import org.lamsfoundation.lams.comments.dao.ICommentDAO; +import org.lamsfoundation.lams.comments.service.ICommentService; import org.lamsfoundation.lams.comments.util.TopicComparator; -import org.springframework.orm.hibernate3.HibernateTemplate; +import org.lamsfoundation.lams.comments.util.TopicComparatorLike; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; /** @@ -76,42 +79,30 @@ /* Thread based lookups - Returns a complex structure so that the likes information can be passed * back with it. */ - private static final String SQL_QUERY_FIND_FIRST_THREAD_TOP = "select uid from lams_comment" - + " where root_comment_uid = :rootUid and comment_level = 1 order by uid DESC"; - - private static final String SQL_QUERY_FIND_NEXT_THREAD_TOP = "select uid from lams_comment" - + " where root_comment_uid = :rootUid and uid < :lastUid and comment_level = 1 order by uid DESC"; - - private static final String SQL_QUERY_FIND_NEXT_THREAD_MESSAGES = + private static final String SQL_QUERY_GET_COMPLETE_THREAD = "SELECT c.*, SUM(l.vote) likes_total, l2.vote user_vote FROM lams_comment c " + " LEFT JOIN lams_comment_likes l ON c.uid = l.comment_uid " + " LEFT JOIN lams_comment_likes l2 ON c.uid = l2.comment_uid AND l2.user_id=:userId " - + " WHERE c.thread_comment_uid IN (:threadIds) " - + " GROUP BY c.uid"; - - private static final String SQL_QUERY_GET_COMPLETE_THREAD = - "SELECT c.*, SUM(l.vote) likes_total, l2.vote user_vote FROM lams_comment c " - + " LEFT JOIN lams_comment_likes l ON c.uid = l.comment_uid " - + " LEFT JOIN lams_comment_likes l2 ON c.uid = l2.comment_uid AND l2.user_id=:userId " + " WHERE c.thread_comment_uid = :threadId " + " GROUP BY c.uid"; @Override @SuppressWarnings("unchecked") - public SortedSet getThreadByThreadId(Long threadCommentId, Integer userId) { + public SortedSet getThreadByThreadId(Long threadCommentId, Integer sortBy, Integer userId) { SQLQuery query = getSession().createSQLQuery(SQL_QUERY_GET_COMPLETE_THREAD); query.addEntity("comment", Comment.class) .addScalar("likes_total", Hibernate.INTEGER) .addScalar("user_vote", Hibernate.INTEGER) .setLong("userId", userId != null ? userId : 0) .setLong("threadId", threadCommentId); List results = query.list(); - return upgradeComments(results); + return upgradeComments(results, sortBy); } - private SortedSet upgradeComments(List rawObjects) { - SortedSet results = new TreeSet(new TopicComparator()); + private SortedSet upgradeComments(List rawObjects, Integer sortBy) { + Comparator comparator = ICommentService.SORT_BY_LIKE.equals(sortBy) ? new TopicComparatorLike() : new TopicComparator(); + SortedSet results = new TreeSet(comparator); for ( Object[] rawObject : rawObjects ) { Comment comment = (Comment) rawObject[0]; Integer likeCount = (Integer) rawObject[1]; @@ -124,34 +115,139 @@ } @Override - @SuppressWarnings("unchecked") - public SortedSet getNextThreadByThreadId(final Long rootTopicId, final Long previousThreadMessageId, Integer numberOfThreads, Integer userId) { + public SortedSet getNextThreadByThreadId(final Long rootTopicId, final Long previousThreadMessageId, + Integer numberOfThreads, Integer sortBy, String extraSortParam, Integer userId) { + if (ICommentService.SORT_BY_LIKE.equals(sortBy)) { + return getNextThreadByThreadIdLikes(rootTopicId, previousThreadMessageId, numberOfThreads, sortBy, extraSortParam, + userId); + } else { + return getNextThreadByThreadIdNewestFirst(rootTopicId, previousThreadMessageId, numberOfThreads, sortBy, userId); + } + + } + + private static final String SQL_QUERY_FIND_FIRST_THREAD_TOP_BY_UID = "SELECT uid FROM lams_comment" + + " WHERE root_comment_uid = :rootUid AND comment_level = 1 ORDER BY uid DESC"; + + private static final String SQL_QUERY_FIND_NEXT_THREAD_TOP = "SELECT uid FROM lams_comment" + + " WHERE root_comment_uid = :rootUid AND uid < :lastUid AND comment_level = 1 ORDER BY uid DESC"; + + private static final String SQL_QUERY_FIND_NEXT_THREAD_MESSAGES = + "SELECT c.*, SUM(l.vote) likes_total, l2.vote user_vote FROM lams_comment c " + + " LEFT JOIN lams_comment_likes l ON c.uid = l.comment_uid " + + " LEFT JOIN lams_comment_likes l2 ON c.uid = l2.comment_uid AND l2.user_id=:userId " + + " WHERE c.thread_comment_uid IN (:threadIds) " + + " GROUP BY c.uid"; + + + @SuppressWarnings({"unchecked" }) + private SortedSet getNextThreadByThreadIdNewestFirst(final Long rootTopicId, + final Long previousThreadMessageId, Integer numberOfThreads, Integer sortBy, Integer userId) { + + // the search to get to the top level is quite light, so get just the uids + // then build a complete set. List threadUidList = null; if (previousThreadMessageId == null || previousThreadMessageId == 0L) { - threadUidList = (List) getSession().createSQLQuery(SQL_QUERY_FIND_FIRST_THREAD_TOP) + threadUidList = (List) getSession(). + createSQLQuery(SQL_QUERY_FIND_FIRST_THREAD_TOP_BY_UID) .setLong("rootUid", rootTopicId) .setMaxResults(numberOfThreads) .list(); } else { - threadUidList = (List) getSession().createSQLQuery(SQL_QUERY_FIND_NEXT_THREAD_TOP) + threadUidList = (List) getSession() + .createSQLQuery(SQL_QUERY_FIND_NEXT_THREAD_TOP) .setLong("rootUid", rootTopicId) .setLong("lastUid", previousThreadMessageId) .setMaxResults(numberOfThreads) .list(); } if (threadUidList != null && threadUidList.size() > 0) { - SQLQuery query = getSession().createSQLQuery(SQL_QUERY_FIND_NEXT_THREAD_MESSAGES); + SQLQuery query = getSession().createSQLQuery(SQL_QUERY_FIND_NEXT_THREAD_MESSAGES); query.addEntity("comment", Comment.class) .addScalar("likes_total", Hibernate.INTEGER) - .addScalar("user_vote", Hibernate.INTEGER) - .setLong("userId", userId != null ? userId : 0) - .setParameterList("threadIds", threadUidList); + .addScalar("user_vote", Hibernate.INTEGER) + .setLong("userId", userId != null ? userId : 0) + .setParameterList("threadIds", threadUidList); List results = query.list(); - return upgradeComments(results); + return upgradeComments(results, sortBy); } return new TreeSet(); } + + private static final String SQL_QUERY_FIND_FIRST_THREAD_TOP_BY_LIKES = "SELECT c.*, COALESCE(SUM(l.vote),0) likes_total, l2.vote user_vote" + + " FROM lams_comment c " + + " LEFT JOIN lams_comment_likes l ON c.uid = l.comment_uid " + + " LEFT JOIN lams_comment_likes l2 ON c.uid = l2.comment_uid AND l2.user_id=:userId " + + " WHERE root_comment_uid = :rootUid AND comment_level = 1 " + + " GROUP BY c.uid " + + " ORDER BY likes_total DESC, c.uid DESC"; + private static final String SQL_QUERY_FIND_NEXT_THREAD_TOP_BY_LIKE = "SELECT * FROM ( " + + " SELECT c.*, COALESCE(SUM(l.vote),0) likes_total, l2.vote user_vote " + + " FROM lams_comment c " + + " LEFT JOIN lams_comment_likes l ON c.uid = l.comment_uid " + + " LEFT JOIN lams_comment_likes l2 ON c.uid = l2.comment_uid AND l2.user_id=:userId " + + " WHERE root_comment_uid = :rootUid AND comment_level = 1 " + + " GROUP BY c.uid " + + " ORDER BY likes_total DESC, c.uid DESC) cl " + + " WHERE (cl.likes_total = :like AND cl.uid < :lastUid ) " + + " OR cl.likes_total < :like"; + + private static final String SQL_QUERY_FIND_NEXT_THREAD_MESSAGES_REPLIES_ONLY = + "SELECT c.*, COALESCE(SUM(l.vote),0) likes_total, l2.vote user_vote FROM lams_comment c " + + " LEFT JOIN lams_comment_likes l ON c.uid = l.comment_uid " + + " LEFT JOIN lams_comment_likes l2 ON c.uid = l2.comment_uid AND l2.user_id=:userId " + + " WHERE c.thread_comment_uid IN (:threadIds) and comment_level > 1 " + + " GROUP BY c.uid"; + + @SuppressWarnings({ "unchecked" }) + private SortedSet getNextThreadByThreadIdLikes(final Long rootTopicId, final Long previousThreadMessageId, + Integer numberOfThreads, Integer sortBy, String extraSortParam, Integer userId) { + + // the search to get to the top level is quite heavy and involves grouping the likes, so get all the data + // for the top level then get the child replies. + List topThreadObjects = null; + if (previousThreadMessageId == null || previousThreadMessageId == 0L) { + topThreadObjects = (List) getSession().createSQLQuery(SQL_QUERY_FIND_FIRST_THREAD_TOP_BY_LIKES) + .addEntity("comment", Comment.class) + .addScalar("likes_total", Hibernate.INTEGER) + .addScalar("user_vote", Hibernate.INTEGER) + .setLong("rootUid", rootTopicId) + .setLong("userId", userId != null ? userId : 0) + .setMaxResults(numberOfThreads) + .list(); + } else { + // get more entries with the same number of likes or less likes + topThreadObjects = (List) getSession() + .createSQLQuery(SQL_QUERY_FIND_NEXT_THREAD_TOP_BY_LIKE) + .addEntity("comment", Comment.class) + .addScalar("likes_total", Hibernate.INTEGER) + .addScalar("user_vote", Hibernate.INTEGER) + .setLong("rootUid", rootTopicId) + .setLong("lastUid", previousThreadMessageId) + .setString("like", extraSortParam) + .setLong("userId", userId != null ? userId : 0) + .setMaxResults(numberOfThreads).list(); + } + if (topThreadObjects != null && topThreadObjects.size() > 0) { + // build the list of uids + List threadUidList = new ArrayList(); + for ( Object[] rawObject : topThreadObjects ) { + Comment comment = (Comment) rawObject[0]; + threadUidList.add(comment.getUid()); + } + SQLQuery query = getSession().createSQLQuery(SQL_QUERY_FIND_NEXT_THREAD_MESSAGES_REPLIES_ONLY); + query.addEntity("comment", Comment.class) + .addScalar("likes_total", Hibernate.INTEGER) + .addScalar("user_vote", Hibernate.INTEGER) + .setLong("userId", userId != null ? userId : 0) + .setParameterList("threadIds", threadUidList); + List results = query.list(); + topThreadObjects.addAll(results); + return upgradeComments(topThreadObjects, sortBy); + } + return new TreeSet(); + } } Index: lams_common/src/java/org/lamsfoundation/lams/comments/service/CommentService.java =================================================================== diff -u -r25e1ec09bef9772ea3a274a6ba5127cbc70d4f16 -r54921c2609f8b6eed36ab972d246bc9094489ebf --- lams_common/src/java/org/lamsfoundation/lams/comments/service/CommentService.java (.../CommentService.java) (revision 25e1ec09bef9772ea3a274a6ba5127cbc70d4f16) +++ lams_common/src/java/org/lamsfoundation/lams/comments/service/CommentService.java (.../CommentService.java) (revision 54921c2609f8b6eed36ab972d246bc9094489ebf) @@ -62,7 +62,8 @@ private ICommentLikeDAO commentLikeDAO; @Override - public List getTopicThread(Long externalId, Integer externalType, String externalSignature, Long lastCommentSeqId, Integer pageSize, Integer userId) { + public List getTopicThread(Long externalId, Integer externalType, String externalSignature, Long lastCommentSeqId, + Integer pageSize, Integer sortBy, String extraSortParam, Integer userId) { long lastThreadMessageUid = lastCommentSeqId != null ? lastCommentSeqId.longValue() : 0L; @@ -74,7 +75,7 @@ return new ArrayList(); } - SortedSet comments = commentDAO.getNextThreadByThreadId(rootTopic.getUid(), lastThreadMessageUid, pageSize, userId); + SortedSet comments = commentDAO.getNextThreadByThreadId(rootTopic.getUid(), lastThreadMessageUid, pageSize, sortBy, extraSortParam, userId); return getSortedCommentDTO(comments); } @@ -90,8 +91,8 @@ return msgDtoList; } - public List getThread( Long threadId, Integer userId ) { - SortedSet comments = commentDAO.getThreadByThreadId(threadId, userId); + public List getThread( Long threadId, Integer sortBy, Integer userId ) { + SortedSet comments = commentDAO.getThreadByThreadId(threadId, sortBy, userId); return getSortedCommentDTO(comments); } Index: lams_common/src/java/org/lamsfoundation/lams/comments/service/ICommentService.java =================================================================== diff -u -r46bcb6ea758a272250071d1a571d008c6745e593 -r54921c2609f8b6eed36ab972d246bc9094489ebf --- lams_common/src/java/org/lamsfoundation/lams/comments/service/ICommentService.java (.../ICommentService.java) (revision 46bcb6ea758a272250071d1a571d008c6745e593) +++ lams_common/src/java/org/lamsfoundation/lams/comments/service/ICommentService.java (.../ICommentService.java) (revision 54921c2609f8b6eed36ab972d246bc9094489ebf) @@ -33,8 +33,13 @@ public interface ICommentService { + public static final Integer SORT_BY_DATE = 0; + public static final Integer SORT_BY_LIKE = 1; + + /** Gets the comments for a tool, based on the tool session and the tool's id. Allows for paging */ - List getTopicThread(Long externalId, Integer externalType, String externalSignature, Long lastMsgSeqId, Integer pageSize, Integer userId); + List getTopicThread(Long externalId, Integer externalType, String externalSignature, Long lastMsgSeqId, + Integer pageSize, Integer sortBy, String extraSortParam, Integer userId); /** Saves a comment - either creating a whole tree one if there is no parent or saving under the given parent. */ Comment createReply(Long parentId, String replyText, User user); @@ -49,7 +54,7 @@ /** * Get one complete thread within a topic Note that the return type is DTO. */ - List getThread( Long threadId, Integer userId ); + List getThread( Long threadId, Integer sortBy, Integer userId ); /** Get a single comment. Note that the return type is DTO */ CommentDTO getComment(Long commentUid); @@ -62,10 +67,6 @@ /** Update the hidden / not hidden flag */ Comment hideComment(Long commentUid, User user, boolean status); - /** - * Get the id of the root topic of this comment. - */ -// public Long getRootTopicId(Long commentId);// /* Utility calls for the Action */ MessageService getMessageService(); Index: lams_common/src/java/org/lamsfoundation/lams/comments/util/TopicComparator.java =================================================================== diff -u -r46bcb6ea758a272250071d1a571d008c6745e593 -r54921c2609f8b6eed36ab972d246bc9094489ebf --- lams_common/src/java/org/lamsfoundation/lams/comments/util/TopicComparator.java (.../TopicComparator.java) (revision 46bcb6ea758a272250071d1a571d008c6745e593) +++ lams_common/src/java/org/lamsfoundation/lams/comments/util/TopicComparator.java (.../TopicComparator.java) (revision 54921c2609f8b6eed36ab972d246bc9094489ebf) @@ -88,8 +88,8 @@ } // If Level = 1 then "top" so sort newest first. Otherwise sort oldest first. - private int compareUids(int compareLevel, Comment c1, Comment c2) { - if ( compareLevel <= 1 ) + protected int compareUids(int compareLevel, Comment c1, Comment c2) { + if ( compareLevel <= 2 ) return c1.getUid() < c2.getUid() ? 1 : -1; else return c1.getUid() > c2.getUid() ? 1 : -1; Index: lams_common/src/java/org/lamsfoundation/lams/comments/util/TopicComparatorLike.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/comments/util/TopicComparatorLike.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/comments/util/TopicComparatorLike.java (revision 54921c2609f8b6eed36ab972d246bc9094489ebf) @@ -0,0 +1,45 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ + +package org.lamsfoundation.lams.comments.util; + +import org.lamsfoundation.lams.comments.Comment; + +/** + * This class implements the java.util.Comparator interface. Sorts Level 1 and Level 2 on # likes, Level 3 onwards on creation date/time. + */ +public class TopicComparatorLike extends TopicComparator { + + protected int compareUids(int compareLevel, Comment c1, Comment c2) { + if ( compareLevel <= 2 ) { + if ( c1.getLikeCount() == c2.getLikeCount() ) + return c1.getUid() < c2.getUid() ? 1 : -1; + else + return c1.getLikeCount() < c2.getLikeCount() ? 1 : -1; + } else { + return c1.getUid() > c2.getUid() ? 1 : -1; + } + } +} Index: lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch2040051.sql =================================================================== diff -u -r46bcb6ea758a272250071d1a571d008c6745e593 -r54921c2609f8b6eed36ab972d246bc9094489ebf --- lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch2040051.sql (.../patch2040051.sql) (revision 46bcb6ea758a272250071d1a571d008c6745e593) +++ lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch2040051.sql (.../patch2040051.sql) (revision 54921c2609f8b6eed36ab972d246bc9094489ebf) @@ -27,9 +27,6 @@ `root_comment_uid` bigint(20) DEFAULT NULL, `comment_level` smallint(6) DEFAULT NULL, `thread_comment_uid` bigint(20) DEFAULT NULL, - `likes` text DEFAULT NULL, - `dislikes` text DEFAULT NULL, - `like_count` int(11) DEFAULT 0, PRIMARY KEY (`uid`), KEY `FK_comment_session` (`session_id`), KEY `FK_comment_create` (`create_by`), Index: lams_tool_nb/web/WEB-INF/tags/Comments.tag =================================================================== diff -u -rf9b66c238ae9c7cd34c559cc80bc7ad8f8c51f5b -r54921c2609f8b6eed36ab972d246bc9094489ebf --- lams_tool_nb/web/WEB-INF/tags/Comments.tag (.../Comments.tag) (revision f9b66c238ae9c7cd34c559cc80bc7ad8f8c51f5b) +++ lams_tool_nb/web/WEB-INF/tags/Comments.tag (.../Comments.tag) (revision 54921c2609f8b6eed36ab972d246bc9094489ebf) @@ -1,3 +1,5 @@ +<%@ tag import="org.lamsfoundation.lams.comments.CommentConstants"%> + <%@ taglib uri="tags-core" prefix="c"%> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> @@ -9,6 +11,8 @@ <%@ attribute name="mode" required="false" rtexprvalue="true"%> <%@ attribute name="likeAndDislike" required="false" rtexprvalue="true"%> <%@ attribute name="readOnly" required="false" rtexprvalue="true"%> +<%@ attribute name="pageSize" required="false" rtexprvalue="true"%> +<%@ attribute name="sortBy" required="false" rtexprvalue="true"%> @@ -32,8 +36,16 @@ - + + + + + + + + +