Mostrando entradas con la etiqueta Office. Mostrar todas las entradas
Mostrando entradas con la etiqueta Office. Mostrar todas las entradas

viernes, 3 de enero de 2014

Tratamiento de URLs largas en el protocolo Sharepoint de Alfresco

Una de las funcionalidades más apreciadas por los usuarios de Alfresco Share es la posibilidad de editar ficheros de MS Office directamente desde la aplicación sin necesidad de descargarse el fichero en local. Alfresco ofrece esta funcionalidad mediante el protocolo Sharepoint incluido en el módulo vti. A pesar de su buena funcionalidad, el módulo no está exento de problemas y uno de ellos es el tratamiento de URLs demasiado largas.

Las URLs utilizadas por Alfresco para invocar la edición online de documentos tienen la siguiente forma:

{protocol}://{host}:{vti_port}/{alfresco_context}/{site}/{path_to_file}/{filename}

Todos estos elementos tienen una longitud más o menos acotada excepto que representa toda la ruta de carpetas desde la raíz del Sitio hasta el fichero. El protocolo Sharepoint tiene un problema cuando esta ruta es demasiado larga y el resultado puede ser que el fichero no se pueda abrir para su edición online. Hasta ahora la única solución era acortar estos paths cambiando el nombre de las carpetas que lo forman, pero esto puede ser una solución que no todos los usuarios de Alfresco estén dispuestos a aceptar.

Buscando una solución a este problema se me ocurrió la posibilidad de trabajar con los indentificadores de fichero de Alfresco en lugar del path. La ventaja de usar identificadores es que su longitud es fija y no excede el límite fijado por el protocolo. Con este enfoque la URL a construir sería del siguiente estilo:

{protocol}://{host}:{vti_port}/{alfresco_context}/{site}/__ID/{content_uuid}/{filename}

En esta nueva URL he usado una partícula (__ID) que me permite identificar que se trata de una URL que contiene un identificador de contenido y he añadido el UUID del contenido que quiero editar. Una vez definida la URL adecuada es hora de construirla y para ello hay que modificar la librería JavaScript que se utiliza en Alfresco para generar estas URLs. En concreto hay que buscar el fichero documentlibrary-actions.js (o su versión minificada para ser más exactos) y buscar el siguiente trozo de código:

var onlineEditUrl = this.doclistMetadata.custom.vtiServer.host + ":" + this.doclistMetadata.custom.vtiServer.port + "/" + $combine("alfresco", loc.site.name, loc.container.name, loc.path, loc.file);

Aquí se puede ver como la URL se compone a partir del site, el path y el nombre del fichero. Hay que sustituir dicho código por el siguiente:

var onlineEditUrl = this.doclistMetadata.custom.vtiServer.host + ":" + this.doclistMetadata.custom.vtiServer.port + "/" + $combine("alfresco", loc.site.name, "__ID", record.jsNode.nodeRef.uri.substring(record.jsNode.nodeRef.uri.lastIndexOf("/")+1), loc.file);

En este nuevo código se utiliza el site, el UUID (calculado a partir del nodeRef del documento) y el nombre del fichero.

El siguiente paso consiste en tratar estas URLs. Hay varias opciones para ello pero yo he optado por modificar una clase del módulo vti de Alfresco que se utiliza para realizar operaciones con el path de los ficheros. La clase en cuestión es:

org.alfresco.module.vti.handler.alfresco.VtiPathHelper

y el código de esta clase se puede obtener del repositotio público de svn de Alfresco (por ejemplo de aquí: /alfresco/COMMUNITYTAGS/V4.0e/root/modules/sharepoint/amp/source/java/org/alfresco/module/vti/handler/alfresco). También se puede obtener del repositorio enterprise si se tiene acceso.

En esta clase hay un método que devuelve la información del fichero a partir del path que le llega por la URL. Este método se utiliza en varias operaciones del protocolo por lo que hay que tener cuidado a la hora de cambiar el código para que no se vea alterado el correcto funcionamiento del módulo. El método que hay que modificar es: resolvePathFileInfo. En el código original del método aparecen las siguientes líneas:

           List splitPath = Arrays.asList(initialURL.split("/"));
           fileInfo = fileFolderService.resolveNamePath(rootNodeRef, splitPath);

Estas líneas hay que sustituirlas por estas otras para poder tratar las nuevas URLs:

List splitPath = Arrays.asList(initialURL.split("/"));
if(splitPath.contains("__ID")){
  if(splitPath.size()==4){
    NodeRef fileNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE

                                   , splitPath.get(2));
    fileInfo = fileFolderService.getFileInfo(fileNodeRef);
  } else if (splitPath.size()==3) {
    NodeRef fileNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE

                                   , splitPath.get(2));
    NodeRef parentNodeRef = nodeService.getPrimaryParent(fileNodeRef)

                                       .getParentRef();
    fileInfo = fileFolderService.getFileInfo(parentNodeRef);                 
  }

}else{
  fileInfo = fileFolderService.resolveNamePath(rootNodeRef, splitPath);
}


El nuevo código permite tratar tanto las nuevas URLs como las antiguas, manteniendo así la compatibilidad con el módulo de Alfresco. La primera parte del condicional (cuando el path contiene cuantro elementos) sirve para localizar la información del fichero que se quiere editar en el momento que se abre el fichero por primera vez. La segunda parte del condicional (cuando el path contiene 3 elementos) se usa cuando se guardan los cambios en el documento y se necesita recuperar la carpeta que lo contiene.

Con este cambio se puede generar un nuevo fichero JAR que contenga la implementación del protocolo vti y desplegarlo en el servidor de aplicaciones.

Este problema afecta a todas las versiones del módulo vti y en Alfresco están trabajando en una solución que estará disponibles en futuras versiones del módulo.

lunes, 11 de abril de 2011

Bug en la edicion online de Alfresco usando Office 2010

En la versión 3.4.0 de Alfresco Enterprise hay un bug en la edición online de documentos de Office cuando se utiliza la suite de programas MSOffice 2010. Este bug hace que se pierda el content type de los documentos editados cuando se guardan los cambios hechos sobre el documento.

Este no es un error excesivamente grave ya que es fácil de subsanar volviendo a asignar manualmente el content type al documento. De todas formas obligar a los usuarios a hacer esta asignación cada vez que editan un documento es bastante poco práctico. Además, si se pierde el content type de un documento, hay un efecto secundario en determinados tipos de ficheros (por ejemplo los documentos de MSOffice 2007) que hace que la siguiente vez que se vaya a editar un documento el sistema no sepa como abrirlo al desconocer el content type del que se trata.

Este problema estará resuelto en la versión 3.4.2. Mientras tanto, hay un posible workaround para evitar la pérdida del content type cuando se guardan los cambios de documento editado online.

Lo primero es crear un script con el siguiente código:

if (document.hasAspect("cm:workingcopy") && document.properties["cm:workingCopyMode"]=="onlineEditing") {

var ref = document.properties["cm:source"];


if (ref.mimetype != document.mimetype) {

document.mimetype = ref.mimetype;

document.save();

}

}


La perdida del content type se produce al guardar los cambios, y esto siempre se hace sobre la copia de trabajo. Por este motivo, voy a buscar el content type al documento original y lo actualizo en la copia de trabajo en el caso de que se haya perdido.

A continuación hay que crear una regla en el espacio raíz del repositorio que aplique a todos los items de cualquier tipo que sean modificados en el repositorio, que ejecute el script anterior y que tenga efecto en todas las subcarpetas del espacio raíz.