Chapter 37. Desktop integration tools

Table of Contents

37.1. Drag and drop browser extensions
37.1.1. Server side import service: the FileManagerService
37.1.2. Microsoft Internet Explorer plugin
37.1.3. Mozilla Firefox plugin
37.2. Online document editing with LiveEdit
37.2.1. Functional overview
37.2.2. Functional use cases
37.2.3. Architectural overview
37.2.4. The Web Service component
37.2.5. More on editor launch
37.2.6. More on pre- and post-editing actions
37.3. Configuring LiveEdit links
37.3.1. Configuration policies
37.3.2. Changing the configuration policy

This chapter is dedicated to modules to improve the user experience through integration of browser and office productivity software with a Nuxeo Enterprise Platform server.

The source code of the desktop integration tools is gathered here: https://svn.nuxeo.org/nuxeo/desktop-integration.

37.1.  Drag and drop browser extensions

The login page of Nuxeo EP advertises two links to download and install browser extensions that makes it possible to import any files from the client's desktop file manager into the Nuxeo EP repository as new documents by drag and dropping the files or folders into the browser window.

Packaged installers for those extensions are made available on the http://updates.nuxeo.org URL.

37.1.1.  Server side import service: the FileManagerService

All drag and drop desktop browser extensions use the FileManagerService and its contributed file importers to perform the actual document creation.

TODO: add here the list of remote interfaces to the FileManagerService API (REST, SOAP?).

37.1.2.  Microsoft Internet Explorer plugin

The Internet Explorer plugin source code is available at: https://svn.nuxeo.org/nuxeo/desktop-intergration/nuxeo-dragdrop-ie-extension . This module is a coded using the C# language and needs the dotNET runtime version 2.0 or later.

TODO: give technical details on the WS protocol used to perform the file uploads.

37.1.3.  Mozilla Firefox plugin

The Firefox plugin source code is available at: https://svn.nuxeo.org/nuxeo/desktop-intergration/nuxeo-dragdrop-ff-extension .

The firefox plugin is packaged as a regular XPI and is platform-independent and uses the built-in Javascript API of Mozilla to upload the content of the files as POST request to a RESTful web service URL.

TODO: give details on the remote RESTlets used for this implementation.

37.2.  Online document editing with LiveEdit

LiveEdit is the generic name of a set of client- and server-side components meant to seemingly integrate remote Office document editing without having to rely of manual upload files through in-browser HTML forms.

37.2.1. Functional overview

The generic functional use case is the following: the users use a standard web browser to login and browse the web interface of Nuxeo workspaces. Upon a click on a link flagged 'edit online' on a Nuxeo document having an Office file as attachment, the user automatically gets the content of the file open for editing in the right client side application (e.g. Microsoft Word, OpenOffice.org, ...)

When saving changes, the new version of the file is automatically re-uploaded to the Nuxeo server through a SOAP or RESTful web service to update the original document content and make the changes available to the other users of the workspace.

The version number can be incremented upon LiveEdit editing. A lock can be optionally set on the original document so that two users do not overwrite each other changes in concurrent LiveEdit sessions.

LiveEdit components should also support 2 auxiliary use cases:

  • creation of a new Nuxeo document with an empty client-side generated attachment of the specified mimetype;

  • creation of a new Nuxeo document with an client-side generated attachment preinitialized with the copy of an existing binary attachment stored elsewhere.

The following introduce the details of the 3 use cases implemented by the LiveEdit system along with the technical components at work.

37.2.2. Functional use cases

37.2.2.1.  Editing the attachment of an existing document of the Nuxeo repository

The user wants to a edit a non-empty Office file stored as a property of a Nuxeo document.

The user authenticate to Nuxeo (login/password or some implementation of SSO) with her web browser (IE or Firefox) and browse her workspaces till the summary view of a document she has the rights to edit.

If the document has Blob storing property containing a non-empty office file with a mimetype flagged as live editable (MS Office and OpenOffice related mimetypes), the web interface generate a link (marked 'edit online') that automatically opens the right desktop application with the content of the attachment in opened in the editing window.

Upon saving, the desktop editor opens popup leaving the user with the option either to save a local copy or the save on the Nuxeo server. For the latter the user can also choose to increment the minor or major version number or to overwrite the current version.

Upon completion the user can check by browsing back to her document that attachment has be updated with her changes on the Nuxeo server.

