mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
ALF-9153 Discussions Topic Finding (lucene based) on the Java Service for getting topics by tag
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29890 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -64,8 +64,10 @@
|
|||||||
<property name="nodeDAO" ref="nodeDAO" />
|
<property name="nodeDAO" ref="nodeDAO" />
|
||||||
<property name="nodeService" ref="NodeService"/>
|
<property name="nodeService" ref="NodeService"/>
|
||||||
<property name="siteService" ref="SiteService"/>
|
<property name="siteService" ref="SiteService"/>
|
||||||
|
<property name="searchService" ref="SearchService"/>
|
||||||
<property name="contentService" ref="ContentService"/>
|
<property name="contentService" ref="ContentService"/>
|
||||||
<property name="taggingService" ref="TaggingService"/>
|
<property name="taggingService" ref="TaggingService"/>
|
||||||
|
<property name="namespaceService" ref="NamespaceService"/>
|
||||||
<property name="fileFolderService" ref="FileFolderService"/>
|
<property name="fileFolderService" ref="FileFolderService"/>
|
||||||
<property name="transactionService" ref="transactionService" />
|
<property name="transactionService" ref="transactionService" />
|
||||||
<property name="cannedQueryRegistry" ref="discussionCannedQueryRegistry" />
|
<property name="cannedQueryRegistry" ref="discussionCannedQueryRegistry" />
|
||||||
|
@@ -53,10 +53,17 @@ import org.alfresco.service.cmr.repository.ContentService;
|
|||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.search.LimitBy;
|
||||||
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
|
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||||
|
import org.alfresco.service.cmr.search.SearchParameters;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.cmr.site.SiteService;
|
import org.alfresco.service.cmr.site.SiteService;
|
||||||
import org.alfresco.service.cmr.tagging.TaggingService;
|
import org.alfresco.service.cmr.tagging.TaggingService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
|
import org.alfresco.util.ISO9075;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
import org.alfresco.util.registry.NamedObjectRegistry;
|
import org.alfresco.util.registry.NamedObjectRegistry;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -77,14 +84,15 @@ public class DiscussionServiceImpl implements DiscussionService
|
|||||||
/**
|
/**
|
||||||
* The logger
|
* The logger
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private static Log logger = LogFactory.getLog(DiscussionServiceImpl.class);
|
private static Log logger = LogFactory.getLog(DiscussionServiceImpl.class);
|
||||||
|
|
||||||
private NodeDAO nodeDAO;
|
private NodeDAO nodeDAO;
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private SiteService siteService;
|
private SiteService siteService;
|
||||||
|
private SearchService searchService;
|
||||||
private ContentService contentService;
|
private ContentService contentService;
|
||||||
private TaggingService taggingService;
|
private TaggingService taggingService;
|
||||||
|
private NamespaceService namespaceService;
|
||||||
private FileFolderService fileFolderService;
|
private FileFolderService fileFolderService;
|
||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
private NamedObjectRegistry<CannedQueryFactory<? extends Object>> cannedQueryRegistry;
|
private NamedObjectRegistry<CannedQueryFactory<? extends Object>> cannedQueryRegistry;
|
||||||
@@ -104,6 +112,11 @@ public class DiscussionServiceImpl implements DiscussionService
|
|||||||
this.siteService = siteService;
|
this.siteService = siteService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSearchService(SearchService searchService)
|
||||||
|
{
|
||||||
|
this.searchService = searchService;
|
||||||
|
}
|
||||||
|
|
||||||
public void setContentService(ContentService contentService)
|
public void setContentService(ContentService contentService)
|
||||||
{
|
{
|
||||||
this.contentService = contentService;
|
this.contentService = contentService;
|
||||||
@@ -114,6 +127,11 @@ public class DiscussionServiceImpl implements DiscussionService
|
|||||||
this.taggingService = taggingService;
|
this.taggingService = taggingService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNamespaceService(NamespaceService namespaceService)
|
||||||
|
{
|
||||||
|
this.namespaceService = namespaceService;
|
||||||
|
}
|
||||||
|
|
||||||
public void setFileFolderService(FileFolderService fileFolderService)
|
public void setFileFolderService(FileFolderService fileFolderService)
|
||||||
{
|
{
|
||||||
this.fileFolderService = fileFolderService;
|
this.fileFolderService = fileFolderService;
|
||||||
@@ -568,6 +586,79 @@ public class DiscussionServiceImpl implements DiscussionService
|
|||||||
return wrap(nodes, nodeRef);
|
return wrap(nodes, nodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PagingResults<TopicInfo> findTopics(String siteShortName,
|
||||||
|
String tag, PagingRequest paging) {
|
||||||
|
NodeRef container = getSiteDiscussionsContainer(siteShortName, false);
|
||||||
|
if(container == null)
|
||||||
|
{
|
||||||
|
// No topics
|
||||||
|
return new EmptyPagingResults<TopicInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can now search by parent nodeRef
|
||||||
|
return findTopics(container, tag, paging);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PagingResults<TopicInfo> findTopics(NodeRef nodeRef,
|
||||||
|
String tag, PagingRequest paging) {
|
||||||
|
// Build the query
|
||||||
|
StringBuilder luceneQuery = new StringBuilder();
|
||||||
|
luceneQuery.append(
|
||||||
|
" +TYPE:\"" + ForumModel.TYPE_TOPIC + "\""
|
||||||
|
);
|
||||||
|
luceneQuery.append(
|
||||||
|
" +PATH:\"" + nodeService.getPath(nodeRef).toPrefixString(namespaceService) + "/*\""
|
||||||
|
);
|
||||||
|
|
||||||
|
if(tag != null)
|
||||||
|
{
|
||||||
|
luceneQuery.append(
|
||||||
|
" +PATH:\"/cm:taggable/cm:" + ISO9075.encode(tag) + "/member\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String sortOn = "@{http://www.alfresco.org/model/content/1.0}created";
|
||||||
|
|
||||||
|
// Query
|
||||||
|
SearchParameters sp = new SearchParameters();
|
||||||
|
sp.addStore(nodeRef.getStoreRef());
|
||||||
|
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||||
|
sp.setQuery(luceneQuery.toString());
|
||||||
|
sp.addSort(sortOn, true);
|
||||||
|
if (paging.getMaxItems() > 0)
|
||||||
|
{
|
||||||
|
sp.setLimit(paging.getMaxItems());
|
||||||
|
sp.setLimitBy(LimitBy.FINAL_SIZE);
|
||||||
|
}
|
||||||
|
if (paging.getSkipCount() > 0)
|
||||||
|
{
|
||||||
|
sp.setSkipCount(paging.getSkipCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Build the results
|
||||||
|
PagingResults<TopicInfo> pagedResults = new EmptyPagingResults<TopicInfo>();
|
||||||
|
ResultSet results = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
results = searchService.query(sp);
|
||||||
|
pagedResults = wrap(results, nodeRef);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if(results != null)
|
||||||
|
{
|
||||||
|
results.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pagedResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PagingResults<PostInfo> listPosts(TopicInfo topic, PagingRequest paging)
|
public PagingResults<PostInfo> listPosts(TopicInfo topic, PagingRequest paging)
|
||||||
{
|
{
|
||||||
@@ -730,6 +821,47 @@ public class DiscussionServiceImpl implements DiscussionService
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our class to wrap up search results as {@link TopicInfo} instances
|
||||||
|
*/
|
||||||
|
private PagingResults<TopicInfo> wrap(final ResultSet finalLuceneResults, final NodeRef container)
|
||||||
|
{
|
||||||
|
final List<TopicInfo> topics = new ArrayList<TopicInfo>();
|
||||||
|
for(ResultSetRow row : finalLuceneResults)
|
||||||
|
{
|
||||||
|
TopicInfo topic = buildTopic(
|
||||||
|
row.getNodeRef(), container, row.getQName().getLocalName()
|
||||||
|
);
|
||||||
|
topics.add(topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap
|
||||||
|
return new PagingResults<TopicInfo>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasMoreItems() {
|
||||||
|
return finalLuceneResults.hasMore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<Integer, Integer> getTotalResultCount() {
|
||||||
|
int skipCount = finalLuceneResults.getStart();
|
||||||
|
int itemsRemainingAfterThisPage = finalLuceneResults.length();
|
||||||
|
final int totalItemsInUnpagedResultSet = skipCount + itemsRemainingAfterThisPage;
|
||||||
|
return new Pair<Integer, Integer>(totalItemsInUnpagedResultSet, totalItemsInUnpagedResultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TopicInfo> getPage() {
|
||||||
|
return topics;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getQueryExecutionId() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Our class to wrap up paged results of NodeBackedEntities as
|
* Our class to wrap up paged results of NodeBackedEntities as
|
||||||
* {@link TopicInfo} instances
|
* {@link TopicInfo} instances
|
||||||
|
@@ -546,6 +546,8 @@ public class DiscussionServiceImplTest
|
|||||||
{
|
{
|
||||||
PagingResults<TopicInfo> topics;
|
PagingResults<TopicInfo> topics;
|
||||||
PagingResults<PostInfo> posts;
|
PagingResults<PostInfo> posts;
|
||||||
|
final String TAG_1 = "topic_tag_one";
|
||||||
|
final String TAG_2 = "topic_tag_two";
|
||||||
|
|
||||||
|
|
||||||
// To start with, there will be no topics
|
// To start with, there will be no topics
|
||||||
@@ -582,6 +584,46 @@ public class DiscussionServiceImplTest
|
|||||||
assertEquals("NT3", topics.getPage().get(2).getTitle());
|
assertEquals("NT3", topics.getPage().get(2).getTitle());
|
||||||
|
|
||||||
|
|
||||||
|
// Add tags to a few
|
||||||
|
siteT2.getTags().add(TAG_1);
|
||||||
|
nodeT2.getTags().add(TAG_1);
|
||||||
|
nodeT2.getTags().add(TAG_2);
|
||||||
|
nodeT3.getTags().add(TAG_1);
|
||||||
|
DISCUSSION_SERVICE.updateTopic(siteT2);
|
||||||
|
DISCUSSION_SERVICE.updateTopic(nodeT2);
|
||||||
|
DISCUSSION_SERVICE.updateTopic(nodeT3);
|
||||||
|
|
||||||
|
|
||||||
|
// Find without tags
|
||||||
|
topics = DISCUSSION_SERVICE.findTopics(DISCUSSION_SITE.getShortName(), null, new PagingRequest(10));
|
||||||
|
assertEquals(2, topics.getPage().size());
|
||||||
|
assertEquals("ST1", topics.getPage().get(0).getTitle());
|
||||||
|
assertEquals("ST2", topics.getPage().get(1).getTitle());
|
||||||
|
|
||||||
|
topics = DISCUSSION_SERVICE.findTopics(FORUM_NODE, null, new PagingRequest(10));
|
||||||
|
assertEquals(3, topics.getPage().size());
|
||||||
|
assertEquals("NT1", topics.getPage().get(0).getTitle());
|
||||||
|
assertEquals("NT2", topics.getPage().get(1).getTitle());
|
||||||
|
assertEquals("NT3", topics.getPage().get(2).getTitle());
|
||||||
|
|
||||||
|
// Find with tags
|
||||||
|
topics = DISCUSSION_SERVICE.findTopics(DISCUSSION_SITE.getShortName(), TAG_1, new PagingRequest(10));
|
||||||
|
assertEquals(1, topics.getPage().size());
|
||||||
|
assertEquals("ST2", topics.getPage().get(0).getTitle());
|
||||||
|
|
||||||
|
topics = DISCUSSION_SERVICE.findTopics(FORUM_NODE, TAG_1, new PagingRequest(10));
|
||||||
|
assertEquals(2, topics.getPage().size());
|
||||||
|
assertEquals("NT2", topics.getPage().get(0).getTitle());
|
||||||
|
assertEquals("NT3", topics.getPage().get(1).getTitle());
|
||||||
|
|
||||||
|
topics = DISCUSSION_SERVICE.findTopics(DISCUSSION_SITE.getShortName(), TAG_2, new PagingRequest(10));
|
||||||
|
assertEquals(0, topics.getPage().size());
|
||||||
|
|
||||||
|
topics = DISCUSSION_SERVICE.findTopics(FORUM_NODE, TAG_2, new PagingRequest(10));
|
||||||
|
assertEquals(1, topics.getPage().size());
|
||||||
|
assertEquals("NT2", topics.getPage().get(0).getTitle());
|
||||||
|
|
||||||
|
|
||||||
// Alter the creation date on a couple, see the ordering change
|
// Alter the creation date on a couple, see the ordering change
|
||||||
pushAuditableDatesBack(siteT2, 2, 2);
|
pushAuditableDatesBack(siteT2, 2, 2);
|
||||||
pushAuditableDatesBack(nodeT3, 3, 3);
|
pushAuditableDatesBack(nodeT3, 3, 3);
|
||||||
|
@@ -164,6 +164,19 @@ public interface DiscussionService {
|
|||||||
@NotAuditable
|
@NotAuditable
|
||||||
PagingResults<TopicInfo> listTopics(NodeRef nodeRef, PagingRequest paging);
|
PagingResults<TopicInfo> listTopics(NodeRef nodeRef, PagingRequest paging);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for all topics in a site, filtered by tag
|
||||||
|
*/
|
||||||
|
@NotAuditable
|
||||||
|
PagingResults<TopicInfo> findTopics(String siteShortName, String tag, PagingRequest paging);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for all topics attached to the specified Node, filtered by tag
|
||||||
|
*/
|
||||||
|
@NotAuditable
|
||||||
|
PagingResults<TopicInfo> findTopics(NodeRef nodeRef, String tag, PagingRequest paging);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all posts in a topic, ordered by creation date
|
* Retrieves all posts in a topic, ordered by creation date
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user