diff --git a/source/java/org/alfresco/repo/content/ContentServicePolicies.java b/source/java/org/alfresco/repo/content/ContentServicePolicies.java index a10bab1bb3..5cdfde2427 100644 --- a/source/java/org/alfresco/repo/content/ContentServicePolicies.java +++ b/source/java/org/alfresco/repo/content/ContentServicePolicies.java @@ -30,6 +30,7 @@ public interface ContentServicePolicies { /** The QName's of the policies */ public static final QName ON_CONTENT_UPDATE = QName.createQName(NamespaceService.ALFRESCO_URI, "onContentUpdate"); + public static final QName ON_CONTENT_READ = QName.createQName(NamespaceService.ALFRESCO_URI, "onContentRead"); /** * On content update policy interface @@ -41,4 +42,17 @@ public interface ContentServicePolicies */ public void onContentUpdate(NodeRef nodeRef, boolean newContent); } + + /** + * On content read policy interface. + * + * This policy is fired when a content reader is requested for a node that has content. + */ + public interface OnContentReadPolicy extends ClassPolicy + { + /** + * @param nodeRef the node reference + */ + public void onContentRead(NodeRef nodeRef); + } } diff --git a/source/java/org/alfresco/repo/content/RoutingContentService.java b/source/java/org/alfresco/repo/content/RoutingContentService.java index 030d4fff4b..9e3a0fc356 100644 --- a/source/java/org/alfresco/repo/content/RoutingContentService.java +++ b/source/java/org/alfresco/repo/content/RoutingContentService.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.content.ContentServicePolicies.OnContentReadPolicy; import org.alfresco.repo.content.ContentServicePolicies.OnContentUpdatePolicy; import org.alfresco.repo.content.filestore.FileContentStore; import org.alfresco.repo.content.transform.ContentTransformer; @@ -77,9 +78,10 @@ public class RoutingContentService implements ContentService private PolicyComponent policyComponent; /** - * The onContentService policy delegate + * Policies delegate */ ClassPolicyDelegate onContentUpdateDelegate; + ClassPolicyDelegate onContentReadDelegate; /** * Default constructor sets up a temporary store @@ -132,6 +134,7 @@ public class RoutingContentService implements ContentService // Register on content update policy this.onContentUpdateDelegate = this.policyComponent.registerClassPolicy(OnContentUpdatePolicy.class); + this.onContentReadDelegate = this.policyComponent.registerClassPolicy(OnContentReadPolicy.class); } /** @@ -259,6 +262,16 @@ public class RoutingContentService implements ContentService reader.setMimetype(contentData.getMimetype()); reader.setEncoding(contentData.getEncoding()); + // Fire the content read policy + if (reader != null) + { + // Fire the content update policy + Set types = new HashSet(this.nodeService.getAspects(nodeRef)); + types.add(this.nodeService.getType(nodeRef)); + OnContentReadPolicy policy = this.onContentReadDelegate.get(types); + policy.onContentRead(nodeRef); + } + // we don't listen for anything // result may be null - but interface contract says we may return null return reader; diff --git a/source/java/org/alfresco/repo/content/RoutingContentServiceTest.java b/source/java/org/alfresco/repo/content/RoutingContentServiceTest.java index 7fa15682fe..4e7cfb0f32 100644 --- a/source/java/org/alfresco/repo/content/RoutingContentServiceTest.java +++ b/source/java/org/alfresco/repo/content/RoutingContentServiceTest.java @@ -257,6 +257,7 @@ public class RoutingContentServiceTest extends BaseSpringTest } private boolean policyFired = false; + private boolean readPolicyFired = false; private boolean newContent = true; /** @@ -298,6 +299,35 @@ public class RoutingContentServiceTest extends BaseSpringTest this.policyFired = true; } + public void testOnContentReadPolicy() + { + // Register interest in the content read event for a versionable node + this.policyComponent.bindClassBehaviour( + QName.createQName(NamespaceService.ALFRESCO_URI, "onContentRead"), + ContentModel.ASPECT_VERSIONABLE, + new JavaBehaviour(this, "onContentReadBehaviourTest")); + + // First check that the policy is not fired when the versionable aspect is not present + this.contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT); + assertFalse(this.readPolicyFired); + + // Write some content and check that the policy is still not fired + ContentWriter contentWriter2 = this.contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true); + contentWriter2.putContent("content update two"); + this.contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT); + assertFalse(this.readPolicyFired); + + // Now check that the policy is fired when the versionable aspect is present + this.nodeService.addAspect(this.contentNodeRef, ContentModel.ASPECT_VERSIONABLE, null); + this.contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT); + assertTrue(this.readPolicyFired); + } + + public void onContentReadBehaviourTest(NodeRef nodeRef) + { + this.readPolicyFired = true; + } + public void testTempWrite() throws Exception { // get a temporary writer