Modifica date documenti

cancel
Showing results for 
Search instead for 
Did you mean: 
barcoffin
Member II

Modifica date documenti

Ciao a tutti,

             ho la necessità di caricare su una repository di Alfresco un documento impostandone però le date (di creazione e di modifica) a mio piacimento.
Basandomi su un lavoro di David Ciamberlano (e sfruttando i suoi suggerimenti) sono riuscito ad arrivare a un buon punto… ora mi serve un ultimo aiuto.
Per prima cosa ho creato una custom action (action-change-date.jar posizionata in tomcat\webapps\alfresco\WEB-INF\lib):


package org.alfresco.repo.action.executer;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.alfresco.model.ContentModel;
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.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;

public class ChangeDateActionExecuter extends ActionExecuterAbstractBase
{
   private NodeService nodeService;
   private BehaviourFilter policyBehaviourFilter;;
      
   public void setNodeService(NodeService nodeService)
      {
                 this.nodeService = nodeService;
      }
   public void setBehaviourFilter(BehaviourFilter policyBehaviourFilter)
   {
      this.policyBehaviourFilter = policyBehaviourFilter;
   }

   @Override
      public void executeImpl(Action action, NodeRef actionedUponNodeRef)
        {
         if (nodeService.exists(actionedUponNodeRef))
           {
         try
         {               
            // recupera le proprietà del nodo corrente
            Map<QName, Serializable> props = nodeService.getProperties(actionedUponNodeRef);
            Date modified = new SimpleDateFormat("yyyy-MM-dd").parse("2013-01-01");
            Date created = new SimpleDateFormat("yyyy-MM-dd").parse("2013-01-02");

            props.put(ContentModel.PROP_MODIFIED, modified);        
            props.put(ContentModel.PROP_CREATED, created);

            // >>>>>>>>>>>>>>> NOTA BENE
            // disabilita il behaviour dell'aspetto Autitable in modo da permettere la modifica
            policyBehaviourFilter.disableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE);
            nodeService.setProperties(actionedUponNodeRef, props);       
         }
         catch (InvalidNodeRefException EX_in)
         {              
            // […]
         }
         catch (ParseException EX_pe)
         {                   
            // […]
         }            
         finally
         {
            policyBehaviourFilter.enableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE);
         }
         }
      }

        @Override
   protected void addParameterDefinitions(List<ParameterDefinition> arg0)
   {
      // TODO Auto-generated method stub
   }
}


Ho quindi inserito il file di configurazione (action-change-date-context.xml posizionata in tomcat\shared\classes\alfresco\extension):

<?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="ChangeDateActionExecuter" class="org.alfresco.repo.action.executer.ChangeDateActionExecuter" parent="action-executer" init-method="init">
      <property name="NodeService">
              <ref bean="nodeService" />
            </property>   
           <property name="BehaviourFilter">
               <ref bean="policyBehaviourFilter" />
           </property>
   </bean>
</beans>


In questa fase ho scoperto che bisogna stare particolarmente attenti alla dichiarazione dei bean; per errore avevo scritto

   public void setPolicyBehaviourFilter(BehaviourFilter policyBehaviourFilter)

invece di

   public void setBehaviourFilter(BehaviourFilter policyBehaviourFilter)

e il risultato era che… Alfresco non mi faceva neanche accedere al sistema.
Comunque, dopo aver risolto (grazie David Smiley Happy ), volendo testare il funzionamento della action, ho eseguito (nella Javascript console) il seguente script su un documento di prova:

<javascript>
var nodeRef = "workspace://SpacesStore/fd556b01-8131-45dd-8ecb-1b159f1e1f20";
var docNode = search.findNode(nodeRef);

var ac = actions.create("ChangeDateActionExecuter");

ac.execute(docNode);
</javascript>

ed effettivamente, date di creazione e modifica del documento sono cambiate.
Fino a questo momento, però, le date sono "inglobate" nel codice java mentre io vorrei riuscire a passarle come parametri; nonostante le indicazioni fornitemi da David non sono ancora riuscito a implementare la cosa e a farla funzionare sempre tramite Javascript console…
Sto cercando di arrivare alla soluzione ma… beh non disdegnerei un aiutino…

…. grazie… Smiley Happy
4 Replies
davidciamberlan
Alfresco Employee

Re: Modifica date documenti

Ciao,

intanto grazie per le menzioni ma ti ho dato solo un paio di dritte… il resto l'hai fatto da solo!

Riguardo la tua domanda: per rendere parametriche le date devi implementare il metodo
<java>void addParameterDefinitions(List<ParameterDefinition>)</java>
nella classe che implementa la action.
Un esempio può essere

<java>
@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList) { 
  paramList.add(
     new ParameterDefinitionImpl(
      PARAM_NAME,
      DataTypeDefinition.TEXT,
      true,
      getParamDisplayLabel(PARAM_NAME)
    )
  );
}

