ALF-9153 Start on unit tests for the new Discussions Service

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29715 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2011-08-12 13:13:33 +00:00
parent 7430652942
commit 16d2b34261
5 changed files with 201 additions and 8 deletions

View File

@@ -10,8 +10,9 @@
<import resource="classpath*:alfresco/portlets-context.xml"/>
<import resource="classpath:alfresco/blog-context.xml"/>
<import resource="classpath:alfresco/calendar-services-context.xml"/>
<import resource="classpath:alfresco/links-services-context.xml"/>
<import resource="classpath:alfresco/comment-services-context.xml"/>
<import resource="classpath:alfresco/discussions-services-context.xml"/>
<import resource="classpath:alfresco/links-services-context.xml"/>
<import resource="classpath:alfresco/rating-services-context.xml"/>
<import resource="classpath:alfresco/rendition-services-context.xml"/>
<import resource="classpath:alfresco/replication-services-context.xml"/>

View File

@@ -0,0 +1,65 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<!-- Discussions Service -->
<bean id="DiscussionService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.service.cmr.discussion.DiscussionService</value>
</property>
<property name="target">
<ref bean="discussionService" />
</property>
<property name="interceptorNames">
<list>
<idref local="DiscussionService_transaction" />
<idref bean="AuditMethodInterceptor" />
<idref bean="exceptionTranslator" />
<idref bean="DiscussionService_security" />
</list>
</property>
</bean>
<!-- Discussions service transaction bean -->
<bean id="DiscussionService_transaction"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">${server.transaction.mode.default}</prop>
</props>
</property>
</bean>
<!-- List of Discussion Canned queries -->
<bean id="discussionCannedQueryRegistry" class="org.alfresco.util.registry.NamedObjectRegistry">
<property name="storageType" value="org.alfresco.query.CannedQueryFactory"/>
</bean>
<!-- The regular GetChildren Auditable Canned Query Factory -->
<!--
<bean name="discussionGetChildrenCannedQueryFactory" class="org.alfresco.repo.node.getchildren.GetChildrenAuditableCannedQueryFactory">
<property name="registry" ref="discussionCannedQueryRegistry"/>
<property name="tenantService" ref="tenantService"/>
<property name="nodeDAO" ref="nodeDAO"/>
<property name="qnameDAO" ref="qnameDAO"/>
<property name="cannedQueryDAO" ref="cannedQueryDAO"/>
<property name="methodSecurity" ref="DiscussionService_security_listPosts"/>
</bean>
-->
<!-- Discussion Service base bean -->
<bean id="discussionService" class="org.alfresco.repo.discussion.DiscussionServiceImpl">
<property name="nodeService" ref="NodeService"/>
<property name="siteService" ref="SiteService"/>
<property name="contentService" ref="ContentService"/>
<property name="taggingService" ref="TaggingService"/>
<property name="fileFolderService" ref="FileFolderService"/>
<property name="transactionService" ref="transactionService" />
<property name="cannedQueryRegistry" ref="wikiCannedQueryRegistry" />
</bean>
</beans>

View File

@@ -1057,6 +1057,33 @@
</bean>
<!-- ========================= -->
<!-- The Discussions Services -->
<!-- ========================= -->
<!-- The discussion service itself does not require any security restrictions, -->
<!-- they are imposed by the node and site services it uses to do its work. -->
<bean id="DiscussionService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
<!-- The canned queries that the discussion services use do however need to check -->
<bean id="DiscussionService_CannedQuery_security" class="org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityInterceptor">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
<property name="accessDecisionManager"><ref local="accessDecisionManager"/></property>
<property name="afterInvocationManager"><ref local="afterInvocationManager"/></property>
<property name="objectDefinitionSource">
<value>
org.alfresco.service.cmr.discussion.DiscussionService.listPosts=ACL_ALLOW,AFTER_ACL_NODE.sys:base.ReadProperties
</value>
</property>
</bean>
<bean id="DiscussionService_security_listPosts" class="org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityBean">
<property name="methodSecurityInterceptor" ref="DiscussionService_CannedQuery_security" />
<property name="service" value="org.alfresco.service.cmr.discussion.DiscussionService" />
<property name="methodName" value="listPosts" />
</bean>
<!-- ======================== -->
<!-- Repository Admin Service -->
<!-- ======================== -->

View File

