Archivos de etiquetas: javascript

LockService en JScript (Java Backend)

folder-blue-locked-iconDesde Java se puede acceder al servicio de bloqueo de nodos de Alfresco, pero desde JScript (WebScripts) no se puede hacer bloquear, si desbloquear (document.unlock()) pero en muchas ocasiones nos interesa bloquear el documento con el que estamos trabajando.

Podemos usar varias soluciones: Sobrecargar o añadir métodos al objeto ScriptNode, exponer el servicio o crear una acción y llamarla desde JScript. En este caso vamos a implementar la exposición de un objeto locker en JScript a través de la forma Java-Backend.

Para esto hay que realizar dos ficheros, la definición del bean para que Rhino pueda tenerlo disponible y el código en Java que defina los servicios para JScript.

En primer lugar, el fichero de definición de bean (javascript-context.xml) puede ser algo así:

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
 <bean id="scriptLocker" class="es.omc.ae.javascript.ScriptLocker"
 parent="baseJavaScriptExtension">
 <property name="extensionName">
 <value>locker</value>
 </property>
 <property name="lockService">
 <ref bean="LockService" />
 </property>
 </bean>
</beans>

Y el código en Java (ScriptLocker.java):


package es.omc.ae.javascript;

import org.alfresco.repo.jscript.ScriptNode;
import org.alfresco.repo.processor.BaseProcessorExtension;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.lock.LockType;

/**
 * Locker and Unlocker (Backend JScript)
 * 
 * @author Fernando González (fegor [at] fegor [dot] com)
 * @version 1.0
 *
 */
public final class ScriptLocker extends BaseProcessorExtension {

 private LockService lockService;

 /**
 * @param nodeRef
 */
 public void unlock(ScriptNode scriptNode) {
 LockStatus lockStatus = lockService.getLockStatus(scriptNode.getNodeRef());
 if (LockStatus.LOCKED.equals(lockStatus)
 || LockStatus.LOCK_OWNER.equals(lockStatus)) {
 this.lockService.unlock(scriptNode.getNodeRef());
 }
 }

 /**
 * @param nodeRef
 */
 public void nodeLock(ScriptNode scriptNode) {
 this.lockService.lock(scriptNode.getNodeRef(), LockType.NODE_LOCK);
 }

 /**
 * @param scriptNode
 * @param timeToExpire (in seconds)
 */
 public void nodeLock(ScriptNode scriptNode, int timeToExpire) {
 this.lockService.lock(scriptNode.getNodeRef(), LockType.NODE_LOCK, timeToExpire);
 }
 
 /**
 * @param nodeRef
 */
 public void readOnlyLock(ScriptNode scriptNode) {
 this.lockService.lock(scriptNode.getNodeRef(), LockType.READ_ONLY_LOCK);
 }

 /**
 * @param scriptNode
 * @param timeToExpire (in seconds)
 */
 public void readOnlyLock(ScriptNode scriptNode, int timeToExpire) {
 this.lockService.lock(scriptNode.getNodeRef(), LockType.READ_ONLY_LOCK, timeToExpire);
 }
 
 /**
 * @param nodeRef
 */
 public void writeLock(ScriptNode scriptNode) {
 this.lockService.lock(scriptNode.getNodeRef(), LockType.WRITE_LOCK);
 }

 /**
 * @param scriptNode
 * @param timeToExpire (in seconds)
 */
 public void writeLock(ScriptNode scriptNode, int timeToExpire) {
 this.lockService.lock(scriptNode.getNodeRef(), LockType.WRITE_LOCK, timeToExpire);
 }
 
 /**
 * @param nodeRef
 * @return
 */
 public String getLockStatus(ScriptNode scriptNode) {
 return this.lockService.getLockStatus(scriptNode.getNodeRef()).name();
 }

 /**
 * @param nodeRef
 * @return
 */
 public String getLockType(ScriptNode scriptNode) {
 return this.lockService.getLockType(scriptNode.getNodeRef()).name();
 }

 /**
 * @param lockService
 */
 public void setLockService(LockService lockService) {
 this.lockService = lockService;
 }
}

Ya solo queda usarlo, por ejemplo en JScript tenemos el objeto document, podemos hacer:


locker.nodeLock(document);

Para bloquearlo, o:


locker.unlock(document);

Para desbloquearlo posteriormente. También disponemos de los mismos métodos pero con un parámetro más para bloquear un número determinado de segundos.

En la versión 5 de Alfresco existen más métodos de este servicio pero he implementado los mínimos para que pueda funcionar desde versiones 3.4 y 4.x.

 

Enlaces de interés:

http://dev.alfresco.com/resource/docs/java/org/alfresco/service/cmr/lock/LockService.html

 

Como no sobrecargar form.get.head.ftl en Alfresco

En el blog de Michal Wróbel y su magnífico artículo «How to perform form field validation in Alfresco Share?» se explica la forma de usar los eventos para validaciones de campos en formulario de Alfresco Share. Lo hace sobreescribiendo la restricción obligatoria (mandatory constraint).

El problema viene cuando creamos un módulo para Alfresco Share con su fichero JAR correspondiente y lo instalamos en un Alfresco Share donde hay otro fichero form.get.head.ftl ya que el del JAR anulará al anterior con lo que no funcionarán las validaciones.

Para esto he decidido usar otra forma de tener cargado el fichero .js que necesitamos para las validaciones, por ejemplo form_validation_module.js dentro de nuestra instalación. La forma es usando la referencia a ficheros javascript de la configuración de los «forms» de forma que podamos tener y cargar los ficheros por cada módulo que tengamos sin tener que tocar el fichero original.

De esta forma, podremos tener el mismo fichero form_validation_module.js en la misma ubicación tomcat/webapps/share/components/form pero ahora lo referenciamos no en form.get.head.ftl sino dentro de nuestro fichero de configuración de los campos, por ejemplo module-form-config.xml de esta forma:


   
       
           
               
           

       
   


   
       
           
               
                   
               
               
                   
                       
                            <constraint type="mandatory"
                                validation-handler=»Alfresco.forms.validation.prueba»/>
                       
                   
               
           
       
   

Lo único que cambia del anterior método es que aquí no hace falta referenciar la parte ${page.url.context}/res y que hay que añadir «-min» al fichero si lo vamos a «compactar».

De esta forma tendrémos más seguridad a la hora de desplegar distintos módulos para Alfresco Share donde haya otros ya instalados.