ALF-9153 Get the discussions reply CQ working, via some careful mybatis collections handling, and add some tests for it

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29843 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2011-08-17 17:50:59 +00:00
parent 7ec7327ec4
commit 2fce262264
4 changed files with 165 additions and 28 deletions

View File

@@ -40,6 +40,7 @@ import org.alfresco.repo.node.getchildren.GetChildrenWithTargetAssocsAuditableCa
import org.alfresco.repo.node.getchildren.GetChildrenWithTargetAssocsAuditableCannedQueryFactory;
import org.alfresco.repo.query.NodeBackedEntity;
import org.alfresco.repo.query.NodeWithTargetsEntity;
import org.alfresco.repo.query.NodeWithTargetsEntity.TargetAndTypeId;
import org.alfresco.repo.site.SiteServiceImpl;
import org.alfresco.service.cmr.discussion.DiscussionService;
import org.alfresco.service.cmr.discussion.PostInfo;
@@ -608,11 +609,77 @@ public class DiscussionServiceImpl implements DiscussionService
CannedQueryResults<NodeWithTargetsEntity> results = cq.execute();
// Prepare to invert
// TODO
Map<Long,NodeRef> idToNode = new HashMap<Long, NodeRef>();
// All done
return null;
Map<Long,NodeRef> idToNodeRef = new HashMap<Long, NodeRef>();
for(NodeWithTargetsEntity e : results.getPage())
{
idToNodeRef.put(e.getId(), e.getNodeRef());
}
Map<NodeRef,List<NodeWithTargetsEntity>> idToReplies = new HashMap<NodeRef, List<NodeWithTargetsEntity>>();
for(NodeWithTargetsEntity e : results.getPage())
{
for(TargetAndTypeId idP : e.getTargetIds())
{
Long id = idP.getTargetId();
NodeRef nodeRef = idToNodeRef.get(id);
if(nodeRef == null)
{
// References a node outside of this topic
continue;
}
if(id.equals(e.getId()))
{
// Self reference
continue;
}
if(! idToReplies.containsKey(nodeRef))
{
idToReplies.put(nodeRef, new ArrayList<NodeWithTargetsEntity>());
}
idToReplies.get(nodeRef).add(e);
}
}
// Grab the list of NodeRefs to pre-load, and pre-load them
List<NodeRef> preLoad = new ArrayList<NodeRef>();
calculateRepliesPreLoad(primaryPost.getNodeRef(), preLoad, idToReplies, levels);
nodeDAO.cacheNodes(preLoad);
// Wrap
return wrap(primaryPost, idToReplies, levels);
}
private void calculateRepliesPreLoad(NodeRef nodeRef, List<NodeRef> preLoad,
Map<NodeRef,List<NodeWithTargetsEntity>> idToReplies, int levels)
{
preLoad.add(nodeRef);
if(levels > 0)
{
List<NodeWithTargetsEntity> replies = idToReplies.get(nodeRef);
if(replies != null && replies.size() > 0)
{
for(NodeWithTargetsEntity entity : replies)
{
calculateRepliesPreLoad(entity.getNodeRef(), preLoad, idToReplies, levels-1);
}
}
}
}
private PostWithReplies wrap(PostInfo post, Map<NodeRef,List<NodeWithTargetsEntity>> idToReplies, int levels)
{
List<PostWithReplies> replies = new ArrayList<PostWithReplies>();
if(levels > 0)
{
List<NodeWithTargetsEntity> replyEntities = idToReplies.get(post.getNodeRef());
if(replyEntities != null && replyEntities.size() > 0)
{
for(NodeWithTargetsEntity entity : replyEntities)
{
PostInfo replyPost = buildPost(entity.getNodeRef(), post.getTopic(), entity.getName(), null);
replies.add(wrap(replyPost, idToReplies, levels-1));
}
}
}
return new PostWithReplies(post, replies);
}

View File

@@ -39,6 +39,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.discussion.DiscussionService;
import org.alfresco.service.cmr.discussion.PostInfo;
import org.alfresco.service.cmr.discussion.PostWithReplies;
import org.alfresco.service.cmr.discussion.TopicInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -686,7 +687,56 @@ public class DiscussionServiceImplTest
for(TopicInfo topic : new TopicInfo[] {siteT1, nodeT1})
{
// Listing initially gives nothing
PostWithReplies pr = DISCUSSION_SERVICE.listPostReplies(topic, 1);
assertEquals(null, pr);
// Add the first post
PostInfo post = DISCUSSION_SERVICE.createPost(topic, "Post");
// Should come back with no replies
pr = DISCUSSION_SERVICE.listPostReplies(topic, 1);
assertNotNull(pr);
assertEquals(post.getNodeRef(), pr.getNodeRef());
assertEquals(0, pr.getReplies().size());
// Add two replies
PostInfo reply1 = DISCUSSION_SERVICE.createReply(post, "R1");
PostInfo reply2 = DISCUSSION_SERVICE.createReply(post, "R2");
// Ask for the replies to the post
pr = DISCUSSION_SERVICE.listPostReplies(topic, 1);
assertNotNull(pr);
assertEquals(post.getNodeRef(), pr.getNodeRef());
assertEquals(2, pr.getReplies().size());
assertEquals(reply1.getNodeRef(), pr.getReplies().get(0).getNodeRef());
assertEquals(reply2.getNodeRef(), pr.getReplies().get(1).getNodeRef());
assertEquals(0, pr.getReplies().get(0).getReplies().size());
assertEquals(0, pr.getReplies().get(1).getReplies().size());
// Check at other levels too:
// Level 0 will mean no replies were fetched
pr = DISCUSSION_SERVICE.listPostReplies(topic, 0);
assertNotNull(pr);
assertEquals(post.getNodeRef(), pr.getNodeRef());
assertEquals(0, pr.getReplies().size());
// Level 5 won't affect things, as there are only 2
pr = DISCUSSION_SERVICE.listPostReplies(topic, 5);
assertNotNull(pr);
assertEquals(post.getNodeRef(), pr.getNodeRef());
assertEquals(2, pr.getReplies().size());
assertEquals(reply1.getNodeRef(), pr.getReplies().get(0).getNodeRef());
assertEquals(reply2.getNodeRef(), pr.getReplies().get(1).getNodeRef());
assertEquals(0, pr.getReplies().get(0).getReplies().size());
assertEquals(0, pr.getReplies().get(1).getReplies().size());
// Add a nesting of replies
}
}