Archivos de etiquetas: TemplateMethodModelEx

Extender Freemarker en Alfresco

El binomio Javascript (Rhino) + Freemarker se ha mostrado como uno de los mejores sistemas para realizar la parte controlador + visor en Alfresco. Su capacidad de acceso desde Javascript al API de Alfresco y la capacidad del motor de plantillas de Freemarker ha marcado el punto de evolución de los llamados Webscritps y ha terminado, por ahora, en un fantástico framework llamado Spring-Surf.

Si bien hay pocas cosas que no puedan hacerse con Freemarker, si podemos encontrar algunas excepciones en las que tengamos que extender su funcionalidad.

Un ejemplo de esto es para el traspaso de datos entre sistemas Alfresco + aplicaciones en los que dicha transferencia puede realizarse vía JSON, XML, etc.

JSON por otra parte se está revelando como un sistema más agil que el traspaso de información mediante XML pero también está limitado a los validadores que en un momento dado pueden echar para atrás una comunicación.

En este sentido, una forma de pasar los datos entre sistemas es usando una codificación ya algo antigua (de 1987), ideada en un principio para transferencias con el correo electrónico pero que es muy válida hoy día.

Extender Freemarker

Vamos a utilizar la siguiente técnica:

Creamos una clase que implemente la interface TemplateMethodModelEx y sobreescribimos el método exec creando nuestro algoritmo de transformación a sistema base64.

Un ejemplo podría ser el siguiente:

Fichero: Base64EncoderMethod.java

package com.fegor.alfresco.freemarker.utils;

import java.io.UnsupportedEncodingException;
import java.util.List;

import org.springframework.security.crypto.codec.Base64;

import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;

/**
 * Codificaci?n en base64 de cadenas pasadas a FreeMarker
 *
 * @author Fernando
 *
 */
public class Base64EncoderMethod implements TemplateMethodModelEx {

    @SuppressWarnings(«rawtypes»)
    @Override
    public Object exec(List args) throws TemplateModelException {
        String result = null;
        SimpleScalar ss = new SimpleScalar(args.get(0).toString());
        String res = ss.getAsString();
        byte[] bytes = res.getBytes();
        byte[] base64 = Base64.encode(bytes);
        try {
            result = (new String(base64, «UTF-8»));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }
}

En este caso he usado la clase Base64 del paquete de SpringFramework, aquí hay que tener cuidado con el que utilizamos ya que algunas clases pueden variar como cortar las líneas en 76 caracteres añadiendo un retorno de carro que hará que los validadores (en el caso de JSON) no funcionen. También hay que tener en cuenta que esta librería no está incluida hasta la versión 4 de Alfresco por lo que si usamos una versión como por ejemplo la 3 tendremos que incluirla en nuestro paquete/módulo.

Si usamos una clase de alguna librería que nos devuelva el resultado de esta forma solo habrá que reemplazar la línea:

     result = (new String(base64, «UTF-8»));
por
     result = (new String(base64, «UTF-8»)).replace(«n», «»);

El siguiente paso será crear una plantilla de utilidad para crear una instancia de esta clase:

Fichero: utils.ftl

Con esto tendríamos nuestra extensión, ahora necesitamos probarla, para ello creamos un Webscript que va a enviarnos la información del título y el contenido de un nodo codificando en base64 el contenido.

Creamos el descriptor…

Fichero: content_base64.get.desc.xml


    content_base64
    Codificar content en base64
    /content_base64?uuid={uuid?}
    /content_base64.json?uuid={uuid?}
    /content_base64.xml?uuid={uuid?}
    user
    extension

Creamos el controlador…

Fichero: content_base64.get.js

var query_lucene = ‘ID:»workspace://SpacesStore/’ + args[«uuid»] + ‘»‘;
var nodeRefs = search.luceneSearch(query_lucene);

model.nodeRef = «none»;

if (nodeRefs.length != 0) {
    model.nodeRef = nodeRefs[0];   
}

Y solo resta crear las plantillas, en este caso crearemos dos, una para JSON y otra para XML…

Fichero: content_base64.get.json.ftl

 {
 «Node» : [ {
  
        «Error»: «nodeRef es null»
  
        «Título»: «${item.properties[‘cm:title’]}»,
        «Contenido»: «${u.base64Encode(item.properties[‘cm:content’].content)}»
  
   } ]
 }

Fichero: content_base64.get.xml.ftl

   
        No se ha encontrado el nodo
          
        ${nodeRef.properties[‘cm:title’]}
        ${u.base64Encode(nodeRef.properties[‘cm:content’].content)}
           

Con esto obtenemos las propiedades que necesitamos codificadas para que los caracteres que puedan contener no afecten en el protocolo ni en el sistema que se van a utilizar. Esto es muy importante cuando hablamos de  las normas ENI (Esquema Nacional de Interoperabilidad) e incluso para algunos casos del ENS (Esquema Nacional de Seguridad) ya que podemos usar este sistema también para transferir información encriptada usando algún algoritmo como RSA.