Eclipse


Un client Java pour Nuxeo

Nuxeo est une application de Gestion Électronique de Documents (GED) qui permet, notamment, de manipuler son contenu via un client HTTP (REST) par l'usage du Nuxeo Automation Client.

La documentation étant très succincte à ce sujet et après de longues recherches pour finaliser un petit client capable de gérer les quelques opérations de base (upload d'un document, publication, création de relations), j'ai décidé de publier le résultat de mes trouvailles. Voici donc la classe du client en question :

import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.ecm.automation.client.Session;
import org.nuxeo.ecm.automation.client.adapters.DocumentService;
import org.nuxeo.ecm.automation.client.jaxrs.impl.HttpAutomationClient;
import org.nuxeo.ecm.automation.client.model.Document;
import org.nuxeo.ecm.automation.client.model.FileBlob;
import org.nuxeo.ecm.automation.client.model.PropertyMap;

/**
 * Used to upload files to Nuxeo
 * 
 */
public class NuxeoAutomationClient {

 // logger
 private static Log LOGGER = LogFactory.getLog("camel");

 // Nuxeo's automation client
 private HttpAutomationClient client;

 // Connection's session
 private Session session;

 private DocumentService dc;

 public NuxeoAutomationClient(String login, String mdp) throws Exception {
  client = new HttpAutomationClient(SERVER_URL);
  session = client.getSession(login, mdp);
  dc = new DocumentService(session);
 }

 public Session getSession() {
  return session;
 }

 /**
  * Upload specified file into specified folder in Nuxeo
  * 
  * @param file the file
  * @param folderName the folder
  * @param publishFile publish File?
  * @throws NuxeoServiceException all
  */
 public void upload(File file, String folderName, boolean publishFile) throws Exception {
  // First get the root document and create a new File document at
  PropertyMap pMap = new PropertyMap();
  pMap.set("dc:title", folderName);
  String uploadFolder = CAMEL_NUXEO_WS_URL + "/" + folderName;
  Document deptFolder = null;
  LOGGER.info("Looking for folder : " + uploadFolder);
  deptFolder = dc.getDocument(uploadFolder);
  LOGGER.info("Uploading to folder : " + deptFolder.getPath());

  // upload file
  // check if file exists
  Document deptDoc = null;
  String dataFileName = file.getName();
  try {
   deptDoc = dc.getDocument(uploadFolder + "/" + dataFileName);
   // If exists, delete it
   if (deptDoc != null) {
    dc.remove(deptDoc);
   }
  } catch (Exception e) { // Document not found
   // foolish exception, do nothing
  }

  pMap = new PropertyMap();
  pMap.set("dc:title", dataFileName);
  pMap.set("file:filename", dataFileName);
  deptDoc = dc.createDocument(deptFolder, "File", dataFileName, pMap);
  LOGGER.info("Uploading file : " + deptDoc.getPath());

  // upload blob
  FileBlob fb = new FileBlob(file);
  fb.setFileName(dataFileName);
  String extension = dataFileName.substring(dataFileName.indexOf(".") + 1, dataFileName.length());
  String mime = "";
  if ("txt".equals(extension)) {
   mime = "text/plain";
  } else {
   mime = "application/" + extension;
  }
  fb.setMimeType(mime);
  dc.setBlob(deptDoc, fb);

  // publish file
  if (publishFile) {
   String pubPath = NUXEO_PUB + "/" + folderName;
   LOGGER.info("Publishing to : " + pubPath);
   deptFolder = dc.getDocument(pubPath);
   // if already published, remove it
   try {
    Document old = dc.getDocument(pubPath + "/" + dataFileName);
    if (old != null) {
     dc.remove(old);
    }
   } catch (Exception e) {
    // Document not found
    // foolish exception, do nothing
   }
   dc.publish(deptDoc, deptFolder, true);
  }

  // manage metadata relations
  String metadataFile = "META_FILE.doc";
  // Create relation
  Document metaDoc = dc.getDocument(CAMEL_NUXEO_WS_URL + "/Métadonnées/" + metadataFile);
  String predicate = "http://purl.org/dc/terms/ConformsTo";
  dc.createRelation(deptDoc, predicate, metaDoc);
  LOGGER.info("Created relation : " + deptDoc.getPath() + " " + predicate + " " + metaDoc.getPath());
 }
}

Son exécution est très simple : création d'un document (avec effacement de l'existant), envoi du blob correspondant (données), publication, liaison à un autre document.

Cela peut paraître simple, mais l'usage du DocumentService n'est pas très explicite dans les documentations.

Le principal écueil ici réside dans la création de la relation entre les documents. Ici le but est de créer les liens du type (basé sur la norme DCMI) :

  • Doc1 "Est conforme à" Doc2
  • Doc2 "A pour conformité" Doc1

où, conceptuellement, "Est conforme à" et "A pour conformité" sont des liens inverses issus du même prédicat de la relation.

Il faut savoir que Nuxeo se base sur un système de vocabulaire permettant, lors de la création de la relation, de gérer automatiquement les libellés des liens inverses issus des prédicats. Ainsi, dans cet exemple, ces liens sont calculés à partir du prédicat (normé selon DCMI) : http://purl.org/dc/terms/ConformsTo

J'espère vous avoir fait économiser quelques heures de recherche!

Sources :


Fichier(s) joint(s) :

5 commentaires: