Extend Nuxeo Drive Extend Nuxeo Drive

Like most parts of the Nuxeo Platform, we designed Nuxeo Drive as something extensible. And there are indeed different ways you can customize it to fit your needs. I'll be writing more posts about how to extend Nuxeo Drive in the coming weeks. Today we'll take a look at what you can do by simply overriding the different operations used by Nuxeo Drive.

Let’s take a very simple example. When Drive detects a conflict, the file is renamed a certain way. This is done using the NuxeoDrive.GenerateConflictedItemName operation. So what we can do is override this operation to specify our own way of renaming a file. Right now what it does is split the name of the file and the extension. Then we generate the contextSection. It's the user's first and last name concatenated with the current date formatted as "yyyy-MM-dd hh-mm". Then it puts them back together.

To override it, you need to declare your operation as usual, but don't forget to use the exact same ID as the operation you want to override. Here I'm changing the date format to "dd-MM-yyyy hh-mm" and adding the user's email address.

* (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and contributors.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* Lesser General Public License for more details.
* Contributors:
* ldoguin

package org.nuxeo.sample;

import java.text.SimpleDateFormat;

* @author ldoguin
// Use the same ID as the operation to override
@Operation(id = NuxeoDriveGenerateConflictedItemName.ID, category = Constants.CAT_SERVICES, label = "Nuxeo Drive: Generate Conflicted Item Name")
public class NuxeoDriveCustomGenerateConflictedItemName {

protected OperationContext ctx;

@Param(name = "name")
protected String name;

@Param(name = "timezone", required = false)
protected String timezone;

public Blob run() throws Exception {

String extension = "";
if (name.contains(".")) {
// Split on the last occurrence of . using a negative lookahead
// regexp.
String[] parts = name.split("\.(?=[^\.]+$)");
name = parts[0];
extension = "." + parts[1];
NuxeoPrincipal principal = (NuxeoPrincipal) ctx.getPrincipal();
String userName = principal.getName(); // fallback
if (!StringUtils.isBlank(principal.getLastName())
&& !StringUtils.isBlank(principal.getFirstName())) {
// build more user friendly name from user info
userName = principal.getFirstName() + " " + principal.getLastName();
Calendar userDate;
if (timezone != null) {
userDate = Calendar.getInstance(TimeZone.getTimeZone(timezone));
} else {
userDate = Calendar.getInstance();
// I'll use a French date format
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy hh-mm");
String formatedDate = dateFormat.format(userDate.getTime());
// and I'll add the user's email
String contextSection = String.format(" (%s - %s - %s)", userName,
principal.getEmail(), formatedDate);
String conflictedName = name + contextSection + extension;
return NuxeoDriveOperationHelper.asJSONBlob(conflictedName);


Don't forget the require tag and the replace)"true" attribute to make sure your operation override the default one:

<component name="org.nuxeo.sample.NuxeoDriveCustomGenerateConflictedItemName">


<extension target="org.nuxeo.ecm.core.operation.OperationServiceComponent"
point="operations" >
<operation replace="true" class="org.nuxeo.sample.NuxeoDriveCustomGenerateConflictedItemName" />


That's just a simple example, but you can do a lot more. Every call from Drive to the server are made through Content Automation. So that means you can override pretty much everything it does. All these operations are located in the nuxeo-drive-operations bundle. Most of them are using the FileSystemItemManager and NuxeoDriveManager services. I'll write more about this in the next posts.