6.12 - Entry

The Entry class is one of the most important one in the API. It describes the base element stored into a LDAP server, and it associates a Dn and some Attributes.

We have two kinds of Entry in the API, depending on the presence of a SchemaManager in the Entry, or not.

We also provide a few extended classes, like the ImmutableEntry, an immutable version of the Entry.

What is an entry ?

An entry is an object containing a Dn and some Attributes. The following schema shows what's inside an entry :

Creating an Entry

We have many ways to create an Entry. Basically, an Entry has a Dn and some Attributes. It can be schema aware, or not. We provide constructors to allow a user to create the kind of Entry he wants.

The simplest way to create an Entry is to call the default constructor. The created entry will have no attributes, and no Dn. We can also make it schema aware by passing a SchemaManager. Here is an example:

Entry entry = new DefaultEntry();

// Now set the DN and some attributes
Entry entry = new DefaultEntry();

entry.setDn( "dc=example, dc=com" );
entry.add( "objectClass", "top", "domain" );
entry.add( "dc", "example" );

// Schema aware entry
Entry entry2 = new DefaultEntry( schemaManager);

entry2.add( "objectClass", "top", "domain" );
entry2.add( "dc", "example" );

You can also create an Entry passing a Dn, but no attribute. We can create schema aware entries this way too, passing a SchemaManager.

Dn dn = new Dn( schemaManager, "DomainComponent=example, dc=COM" );
Entry entry = new DefaultEntry( "dc=example, dc=com" );

entry.add( "objectClass", "top", "domain" );
entry.add( "dc", "example" );

Entry entry2 = new DefaultEntry( schemaManager, "dc=example, dc=com" );

entry2.add( "objectClass", "top", "domain" );
entry2.add( "dc", "example" );
...

We can also create an entry by copying an existing entry. The created Entry must be schema aware. Here is an example:

Entry entry = new DefaultEntry( schemaManager, "dc=example, dc=com" );

entry2.add( "objectClass", "top", "domain" );
entry2.add( "dc", "example" );

Entry entry2 = new DefaultEntry( schemaManager, entry );

assertEquals( entry.getDn(), entry2.getDn() );

entry.clear();

Last, not least, it's possible to create an Entry using a list of LDIF formated attributes. An example worth ten lines of documentation, so let's see what it means.

First, we will create a schema agnostic entry:

Entry entry = new DefaultEntry( 
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: domain",
    "dc: example"
    );

