# Basic Operations

## Search and Lookup Using AttributesMapper

In this example we will use an `AttributesMapper` to easily build a List of all common names of all person objects.

AttributesMapper that returns a single attribute

    package com.example.dao;

    public class PersonDaoImpl implements PersonDao {
       private LdapTemplate ldapTemplate;

       public void setLdapTemplate(LdapTemplate ldapTemplate) {
          this.ldapTemplate = ldapTemplate;
       }

       public List getAllPersonNames() {
          return ldapTemplate.search(
             "", "(objectclass=person)",
             new AttributesMapper() {
                public Object mapFromAttributes(Attributes attrs)
                   throws NamingException {
                   return attrs.get("cn").get();
                }
             });
       }
    }

The inline implementation of `AttributesMapper` just gets the desired attribute value from the `Attributes` and returns it. Internally, `LdapTemplate` iterates over all entries found, calling the given `AttributesMapper` for each entry, and collects the results in a list. The list is then returned by the `search` method.

Note that the `AttributesMapper` implementation could easily be modified to return a full `Person` object:

AttributesMapper that returns a Person object

    package com.example.dao;

    public class PersonDaoImpl implements PersonDao {
       private LdapTemplate ldapTemplate;
       ...
       private class PersonAttributesMapper implements AttributesMapper {
          public Object mapFromAttributes(Attributes attrs) throws NamingException {
             Person person = new Person();
             person.setFullName((String)attrs.get("cn").get());
             person.setLastName((String)attrs.get("sn").get());
             person.setDescription((String)attrs.get("description").get());
             return person;
          }
       }

       public List getAllPersons() {
          return ldapTemplate.search("", "(objectclass=person)", new PersonAttributesMapper());
       }
    }

If you have the distinguished name (`dn`) that identifies an entry, you can retrieve the entry directly, without searching for it. This is called a lookup in Java LDAP. The following example shows how a lookup results in a Person object:

A lookup resulting in a Person object

    package com.example.dao;

    public class PersonDaoImpl implements PersonDao {
       private LdapTemplate ldapTemplate;
       ...
       public Person findPerson(String dn) {
          return (Person) ldapTemplate.lookup(dn, new PersonAttributesMapper());
       }
    }

This will look up the specified `dn` and pass the found attributes to the supplied `AttributesMapper`, in this case resulting in a `Person` object.

## Building Dynamic Filters

We can build dynamic filters to use in searches, using the classes from the `org.springframework.ldap.filter` package. Let's say that we want the following filter: `(&(objectclass=person)(sn=?))`, where we want the `?` to be replaced with the value of the parameter `lastName`. This is how we do it using the filter support classes:

Building a search filter dynamically

    package com.example.dao;

    public class PersonDaoImpl implements PersonDao {
       private LdapTemplate ldapTemplate;
       ...
       public List getPersonNamesByLastName(String lastName) {
          AndFilter filter = new AndFilter();
          filter.and(new EqualsFilter("objectclass", "person"));
          filter.and(new EqualsFilter("sn", lastName));
          return ldapTemplate.search(
             "", filter.encode(),
             new AttributesMapper() {
                public Object mapFromAttributes(Attributes attrs)
                   throws NamingException {
                   return attrs.get("cn").get();
                }
             });
       }
    }

To perform a wildcard search, it's possible to use the `WhitespaceWildcardsFilter`:

Building a wildcard search filter

    AndFilter filter = new AndFilter();
    filter.and(new EqualsFilter("objectclass", "person"));
    filter.and(new WhitespaceWildcardsFilter("cn", cn));

In addition to simplifying building of complex search filters, the `Filter` classes also provide proper escaping of any unsafe characters. This prevents "ldap injection", where a user might use such characters to inject unwanted operations into your LDAP operations.

## Building Dynamic Distinguished Names

The standard Name interface represents a generic name, which is basically an ordered sequence of components. The `Name` interface also provides operations on that sequence; e.g., `add` or `remove`. LdapTemplate provides an implementation of the `Name` interface: `DistinguishedName`. Using this class will greatly simplify building distinguished names, especially considering the sometimes complex rules regarding escapings and encodings. As with the `Filter` classes this helps preventing potentially malicious data being injected into your LDAP operations.

