miércoles, 9 de marzo de 2011

Alfresco WebServices - Manipulando contenido

Cuando queramos hacer una apliación a medida en Java y trabajar con el repositorio de Alfresco, podremos usar, entre otras cosas, los webservices. Para ello, una de las librerias que necesitaremos es alfresco-web-service-client.jar, donde podemos encontrar los siguientes servicios:

AuthenticationService
RepositoryService
ContentService
AuthoringService
ClassificationService
ActionService
AccessControlService
AdministrationService
DictionaryService

Hoy me voy a centrar en la manipulación de contenido, veremos como crearlo, modificar propiedades, crear aspectos, crear asociaciones...

Lo primero que tenemos que hacer es autenticarnos en Alfresco:

AuthenticationUtils.startSession(USERNAME, PASSWORD);

Aprovecho esto para explicar brevemente como crear un pdf con jasperreports que posteriormente utilizaremos para crear nuestro nodo en el repositorio. Con la herramienta iReport podemos crear una plantilla para pdfs que nos generará dos ficheros, un *.jasper y otro *.jrxml, ambos ficheros deben estar dentro de nuestro proyecto. (prometo crear un post explicando esta herramienta más extensamente :-))

Para generar el pdf podriamos implementar el siguiente método:

public static byte[] obtenerPdf(String rutaReport) { byte[] pdf = null; try { //en ruta report se encuentran los ficheros necesarios que hemos mencionado anteriormente JasperReport jasperReport = (JasperReport) JRLoader.loadObject(new URL(rutaReport)); //el método fillReport nos da la posibilidad de añadir parámetros pero en este caso no es necesario JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null); ByteArrayOutputStream pdfOutput = new ByteArrayOutputStream(); JRPdfExporter exporter = new JRPdfExporter(); exporter.setParameter(JRPdfExporterParameter.METADATA_AUTHOR, "autor"); exporter.setParameter(JRPdfExporterParameter.METADATA_CREATOR, "creador"); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, pdfOutput); exporter.exportReport(); pdf = pdfOutput.toByteArray(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JRException e) { // TODO Auto-generated catch block e.printStackTrace(); } return pdf; }


Comenzaremos ahora a crear nuestro contenido, para lo que necesitaremos los siguientes servicios:

RepositoryServiceSoapBindingStub repositoryService = WebServiceFactory.getRepositoryService();
ContentServiceSoapBindingStub contentService = WebServiceFactory.getContentService();


Primero tenemos que decidir donde lo vamos a guardar, podemos hacerlo bien en companyHome:

Store storeRef = new Store(Constants.WORKSPACE_STORE, "SpacesStore");
ParentReference companyHomeParent = new ParentReference(storeRef, null, "/app:company_home", Constants.ASSOC_CONTAINS, "nombrePdf");

o bien podemos indicarle el path de un espacio concreto donde lo queramos almacenar:

String pathEncoded = "/app:company_home"+"/cm:"+ISO9075.encode("Mis documentos");
Store storeRef = new Store(Constants.WORKSPACE_STORE, "SpacesStore");
ParentReference parentReference = new ParentReference(storeRef, null,pathEncoded, Constants.ASSOC_CONTAINS, "nombrePdf");


Le indicamos de que tipo será el contenido

ContentFormat contentFormat = new ContentFormat("application/pdf", "UTF-8");

modificamos sus propiedades, en este caso el nombre y la descripción:

NamedValue[] propiedades = new NamedValue[2]; propiedades[0] = Utils.createNamedValue(Constants.PROP_NAME, "nombrePdf"); propiedades[1] = Utils.createNamedValue(Constants.PROP_DESCRIPTION, "descripción del nuevo nodo");

y finalmente creamos el contenido:

CMLCreate create = new CMLCreate("1", parentReference, null, null, null, Constants.TYPE_CONTENT, propiedades); CML cml = new CML(); cml.setCreate(new CMLCreate[]{create}); UpdateResult[] result = repositoryService.update(cml);

Reference newContentNode = result[0].getDestination(); byte contentString[] = obtenerPdf(ruta); //Modificamos el contenido de nuestro nuevo nodo con el pdf que hemos obtenido contentService.write(newContentNode, Constants.PROP_CONTENT, contentString, contentFormat);

Ya tenemos creado nuestro nodo (newContentNode) y ahora podemos actualizar sus propiedades

CMLUpdate update = new CMLUpdate(); NamedValue[] props = new NamedValue[1]; props[0] = Utils.createNamedValue(Constants.PROP_DESCRIPTION, "esta es una modificación del nodo"); update.setProperty(props); update.setWhere(new Predicate(new Reference[]{newContentNode}, storeRef, null));
cml.setUpdate(new CMLUpdate[]{update});
repositoryService.update(cml);

y añadirle aspectos y asociaciones

CMLAddAspect addAspect = new CMLAddAspect();
addAspect.setAspect(Constants.ASPECT_VERSIONABLE);

addAspect.setWhere(new Predicate(new Reference[]{newContentNode}, storeRef, null));
cml.setAddAspect(new CMLAddAspect[]{addAspect});

CMLCreateAssociation createAssoc = new CMLCreateAssociation();
createAssoc.setAssociation(Constants.ASSOC_CHILDREN);
createAssoc.setFrom(Predicate)//Nodo hijo que hayamos creado o que ya exista en Alfresco
createAssoc.setTo(new Predicate(new Reference[]{newContentNode}, storeRef, null))//Nodo padre

cml.setCreateAssociation(new CMLCreateAssociation[]{createAssoc});

repositoryService.update(cml);

También podemos mover nuestro nodo a otro espacio

CMLMove move = new CMLMove();
//carpeta destino
move.setTo(companyHomeParent);
//nodo que vamos a mover
move.setWhere(new Predicate(new Reference[]{newContentNode}, storeRef, null));
cml.setMove(new CMLMove[]{move});
repositoryService.update(cml);

o bien borrarlo:

CMLDelete delete = new CMLDelete(new Predicate(new Reference[]{newContentNode}, storeRef, null));
cml.setDelete(new CMLDelete[]{delete});

repositoryService.update(cml);

Una vez hayamos terminado, no nos olvidemos nunca de finalizar la sesión:

AuthenticationUtils.endSession();

7 comentarios:

  1. Muy bueno el post, seguro que a más de uno le ayuda ;)

    Un saludo!

    ResponderEliminar
  2. Hola Cristina, este post me esta medio-salvando la vida, la verdad.
    Mi problema es que no gestiono contenidos con alfresco si no contenidos Web.
    Necesito crear contenidos web desde una aplicacion java externa.

    Para ello tengo en el raiz de alfresco un Web Project y asociado al mismo un webForm.

    Lo que necesito es crear un contenido en el webProyect utilizando el webForm dado de alta y no se cómo hacerlo.

    Podrías hecharme una mano? 1000 gracias de antemano!

    ResponderEliminar
  3. Hola Pablo! Gracias por tu comentario :)

    Lamentablemente no he trabajado nunca con web projects y web forms y no se de que forma podrían aplicarse los webservices en ese caso... si me mandas un correo y me dices que es lo que quieres hacer, a lo mejor te puedo echar un cable.

    Un saludo!

    ResponderEliminar
  4. Hola Yo soy algo nuevo en Alfresco basicamente necesito un tema de subida de archivos, yo tengo desarrollado un aplicativo de escritorio que genera pdf y las guarda a un filesystem lo que yo deseo es que al generar este pdf lanzar esto tambien al alfresco e buscado incanzablemente ayuda de este tipo en internet pero no la e encontrado, quiero saber como se puede subir un archivo pdf desde un desarrollo de escritorio solo eso. Por favor ayuda!! que lo necesito
    Gracias

    ResponderEliminar
  5. Excelente! me funcionó de maravilla, tienes algun ejemplo donde se pueda crear carpetas dentro de alfresco?

    ResponderEliminar
  6. Hola EH, me alegro de que te sirviera de ayuda :) Para crear carpetas tienes que seguir el mismo procedimiento, pero en lugar de usar Constants.TYPE_CONTENT, tendrás que usar Constants.TYPE_FOLDER. Un saludo!

    ResponderEliminar
  7. Muchas gracias por tu pronta respuesta! y funcionó :-D
    ahora tengo otra duda, cómo puedo validar si el directorio que se intenta crear ya existe? al menos para mostrar un mensaje de error
    de antemano gracias!

    ResponderEliminar