</java>

Devi aggiungere a paramList tanti oggetti ParameterDefinitionImpl quanti sono i parametri che vuoi utilizzare.

Queste proprietà potrai poi leggerle nel metodo executeImpl utilizzando il getParameterValue sull'oggetto action

<java>
action.getParameterValue(PARAM_NAME);
</java>

Infine da javascript potrai valorizzare i parametri aggiungendogli all'oggetto parameters dell'action che avrai creato (come riportato nell'esempio)

<javascript>

var ac = actions.create("your-custom-action");
ac.parameters.param1= "Param1";
ac.parameters.param2= "Param2";

[…]

</javascript>

Spero di esserti stato d'aiuto.

PS: per le custom action, se non l'hai già fatto, ti consiglio di leggere l'ottimo tutorial di Jeff Potts: <cite>Developing Custom Actions</cite> che puoi reperire googlando un po'.




barcoffin
Member II

Re: Modifica date documenti

Solo un paio di dritte, si… ma quando  … si brancola nel buio…
comunque… sono riuscito nel mio intento (almeno… nella prima parte …alla fine spiego perché)
Riporto il codice che ho utilizzato e che effettivamente permette di modificare le date di creazione e di ultima modifica di un documento; mentre il file di configurazione rimane lo stesso, la custom action, opportunamente modificata, ora risulta essere:
<java>
package org.alfresco.repo.action.executer;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
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.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;

public class ChangeDateActionExecuter extends ActionExecuterAbstractBase
{
   public static final String DATE_CREATED = "DataCreazione";
   public static final String DATE_MODIFIED = "DataModifica";
   
   private NodeService nodeService;
   private BehaviourFilter behaviourFilter;;
      
   public void setNodeService(NodeService nodeService)
      {
            this.nodeService = nodeService;
      }

   public void setBehaviourFilter(BehaviourFilter behaviourFilter)
   {
      this.behaviourFilter = behaviourFilter;
   }

   @Override
      public void executeImpl(Action action, NodeRef actionedUponNodeRef)
   {
         if (nodeService.exists(actionedUponNodeRef))
      {
         try
         {               
            // recupera le proprietà del nodo corrente
            Map<QName, Serializable> props = nodeService.getProperties(actionedUponNodeRef);

               Date created = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(action.getParameterValue(DATE_CREATED).toString());
               Date modified = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(action.getParameterValue(DATE_MODIFIED).toString());
           
               props.put(ContentModel.PROP_MODIFIED, modified);        
               props.put(ContentModel.PROP_CREATED, created);

            // >>>>>>>>>>>>>>> NOTA BENE
            // disabilita il behaviour dell'aspetto Autitable in modo da permettere la modifica
               behaviourFilter.disableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE);
               nodeService.setProperties(actionedUponNodeRef, props);       
         }
         catch (InvalidNodeRefException EX_in)
         {              
                  // […]
         }
         catch (ParseException EX_pe)
         {                   
                  // […]
         }            
         finally
         {
            behaviourFilter.enableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE);
         }
      }
   }

   @Override
   protected void addParameterDefinitions(List<ParameterDefinition> paramList)
   {
      paramList.add(new ParameterDefinitionImpl
         (
            DATE_CREATED,
            DataTypeDefinition.TEXT,
            false,
            getParamDisplayLabel(DATE_CREATED)
         )
      );
      
      paramList.add(new ParameterDefinitionImpl
         (
            DATE_MODIFIED,
            DataTypeDefinition.TEXT,
            false,
            getParamDisplayLabel(DATE_MODIFIED)
         )
      );      
   }
}
</java>

Nella Javascript console il codice che ho utilizzato (sul solito documento di prova) è il seguente:

<javascript>
var nodeRef = "workspace://SpacesStore/fd556b01-8131-45dd-8ecb-1b159f1e1f20";

var docNode = search.findNode(nodeRef);

var ac = actions.create("ChangeDateActionExecuter");

ac.parameters.DataCreazione = "2013-05-16 20:03:33"
ac.parameters.DataModifica = "2013-05-19 18:43:12"
 
ac.execute(docNode);
</javascript>

In questo modo le date di creazione e di modifica del documento vengono cambiate.
Ora però (ed ecco la seconda parte) vorrei riuscire a impostare a mio piacimento anche le date relative alle varie versioni del documento; da quello che ho capito cercando in giro suppongo che sia necessario operare in modo diverso e intervenire direttamente nella fase di caricamento della nuova versione e che non sia possibile operare, come in questo caso, una volta che la nuova versione è stata inserita.
Non so se è il caso di proseguire su questo topic o segnalare questo come risolto ed eventualmente, aprirne un altro; nel frattempo… qualche dritta (anche semplicemente su dove trovare del materiale da studiare) … sarebbe gradita  Smiley Happy

