Creating a public contactslist in Exchange 2003 using Jakarta Slide javacode 9085791

Creating a public contactslist in Exchange 2003 using Jakarta Slide

The requirement my customer has: create a nice web application that will allow our company to manage our contacts and stores them in a database. While you’re at it, sync those contacts with Exchange in such a way that only the web app can create, modify and delete contacts in Exchange but all Outlook users can use the contacts to send mail to.

The solution: create an Oracle ADF web application with JDeveloper and JHeadstart and use Jakarta Slide to sync the database with Exchange via Webdav.

I guess there are enough JDeveloper/JHeadstart tutorials roaming around the internet. But I found it quite hard to find a good Slide tutorial. Well, this isn’t exactly a tutorial, but it should get you on your way anyway. In testing my code I used both NetBeans (5.0 beta 2) and JDeveloper (10.1.2.1.0 build 1913). This brief article will tell you how to create a Contacts folder in Exchange and populate it with a Contact. It will also give you enough info to figure out the rest yourself.

Please note I did my tests with Slide 2.1 on Exchange 2003 SP2. Other versions of Slide or Exchange may or may not work with this code.

The Jakarta Slide project comes with two subprojects. There is a server version and there is a client version. The server version is needed when you want to setup your own Webdav server. It can be used to store all files and folders being uploaded to the server via Webdav to a database. In order to connect to either that Webdav server or to Exchange, the Slide client is needed. So, download the client binary version (or the source version if you’d like to compile it yourself) and unpack the zip or tgz file. Next, start your favourite IDE and make the Slide jars available to it through a custom library definition.

The central Slide class to connect to an Exchange store is called “WebdavResource”. This class contains methods for all Webdav commands. All these WebdavResource commands generate the correct XML messages that are sent to the Exchange store to do the tasks you’d like to do. The Webdav commands you’ll need to know about in order to connect to and work with Exchange can be found in the MicroSoft WebDav Protocol Reference. All you need to do is create an HttpURL with the correct username and password to login to the Webdav store at the URL that you also need to provide and then create a WebdavResource from that HttpURL:

HttpURL url = null;
WebdavResource resource = null;
try {
url = new HttpURL(USERNAME, PASSWORD, DAV_URL);
resource = new WebdavResource(url);
resource.close();
} catch (URIException ex) {
//ex.printStackTrace();
} catch (IOException ex) {
//ex.printStackTrace();
}

 

DAV_URL represents the URL to the Webdav store and could, for instance, be http://myexchangeserver/Public

Webdav basically works with two kinds of objects. These are called collections (folders) and messages (files). Both collections and messages exist in different types. A collection can be of type MailItems (IPF.Note), ContactItems (IPF.Contact), AppointmentItems (IPF.Appointment), NoteItems (IPF.StickyNote), TaskItems (IPF.Task) or  JournalItems (IPF.Journal). The Webdav internal type that they are known by are mentioned in the brackets behind every type.

Webdav recognises the type you’d like to set by the “outlookfolderclass” tag in the “http://schemas.microsoft.com/exchange/” XML namespace. See for a C# example on how to create an AppointmentItems collection this Microsoft KnowledgeBase article. Since I have been dealing with creating ContactItems collections, I’ll be dealing with that here too. In order to create a collection, forst the MKCOL command needs to be executed on the Webdav store. To set the correct type of collection, the PROPPATCH command needs to be executed. Using Slide this goes as follows:

HttpURL url = null;
WebdavResource resource = null;
try {
url = new HttpURL(USERNAME, PASSWORD,DAV_URL);
resource = new WebdavResource(url);
resource.mkcolMethod(DAV_URL + CONTACTS_DIRECTORY);
Hashtable contactProps = new Hashtable();
contactProps.put(new PropertyName(EXCHANGE_XML_NAMESPACE,”outlookfolderclass”), “IPF.Contact”);
if (resource.proppatchMethod(DAV_URL + CONTACTS_DIRECTORY, contactProps, true))
{
System.out.println(“Status code returned: ” + resource.getStatusMessage());
} else
{
System.out.println(“Request failed:”);
System.out.println(“Status code returned: ” + resource.getStatusMessage());
}
resource.close();
} catch (URIException ex) {
//ex.printStackTrace();
} catch (IOException ex) {
//ex.printStackTrace();
}