The following example illustrates how `DistinguishedName` can be used to dynamically construct a distinguished name:

Building a distinguished name dynamically

    package com.example.dao;

    import org.springframework.ldap.core.support.DistinguishedName;
    import javax.naming.Name;

    public class PersonDaoImpl implements PersonDao {
       public static final String BASE_DN = "dc=example,dc=com";
       ...
       protected Name buildDn(Person p) {
          DistinguishedName dn = new DistinguishedName(BASE_DN);
          dn.add("c", p.getCountry());
          dn.add("ou", p.getCompany());
          dn.add("cn", p.getFullname());
          return dn;
       }
    }

Assuming that a Person has the following attributes:

`country` | Sweden
`company` | Some Company
`fullname` | Some Person

The code above would then result in the following distinguished name:

    cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com

In Java 5, there is an implementation of the Name interface: LdapName. If you are in the Java 5 world, you might as well use `LdapName`. However, you may still use `DistinguishedName` if you so wish.

## Binding and Unbinding

### Binding Data

Inserting data in Java LDAP is called binding. In order to do that, a distinguished name that uniquely identifies the new entry is required. The following example shows how data is bound using LdapTemplate:

Binding data using Attributes

    package com.example.dao;

    public class PersonDaoImpl implements PersonDao {
       private LdapTemplate ldapTemplate;
       ...
       public void create(Person p) {
          Name dn = buildDn(p);
          ldapTemplate.bind(dn, null, buildAttributes(p));
       }

       private Attributes buildAttributes(Person p) {
          Attributes attrs = new BasicAttributes();
          BasicAttribute ocattr = new BasicAttribute("objectclass");
          ocattr.add("top");
          ocattr.add("person");
          attrs.put(ocattr);
          attrs.put("cn", "Some Person");
          attrs.put("sn", "Person");
          return attrs;
       }
    }

The Attributes building is--while dull and verbose--sufficient for many purposes. It is, however, possible to simplify the binding operation further, which will be described in .

### Unbinding Data

Removing data in Java LDAP is called unbinding. A distinguished name (dn) is required to identify the entry, just as in the binding operation. The following example shows how data is unbound using LdapTemplate:

Unbinding data

    package com.example.dao;

    public class PersonDaoImpl implements PersonDao {
       private LdapTemplate ldapTemplate;
       ...
       public void delete(Person p) {
          Name dn = buildDn(p);
          ldapTemplate.unbind(dn);
       }
    }

## Modifying

In Java LDAP, data can be modified in two ways: either using rebind or modifyAttributes.

### Modifying using `rebind`

A `rebind` is a very crude way to modify data. It's basically an `unbind` followed by a `bind`. It looks like this:

Modifying using rebind

    package com.example.dao;

    public class PersonDaoImpl implements PersonDao {
       private LdapTemplate ldapTemplate;
       ...
       public void update(Person p) {
          Name dn = buildDn(p);
          ldapTemplate.rebind(dn, null, buildAttributes(p));
       }
    }

### Modifying using `modifyAttributes`

If only the modified attributes should be replaced, there is a method called `modifyAttributes` that takes an array of modifications:

Modifying using modifyAttributes

    package com.example.dao;

    public class PersonDaoImpl implements PersonDao {
       private LdapTemplate ldapTemplate;
       ...
       public void updateDescription(Person p) {
          Name dn = buildDn(p);
          Attribute attr = new BasicAttribute("description", p.getDescription())
          ModificationItem item = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr);
          ldapTemplate.modifyAttributes(dn, new ModificationItem[] {item});
       }
    }

Building `Attributes` and `ModificationItem` arrays is a lot of work, but as you will see in , the update operations can be simplified.

## Sample applications

It is recommended that you review the Spring LDAP sample applications included in the release distribution for best-practice illustrations of the features of this library. A description of each sample is provided below:

1. spring-ldap-person - the sample demonstrating most features.

2. spring-ldap-article - the sample application that was written to accompany a java.net article about Spring LDAP.