We can also provide a complete LDIF file (except that we can't add the dn):

String ldif =
    "objectClass: top\n" +           // The \n is mandatory.
    "objectClass: domain\n" +
    "dc: example";

Entry entry = new DefaultEntry( "dc=example, dc=com", ldif );

One can also combine LDIF and variables like in this example (note that if you use a variable, the attribute must not be followed by the ':' char):

String domain = "example";

Entry entry = new DefaultEntry( 
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: domain",
    "cc", domain             // No ':'
    );

All in all, the following constructors are available :

  • DefaultEntry() : Default constructor
  • DefaultEntry(SchemaManager) : Default constructor for a schema aware entry
  • DefaultEntry(String) : Creates an entry with a DN as a String
  • DefaultEntry(SchemaManager, String) : Creates a schema aware entry with a DN as a String
  • DefaultEntry(Dn) : Creates an entry with a DN
  • DefaultEntry(SchemaManager, Dn) : Creates a schema aware entry with a DN as a String
  • DefaultEntry(Dn, Object...) : Creates an entry with a DN and some attributes
  • DefaultEntry(SchemaManager, String, Object...) : Creates a schema aware entry with a DN as a String, and some attributes
  • DefaultEntry(SchemaManager, Dn, Object...) : Creates a schema aware entry with a DN and some attributes
  • DefaultEntry(SchemaManager, Entry) : Creates an entry using a copy of another entry

Modifying an Entry

We have six methods available that modify the Entry content : add, clear, put, remove, removeAttribute and setDn. We will review six four methods in the following paragraphs.

Adding Attributes

Two methods can be used to add some attribute into an Entry. The first one will add a complete Attribute, the second one will add some values to an existing Attribute.

In any case, we can add either an empty attribute, or an attribute with some values. Those values can be Strings, byte[] or Values. The added attributes can be schema aware, and we can also provide a user provided name for the attribute type.

add() methods

The first method makes it possible to add some existing Attribute to an Entry. Let's see how it works:

Attribute cn = new DefaultAttribute( "cn", "test" );
Attribute cn2 = new DefaultAttribute( "cn", "test2" );

Entry entry = new DefaultEntry( 
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test" );

// Add the new attribute
entry.add( cn );

// Try to add a second value
entry.add( cn2 );

Otherwise, we can add a new attribute and values into the Entry by passing both parameters. We can also pass an AttributeType to the add() method, making the added attribute schema aware. Note that if the Entry itself is already schema aware, this is not necessary.

Here are some examples, the first one with a schema aware Entry, the second one with a schema agnostic Entry:

For a schema aware entry :

Entry entry = new DefaultEntry( 
    schemaManager,
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test" );

// Add the new attribute
entry.add( "cn", "test" );

// Try to add a second value
entry.add( "cn", "A  second test   " );

// We can also add a value to an existing Attribute 
entry.add( "sn", "Another SN" );

// And even add many values in one shot
entry.add( "cn", "value1", "value2" );

For a schema agnostic entry :

Entry entry = new DefaultEntry( 
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test" );

// Add the new attribute
entry.add( "cn", "test" );

// Try to add a second value
entry.add( "cn", "A  second  test" );

As you can see, there is no real difference between those two methods, except that we pass the schemaManager in the first one.

put() methods

The big difference with the add method is that the attribute is not added, it will replace an existing one. let's see with an example :

Entry entry = new DefaultEntry( 
    schemaManager, 
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test" );

// Add the new attribute
entry.put( "cn", "test" );

// Try to add a second value : the 'cn' attribute will now contain only 'test2'
entry.put( "cn", "test2" );

Removing Attributes

We can remove either an attribute having a specific value, or an entire attribute. In order to remove a complete attribute, you just have to provide the attribute's name, and use the removeAttributes method.

Here are some example for both usages :

Entry entry = new DefaultEntry( 
    schemaManager,
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test",
    "cn: test1",
    "cn: test2",
    "cn: test3" );

// Remove the "test2" value
entry.remove( "cn", "test2" );

// Try to remove the full attribute
entry.removeAttributes( "cn" );

Storing a Dn

It's also possible to store a new Dn into the Entry, using the setDn() method. It will replace an existing _Dn This method takes either a Dn instance, or a String representing a valid Dn.

Clearing the Entry

You can remove all the Attribute from the entry, using the clear() method :

Entry entry = new DefaultEntry( 
    schemaManager,
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test",
    "cn: test1",
    "cn: test2",
    "cn: test3" );

// Remove all the attributes
entry.clear();

The Dn will still be around though.

Attribute data access methods

The API provides convenient methods to access the Entry content, and to check if it contains some attributes or some values. We will shortly expose those methods in the following paragraphs.

Contains method

The contains and containsAttributes methods check that the Entry contains Attributes and values.

One can check for the existence of a specific value for a given attribute, or even for multiple values for a specific attribute. Let's see the contains method in action:

Entry entry = new DefaultEntry( 
    schemaManager,
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test",
    "cn: test1",
    "cn: test2",
    "cn: test3" );

// Check that the entry contains the 'cn' and 'sn' Attributes
boolean contains = entry.containsAttribute( "cn", "sn" );

// Check that the entry contains 3 given values of the 'cn' Attribute
contains = entry.contains( "cn", "test1", "test2", "test3" );

Note that if one value does not exist, the _contains() method will return false.

getAttributes() and get() methods

Returns the Attribute having the given name if it exists. The following test demonstrates its usage:

Entry entry = new DefaultEntry( 
    schemaManager,
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test",
    "cn: test1",
    "cn: test2",
    "cn: test3" );

// Get the 'cn' Attribute
Attribute cn = entry.get( "cn" );

// Get all the Attributes
Collection<Attribute> attributes = entry.getAttributes();

getDn()

This method returns the Entry's Dn.

hasObjectClass methods

The hasObjectClass() methods are used to discover if an Entry has a specific ObjectClass. This is a convenient method, as it's possible to do the same thing with a contains() call, but with one less parameter (you don't have to provide the "ObjectClass" as a first parameter).

Here is an example using the two existing methods:

Entry entry = new DefaultEntry( 
    schemaManager,
    "cn=example, dc=com", 
    "objectClass: top",
    "objectClass: person",
    "cn: example",
    "sn: test"
    );

// Test the presence
boolean isPresent = entry.hasObjectClass( "person", " TOP " );

As for the contains() method, it will return true if and only if all the ObjectClasses are present in the entry.

Obviously, dealing with a schema agnostic Entry, those methods are more strict. You have to use the exact ObjectClasses case sensitive trimmed names (in the previous example, we can use upper cased names, even with spaces around the names).

Also note that the hasObjectClass method used with AttributeType does not work on a schema agnostic entry.

Miscellaneous methods

We also have some other methods which can be used on an Entry. Here is a list of those methods.

clone()

Creates a copy of the current Entry. All the Attributes are also cloned.

iterator()

Allows an iteration over all the Attributes. The following examples shows how this can be used:

@Test
Entry entry = new DefaultEntry( 
    "cn=example, dc=com", 
    "objectClass: top",
    "objectClass: person",
    "cn: example",
    "sn: test"
    );

for ( Attribute attribute : entry )
{
    System.out.println( "Attribute : \n" + attribute.toString() );
}

This produces the following output:

Attribute : 
    sn: test

Attribute : 
    cn: example

Attribute : 
    objectclass: top
    objectclass: person

Note that the Attribute order is not guaranteed.

isSchemaAware()

Tells if the ยจEntry has an associated SchemaManager.

size()

Returns the number of Attribute stored in the Entry.

equals(Object)

Check if two Entries are equal or not. It's important to understand that depending on whether the entry is schema aware or not, the comparison will be processed differently. Typically, the attribute's name must be equals when they have been trimmed and lower cased if the entry is not schema aware, and we can't compare an attribute named 'cn' with another one named '2.5.4.3' in this case (the Entry must be schema aware to allow such comparison). More important, the values must be identical (same casing, same spaces) in this case. The attribute's values order is irrelevant.

Here are one example with a schema agnostic Entry:

Entry entry = new DefaultEntry( 
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test",
    "cn: test1",
    "cn: test2",
    "cn: test3" );

Entry entry2 = new DefaultEntry( 
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test",
    "cn: test2",
    "CN: test1",
    "cn: test3" );

// Will return true
boolean result = entry.equals( entry2 );

and another example with a schema aware Entry:

Entry entry = new DefaultEntry( 
    schemaManager,
    "dc=example, dc=com",
    "objectClass: top",
    "objectClass: person",
    "sn: test",
    "cn: test1",
    "cn: test2",
    "cn: test3" );

Entry entry2 = new DefaultEntry( 
    schemaManager,
    "dc=example,dc=com",
    "objectClass: TOP",
    "objectClass: person",
    "sn: Test",
    "cn: Test2",
    "2.5.4.3: test1",
    "CommonName: test3" );

// Will return true
boolean result = entry.equals( entry2 );