martes, 28 de agosto de 2012

Alfresco Custom Behavior

El repositorio de Alfresco permite la automatización de acciones sobre los contenidos que alberga. Hay varias formas que automatizar estas acciones como pueden ser las reglas sobre carpetas o las tareas programadas. En este artículo exploraremos una tercera opción: los behaviors.

Los behaviors son porciones de lógica de negocio que están vinculadas a políticas del repositorio. En el repositorio hay definido un conjunto de políticas que no son más que interfaces Java que son llamadas por los servicios de Alfresco. Las políticas disponibles en Alfresco para el servicio de nodo (NodeService) son:


Interface
Inner Interface
NodeServicePolicies
BeforeCreateStorePolicy

OnCreateStorePolicy

BeforeCreateNodePolicy

OnCreateNodePolicy

BeforeMoveNodePolicy

OnMoveNodePolicy

BeforeUpdateNodePolicy

OnUpdateNodePolicy

OnUpdatePropertiesPolicy

BeforeDeleteNodePolicy

OnDeleteNodePolicy

BeforeAddAspectPolicy

OnAddAspectPolicy

BeforeRemoveAspectPolicy

OnRemoveAspectPolicy

OnRestoreNodePolicy

BeforeCreateNodeAssociationPolicy

OnCreateNodeAssociationPolicy

OnCreateChildAssociationPolicy

BeforeDeleteChildAssociationPolicy

OnDeleteChildAssociationPolicy

OnCreateAssociationPolicy

OnDeleteAssociationPolicy

BeforeSetNodeTypePolicy

OnSetNodeTypePolicy

Tambíen hay políticas para el ContentService, el CopyService y el VersionService.

Un behavior sólo es una clase Java que implementa una de estas interfaces. La ventaja de un behavior sobre una regla es que los behavior aplican a todo el reposiotio mientras que las reglas aplican sobre carpetas concretas del reposiotio. Respecto a las tareas programadas, un behavior tiene la ventaja que se aplica en tiempo real y no hay que esperar hasta la hora de ejecución de la tarea para comprobar sus efectos.

Realizaré un ejemplo práctico extendiendo el ejemplo que propuse en este artículo. La idea es que todos los contenidos que se creen cuyo mimetype sea image/tiff se almacenen físicamente en un alamcen de contenidos especial. Para ello crearé un behavior vinculado a la política onCreateNodePolicy que añada el aspecto storeSelector e informe la propiedad storeName.

La definición de la clase será:

public class StoreSelectorBehavior implements NodeServicePolicies.OnCreateNodePolicy 


A continuación definimos las propiedades que inyectaremos desde Spring:


private NodeService nodeService;
private PolicyComponent policyComponent;



Creamos un método para inicializar el behavior y registrar la clase con la política adecuada. En este caso lo haremos para todos los contenidos de tipo cm:content :



public void init() {
    // Create behavior
    this.onCreateNode = new JavaBehaviour(this,"onCreateNode",NotificationFrequency.TRANSACTION_COMMIT);
    // Bind behavior to node policy
    this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI,"onCreateNode"),QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI ,"content"),this.onCreateNode);
}



Definimos el método que se ejecutará al crearse un nodo y donde comprobamos el mimetype y asignamos el aspecto storeSelector cuando sea necesario:


    public void onCreateNode(ChildAssociationRef childAssocRef) {
        // get the child node
        NodeRef node = childAssocRef.getChildRef();

        // check if the node has the correct mimetype
        ContentData contentData = (ContentData) nodeService.getProperty(node, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content"));
        if (contentData.getMimetype().equalsIgnoreCase("image/tiff")) {
        // ass the aspect
            Map storeSelectorProps = new HashMap(1, 1.0f);
            storeSelectorProps.put(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,"storeName"), "images"); 
            nodeService.addAspect(node, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "storeSelector"), storeSelectorProps);
        }
    }



Por último hay que definir el bean para cargar el behavior desde el contexto de Spring.



    <bean class="org.alfresco.sample.StoreSelectorBehavior" id="store-selector-behavior" init-method="init">
        <property name="nodeService">
            <ref bean="nodeService">
        </ref></property>
        <property name="policyComponent">
            <ref bean="policyComponent">
        </ref></property>
    </bean>
 
 

Ahora sólo falta desplegar los cambios y reiniciar Alfresco. A partir de este momento cada vez que se cree un contenido que tenga mimetype image/tiff se almacenará en el store images.