37.2.2.2. Creating a new document with an empty attachment

The user wants to create a new Nuxeo document from scratch directly from an Office productivity application.

The user authenticate to Nuxeo (login/password or some implementation of SSO) with her web browser (IE or Firefox) and has the possibility to click on a document creation menu with the following items:

  • New Word document

  • New Powerpoint presentation

  • New Excel spreadsheet

  • etc. (similar options for OpenOffice.org apps)

Clicking one of those links automatically opens the right desktop application with a new empty document opened in the editing window.

Upon saving, the desktop editor opens popup leaving the user with the option either to save a local copy or the save on the Nuxeo server. For the latter the user has to choose among a flat list of candidate remote locations selected are labeled with both a title (e.g. 'My Workspace') and a path to the location (e.g. /default-domain/workspace/my-workspace )

Upon completion the user can check by browsing to her new document at the selected location. The file attachment of that document has the content of the saved Office file.

37.2.2.3.  Creating a new document preinitialized with an existing attachment

The user wants to create a new Nuxeo document directly from an Office productivity application but reusing the content of an attachment stored as a property of an existing Nuxeo document.

The user authenticate to Nuxeo (login/password or some implementation of SSO) with her web browser (IE or Firefox) and browse her workspaces till reaching a document with a non-empty Office file attachment. The view of that file carries a link labeled 'edit online as a new document' .

Clicking on that link opens the right desktop application preinitialized with a copy of the content of the template document attachment.

Upon saving, the desktop editor opens popup leaving the user with the option either to save a local copy or the save on the Nuxeo server. For the latter the user has to choose among a flat list of candidate remote locations selected are labeled with both a title (e.g. 'My Workspace' ) and a path to the location (e.g. /default-domain/workspace/my-workspace )

Upon completion the user can check by browsing to her new document at the selected location. The file attachment of that document has the content of the saved Office file.

37.2.3. Architectural overview

37.2.3.1. Overview of the components

The LiveEdit feature is built upon a set of the following interacting components:

  • webapp components to generate a link to a generated XML bootstrap file describing the file to edit remotely along with connection parameters. Such a sample bootstrap file is provided in the technical annexes of this specification file.

  • a browser protocol handler (i.e. plugin for Internet Explorer or Firefox) that parses the xml bootstrap size and launch the relevant desktop application according to the mimetype

  • an editor plugin for each desktop application (MS Office, OpenOffice) to be able to make the desktop application fetch the file from Nuxeo through SOAP or REST GET with connection parameters provided in the bootstrap file and save it back to the server using SOAP or REST POST as well.

    Before and after editing the document, the editor plugin can fetches a list of configurable actions to call on the server through SOAP or REST GET (lock/unlock, check in/ check out, validate, etc.).

  • a web service component (EJB3 stateful bean with JAXWS extensions) to implement the required methods along with the WSDL definition need by the desktop client

The source code of the various LiveEdit client side components is available at: https://svn.nuxeo.org/nuxeo/desktop-intergration/nuxeo-liveedit-* .

37.2.3.2. The Bootstrap client module (part 1)

The Bootstrap module must intercept the click on the "online edit" link using a dedicated protocol handler packaged as a browser plugin.

The "online edit" link has the following pattern:

nxedit:http://localhost:8080/nuxeo/nxliveedit.faces?action=edit&repoID=[repoID]&docRef=[docRef]&schema=[schema]&blobField=[blobField]&filenameField=[filenameField]&conversationId=[SEAM_CONVERSATION_ID]

The protocol handler will be called by the OS/Browser and receive the URL. In turn it will receive the XML bootstrap file.

In case of create use cases the previous patterns change as follows:

  • user case #2: no docid but need to provide the type of the future document and field location of the blob to be stored in:

    • nxedit:http://localhost:8080/nuxeo/nxliveedit.faces?action=create&repoID=[repoID]&mimetype=[mimetype]&schema=[schema]&blobField=[blobField]&filenameField=[filenameField]&docType=[docType]&conversationId=[SEAM_CONVERSATION_ID]

  • user case#3: docid and field path of the original blob AND doctype and fieldpath to of the document that will host the result:

    • nxedit:http://localhost:8080/nuxeo/nxliveedit.faces?action=createFromTemplate&templateRepoID=[templateRepoID]&templateDocRef=[templateDocRef]&templateSchema=[templateSchema]&templateBlobField=[templateBlobField]&repoID=[repoID]&schema=[schema]&blobField=[blobField]&filenameField=[filenameField]&docType=[docType]&conversationId=[SEAM_CONVERSATION_ID]

