JGroupDAV API introduction

Revision 1. Written by Mathew McBride – matt@mcbridematt.dhs.org

Abstract
JGroupDAV is a Java package which handles communication with GroupDAV-compatible 'groupware' servers. It includes both a basic GroupDAV protocol client and a system for managing the retrieval and storage of GroupDAV data. Its main production application is the Funambol GroupDAV Connector.

Package overview

net.bionicmessage.objects – Main JGroupDAV package

MultipleSourceICalendarObjectStore – manages the retrieval, storage and search functions for calendar and task data MultipleSourceVCardObjectStore – as above, but for address book data MultipleSourceObjectTracking – the database management layer for the above classes

○ ○ ●

net.bionicmessage.groupdav – GroupDAV protocol client groupDAV – (Badly written!) GroupDAV protocol client – manages WebDAV operations such as creation, deletion, updating, listing and retrieving objects GroupDAVObject.java – a wrapper for HTTP WebDAV queries, used by the above class

net.bionicmessage.utils – Utility methods

HTMLFormatter – used by net.bionicmessage.objects to produce HTML-formatted log files

Classes not in active use are not shown

Dependencies and Licences
JGroupDAV itself is licensed under a BSD style license. Permission is hereby granted, free of charge, to any person obtaining acopy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. JGroupDAV uses ical4j for parsing and manipulation of RFC2445 (iCalendar) data and the

Funambol foundation infrastructure for vCard. ical4j is licensed under a BSD style license, similar to the above. Funambol foundation is under the Affero General Public License, version 3. This a version of the well known General Public License which adds a condition allowing users of a network service to request the service source code. JGroupDAV uses the SmallSQL database for storing data. If you intend to use the address book management functions in a published aplication (i.e you will distribute it) your code must be under the AGPLv3 (or other compatible license). Please contact me to discuss your options if you cannot satisfy this requirement in your application.

Obtaining source code
The JGroupDAV source code is managed by git and hosted at repo.or.cz. Source code can be downloaded via git directly, or as a snapshot tarball from the repo.or.cz webview. JGroupDAV is built using the Apache Maven build system. I highly recommend that projects using JGroupDAV using maven for the build process, as it will simplify the dependency-gathering process. As described on the building Funambol 6.5 page, you need to copy settings.xml into $HOME/.m2/. This is necessary for Maven's 'famed' dependency management can download the Funambol modules. Others will be downloaded as normal, automatically.

Building JGroupDAV
If you need to modify JGroupDAV and build a new jar file, run: mvn -Dmvn.test.execute=false package Note that the testcases are disabled, if you want to run them, you would create a textfile like this: store.location = /tmp/multipleicalobjectstore store.server = http://comalies.citadel.org:2000 store.user = testuser store.password = testpassword store.source.default = /groupdav/Calendar store.source.two = /groupdav/Calendar2 and save it to $HOME/.multiplesource_icalobject_test_props or .multiplesource_icaltodo_test_props . Read the test source files themselves for more information.

Setting up a maven project for JGroupDAV

Maven in five minutes - basics of maven projects

To use JGroupDAV, add the JGroupDAV information to the dependency block of pom.xml: <dependency>

<groupId>bmessage</groupId> <artifactId>jgroupdav</artifactId> <version>1.2</version> <scope>compile</scope> </dependency>

Setting up a GroupDAV Sink
You probably want to know about setting up a calendar sink. To do that, you will use MultipleSourceICalendarObjectStore (the vcard store follows similar processes, however). Its constructor is: public MultipleSourceICalendarObjectStore(String storedir, int options) storedir is a location on the filesystem where JGroupDAV will place its database and logging information. It doesn't have to exist at runtime (that includes the entire path to create it), but the user needs write permissions to it. options is an integer controlling the initial setup of the sink. Current options are: ● MultipleSourceICalendarObjectStore.OPTION_SSL: Enables the use of SSL http connections. You will need to add your certificates to the Java certificate store to do this. You may find using HTTP or decrypting the stream using stunnel first easier. ● MultipleSourceICalendarObjectStore.OPTION_PURGE: Purges the sink database, all data will be pulled from the server again ● MultipleSourceICalendarObjectStore.OPTION_SINGLELOG: Sets up single log file mode, recommended for end-user deployments. By default, the sink will create a new log file for each session During development, please keep watch on your terminal. Any exceptions thrown by the constructor will appear there! Next, you need to tell the sink about your server, where the events/todos are on it. Create a java.util.Properties dictionary with the following attributes: ● store.server – Server host and port in the format of “http://server:port/” ● store.user – Username (you don't need to specify this here, read on) ● store.password – Password (as above) ● store.source.default – The first location you will be pulling/pushing data from, i.e “/groupdav/Calendar/”, “/zidestore/dav/matt/public/Calendar/” ● store.source.xxx – As above, specify as many as you need, name does not matter Note that you don't necessarily have to set these options in a single instance, they can be done programmatically, see the javadocs. Set the sink properties by setProperties(Properties p); and then tell it to load the data sources from them: loadSourcesFromProps() Once setup is done, you can start the sync process with startSync(): /** Starts the synchronisation process. Pulls new and updated

* data from the server and deletes any objects as needed * @throws java.lang.Exception */ public void startSync() throws Exception

Retrieving changes
MultipleSourceICalendarObjectStore has several methods that report changes to the database in the last sync cycle:
● ● ●

ArrayList getAddedToStoreUIDS() ArrayList getDeletedFromStoreUIDS() ArrayList getUpdatedInStoreUIDS()

Rather confusingly, these methods have been named to/from/in “store” rather than “server”. Store refers to operations done to the database, while “server” refers to operations done to the server. The equivalent server functions are used mainly for logging. Internally, objects are identified in the local database by the iCalendar “UID” property. The arrays above contain String references to the UID properties.

Retrieving objects
To retrieve objects that have been stored locally, use getObjectFromStore: public net.fortuna.ical4j.model.Calendar getObjectFromStore(java.lang.String uid) throws java.lang.Exception As you can see, to retrieve objects use the UID reference (i.e from the arrays above), which will return an ical4j VCALENDAR object.

Adding objects to the server
Adding objects is a dramatically different operation from retrieving them. Since the ICalendarObjectStore was designed around the requirements for Funambol and the need to compare objects from clients and servers, some metadata is stored for quick searching. /** Adds an object to the server. * @param sourceName the name of the source to add to * @param uid The UID of the object to add * @param name Name of the object to be added

* @param contents The ical2 data of the object * @param dtstart The DTSTART of the object in Unix time * @param dtend The DTEND of the object in Unix time * @return Server UID of object added. */ public String addObject(String sourceName, String uid, String name, String contents, long dtstart, long dtend) throws Exception For tasks, you can specify “0” for dtstart and dtend. When using ical4j, you can get the string serialisation of the iCalendar object using Calendar.toString(). As the server may manipulate the object you add, you MUST take the returned UID, retrieve it with getObjectFromStore and update your own records!

Updating objects
Updating is similar to adding method wise: public int replaceObject(String storeName, String uid, String name, String contents, long dtstart, long dtend) throws Exception There is no need to monitor the returned integer value – it is fixed at 0 for historical reasons.

Deleting objects
To delete an object from the server use the UID of the object you want to delete public void deleteObject(String uid) throws Exception

Searching for objects
You can search for an object using its “name” (iCalendar SUMMARY), start date/time and end date/time. Only an exact match for all three properties will be returned public String searchUids(String name, long dstime, long detime) throws Exception

Finishing up
Once you are done operating on the local database and server, close the database session and logger: public void close() throws Exception