org.springframework.ldap.demo.dao.PersonDaoImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ldap.demo.dao.PersonDaoImpl.java

Source

/*
 * Copyright 2005-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.ldap.demo.dao;

import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;

import javax.naming.Context;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.demo.dao.PersonDao;
import org.springframework.ldap.demo.domain.Person;

/**
 * Traditional implementation of PersonDao. This implementation uses the basic
 * JNDI interfaces and classes {@link DirContext}, {@link Attributes},
 * {@link Attribute}, and {@link NamingEnumeration}. The purpose is to contrast
 * this implementation with an implementation based on Spring LDAP.
 * 
 * @author Mattias Hellborg Arthursson
 * @author Ulrik Sandberg
 */
public class PersonDaoImpl implements PersonDao {

    private String userName;

    private String password;

    private String url;

    private String base;

    /*
     * @see PersonDao#create(Person)
     */
    public void create(Person person) {
        DirContext ctx = createAuthenticatedContext();
        String dn = buildDn(person);
        try {
            Attributes attrs = getAttributesToBind(person);
            ctx.bind(dn, null, attrs);
        } catch (NamingException e) {
            throw new RuntimeException(e);
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }
    }

    /*
     * @see PersonDao#update(Person)
     */
    public void update(Person person) {
        DirContext ctx = createAuthenticatedContext();
        String dn = buildDn(person);
        try {
            ctx.rebind(dn, null, getAttributesToBind(person));
        } catch (NamingException e) {

            throw new RuntimeException(e);
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }
    }

    /*
     * @see PersonDao#delete(Person)
     */
    public void delete(Person person) {
        DirContext ctx = createAuthenticatedContext();
        String dn = buildDn(person);
        try {
            ctx.unbind(dn);
        } catch (NamingException e) {
            throw new RuntimeException(e);
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }
    }

    /*
     * @see PersonDao#getAllPersonNames()
     */
    public List<String> getAllPersonNames() {
        DirContext ctx = createAnonymousContext();

        LinkedList<String> list = new LinkedList<String>();
        NamingEnumeration<?> results = null;
        try {
            SearchControls controls = new SearchControls();
            controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            results = ctx.search("", "(objectclass=person)", controls);

            while (results.hasMore()) {
                SearchResult searchResult = (SearchResult) results.next();
                Attributes attributes = searchResult.getAttributes();
                Attribute attr = attributes.get("cn");
                String cn = (String) attr.get();
                list.add(cn);
            }
        } catch (NamingException e) {
            throw new RuntimeException(e);
        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }
        return list;
    }

    /*
     * @see PersonDao#findAll()
     */
    public List<Person> findAll() {
        DirContext ctx = createAnonymousContext();

        LinkedList<Person> list = new LinkedList<Person>();
        NamingEnumeration<?> results = null;
        try {
            SearchControls controls = new SearchControls();
            controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            results = ctx.search("", "(objectclass=person)", controls);

            while (results.hasMore()) {
                SearchResult searchResult = (SearchResult) results.next();
                String dn = searchResult.getName();
                Attributes attributes = searchResult.getAttributes();
                list.add(mapToPerson(dn, attributes));
            }
        } catch (NamingException e) {
            throw new RuntimeException(e);
        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }
        return list;
    }

    /*
     * @see PersonDao#findByPrimaryKey(java.lang.String, java.lang.String,
     * java.lang.String)
     */
    public Person findByPrimaryKey(String country, String company, String fullname) {

        DirContext ctx = createAnonymousContext();
        String dn = buildDn(country, company, fullname);
        try {
            Attributes attributes = ctx.getAttributes(dn);
            return mapToPerson(dn, attributes);
        } catch (NameNotFoundException e) {
            throw new RuntimeException("Did not find entry with primary key '" + dn + "'", e);
        } catch (NamingException e) {
            throw new RuntimeException(e);
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }
    }

    private String buildDn(Person person) {
        return buildDn(person.getCountry(), person.getCompany(), person.getFullName());
    }

    private String buildDn(String country, String company, String fullname) {
        StringBuffer sb = new StringBuffer();
        sb.append("cn=");
        sb.append(fullname);
        sb.append(", ");
        sb.append("ou=");
        sb.append(company);
        sb.append(", ");
        sb.append("c=");
        sb.append(country);
        String dn = sb.toString();
        return dn;
    }

    private DirContext createContext(Hashtable<String, String> env) {
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        String tempUrl = createUrl();
        env.put(Context.PROVIDER_URL, tempUrl);
        DirContext ctx;
        try {
            ctx = new InitialDirContext(env);
        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
        return ctx;
    }

    private DirContext createAnonymousContext() {
        Hashtable<String, String> hashtable = new Hashtable<String, String>();
        Hashtable<String, String> env = hashtable;
        return createContext(env);
    }

    private DirContext createAuthenticatedContext() {
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, userName);
        env.put(Context.SECURITY_CREDENTIALS, password);
        return createContext(env);
    }

    private Attributes getAttributesToBind(Person person) {
        Attributes attrs = new BasicAttributes();
        BasicAttribute ocattr = new BasicAttribute("objectclass");
        ocattr.add("top");
        ocattr.add("person");
        attrs.put(ocattr);
        attrs.put("cn", person.getFullName());
        attrs.put("sn", person.getLastName());
        attrs.put("description", person.getDescription());
        attrs.put("telephoneNumber", person.getPhone());
        return attrs;
    }

    private Person mapToPerson(String dn, Attributes attributes) throws NamingException {
        Person person = new Person();
        person.setFullName((String) attributes.get("cn").get());
        person.setLastName((String) attributes.get("sn").get());
        person.setDescription((String) attributes.get("description").get());
        person.setPhone((String) attributes.get("telephoneNumber").get());

        // Remove any trailing spaces after comma
        String cleanedDn = dn.replaceAll(", *", ",");

        String countryMarker = ",c=";
        int countryIndex = cleanedDn.lastIndexOf(countryMarker);

        String companyMarker = ",ou=";
        int companyIndex = cleanedDn.lastIndexOf(companyMarker);

        String country = cleanedDn.substring(countryIndex + countryMarker.length());
        person.setCountry(country);
        String company = cleanedDn.substring(companyIndex + companyMarker.length(), countryIndex);
        person.setCompany(company);
        return person;
    }

    private String createUrl() {
        String tempUrl = url;
        if (!tempUrl.endsWith("/")) {
            tempUrl += "/";
        }
        if (StringUtils.isNotEmpty(base)) {
            tempUrl += base;
        }
        return tempUrl;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setBase(String base) {
        this.base = base;
    }

    public void setPassword(String credentials) {
        this.password = credentials;
    }

    public void setUserDn(String principal) {
        this.userName = principal;
    }
}