@@ -298,18 +298,31 @@ public class DiscussionServiceImpl implements DiscussionService
throw new IllegalArgumentException("Can't create posts for a topic that was never persisted!");
}
// Are we going to be the primary post?
boolean isPrimary = false;
if(getPrimaryPost(topic) == null)
{
isPrimary = true;
}
// Decide on the name. If this is the first post in a topic,
// it should share the topic's name, otherwise needs a new one
String name = generateName();
if(getPrimaryPost(topic) == null)
if(isPrimary)
{
name = topic.getSystemName();
}
// Get the properties for the node
// Create the properties for the node
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(ContentModel.PROP_NAME, name);
// Do we want a title? By default, primary posts share a title
// with the topic, but replies are title-free
if(isPrimary)
{
props.put(ContentModel.PROP_TITLE, topic.getTitle());
}
// Build the node
NodeRef nodeRef = nodeService.createNode(
@@ -330,6 +343,31 @@ public class DiscussionServiceImpl implements DiscussionService
return buildPost(nodeRef, topic, name, contents);
}
@Override
public PostInfo createReply(PostInfo parentPost, String contents)
{
// Sanity check what we were given
if(parentPost.getNodeRef() == null)
{
throw new IllegalArgumentException("Can't reply to a post that was never persisted");
}
if(parentPost.getTopic() == null)
{
throw new IllegalArgumentException("Can't reply to a post with no attached topic");
}
// Have the post created
PostInfo reply = createPost(parentPost.getTopic(), contents);
// Now make it a reply
nodeService.createAssociation(
reply.getNodeRef(), parentPost.getNodeRef(), ContentModel.ASSOC_REFERENCES
);
// All done
return reply;
}
@Override
public TopicInfo updateTopic(TopicInfo topic)
@@ -467,7 +505,7 @@ public class DiscussionServiceImpl implements DiscussionService
PostInfo post = getPost(topic, topic.getSystemName());
if(post != null)
{
return null;
return post;
}
// Cater for the explorer case, we want the first child
@@ -485,6 +523,35 @@ public class DiscussionServiceImpl implements DiscussionService
}
@Override
public PagingResults<TopicInfo> listTopics(String siteShortName,
PagingRequest paging) {
NodeRef container = getSiteWikiContainer(siteShortName, false);
if(container == null)
{
// No topics
return new EmptyPagingResults<TopicInfo>();
}
// We can now fetch by parent nodeRef
return listTopics(container, paging);
}
@Override
public PagingResults<TopicInfo> listTopics(NodeRef nodeRef,
PagingRequest paging) {
// TODO
return new EmptyPagingResults<TopicInfo>();
}
@Override
public PagingResults<PostInfo> listPosts(TopicInfo topic, PagingRequest paging)
{
// TODO
return new EmptyPagingResults<PostInfo>();
}
@Override
public PagingResults<PostInfo> listPostReplies(PostInfo primaryPost,
int levels, PagingRequest paging) {

View File

@@ -33,13 +33,28 @@ import org.alfresco.service.cmr.repository.NodeRef;
public interface DiscussionService {
/**
* Creates a new {@link PostInfo} in the given topic,
* specified contents
* with the specified contents.
* Normally only one post is created this way on a topic,
* and the remainder of the posts are created as
* replies to the {@link #getPrimaryPost(TopicInfo)}
* primary post.
*
* @return The newly created {@link PostInfo}
*/
@NotAuditable
PostInfo createPost(TopicInfo topic, String contents);
/**
* Creates a new {@link PostInfo} which is a reply to
* the specified other post, with the given contents.
* The link between the parent post and the reply is
* created as part of this.
*
* @return The newly created {@link PostInfo}
*/
@NotAuditable
PostInfo createReply(PostInfo parentPost, String contents);
/**
* Creates a new {@link TopicInfo} in the given site
*/
@@ -113,6 +128,24 @@ public interface DiscussionService {
TopicInfo getTopic(NodeRef parentNodeRef, String topicName);
/**
* Retrieves all topics in a site
*/
@NotAuditable
PagingResults<TopicInfo> listTopics(String siteShortName, PagingRequest paging);
/**
* Retrieves all topics attached to the specified Node
*/
@NotAuditable
PagingResults<TopicInfo> listTopics(NodeRef nodeRef, PagingRequest paging);
/**
* Retrieves all posts in a topic, ordered by creation date
*/
@NotAuditable
PagingResults<PostInfo> listPosts(TopicInfo topic, PagingRequest paging);
/**
* Retrieves all replies on a Topic
*/
@@ -126,13 +159,13 @@ public interface DiscussionService {
PagingResults<PostInfo> listPostReplies(PostInfo primaryPost, int levels, PagingRequest paging);
/**
* Retrieves all posts in a site
* Retrieves all posts in a site, across all topics
*/
@NotAuditable
PagingResults<PostInfo> listPosts(String siteShortName, PagingRequest paging);
/**
* Retrieves all posts attached to the specified Node
* Retrieves all posts attached to the specified Node, across all topics
*/
@NotAuditable
PagingResults<PostInfo> listPosts(NodeRef nodeRef, PagingRequest paging);