The Bootstrap client module rewrites each of those URIs as valid HTTP GET by swapping the prefix:

  • http://localhost:8080/nuxeo/nxliveedit.faces?[query_parameters]

The Bootstrap client protocol must strip the "nxedit:" prefix of the URI to get the HTTP URL and thus work either with SSL or not:

  • nxedit:http://localhost:8080/nuxeo/nxliveedit.faces?[query_parameters]

should be transformed into:

  • http://localhost:8080/nuxeo/nxliveedit.faces?[query_parameters]

while:

  • nxedit:https://localhost:8080/nuxeo/nxliveedit.faces?[query_parameters]

should be transformed into:

  • https://localhost:8080/nuxeo/nxliveedit.faces?[query_parameters]

In order to generate valid nxedit: URIs it is strongly advised to use the JSF functions defined in the org.nuxeo.ecm.platform.ui.web.tag.fn.DocumentModelFunctions class.

The functions are available under the nxd ( http://nuxeo.org/nxweb/document ) namespace:

  • liveEditUrl(DocumentModel) : get the nxedit: URL to edit a document file attachment (default File-like types)

  • liveEditUrl(DocumentModel, String, String, String) : get the nxedit: URI to edit a document providing schema, blob field and filename field names

  • liveCreateUrl(String) : get the nxedit: URI to create a new document of type File providing the mimetype as argument

  • liveCreateUrl(String, String, String, String, String) : get the nxedit: URI to create a new document with parameters: mimetype, doctype, schema, blob and filename field names

  • liveCreateFromTemplateUrl(DocumentModel) : get the nxedit: URI to create a new document of type File reusing the content of the blob of the provided template DocumentModel (assumed to have the "file" schema).

  • liveCreateFromTemplateUrl(DocumentModel, String, String, String, String, String, String) : get the nxedit: URI to create a new document from template. Parameters are: template DocumentModel, template schema, template blob field, target document type, target schema, target, blob field name, target filename field.

37.2.3.3. The Bootstrap server module

The Bootstrap server module will be a simple Seam component called using the info passed as request parameters to generate the XML payload of the bootstrap file.

The boostrap server module is currently located in webapp-core here:

  • org.nuxeo.ecm.webapp.liveedit.LiveEditBootstrapHelper

37.2.3.4. Bootstrap data download

The HTTP response to that GET URL is a bootstrap file containing an XML payload. This file contains:

  • the action ID so the client knows to interpret it

  • repo name

  • document unique reference (in case of editing) or template reference (new from template)

  • the document Nuxeo type of the document to create or edit

  • the fieldpath hosting the binary attachment

  • associated filename

  • associated mime-type

  • principal name

  • whether the result of this editing session should be saved as a new Nuxeo document else where in the repository (creation use cases)

In case of creating from a sample document:

  • the document id of the template

  • the fieldpath hosting the binary attachment to initialized the editor with

The XML payload further contain a copy of all the HTTP request headers and cookies + basic auth credentials and the adress of the WSDL description of the LiveEdit webservice.

Please refer to the sample XML bootstrap file in the annexes for more details on the syntax. Some fields (eg. document reference) might be empty or missing in case of document creation (use cases #2 and #3).

37.2.3.5. The bootstrap client module (part 2)

The bootstrap module receives and parses the content of the XML bootstrap file. According to a set of configurable rules the bootstrap module launch the right editor with bootstrap file as command line parameter.

37.2.3.6. Authentication management during bootstrap

The Bootstrap client will need to do an http call to get the xml file from the server. This call must be authenticated. So the protocol handler must reuse the browser session.

37.2.3.7. The client editor and its plugin

In case of document editing (use case #1):

  • call WS to get list of pre-edit actions

  • display a dialog for letting user select action

  • call WS to download the file

  • call WS to get list of post-edit actions

  • display a dialog for letting user select action

  • save and upload the file to Nuxeo Server

  • terminate (close the WS session)

In case of document creation (use case #2 and #3):

  • call WS to get list of pre-edit actions

  • display a dialog for letting user select action

  • call WS to download the template file (use case #3)

  • call WS to get list of post-edit actions (e.g. choose title)

  • call WS for the list of candidate server locations

  • display a dialog with actions and dropdown list of candidate locations

  • create new document and upload the file to Nuxeo Server

  • terminate (close the WS session)

37.2.3.8. Authentication of the client editor

All WS requests (SOAP and RESTful) from the editor plugin back to the WS server should reuse all the HTTP cookies along with any basic auth parameters to ensure the request will pass through any authenticating reverse proxies (e.g. CAS, mod_sso, ...) as if they were the original browser.

37.2.4. The Web Service component

It is responsible to answer the WS calls of the editor client. Most of its business logics should be defined has an overridable extension point so that customer project can change most of the LiveEdit global behavior without having to re-compile / re-package the client part.

In particular the list of candidate locations to 'save as new document' is provided by the WS server-side API to the LiveEdit client. The list should default to the list of Workspaces the user currently has the "AddChildren" permission. The WS server should dynamically compute that list according to an extensible service (i.e. overridable by a extension point) so that customer project can register a custom Java class that is responsible to implement the custom business logics in case the list of workspaces is not enough.

The location selected by default should also be defined on the server side and overridable by the same extension point.

37.2.5. More on editor launch

Based on a configuration file containing mimetype/editor mapping, the bootstrap module will launch an editor. This configuration file should look like that:

          <editors> <editor name="MSOOfficePlugin">
          <pluginType>.net<pluginType> <mime-types>
          <mime-type>application/msword</mime-type> ...
          </mime-types> </editor> <editor
          name="OOfficePlugin">
          <pluginType>exec<pluginType> <mime-types>
          <mime-type>application/vnd.oasis.opendocument</mime-type>
          ... </mime-types> </editor> ... </editors>
        

This is very important that bootstrap client can be separated from the editors plugins, because there will plugins contributed for specific editors. The simplest and most neutral way of launching an editor plugin is just executing the editor plugin passing it a copy of the bootstrap file. This file will be the same as the one returned by Nuxeo server with additional authentication information: cookies and Login/Password.

37.2.6. More on pre- and post-editing actions

Actions available on the document may depend on the custom project specifications, and it is important that it is totally transparent for the client plugin UI: we don't want to build a version of the client plugins for each project.

So the idea is that the WebService will provide the client editor plugin a simple list of actions, the client will simply display available actions, and eventually ask the server to execute them without knowing the underlying logic.

This "action logic" is somehow close to what we already do in the web layer, an action defines an action id and a label.

If several actions can be done (like checkout + lock), then they will be combined as compound actions: checkout, lock, checkout_and_lock. This way we won't have to handle associations conditions on the client side: the user can always select at most one action: none / lock / checkout / checkout_and_lock

37.3. Configuring LiveEdit links

37.3.1. Configuration policies

Starting with Nuxeo 5.1.6, the liveEdit link display policy is pluggable.

This means you can define on what kind of documents the liveEdit links will be displayed.

Nuxeo supports 3 different policies :

  • Client based configuration

    The client browser tells the server what kind of documents can be "live edited".

  • Server based configuration

    Links are only displayed on mime-types that are configured on the server to be live editable.

  • Mixed configuration

    Links are only when server and client policy both apply.

37.3.1.1. Client based configuration policy

For that the firefox and msie plugins add the live editable mime-types to the accept header sent by the browser. This way, the server can decide on what type of file the liveedit link must be displayed. If you use Firefox, just upgrade to the last version and use the configuration pannel to tell on what mime-types you want liveedit links.

The main advantage of this policy is that only the users that have LiveEdit plugin installed will see the liveEdit links.

The accept header send by a LiveEdit enabled client looks like that :

...,application/x-nuxeo-liveedit;application/vnd.oasis.opendocument.text;application/vnd.oasis.opendocument.presentation;...
		  

37.3.1.2. Server based configuration policy

In this case the server will only display the LiveEdit links for files that have a mime-types that is declared "LiveEditable" in the MimeTypesRegistry service.

37.3.1.3. Mixed configuration policy

Simply display links on mimetypes that are livededitable on the client side and on the server.

37.3.2. Changing the configuration policy

Default policy is client based, in order to change that, the only thing you have to do is edit the nuxeo.properties file in nuxeo.ear/config.

# LiveEdit configuration detection (client/server/both)
org.nuxeo.ecm.platform.liveedit.config=client