This blog post will be about sharing what I learned around developping Funambol Connector. It is not intended to be complete or a replacement of any Funambol tutorial. However, I'll try to give some tips here to better understand.
Basic documentation
First things firsts, before anything else, you should have a serious look at the Funambol module development tutorial. This will guide you in the creation of a dummy connector. However, this paper is not complete enough for new developers. Thus I'll try to explain some difficult points here.
Take care of which API reference you are reading. The j2se and DS-server APIs are different with similar concepts and names...
Understanding modules
First of all, the tutorial is about modules and not connectors... what's the difference ? In fact a module is a general additionnal component to Funambol which contains one or more connectors.
As you might have understood from the tutorial, the module is composed of several parts:
- The Java sources of you module, of course.
- SQL scripts used for installing and uninstalling the module and connector in the Funambol DS server.
- An optional install/install.xml ant script to run at the installation time
- Dependencies libraries.
There are two things to develop to create a complete connector:
- The Synchronisation source type class, which will access the data.
- The configuration panel that will be shown in the Funambol admin tool for easy configuration of the new synchronization source type.
Why are SQL scripts needed and what are they for ? Funambol is connected to a database describing the connectors and their informations. Thus the informations about your new connector have to be stored in order for it to be used. These informations include the class name of the source type and the one of the panel. There are three possible SQL scripts:
- create_schema.sql, to use if the module needs a custom data schema
- drop_schema.sql, called when uninstalling the module to remove the data
- init_schema.sql, called when installing the module to fill the data
SyncSource interface
The synchronization source type of your connector has to implement the ds-serveur SyncSource interface. These next lines will try to detail what the different methods are for.
Synchronization starting and ending
public void beginSync(SyncContext ctx) throws SyncSourceException; public void endSync() throws SyncSourceException; public void commitSync() throws SyncSourceException;
These methods are called to initialize and stop the synchronization. Thes can be used, for example, to start and stop a connection to the source. The commit method will commit the changes made during the synchronization to the source.
Element getters
public abstract SyncItemKey[] getAllSyncItemKeys()
throws SyncSourceException;
This method will have to return all the items to synchronize in the source. This method is used in the synchronization mode. The result is an array of all the unique keys describing each element.
public abstract SyncItemKey[] getDeletedSyncItemKeys(Timestamp sinceTs, Timestamp untilTs)
throws SyncSourceException;
public abstract SyncItemKey[] getNewSyncItemKeys(Timestamp sinceTs, Timestamp untilTs)
throws SyncSourceException;
public SyncItemKey[] getUpdatedSyncItemKeys(Timestamp since, Timestamp until)
throws SyncSourceException;
These three methods will return the deleted, new and updated items between the since and until timestamps. These methods are used in the fast synchronization mode. The result is an array of all the unique keys describing each element.
public abstract SyncItem getSyncItemFromId(SyncItemKey syncItemKey)
throws SyncSourceException;
This method returns and item from its key. This is a difference between the client and server SyncSource interfaces: from the server side, using only keys and getting the item at the very last time helps to avoid big memory uses.
Elements setters
public abstract void removeSyncItem(SyncItemKey syncItemKey, Timestamp time, boolean softDelete)
throws SyncSourceException;
public abstract SyncItem updateSyncItem(SyncItem syncInstance)
throws SyncSourceException;
public abstract SyncItem addSyncItem(SyncItem syncInstance)
throws SyncSourceException;
These methods will remove, add and update items in the source. The returned sync item correspond to the inserted or updated item. The update and add methods should solve the conflicts between the items that is already present on the server and the one that is about to be added or updated.
Extra methods
public abstract SyncItemKey[] getSyncItemKeysFromTwin(SyncItem syncItem)
throws SyncSourceException;
This method returns the twin items keys, i.e. the keys of the items that are considered as identical. This notion of identical items is defined in this method.
public abstract void setOperationStatus(String operationName, int status, SyncItemKey[] keys);
This method is called by the DS-server to notify the status of an operation. The operation name can be either one of "Add", "Replace" or "Delete".
Configuration panel implementation
To create a new source configuration panel, you will need to extend the SourceManagementPanel class. The only thing to know here is to set the following properties into your synchronization source when clicking on the validation button. The validation method should contain the following skeleton:
if (getSyncSource() instanceof JCRSyncSource) {
JCRSyncSource source = (JCRSyncSource)getSyncSource();
source.setSourceURI(uriText.getText().trim());
source.setName(nameText.getText().trim());
source.setType(typeText.getText().trim());
// TODO set your source specific values
ContentType[] contentTypes = new ContentType[] {
new ContentType("text/plain", "1.0")
};
source.setInfo(new SyncSourceInfo(contentTypes, 0));
}
You just have to replace the TODO comment by lines setting the specific values to your source. Of course, you need to replace the JCRSyncSource class by your SyncSource class.
(Post originally written by Cedric Bosdonnat on the old Nuxeo blogs.)
Comments