OpenDJ LDAP SDK provides capabilities for working with LDAP Data Interchange Format (LDIF) content. This chapter demonstrates how to use those capabilities.
LDAP Data Interchange Format provides a mechanism to represent directory data in text format. LDIF data is typically used to initialize directory databases, but also may be used to move data between different directories that cannot replicate directly, or even as an alternative backup format. When you read OpenDJ's external change log, you get changes expressed in LDIF.
LDIF uses base64 encoding to store values that are not safe for use in a text file, including values that represent binary objects like JPEG photos and X509 certificates, but also values that hold bits of LDIF, and values that end in white space. The description in the following LDIF holds, "Space at the end of the line " for example. Notice that continuation lines shown in the excerpt of the JPEG photo value start with spaces.
dn: uid=bjensen,ou=People,dc=example,dc=com description:: U3BhY2UgYXQgdGhlIGVuZCBvZiB0aGUgbGluZSA= uid: bjensen jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABt bnRyUkdCIFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tY AAQAAAADTLUhQICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB ... Pxv8A8lh8J/8AXUfzr1qP/WSfWlzPlsZSi3VHqMA/WinUVB0n/9k= facsimileTelephoneNumber: +1 408 555 1992 objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: top givenName: Barbara cn: Barbara Jensen cn: Babs Jensen telephoneNumber: +1 408 555 1862 sn: Jensen roomNumber: 0209 homeDirectory: /home/bjensen ou: Product Development ou: People l: Cupertino mail: bjensen@example.com uidNumber: 1076 gidNumber: 1000
LDIF can serve to describe not only entries with their attributes but also changes to entries. For example, you can express adding a JPEG photo to Babs Jensen's entry as follows.
dn: uid=bjensen,ou=people,dc=example,dc=com changetype: modify add: jpegPhoto jpegPhoto:< file:///tmp/opendj-logo.jpg
You can also replace and delete attribute values. Notice the dash,
-
, used to separate changes.
dn: uid=bjensen,ou=people,dc=example,dc=com changetype: modify replace: roomNumber roomNumber: 1234 - delete: description - delete: jpegPhoto
LDIF also allows changetype
s of
add
to create entries, delete
to
remove entries, and modrdn
to rename entries.
For more examples, see the LDIF specification, RFC 2849.
OpenDJ LDAP SDK provides ChangeRecordReader
s to
read requests to modify directory data, and EntryReader
s
to read entries from a data source such as a file or other source. Both of
these are interfaces.
The ConnectionEntryReader
class offers methods
to iterate through entries and references returned by a search.
The LDIFChangeRecordReader
and
LDIFEntryReader
classes offer methods to handle LDIF as
strings or from an input stream.
Both classes give you some methods to filter content. You can also
use the LDIF
static methods to filter content.
The following short excerpt shows a reader that takes LDIF change records from standard input.
InputStream ldif = System.in; final LDIFChangeRecordReader reader = new LDIFChangeRecordReader(ldif);
ChangeRecordWriter
s let you write requests to modify
directory data, whereas EntryWriter
s let you write entries
to a file or an output stream. Both of these are interfaces.
The ConnectionChangeRecordWriter
and
ConnectionEntryWriter
classes let you write directly
to a connection to the directory.
The LDIFChangeRecordWriter
and
LDIFEntryWriter
classes let you write to a file or other
output stream. Both classes offer methods to filter content.
The following excerpt shows a writer pushing LDIF changes to a directory server.
final LDIFChangeRecordReader reader = new LDIFChangeRecordReader(ldif); final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port); Connection connection = null; try { connection = factory.getConnection(); connection.bind(userDN, password.toCharArray()); final ConnectionChangeRecordWriter writer = new ConnectionChangeRecordWriter(connection); while (reader.hasNext()) { ChangeRecord changeRecord = reader.readChangeRecord(); writer.writeChangeRecord(changeRecord); } } catch (final ErrorResultException e) { System.err.println(e.getMessage()); System.exit(e.getResult().getResultCode().intValue()); return; } catch (final IOException e) { System.err.println(e.getMessage()); System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue()); return; } finally { if (connection != null) { connection.close(); } }