Grazie ancora….
davidciamberlan
Alfresco Employee

Re: Modifica date documenti

Ciao,

quello che segnali è lo stesso problema in cui mi sono imbattuto io qualche tempo fa. Ho anche posto una domanda sul forum.

Purtroppo devo dire di non esserne venuto a capo… ho provato diverse strade e ogni volta c'era qualcosa che mi impediva di proseguire.
Alla fine ho messo da parte la cosa (stava rallentando troppo il lavoro). Chissà che adesso non venga fuori qualcosa di interessante.

L'unico workaround che ho trovato è stata nascondere le date di creazione nella pagina di dettaglio delle versioni.

barcoffin
Member II

Re: Modifica date documenti

Volendo modificare anche le date relative alle varie versioni di un documento alla fine ho trovato una soluzione piuttosto… sporca (ma che … funziona) sfruttando il modulo <strong>alfresco-bulk-filesystem-import</strong>; è piuttosto noiosa e non ha nulla di "tecnico" ma, se può servire:
1. Per prima cosa si scaricano tutti i documenti (le varie versioni del documento) di cui si vogliono modificare le date
2. Seguendo le istruzioni del modulo si rinominano opportunamente i file stessi; il documento finale non viene modificato, agli altri si aggiunge il suffisso .v1, .v2,… al nome (es. Doc1.doc per il documento finale, Doc1.doc.v1 per la prima versione, Doc1.doc.v2 per la seconda e così via)
3. Per il documento "finale" si crea un file xml in cui si definiscono i metadati (e le date di creazione e modifica); così, per esempio, si crea il file Doc1.doc.metadata.properties.xml del tipo:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
  <properties>
    <entry key="cm:created">2013-07-31T12:40:19.789+02:00</entry>
    <entry key="cm:author">Pippo</entry>
    <entry key="cm:modified">2013-08-28T16:04:23.321+02:00</entry>
    <entry key="cm:modifier">Pluto</entry>

    <entry key="cm:publisher"> </entry>
    <entry key="cm:contributor"> </entry>

    <entry key="cm:type"> </entry>
    <entry key="cm:identifier"> </entry>

    <entry key="cm:dcsource"> </entry>
    <entry key="cm:coverage"> </entry>
    <entry key="cm:rights"> </entry>
    <entry key="cm:subject"> </entry>

</properties>
 

4. Per la prima versione si crea un file analogo in cui si impostano i dati relativi alla modifica (data e autore) uguali a quelli di creazione; questo file deve essere nominato Doc1.doc.metadata.properties.xml.v1


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
  <properties>
    <entry key="cm:created">2013-07-31T12:40:19.789+02:00</entry>
    <entry key="cm:author">Pippo</entry>
    <entry key="cm:modified">2013-07-31T12:40:19.789+02:00</entry>
    <entry key="cm:modifier">Pippo</entry>

    <entry key="cm:publisher"> </entry>
    <entry key="cm:contributor"> </entry>

    <entry key="cm:type"> </entry>
    <entry key="cm:identifier"> </entry>

    <entry key="cm:dcsource"> </entry>
    <entry key="cm:coverage"> </entry>
    <entry key="cm:rights"> </entry>
    <entry key="cm:subject"> </entry>

</properties>


5. Per tutte le versioni successive si devono creare file uguali modificando opportunamente solo i valori per "cm:modified" (ed eventualmente per "cm:modifier"); il nome del file deve essere sempre del tipo Doc1.doc.metadata.properties.xml.v2 (ovviamente Doc1.doc.metadata.properties.xml.v2 imposta i metadati del file Doc1.doc.v2 relativo alla seconda versione e così via…)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
  <properties>
    <entry key="cm:created">2013-07-31T12:40:19.789+02:00</entry>
    <entry key="cm:author">Pippo</entry>
    <entry key="cm:modified">2013-08-24T09:27:33.654+02:00</entry>
    <entry key="cm:modifier">Paperino</entry>

    <entry key="cm:publisher"> </entry>
    <entry key="cm:contributor"> </entry>

    <entry key="cm:type"> </entry>
    <entry key="cm:identifier"> </entry>

    <entry key="cm:dcsource"> </entry>
    <entry key="cm:coverage"> </entry>
    <entry key="cm:rights"> </entry>
    <entry key="cm:subject"> </entry>

</properties>


6. A questo punto, utilizzando il modulo <strong>alfresco-bulk-filesystem-import</strong> (<a href="https://code.google.com/p/alfresco-bulk-filesystem-import/">qui</a> è descritto il suo funzionamento), si "caricano" i file nel repository desiderato e si avrà così il documento con tutte le versioni che risulteranno avere le date di modifica desiderate; per poter utilizzare il modulo suddetto i file devono essere inseriti in una cartella che deve essere posizionata sul server su cui lavora alfresco.

Come detto la procedura non è… elegante… ma funziona…