cancel
Showing results for 
Search instead for 
Did you mean: 

Programatically Setting Modified Date & User

simon_white
Champ in-the-making
Champ in-the-making
Hello all,

I've had a search around the forums and wiki for similar problems, but the discussions I've found tend to be about extracting metadata from files on initial upload to DM, or suitable for one off use, whereas my client's problem is a little different…

Essentially, my client wants to be able  to move wiki pages, documents and entire discussions between sites in share.  They want to do this whilst leaving the metadata of the original documents, including creation date, modification date and modified-by, intact.  They want to do this in the course of normal operation, so meddling directly with the database, taking anything offline etc is out.

I'm pretty confident that I can set the modified-by user correctly - if I need to, I can encapsulate the modification in a RunAsWork although I'm sure I won't have to go that far.  But I was having a little more trouble setting the modification date correctly.

Does anyone know how, via Java or Javascript, to explicitly set the modification date of a node to a date other than _now_?

Many thanks in advance,

Simon White


simon.white@gmail.com
simon.white@surevine.com
5 REPLIES 5

mrogers
Star Contributor
Star Contributor
It's easiest from Java.   The trick is to disable the cm:auditable aspect for the duration of your transaction.   You do that with the PolicyComponent,

I suggest you look at the Alfresco source code itself for examples of how to do this.

simon_white
Champ in-the-making
Champ in-the-making
Mark, Alfresco folks,

Thanks for the reply.  I've had a look at the Alfresco source and thought that what I needed to do was fairly simple - I've encapsulated a test case in an action and run it against a node (representing a share wiki page for what it's worth) in Alfresco Explorer. 

However, it doesn't seem to behave as I'd expect. 

Here's my test code:

package com.surevine.proto.alfresco.repo.action;

public class ChangeModificationDateAction extends ActionExecuterAbstractBase {

   private NodeService _nodeService;
   
   private BehaviourFilter _policyFilter;
   
   public void setPolicyFilter(BehaviourFilter setFilter)
   {
      _policyFilter=setFilter;
   }
   
   public void setNodeService(NodeService nodeService)
   {
      _nodeService=nodeService;
   }
   
   @Override
   protected void executeImpl(Action arg0, NodeRef arg1) {
      try
      {
         Date yesterday = new Date(new Date().getTime()-(1000l*60l*60l*24l)); //I've also tried new Date(0l)
         _policyFilter.disableBehaviour(arg1, ContentModel.ASPECT_AUDITABLE);
         _nodeService.setProperty(arg1, ContentModel.PROP_TITLE, "Modified by test action!"); //Just to confirm the action has actually run
         _nodeService.setProperty(arg1, ContentModel.PROP_MODIFIED, yesterday);
      }
      finally
      {
         _policyFilter.enableBehaviour(arg1, ContentModel.ASPECT_AUDITABLE);
      }
   }
   
   @Override
   protected void addParameterDefinitions(List<ParameterDefinition> arg0)
   {
      //Intentionally blank
   }
}

(The Spring config is available if required)

After running the action, the title of my node changes as expected, indicating that the action is running, no error messages appear in the UI or the logs and the modified date is set to when I ran the action, not the date specified.

I've also tried disabling auditing by running the following, but the modification date is still set to today's date:


curl -u admin:xxxxxxxxx -d "" "http://localhost:8080/alfresco/service/api/audit/control/CMISChangeLog/CMISChangeLog?enable=false"

If anyone can spot what I'm doing wrong, I'd be most grateful!

Thanks in advance,

Simon

simon_white
Champ in-the-making
Champ in-the-making
I've now worked this out - you need to also remove the versionable aspect (if present). 

Thanks a lot for the help, Mark

For future reference, the following code provides an example of how to achieve this in an action:


package com.surevine.alfresco.repo.action;

import java.util.Date;
import java.util.List;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;

/**
*Prototype code - not for production use
* @author simon.white@surevine.com simon.white@gmail.com
*/
public class ChangeModificationDateAction extends ActionExecuterAbstractBase {

   private NodeService _nodeService;
   
   private BehaviourFilter _policyFilter;
   
   public void setPolicyFilter(BehaviourFilter setFilter)
   {
      _policyFilter=setFilter;
   }
   
   public void setNodeService(NodeService nodeService)
   {
      _nodeService=nodeService;
   }
   
   @Override
   protected void executeImpl(Action arg0, NodeRef arg1) {
      try
      {
         Date yesterday = new Date(new Date().getTime()-(1000l*60l*60l*24l));
         _policyFilter.disableBehaviour( ContentModel.ASPECT_VERSIONABLE);
         _policyFilter.disableBehaviour(arg1, ContentModel.ASPECT_AUDITABLE);
         _nodeService.setProperty(arg1, ContentModel.PROP_TITLE, "Modified by test action!");
         _nodeService.setProperty(arg1, ContentModel.PROP_MODIFIED, yesterday);
      }
      finally
      {
         _policyFilter.enableBehaviour(arg1, ContentModel.ASPECT_AUDITABLE);
         _policyFilter.enableBehaviour(arg1, ContentModel.ASPECT_VERSIONABLE);
      }
   }
   
   @Override
   protected void addParameterDefinitions(List<ParameterDefinition> arg0)
   {
      //Intentionally blank
   }
}

And the spring config is here:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
    <bean id="com.surevine.alfresco.repo.action.ChangeModificationDateAction" class="com.surevine.alfresco.repo.action.ChangeModificationDateAction" parent="action-executer">
        <property name="nodeService">
            <ref bean="nodeService" />
        </property>
        <property name="policyFilter">
            <ref bean="policyBehaviourFilter" />
        </property>
    </bean>
</beans>

paulm
Champ in-the-making
Champ in-the-making
Thank you, I finally have my webscript working, thanks to this solution! I was wrestling with this for a while.

rajasacet
Champ in-the-making
Champ in-the-making
Can you post the modified date and user javascript code in this thread. I have tried with about code, but i am not able to update the modified date and users using javascript api.