Introduction
This tutorial is meant to show how to use the CalDAV4j at the various levels of its API. It assumes that you have access to CalDAV server such as
Cosmo
HttpClient Methods
The lowest-level API available to the developer are the various Http method classes (implementations of org.apache.commons.httpclient.HttpMethod) like GET, PUT, DELETE and REPORT. Using these classes you have full control over what get sent in the Http request.
HttpClient and HostConfiguration
The range of configuration options for HttpClient and HostConfiguration are beyond the scope of this page, so I'll just show a relatively simple case - connecting to a Cosmo server. Here's how to set up the HttpClient:
HttpClient httpClient = new HttpClient();
Credentials credentials = new UsernamePasswordCredentials("username", "mysecretpassword");
httpClient.getState().setCredentials(null, null, credentials);
httpClient.getState().setAuthenticationPreemptive(true);
and the HostConfiguration:
HostConfiguration hostConfig = new HostConfiguration();
hostConfig.setHost("cosmo-demo.osafoundation.org", 8080);
Method Factory
You can create new instances of your methods with the constructor and manually set a bunch of properties, but it is far easier to first create a CalDAV4JMethodFactory and obtain all instances from there:
...
private CalDAV4JMethodFactory methodFactory = new CalDAV4JMethodFactory();
methodFactory.setProcId("//OSAF//NONSGML My First CalDAV Client//EN");
methodFactory.setCalendarValidatingOutputter(true);
...
MKCALENDAR method
All icalendar resources must be contained within a CalDAV calendar collection, which we create using the MKCALENDAR method.
So first we'll use the method factory to create a
MkCalendarMethod?:
MkCalendarMethod mkCalendarMethod = methodFactory.createMkCalendarMethod()
And now we set the path to where we want the collection:
mkCalendarMethod.setPath("/cosmo/home/username/mycalendar");
Finally we execute the method:
httpClient.executeMethod(hostConfig, mCalendarMethod);
int statusCode = mCalendarMethod.getStatusCode();
<< check the status code for unexpected values >>
It is important that you check the status code and make sure it is what you expected it to be -
HttpClient? does not throw an exception when the remote server returns an error code, it only throws an exception if there is a problem actually connecting to the server.
PUT, GET Methods
CalDAV4j's PUT and GET methods are not that different than the PUT and GET methods that ship with
HttpClient?, there is just a some added functionality for parsing and serializing icalendar streams and adding e-tags to the headers.
Let's create a VCALENDAR and PUT it on our server
Here are some of the classes you'll need to import:
import net.fortuna.ical4j.model.Calendar
import org.osaf.caldav4j.methods.PutMethod
import org.osaf.caldav4j.methods.GetMethod
First we create our Calendar:
...
Calendar calendar = new Calendar();
...
<add some VEVENTS to the calendar perhaps...>
...
Now we use the method factory from before to get an instance of
PutMethod?:
PutMethod put = methodFactory.createPutMethod();
This is a brand new icalendar resource, so we want to make sure that there isn't something already there with the same name. To do that we set the "If-None-Match" http header with the "*" wild card. What that means is if any version at all of this resource exists, this method will fail.
put.setIfNoneMatch(true);
put.setAllEtags(true);
put.setRequestBody(cal);
Now we need to set the path where we want the resource to go. Note that this path must within a calendar collection:
put.setPath("/cosmo/home/username/mycalendar/myevent.ics");
Now we can execute the method using the HttpClient and HostConfiguration we created before:
httpClient.executeMethod(hostConfig, put);
int statusCode = put.getStatusCode();
...
<< some code to make sure the statusCode was what was expected>>
...
To retrieve the resource from the server, we create the
GetMethod?, set the path and execute it like before:
GetMethod get = methodFactory.createGetMethod();
get.setPath("/cosmo/home/username/mycalendar/myevent.ics");
httpClient.executeMethod(hostConfig, get);
int statusCode = get.getStatusCode();
<< insert status code checks here >>
And now we can get VCALENDAR out as an iCal4j Calendar:
Calendar calendar = get.getResponseBodyAsCalendar();
REPORT Method
The REPORT method allows for flexible querying of CalDAV collections. The full range of its power is beyond the scope of this document, so just one of the most common use cases will be demonstrated - querying a collection for VEVENTS within a given time-range.
There are several different types of REPORT requests, but the most common one and the only one supported right now in CalDAV4j is the <calendar-query>. The <calendar-query> we would like to create looks like this:
<?xml version="1.0"?>
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop xmlns:D="DAV:">
<C:calendar-data/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20060101T000000Z" end="20060107T000000Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>
Basically, what this query is saying is "give me all the calendar data for VEVENT's in VCALENDAR's which occur between 1/1/2006 and 1/7/2006 exclusive"