diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/query-auditable-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/query-auditable-common-SqlMap.xml
index 6adaf92bac..001930c8ad 100644
--- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/query-auditable-common-SqlMap.xml
+++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/query-auditable-common-SqlMap.xml
@@ -18,8 +18,12 @@
-
-
+
+
+
+
+
+
@@ -60,19 +64,21 @@
childNode.audit_modified as audit_modified,
childNode.audit_modifier as audit_modifier,
prop_name.string_value as name,
- targetAssoc.parent_node_id as target_node_id,
+ targetAssoc.target_node_id as target_node_id,
targetAssoc.type_qname_id as target_assoc_type_id
from
alf_child_assoc assoc
join alf_node childNode on (childNode.id = assoc.child_node_id)
join alf_store childStore on (childStore.id = childNode.store_id)
left join alf_node_properties prop_name on (prop_name.node_id = childNode.id and prop_name.qname_id = #{nameQNameId})
- left join alf_child_assoc targetAssoc on (childNode.id = targetAssoc.child_node_id)
+ left join alf_node_assoc targetAssoc on (
+ childNode.id = targetAssoc.source_node_id
+
+ and targetAssoc.type_qname_id = #{assocTypeId}
+
+ )
where
assoc.parent_node_id = #{parentNodeId}
and childNode.type_qname_id = #{contentTypeQNameId}
-
- and targetAssoc.type_qname_id = #{assocTypeId}
-
diff --git a/source/java/org/alfresco/repo/discussion/DiscussionServiceImpl.java b/source/java/org/alfresco/repo/discussion/DiscussionServiceImpl.java
index 1d7b3abf1c..66190fd919 100644
--- a/source/java/org/alfresco/repo/discussion/DiscussionServiceImpl.java
+++ b/source/java/org/alfresco/repo/discussion/DiscussionServiceImpl.java
@@ -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 results = cq.execute();
// Prepare to invert
- // TODO
- Map idToNode = new HashMap();
-
- // All done
- return null;
+ Map idToNodeRef = new HashMap();
+ for(NodeWithTargetsEntity e : results.getPage())
+ {
+ idToNodeRef.put(e.getId(), e.getNodeRef());
+ }
+
+ Map> idToReplies = new HashMap>();
+ 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());
+ }
+ idToReplies.get(nodeRef).add(e);
+ }
+ }
+
+ // Grab the list of NodeRefs to pre-load, and pre-load them
+ List preLoad = new ArrayList();
+ calculateRepliesPreLoad(primaryPost.getNodeRef(), preLoad, idToReplies, levels);
+ nodeDAO.cacheNodes(preLoad);
+
+ // Wrap
+ return wrap(primaryPost, idToReplies, levels);
+ }
+ private void calculateRepliesPreLoad(NodeRef nodeRef, List preLoad,
+ Map> idToReplies, int levels)
+ {
+ preLoad.add(nodeRef);
+ if(levels > 0)
+ {
+ List 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> idToReplies, int levels)
+ {
+ List replies = new ArrayList();
+ if(levels > 0)
+ {
+ List 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);
}
diff --git a/source/java/org/alfresco/repo/discussion/DiscussionServiceImplTest.java b/source/java/org/alfresco/repo/discussion/DiscussionServiceImplTest.java
index 65b549a9a5..7499f26d8e 100644
--- a/source/java/org/alfresco/repo/discussion/DiscussionServiceImplTest.java
+++ b/source/java/org/alfresco/repo/discussion/DiscussionServiceImplTest.java
@@ -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
}
}
diff --git a/source/java/org/alfresco/repo/query/NodeWithTargetsEntity.java b/source/java/org/alfresco/repo/query/NodeWithTargetsEntity.java
index 7b103c8744..99008065f5 100644
--- a/source/java/org/alfresco/repo/query/NodeWithTargetsEntity.java
+++ b/source/java/org/alfresco/repo/query/NodeWithTargetsEntity.java
@@ -31,8 +31,7 @@ import org.alfresco.repo.domain.node.NodeEntity;
*/
public class NodeWithTargetsEntity extends NodeBackedEntity
{
- private List targetIds;
- private List targetAssocTypeIds;
+ private List targets;
// Supplemental query-related parameters
private Long assocTypeId;
@@ -53,24 +52,17 @@ public class NodeWithTargetsEntity extends NodeBackedEntity
this.assocTypeId = assocTypeId;
}
- public List getTargetIds()
+ /**
+ * @return Pairs of (Target Node, Assoc Type)
+ */
+ public List getTargetIds()
{
- return targetIds;
+ return targets;
}
- public void setTargetIds(List targetIds)
+ public void setTargets(List targets)
{
- this.targetIds = targetIds;
- }
-
- public List getTargetAssocTypeIds()
- {
- return targetAssocTypeIds;
- }
-
- public void setTargetAssocTypeIds(List targetAssocTypeIds)
- {
- this.targetAssocTypeIds = targetAssocTypeIds;
+ this.targets = targets;
}
/**
@@ -81,4 +73,26 @@ public class NodeWithTargetsEntity extends NodeBackedEntity
{
return assocTypeId;
}
+
+ public static class TargetAndTypeId
+ {
+ private final Long targetId;
+ private final Long assocTypeId;
+
+ public TargetAndTypeId(Long targetId, Long assocTypeId)
+ {
+ this.targetId = targetId;
+ this.assocTypeId = assocTypeId;
+ }
+
+ public Long getTargetId()
+ {
+ return targetId;
+ }
+
+ public Long getAssocTypeId()
+ {
+ return assocTypeId;
+ }
+ }
}