Last week I started a series of blog post on how to extend Nuxeo Drive. Today I'll write about factories and adapters. Every file or folder on the client file system is represented on the server side using adapters. Those adapters are associated to a particular document through a factory.
- FileSystemItem // Represents any file on the fs
| -- FileItem // A File
|-- DocumentBackedFileItem // Default adapter implementation for non-folderish document
| -- FolderItem // A Folder
| -- AbstractVirtualFolderItem // Represents a folder on the client side, that is not backed by an actual document
| -- DefaultTopLevelFolderItem // The default Nuxeo Drive folder, containing your synchronized documents.
| -- DocumentBackedFolderItem // Default adapter for folderish document
| -- DefaultSyncRootFolderItem // Adapter for the root synchronized doc. (put simply, the docs where you clicked on the sync button)
| -- UserWorkspaceTopLevelFolderItem // User workspace based implementation of the top level
| -- UserWorkspaceSyncRootParentFolderItem // User workspace based implementation of the synchronization root parent
We can take the default configuration as an example to better understand this.
A look at the default configuration
Using Drive on the client side, the first entry point is the Nuxeo Drive folder. It contains all the documents you have synchronized. This folder is represented on the server side through the DefaultTopLevelFolderItem adapter, and returned by the DefaultTopLevelFolderItemFactory factory. This configuration is declared in the org.nuxeo.drive.service.FileSystemItemAdapterService#topLevelFolderItemFactory extension point:
<parameter name="folderName">Nuxeo Drive</parameter>
As you can see, you can change the folderName parameter to something else. Some might prefer 'My Drive' or 'My Nuxeo Files' as name for your sync documents. The default implementation simply lists all the synchronization roots, which is to say all the document where you clicked on the Sync Drive icon. You can imagine different implementations like one that would display the content of your personal workspace along your synchronization roots. You could also have a hard-coded implementation that shows the same documents for every Nuxeo users. That's really up to you :) . It doesn't even have to be documents. You could have a folder called My Directories that would have a CSV file per directories declared in Nuxeo. (lots of coding involved but why not?)
Anyway, inside the default Nuxeo Drive folder you will see your synchronized roots and their children. This is managed by the org.nuxeo.drive.service.FileSystemItemAdapterService#fileSystemItemFactory extension point. Every one of these factories has an order attribute. They are resolved from the lowest to the highest. The first factory that returns an adapter is used. As you can see the lowest order is set on the defaultSyncRootFolderItemFactory. It will be returned if the adapted document has the DriveSynchronized facet. And the thing is, each time you click on the sync button, this facet is added to the document. As the child documents won't have this facet, defaultSyncRootFolderItemFactory won't match and the defaultFileSystemItemFactory will be used.
As you can see the defaultFileSystemItemFactory factory takes some parameters. They describe the default versioning behaviour. The adapter returned by the factory is DocumentBackedFileItem, which has a versionIfNeeded method called when the associated file is changing. This method first looks if the document needs to be versioned. This will occur if the current contributor is different from the last contributor or if the last modification was done more than 3600 seconds ago. As you have already guessed, 3600 is not arbitrary and comes from the versioningDelay parameter of the factory. If the doc needs to be versioned, the following code is executed:
We put the versioningOption parameter in the document context map. This information will be retrieved and used next time the document is saved. So by default, we do minor increments. Possible values are MINOR, MAJOR and NONE.
Customize the default configuration
Here's an example of custom configuration of the default factories (no, we're not going to write a complete new adapter or factory just yet). Let's say I don't want my Drive folder to be called Nuxeo Drive. I want it to be called 'My Favorite Nuxeo Files'. And I also want to upgrade the major increment version number each time a document is modified using drive. This can be done using the following contributions.
<component name="org.nuxeo.sample.drive.adapters" version="1.0">
<!-- Make sure your contribution is registered after the default one -->
<!-- Override the folderName parameter. No need to specify the class again as there can be only one topLevelFolderItemFactory. -->
<parameter name="folderName">My Favorite Nuxeo Files</parameter>
<!-- Override the versioningOption parameter. We need to keep the name of the contribution we want to override. The parameters will be merge with the existing one.-->
Next week we'll dig deeper into these factories and adapters.