Here, CONTACTS_DIRECTORY is a String containing the name of the collection to create and EXCHANGE_XML_NAMESPACE is a String containing the correct XML namespace. As stated before, this is “http://schemas.microsoft.com/exchange/”.

Please note: the PROPPATCH method will create an item on which the properties are set if it doesn’t exist. But the PROPPATCH command will always create a message and never a collection, even if the property to set is the “outlookfolderclass” property. Therefore, creating a collection always involves first creating it and then setting its type.

So, now that our ContactItems collection exists we can put a contact in it. Since Webdav only knows of collections and messages, a Contact actually is a message. But the “outlookmessageclass” now is “IPM.Contact” (in contrast to IPF.Contact for a ContactItems collection). I guess the M in IPM indicates we’re dealing with a message as opposed to the F in IPF when dealing with a collection which actually is a folder.

Anyway, as can be read in this MicroSoft KnowledgeBase article only one other property is required in order to create a Contact, which is the “contentclass” property in the “DAV:” namespace (mind the trailing “:”!!!) which needs to be set to “urn:content-classes:person”. The same KB article shows which properties are available for a Webdav Contact and this code sets a few of them and then calls the PROPPATCH command to store the contact in Webdav:

HttpURL url = null;
WebdavResource resource = null;

try {
url = new HttpURL(USERNAME, PASSWORD,DAV_URL);
resource = new WebdavResource(url);
Hashtable contactProps = new Hashtable();
contactProps.put(new PropertyName(DAV_XML_NAMESPACE,”contentclass”), “urn:content-classes:person”);
contactProps.put(new PropertyName(EXCHANGE_XML_NAMESPAC
E,”outlookmessageclass&
quot;), “IPM.Contact”);
contactProps.put(new PropertyName(URN_SCHEMAS_CONTACTS_XML_NAMESPACE,”givenName”), firstname);
contactProps.put(new PropertyName(URN_SCHEMAS_CONTACTS_XML_NAMESPACE,”middlename”), middlename);
contactProps.put(new PropertyName(URN_SCHEMAS_CONTACTS_XML_NAMESPACE,”sn”), lastname);
contactProps.put(new PropertyName(URN_SCHEMAS_CONTACTS_XML_NAMESPACE,”cn”), firstname + ” ” + middlename + ” ” + lastname);
contactProps.put(new PropertyName(URN_SCHEMAS_CONTACTS_XML_NAMESPACE,”fileas”), firstname + ” ” + middlename + ” ” + lastname);
if (resource.proppatchMethod(DAV_URL + path + CONTACTS_DIRECTORY + lastname + CONTACTS_EXTENSION, contactProps, true))
{
System.out.println(“Status code returned: ” + resource.getStatusMessage());
} else
{
System.out.println(“Request failed:”);
System.out.println(“Status code returned: ” + resource.getStatusMessage());
}
resource.close();
} catch (URIException ex) {
//ex.printStackTrace();
} catch (IOException ex) {
//ex.printStackTrace();
}

Fill the variables “firstname”, “middlename” and “lastname” with the properties you’d like to store and make sure de Strings DAV_XML_NAMESPACE, EXCHANGE_XML_NAMESPACE and URN_SCHEMAS_CONTACTS_XML_NAMESPACE contain the values “DAV:”, “http://schemas.microsoft.com/exchange/” and “urn:schemas:contacts:” and give it a go.

The contact created this way is of little use to ay real life Outlook users. It doesn’t contain an email addres, nor a phone number or anything of the kind. But it proves Slide works like a charm.

7 Comments

  1. Wouter van Reeven April 6, 2006
  2. Troy Wolf April 5, 2006
  3. Chris Gralike December 16, 2005
  4. Marco Gralike December 13, 2005
  5. Chris Gralike December 9, 2005
  6. Aino Andriessen December 9, 2005
  7. Maike Dulk December 8, 2005