LDAP-262: Cleaned up and consolidated the samples.
This commit is contained in:
@@ -540,13 +540,14 @@ public final class LdapUtils {
|
||||
* @param index The 0-based index of the rdn value to retrieve. Must be in the range [0,size()).
|
||||
* @return the value of the rdn at the requested index.
|
||||
* @throws IndexOutOfBoundsException if index is outside the specified range.
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Object getValue(Name name, int index) {
|
||||
Assert.notNull(name, "name must not be null");
|
||||
|
||||
LdapName ldapName = returnOrConstructLdapNameFromName(name);
|
||||
Rdn rdn = ldapName.getRdn(index);
|
||||
if(rdn.size() > 0) {
|
||||
if(rdn.size() > 1) {
|
||||
logger.warn("Rdn at position " + index + " of dn '" + name +
|
||||
"' is multi-value - returned value is not to be trusted. " +
|
||||
"Consider using name-based getValue method instead");
|
||||
@@ -562,6 +563,7 @@ public final class LdapUtils {
|
||||
* @return the value of the rdn at the requested index as a String.
|
||||
* @throws IndexOutOfBoundsException if index is outside the specified range.
|
||||
* @throws ClassCastException if the value of the requested component is not a String.
|
||||
* @since 2.0
|
||||
*/
|
||||
public static String getStringValue(Name name, int index) {
|
||||
return (String) getValue(name, index);
|
||||
|
||||
4
samples/article-spring20/.gitignore
vendored
4
samples/article-spring20/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
target
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.0.6.v200806241357]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
<config>src/main/webapp/WEB-INF/applicationContext.xml</config>
|
||||
<config>src/main/webapp/WEB-INF/basic-servlet.xml</config>
|
||||
<config>src/test/resources/config/testContext.xml</config>
|
||||
</configs>
|
||||
<configSets>
|
||||
<configSet>
|
||||
<name><![CDATA[web]]></name>
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
<incomplete>false</incomplete>
|
||||
<configs>
|
||||
<config>src/main/webapp/WEB-INF/applicationContext.xml</config>
|
||||
<config>src/main/webapp/WEB-INF/basic-servlet.xml</config>
|
||||
</configs>
|
||||
</configSet>
|
||||
</configSets>
|
||||
</beansProjectDescription>
|
||||
@@ -1,25 +0,0 @@
|
||||
apply from: JAVA_SCRIPT
|
||||
apply plugin: 'war'
|
||||
apply plugin: 'jetty'
|
||||
|
||||
ext.springVersion = "2.0.8"
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-ldap-test'),
|
||||
project(':spring-ldap-samples-utils'),
|
||||
'log4j:log4j:1.2.9',
|
||||
'javax.servlet:jstl:1.2',
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-core:$springVersion",
|
||||
"org.springframework:spring-dao:$springVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion",
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"org.springframework:spring-webmvc:$springVersion",
|
||||
"org.springframework:spring-support:$springVersion"
|
||||
|
||||
provided "javax.servlet:servlet-api:2.5"
|
||||
|
||||
testCompile "org.springframework:spring-mock:$springVersion",
|
||||
"junit:junit:$junitVersion"
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
Uses Spring 2.0.
|
||||
Sample application demonstrating how to do the most basic stuff in Spring LDAP.
|
||||
A very simple dao implementation is provided in
|
||||
org.springframework.ldap.samples.article.dao.PersonDaoImpl
|
||||
It demonstrates some basic operations using Spring LDAP. For reference purposes,
|
||||
a corresponding implementation using ordinary Java LDAP/JNDI implementation is
|
||||
available in TraditionalPersonDaoImpl.
|
||||
|
||||
How to use:
|
||||
-----------
|
||||
The project is in a Maven build structure. Make sure you have installed the samples-utils artifact, as this will be
|
||||
needed for this project to work.
|
||||
|
||||
'mvn jetty:run' will start up a web server demonstrating the capabilities. The web application will be available
|
||||
under http://localhost:8080/spring-ldap-person-article-spring20/
|
||||
|
||||
'mvn eclipse:eclipse' will construct an Eclipse project for you to use. Import that project into Eclipse using
|
||||
File/Import/Existing Project, and select this directory.
|
||||
|
||||
'mvn test' will run some integration tests that require the LDAP server to be running. It's recommended to run
|
||||
'mvn jetty:run' from another terminal window before 'mvn test'.
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import org.springframework.ldap.core.AttributesMapper;
|
||||
import org.springframework.ldap.core.ContextMapper;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.LdapTemplate;
|
||||
import org.springframework.ldap.filter.EqualsFilter;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.ldap.support.LdapNameBuilder;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default implementation of PersonDao. This implementation uses
|
||||
* DirContextAdapter for managing attribute values. It has been specified in the
|
||||
* Spring Context that the DirObjectFactory should be used when creating objects
|
||||
* from contexts, which defaults to creating DirContextAdapter objects. This
|
||||
* means that we can use a ContextMapper to map from the found contexts to our
|
||||
* domain objects. This is especially useful since we in this case have
|
||||
* properties in our domain objects that depend on parts of the DN.
|
||||
*
|
||||
* We could have worked with Attributes and an AttributesMapper implementation
|
||||
* instead, but working with Attributes is a bore and also, working with
|
||||
* AttributesMapper objects (or, indeed Attributes) does not give us access to
|
||||
* the distinguished name. However, we do use it in one method that only needs a
|
||||
* single attribute: {@link #getAllPersonNames()}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PersonDaoImpl implements PersonDao {
|
||||
|
||||
private LdapTemplate ldapTemplate;
|
||||
|
||||
/*
|
||||
* @see PersonDao#create(Person)
|
||||
*/
|
||||
public void create(Person person) {
|
||||
Name dn = buildDn(person);
|
||||
DirContextAdapter context = new DirContextAdapter(dn);
|
||||
mapToContext(person, context);
|
||||
ldapTemplate.bind(dn, context, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#update(Person)
|
||||
*/
|
||||
public void update(Person person) {
|
||||
Name dn = buildDn(person);
|
||||
DirContextAdapter context = (DirContextAdapter) ldapTemplate.lookup(dn);
|
||||
mapToContext(person, context);
|
||||
ldapTemplate.modifyAttributes(dn, context.getModificationItems());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#delete(Person)
|
||||
*/
|
||||
public void delete(Person person) {
|
||||
ldapTemplate.unbind(buildDn(person));
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#getAllPersonNames()
|
||||
*/
|
||||
public List getAllPersonNames() {
|
||||
EqualsFilter filter = new EqualsFilter("objectclass", "person");
|
||||
return ldapTemplate.search(LdapUtils.emptyLdapName(), filter.encode(), new AttributesMapper() {
|
||||
public Object mapFromAttributes(Attributes attrs) throws NamingException {
|
||||
return attrs.get("cn").get();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findAll()
|
||||
*/
|
||||
public List findAll() {
|
||||
EqualsFilter filter = new EqualsFilter("objectclass", "person");
|
||||
return ldapTemplate.search(LdapUtils.emptyLdapName(), filter.encode(), getContextMapper());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findByPrimaryKey(java.lang.String, java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Person findByPrimaryKey(String country, String company, String fullname) {
|
||||
Name dn = buildDn(country, company, fullname);
|
||||
return (Person) ldapTemplate.lookup(dn, getContextMapper());
|
||||
}
|
||||
|
||||
private ContextMapper getContextMapper() {
|
||||
return new PersonContextMapper();
|
||||
}
|
||||
|
||||
private Name buildDn(Person person) {
|
||||
return buildDn(person.getCountry(), person.getCompany(), person.getFullName());
|
||||
}
|
||||
|
||||
private Name buildDn(String country, String company, String fullname) {
|
||||
return LdapNameBuilder.newInstance()
|
||||
.add("c", country)
|
||||
.add("ou", company)
|
||||
.add("cn", fullname)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void mapToContext(Person person, DirContextAdapter context) {
|
||||
context.setAttributeValues("objectclass", new String[] { "top", "person" });
|
||||
context.setAttributeValue("cn", person.getFullName());
|
||||
context.setAttributeValue("sn", person.getLastName());
|
||||
context.setAttributeValue("description", person.getDescription());
|
||||
context.setAttributeValue("telephoneNumber", person.getPhone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps from DirContextAdapter to Person objects. A DN for a person will be
|
||||
* of the form <code>cn=[fullname],ou=[company],c=[country]</code>, so
|
||||
* the values of these attributes must be extracted from the DN. For this,
|
||||
* we use LdapName and helper methods in LdapUtils.
|
||||
*
|
||||
*Mattias Hellborg Arthurssonellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
private static class PersonContextMapper implements ContextMapper {
|
||||
|
||||
public Object mapFromContext(Object ctx) {
|
||||
DirContextAdapter context = (DirContextAdapter) ctx;
|
||||
Name dn = context.getDn();
|
||||
Person person = new Person();
|
||||
person.setCountry(LdapUtils.getStringValue(dn, 0));
|
||||
person.setCompany(LdapUtils.getStringValue(dn, 1));
|
||||
person.setFullName(context.getStringAttribute("cn"));
|
||||
person.setLastName(context.getStringAttribute("sn"));
|
||||
person.setDescription(context.getStringAttribute("description"));
|
||||
person.setPhone(context.getStringAttribute("telephoneNumber"));
|
||||
|
||||
return person;
|
||||
}
|
||||
}
|
||||
|
||||
public void setLdapTemplate(LdapTemplate ldapTemplate) {
|
||||
this.ldapTemplate = ldapTemplate;
|
||||
}
|
||||
}
|
||||
@@ -1,377 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.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.samples.article.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 that of {@link PersonDaoImpl}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class TraditionalPersonDaoImpl 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 getAllPersonNames() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 findAll() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 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 env = new Hashtable();
|
||||
return createContext(env);
|
||||
}
|
||||
|
||||
private DirContext createAuthenticatedContext() {
|
||||
Hashtable env = new Hashtable();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.domain;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* Simple class representing a single person.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class Person {
|
||||
private String fullName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String description;
|
||||
|
||||
private String country;
|
||||
|
||||
private String company;
|
||||
|
||||
private String phone;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return EqualsBuilder.reflectionEquals(
|
||||
this, obj);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return HashCodeBuilder
|
||||
.reflectionHashCode(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ToStringBuilder.reflectionToString(
|
||||
this, ToStringStyle.MULTI_LINE_STYLE);
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package org.springframework.ldap.samples.article.web;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.ldap.samples.article.dao.PersonDao;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.ldap.samples.utils.HtmlRowLdapTreeVisitor;
|
||||
import org.springframework.ldap.samples.utils.LdapTree;
|
||||
import org.springframework.ldap.samples.utils.LdapTreeBuilder;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
/**
|
||||
* Default controller.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class DefaultController extends MultiActionController {
|
||||
|
||||
private LdapTreeBuilder ldapTreeBuilder;
|
||||
|
||||
public void setLdapTreeBuilder(LdapTreeBuilder ldapTreeBuilder) {
|
||||
this.ldapTreeBuilder = ldapTreeBuilder;
|
||||
}
|
||||
|
||||
public void setPersonDao(PersonDao personDao) {
|
||||
this.personDao = personDao;
|
||||
}
|
||||
|
||||
private PersonDao personDao;
|
||||
|
||||
public ModelAndView welcomeHandler(HttpServletRequest request, HttpServletResponse response) {
|
||||
return new ModelAndView("welcome");
|
||||
}
|
||||
|
||||
public ModelAndView showTree(HttpServletRequest request, HttpServletResponse response) {
|
||||
LdapTree ldapTree = ldapTreeBuilder.getLdapTree(LdapUtils.emptyLdapName());
|
||||
HtmlRowLdapTreeVisitor visitor = new PersonLinkHtmlRowLdapTreeVisitor();
|
||||
ldapTree.traverse(visitor);
|
||||
return new ModelAndView("showTree", "rows", visitor.getRows());
|
||||
}
|
||||
|
||||
public ModelAndView addPerson(HttpServletRequest request, HttpServletResponse response) {
|
||||
Person person = getPerson();
|
||||
|
||||
personDao.create(person);
|
||||
return showTree(request, response);
|
||||
}
|
||||
|
||||
public ModelAndView updatePhoneNumber(HttpServletRequest request, HttpServletResponse response) {
|
||||
Person person = personDao.findByPrimaryKey("Sweden", "company1", "John Doe");
|
||||
person.setPhone(StringUtils.join(new String[] { person.getPhone(), "0" }));
|
||||
|
||||
personDao.update(person);
|
||||
return showTree(request, response);
|
||||
}
|
||||
|
||||
public ModelAndView removePerson(HttpServletRequest request, HttpServletResponse response) {
|
||||
Person person = getPerson();
|
||||
|
||||
personDao.delete(person);
|
||||
return showTree(request, response);
|
||||
}
|
||||
|
||||
public ModelAndView showPerson(HttpServletRequest request, HttpServletResponse response, Person query) {
|
||||
String country = query.getCountry();
|
||||
String company = query.getCompany();
|
||||
String fullName = query.getFullName();
|
||||
Person person = personDao.findByPrimaryKey(country, company, fullName);
|
||||
return new ModelAndView("showPerson", "person", person);
|
||||
}
|
||||
|
||||
private Person getPerson() {
|
||||
Person person = new Person();
|
||||
person.setFullName("John Doe");
|
||||
person.setLastName("Doe");
|
||||
person.setCompany("company1");
|
||||
person.setCountry("Sweden");
|
||||
person.setDescription("Test user");
|
||||
return person;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates appropriate links for person leaves in the tree.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
private static final class PersonLinkHtmlRowLdapTreeVisitor extends HtmlRowLdapTreeVisitor {
|
||||
@Override
|
||||
protected String getLinkForNode(DirContextOperations node) {
|
||||
String[] objectClassValues = node.getStringAttributes("objectClass");
|
||||
if (containsValue(objectClassValues, "person")) {
|
||||
Name dn = node.getDn();
|
||||
String country = encodeValue(LdapUtils.getStringValue(dn, "c"));
|
||||
String company = encodeValue(LdapUtils.getStringValue(dn, "ou"));
|
||||
String fullName = encodeValue(LdapUtils.getStringValue(dn, "cn"));
|
||||
|
||||
return "showPerson.do?country=" + country + "&company=" + company + "&fullName=" + fullName;
|
||||
}
|
||||
else {
|
||||
return super.getLinkForNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
private String encodeValue(String value) {
|
||||
try {
|
||||
return URLEncoder.encode(value, "UTF8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
// Not supposed to happen
|
||||
throw new RuntimeException("Unexpected encoding exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsValue(String[] values, String value) {
|
||||
for (String oneValue : values) {
|
||||
if (StringUtils.equals(oneValue, value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<body>
|
||||
This document is the API specification for the Spring LDAP Article sample.
|
||||
</body>
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="/WEB-INF/ldap.properties" />
|
||||
</bean>
|
||||
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="/WEB-INF/setup_data.ldif" />
|
||||
<property name="port" value="18881" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTemplate"
|
||||
class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTreeBuilder"
|
||||
class="org.springframework.ldap.samples.utils.LdapTreeBuilder">
|
||||
<constructor-arg ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
<bean id="personDao"
|
||||
class="org.springframework.ldap.samples.article.dao.PersonDaoImpl">
|
||||
<property name="ldapTemplate" ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
<bean id="propsResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
|
||||
<property name="mappings">
|
||||
<value>
|
||||
/welcome.do=welcome
|
||||
/showTree.do=showTree
|
||||
/addPerson.do=addPerson
|
||||
/updatePhoneNumber.do=updatePhoneNumber
|
||||
/removePerson.do=removePerson
|
||||
/showPerson.do=showPerson
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
|
||||
<property name="mappings">
|
||||
<value>
|
||||
/*.do=defaultController
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
<bean id="defaultController"
|
||||
class="org.springframework.ldap.samples.article.web.DefaultController">
|
||||
<property name="ldapTreeBuilder" ref="ldapTreeBuilder"/>
|
||||
<property name="personDao" ref="personDao"/>
|
||||
</bean>
|
||||
<bean
|
||||
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
|
||||
<property name="prefix" value="/WEB-INF/jsp/" />
|
||||
<property name="suffix" value=".jsp" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,4 +0,0 @@
|
||||
urls=ldap://127.0.0.1:18881
|
||||
userDn=uid=admin,ou=system
|
||||
password=secret
|
||||
base=dc=jayway,dc=se
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app id="Tiink-preview" xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||
version="2.4">
|
||||
|
||||
<display-name>Spring LDAP Basic Example</display-name>
|
||||
<listener>
|
||||
<listener-class>
|
||||
org.springframework.web.context.ContextLoaderListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>basic</servlet-name>
|
||||
<servlet-class>
|
||||
org.springframework.web.servlet.DispatcherServlet
|
||||
</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/basic-servlet.xml</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>basic</servlet-name>
|
||||
<url-pattern>*.do</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.htm</welcome-file>
|
||||
</welcome-file-list>
|
||||
</web-app>
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ldap.NameNotFoundException;
|
||||
import org.springframework.ldap.samples.article.dao.PersonDao;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
|
||||
/**
|
||||
* Abstract base class for PersonDao integration tests.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public abstract class AbstractPersonDaoIntegrationTest
|
||||
extends
|
||||
AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
protected Person person;
|
||||
|
||||
protected PersonDao personDao;
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] { "config/testContext.xml" };
|
||||
}
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
super.onSetUp();
|
||||
person = new Person();
|
||||
person.setCountry("Sweden");
|
||||
person.setCompany("company1");
|
||||
person.setFullName("Some Person");
|
||||
person.setLastName("Person");
|
||||
person
|
||||
.setDescription("Sweden, Company1, Some Person");
|
||||
person.setPhone("+46 555-123456");
|
||||
}
|
||||
|
||||
protected void onTearDown() throws Exception {
|
||||
super.onTearDown();
|
||||
person = null;
|
||||
personDao = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Having a single test method test create, update and delete is not exactly
|
||||
* the ideal way of testing, since they depend on each other. A better way
|
||||
* would be to separate the tests and load a test fixture before each
|
||||
* operation, in order to guarantee the expected state every time. See the
|
||||
* ldaptemplate-person sample for the correct way to do this.
|
||||
*/
|
||||
public void testCreateUpdateDelete() {
|
||||
try {
|
||||
person.setFullName("Another Person");
|
||||
personDao.create(person);
|
||||
personDao.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
// if we got here, create succeeded
|
||||
|
||||
person
|
||||
.setDescription("Another description");
|
||||
personDao.update(person);
|
||||
Person result = personDao
|
||||
.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
assertEquals(
|
||||
"Another description", result
|
||||
.getDescription());
|
||||
} finally {
|
||||
personDao.delete(person);
|
||||
try {
|
||||
personDao.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
fail("NameNotFoundException (when using Spring LDAP) or RuntimeException (when using traditional) expected");
|
||||
} catch (NameNotFoundException expected) {
|
||||
// expected
|
||||
} catch (RuntimeException expected) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetAllPersonNames() {
|
||||
List result = personDao.getAllPersonNames();
|
||||
assertEquals(2, result.size());
|
||||
String first = (String) result.get(0);
|
||||
assertEquals("Some Person", first);
|
||||
}
|
||||
|
||||
public void testFindAll() {
|
||||
List result = personDao.findAll();
|
||||
assertEquals(2, result.size());
|
||||
Person first = (Person) result.get(0);
|
||||
assertEquals("Some Person", first
|
||||
.getFullName());
|
||||
}
|
||||
|
||||
public void testFindByPrimaryKey() {
|
||||
Person result = personDao.findByPrimaryKey(
|
||||
"Sweden", "company1", "Some Person");
|
||||
assertEquals(person, result);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import org.springframework.ldap.samples.article.dao.PersonDaoImpl;
|
||||
|
||||
/**
|
||||
* Integration tests for the PersonDaoImpl class.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PersonDaoImplIntegrationTest extends
|
||||
AbstractPersonDaoIntegrationTest {
|
||||
|
||||
public void setPersonDao(
|
||||
PersonDaoImpl personDao) {
|
||||
this.personDao = personDao;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
/**
|
||||
* Integration tests for the TraditionalPersonDaoImpl class.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class TraditionalPersonDaoImplIntegrationTest
|
||||
extends AbstractPersonDaoIntegrationTest {
|
||||
|
||||
public void setPersonDao(
|
||||
TraditionalPersonDaoImpl personDao) {
|
||||
this.personDao = personDao;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
urls=ldap://127.0.0.1:18881
|
||||
userDn=uid=admin,ou=system
|
||||
password=secret
|
||||
base=dc=jayway,dc=se
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="classpath:/config/ldap.properties" />
|
||||
</bean>
|
||||
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="/setup_data.ldif" />
|
||||
<property name="port" value="18881" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="personDao"
|
||||
class="org.springframework.ldap.samples.article.dao.PersonDaoImpl">
|
||||
<property name="ldapTemplate" ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
<bean id="traditionalPersonDao"
|
||||
class="org.springframework.ldap.samples.article.dao.TraditionalPersonDaoImpl">
|
||||
<property name="url" value="ldap://localhost:18881" />
|
||||
<property name="base" value="dc=jayway,dc=se" />
|
||||
<property name="userDn" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
</bean>
|
||||
</beans>
|
||||
4
samples/article-spring30/.gitignore
vendored
4
samples/article-spring30/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
target
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.0.5.v200805211800]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
</configs>
|
||||
<configSets>
|
||||
</configSets>
|
||||
</beansProjectDescription>
|
||||
@@ -1,23 +0,0 @@
|
||||
apply from: JAVA_SCRIPT
|
||||
apply plugin: 'war'
|
||||
apply plugin: 'jetty'
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-ldap-test'),
|
||||
project(':spring-ldap-samples-utils'),
|
||||
'log4j:log4j:1.2.9',
|
||||
'javax.servlet:jstl:1.2',
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-core:$springVersion",
|
||||
"org.springframework:spring-tx:$springVersion",
|
||||
"org.springframework:spring-jdbc:$springVersion",
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"org.springframework:spring-webmvc:$springVersion",
|
||||
"org.springframework:spring-aop:$springVersion"
|
||||
|
||||
provided "javax.servlet:servlet-api:2.5"
|
||||
|
||||
testCompile "org.springframework:spring-test:$springVersion",
|
||||
"junit:junit:$junitVersion"
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
Uses Spring 3.0.
|
||||
Sample application demonstrating how to do the most basic stuff in Spring LDAP.
|
||||
A very simple dao implementation is provided in
|
||||
org.springframework.ldap.samples.article.dao.PersonDaoImpl
|
||||
It demonstrates some basic operations using Spring LDAP. For reference purposes,
|
||||
a corresponding implementation using ordinary Java LDAP/JNDI implementation is
|
||||
available in TraditionalPersonDaoImpl.
|
||||
|
||||
How to use:
|
||||
-----------
|
||||
The project is in a Maven build structure. Make sure you have installed the samples-utils artifact, as this will be
|
||||
needed for this project to work.
|
||||
|
||||
'mvn jetty:run' will start up a web server demonstrating the capabilities. The web application will be available
|
||||
under http://localhost:8080/spring-ldap-person-article-spring30/
|
||||
|
||||
'mvn eclipse:eclipse' will construct an Eclipse project for you to use. Import that project into Eclipse using
|
||||
File/Import/Existing Project, and select this directory.
|
||||
|
||||
'mvn test' will run some integration tests that require the LDAP server to be running. It's recommended to run
|
||||
'mvn jetty:run' from another terminal window before 'mvn test'.
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
|
||||
|
||||
/**
|
||||
* Data Access Object interface for the Person entity.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public interface PersonDao {
|
||||
void create(Person person);
|
||||
|
||||
void update(Person person);
|
||||
|
||||
void delete(Person person);
|
||||
|
||||
List getAllPersonNames();
|
||||
|
||||
List findAll();
|
||||
|
||||
Person findByPrimaryKey(String country,
|
||||
String company, String fullname);
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import org.springframework.ldap.core.AttributesMapper;
|
||||
import org.springframework.ldap.core.ContextMapper;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.LdapTemplate;
|
||||
import org.springframework.ldap.filter.EqualsFilter;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.ldap.support.LdapNameBuilder;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default implementation of PersonDao. This implementation uses
|
||||
* DirContextAdapter for managing attribute values. It has been specified in the
|
||||
* Spring Context that the DirObjectFactory should be used when creating objects
|
||||
* from contexts, which defaults to creating DirContextAdapter objects. This
|
||||
* means that we can use a ContextMapper to map from the found contexts to our
|
||||
* domain objects. This is especially useful since we in this case have
|
||||
* properties in our domain objects that depend on parts of the DN.
|
||||
*
|
||||
* We could have worked with Attributes and an AttributesMapper implementation
|
||||
* instead, but working with Attributes is a bore and also, working with
|
||||
* AttributesMapper objects (or, indeed Attributes) does not give us access to
|
||||
* the distinguished name. However, we do use it in one method that only needs a
|
||||
* single attribute: {@link #getAllPersonNames()}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PersonDaoImpl implements PersonDao {
|
||||
|
||||
private LdapTemplate ldapTemplate;
|
||||
|
||||
/*
|
||||
* @see PersonDao#create(Person)
|
||||
*/
|
||||
public void create(Person person) {
|
||||
Name dn = buildDn(person);
|
||||
DirContextAdapter context = new DirContextAdapter(dn);
|
||||
mapToContext(person, context);
|
||||
ldapTemplate.bind(dn, context, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#update(Person)
|
||||
*/
|
||||
public void update(Person person) {
|
||||
Name dn = buildDn(person);
|
||||
DirContextAdapter context = (DirContextAdapter) ldapTemplate.lookup(dn);
|
||||
mapToContext(person, context);
|
||||
ldapTemplate.modifyAttributes(dn, context.getModificationItems());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#delete(Person)
|
||||
*/
|
||||
public void delete(Person person) {
|
||||
ldapTemplate.unbind(buildDn(person));
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#getAllPersonNames()
|
||||
*/
|
||||
public List getAllPersonNames() {
|
||||
EqualsFilter filter = new EqualsFilter("objectclass", "person");
|
||||
return ldapTemplate.search(LdapUtils.emptyLdapName(), filter.encode(), new AttributesMapper() {
|
||||
public Object mapFromAttributes(Attributes attrs) throws NamingException {
|
||||
return attrs.get("cn").get();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findAll()
|
||||
*/
|
||||
public List findAll() {
|
||||
EqualsFilter filter = new EqualsFilter("objectclass", "person");
|
||||
return ldapTemplate.search(LdapUtils.emptyLdapName(), filter.encode(), getContextMapper());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findByPrimaryKey(java.lang.String, java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Person findByPrimaryKey(String country, String company, String fullname) {
|
||||
Name dn = buildDn(country, company, fullname);
|
||||
return (Person) ldapTemplate.lookup(dn, getContextMapper());
|
||||
}
|
||||
|
||||
private ContextMapper getContextMapper() {
|
||||
return new PersonContextMapper();
|
||||
}
|
||||
|
||||
private Name buildDn(Person person) {
|
||||
return buildDn(person.getCountry(), person.getCompany(), person.getFullName());
|
||||
}
|
||||
|
||||
private Name buildDn(String country, String company, String fullname) {
|
||||
return LdapNameBuilder.newInstance()
|
||||
.add("c", country)
|
||||
.add("ou", company)
|
||||
.add("cn", fullname)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void mapToContext(Person person, DirContextAdapter context) {
|
||||
context.setAttributeValues("objectclass", new String[] { "top", "person" });
|
||||
context.setAttributeValue("cn", person.getFullName());
|
||||
context.setAttributeValue("sn", person.getLastName());
|
||||
context.setAttributeValue("description", person.getDescription());
|
||||
context.setAttributeValue("telephoneNumber", person.getPhone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps from DirContextAdapter to Person objects. A DN for a person will be
|
||||
* of the form <code>cn=[fullname],ou=[company],c=[country]</code>, so
|
||||
* the values of these attributes must be extracted from the DN. For this,
|
||||
* we use LdapName and utility methods in LdapUtils.
|
||||
*
|
||||
*Mattias Hellborg Arthurssonellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
private static class PersonContextMapper implements ContextMapper {
|
||||
|
||||
public Object mapFromContext(Object ctx) {
|
||||
DirContextAdapter context = (DirContextAdapter) ctx;
|
||||
Name dn = context.getDn();
|
||||
Person person = new Person();
|
||||
person.setCountry(LdapUtils.getStringValue(dn, 0));
|
||||
person.setCompany(LdapUtils.getStringValue(dn, 1));
|
||||
person.setFullName(context.getStringAttribute("cn"));
|
||||
person.setLastName(context.getStringAttribute("sn"));
|
||||
person.setDescription(context.getStringAttribute("description"));
|
||||
person.setPhone(context.getStringAttribute("telephoneNumber"));
|
||||
|
||||
return person;
|
||||
}
|
||||
}
|
||||
|
||||
public void setLdapTemplate(LdapTemplate ldapTemplate) {
|
||||
this.ldapTemplate = ldapTemplate;
|
||||
}
|
||||
}
|
||||
@@ -1,377 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.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.samples.article.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 that of {@link PersonDaoImpl}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class TraditionalPersonDaoImpl 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 getAllPersonNames() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 findAll() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 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 env = new Hashtable();
|
||||
return createContext(env);
|
||||
}
|
||||
|
||||
private DirContext createAuthenticatedContext() {
|
||||
Hashtable env = new Hashtable();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.domain;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* Simple class representing a single person.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class Person {
|
||||
private String fullName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String description;
|
||||
|
||||
private String country;
|
||||
|
||||
private String company;
|
||||
|
||||
private String phone;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return EqualsBuilder.reflectionEquals(
|
||||
this, obj);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return HashCodeBuilder
|
||||
.reflectionHashCode(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ToStringBuilder.reflectionToString(
|
||||
this, ToStringStyle.MULTI_LINE_STYLE);
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package org.springframework.ldap.samples.article.web;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.ldap.samples.article.dao.PersonDao;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.ldap.samples.utils.HtmlRowLdapTreeVisitor;
|
||||
import org.springframework.ldap.samples.utils.LdapTree;
|
||||
import org.springframework.ldap.samples.utils.LdapTreeBuilder;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.naming.Name;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
/**
|
||||
* Default controller.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
@Controller
|
||||
public class DefaultController {
|
||||
|
||||
@Autowired
|
||||
private LdapTreeBuilder ldapTreeBuilder;
|
||||
|
||||
@Autowired
|
||||
private PersonDao personDao;
|
||||
|
||||
@RequestMapping("/welcome.do")
|
||||
public void welcomeHandler() {
|
||||
}
|
||||
|
||||
@RequestMapping("/showTree.do")
|
||||
public ModelAndView showTree() {
|
||||
LdapTree ldapTree = ldapTreeBuilder.getLdapTree(LdapUtils.emptyLdapName());
|
||||
HtmlRowLdapTreeVisitor visitor = new PersonLinkHtmlRowLdapTreeVisitor();
|
||||
ldapTree.traverse(visitor);
|
||||
return new ModelAndView("showTree", "rows", visitor.getRows());
|
||||
}
|
||||
|
||||
@RequestMapping("/addPerson.do")
|
||||
public ModelAndView addPerson() {
|
||||
Person person = getPerson();
|
||||
|
||||
personDao.create(person);
|
||||
return showTree();
|
||||
}
|
||||
|
||||
@RequestMapping("/updatePhoneNumber.do")
|
||||
public ModelAndView updatePhoneNumber() {
|
||||
Person person = personDao.findByPrimaryKey("Sweden", "company1", "John Doe");
|
||||
person.setPhone(StringUtils.join(new String[] { person.getPhone(), "0" }));
|
||||
|
||||
personDao.update(person);
|
||||
return showTree();
|
||||
}
|
||||
|
||||
@RequestMapping("/removePerson.do")
|
||||
public ModelAndView removePerson() {
|
||||
Person person = getPerson();
|
||||
|
||||
personDao.delete(person);
|
||||
return showTree();
|
||||
}
|
||||
|
||||
@RequestMapping("/showPerson.do")
|
||||
public ModelMap showPerson(String country, String company, String fullName) {
|
||||
Person person = personDao.findByPrimaryKey(country, company, fullName);
|
||||
return new ModelMap("person", person);
|
||||
}
|
||||
|
||||
private Person getPerson() {
|
||||
Person person = new Person();
|
||||
person.setFullName("John Doe");
|
||||
person.setLastName("Doe");
|
||||
person.setCompany("company1");
|
||||
person.setCountry("Sweden");
|
||||
person.setDescription("Test user");
|
||||
return person;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates appropriate links for person leaves in the tree.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
private static final class PersonLinkHtmlRowLdapTreeVisitor extends HtmlRowLdapTreeVisitor {
|
||||
@Override
|
||||
protected String getLinkForNode(DirContextOperations node) {
|
||||
String[] objectClassValues = node.getStringAttributes("objectClass");
|
||||
if (containsValue(objectClassValues, "person")) {
|
||||
Name dn = node.getDn();
|
||||
String country = encodeValue(LdapUtils.getStringValue(dn, "c"));
|
||||
String company = encodeValue(LdapUtils.getStringValue(dn, "ou"));
|
||||
String fullName = encodeValue(LdapUtils.getStringValue(dn, "cn"));
|
||||
|
||||
return "showPerson.do?country=" + country + "&company=" + company + "&fullName=" + fullName;
|
||||
}
|
||||
else {
|
||||
return super.getLinkForNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
private String encodeValue(String value) {
|
||||
try {
|
||||
return URLEncoder.encode(value, "UTF8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
// Not supposed to happen
|
||||
throw new RuntimeException("Unexpected encoding exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsValue(String[] values, String value) {
|
||||
for (String oneValue : values) {
|
||||
if (StringUtils.equals(oneValue, value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<body>
|
||||
This document is the API specification for the Spring LDAP Article sample.
|
||||
</body>
|
||||
@@ -1,7 +0,0 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
log4j.logger.org.apache.directory=ERROR
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="/WEB-INF/ldap.properties" />
|
||||
</bean>
|
||||
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="/WEB-INF/setup_data.ldif" />
|
||||
<property name="port" value="18882" />
|
||||
</bean>
|
||||
z
|
||||
<bean id="ldapTemplate"
|
||||
class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTreeBuilder"
|
||||
class="org.springframework.ldap.samples.utils.LdapTreeBuilder">
|
||||
<constructor-arg ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
<bean id="personDao"
|
||||
class="org.springframework.ldap.samples.article.dao.PersonDaoImpl">
|
||||
<property name="ldapTemplate" ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -1,20 +0,0 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<html>
|
||||
<body>
|
||||
<a href="showTree.do">Back</a>
|
||||
<p>
|
||||
|
||||
Full name: ${person.fullName}
|
||||
<br>
|
||||
LastName: ${person.lastName}
|
||||
<br>
|
||||
Description: ${person.description}
|
||||
<br>
|
||||
Country: ${person.country}
|
||||
<br>
|
||||
Company: ${person.company}
|
||||
<br>
|
||||
Phone: ${person.phone}
|
||||
<br>
|
||||
</p>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<html>
|
||||
<body>
|
||||
<h2>Operations</h2>
|
||||
<h3>Clicking a link below performs the described operation which will be reflected in the LDAP tree below</h3>
|
||||
<a href="addPerson.do">Add new test person 'John Doe'</a> (only works once)<br>
|
||||
<a href="updatePhoneNumber.do">Add a '0' to the phone number of test person</a> (only works if the person has been created)<br>
|
||||
<a href="removePerson.do">Remove test person</a><br>
|
||||
<p>
|
||||
<h2>Tree contents</h2>
|
||||
<h3>Click a person row to see the attribute values (country and company rows do not have additional info)</h3>
|
||||
<c:forEach var="row" items="${rows}">
|
||||
${row}
|
||||
</c:forEach>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +0,0 @@
|
||||
urls=ldap://127.0.0.1:18882
|
||||
userDn=uid=admin,ou=system
|
||||
password=secret
|
||||
base=dc=jayway,dc=se
|
||||
@@ -1,35 +0,0 @@
|
||||
dn: c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: country
|
||||
c: Sweden
|
||||
description: The country of Sweden
|
||||
|
||||
dn: ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: company1
|
||||
description: First company in Sweden
|
||||
|
||||
dn: cn=Some Person,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person
|
||||
userPassword: password
|
||||
cn: Some Person
|
||||
sn: Person
|
||||
description: Sweden, Company1, Some Person
|
||||
telephoneNumber: +46 555-123456
|
||||
|
||||
dn: cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person2
|
||||
userPassword: password
|
||||
cn: Some Person2
|
||||
sn: Person2
|
||||
description: Sweden, Company1, Some Person2
|
||||
telephoneNumber: +46 555-654321
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app id="Tiink-preview" xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||
version="2.4">
|
||||
|
||||
<display-name>Spring LDAP Basic Example</display-name>
|
||||
<listener>
|
||||
<listener-class>
|
||||
org.springframework.web.context.ContextLoaderListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>basic</servlet-name>
|
||||
<servlet-class>
|
||||
org.springframework.web.servlet.DispatcherServlet
|
||||
</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/basic-servlet.xml</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>basic</servlet-name>
|
||||
<url-pattern>*.do</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.htm</welcome-file>
|
||||
</welcome-file-list>
|
||||
</web-app>
|
||||
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta HTTP-EQUIV="REFRESH" content="0; url=showTree.do">
|
||||
</head>
|
||||
</html>
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ldap.NameNotFoundException;
|
||||
import org.springframework.ldap.samples.article.dao.PersonDao;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
|
||||
/**
|
||||
* Abstract base class for PersonDao integration tests.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public abstract class AbstractPersonDaoIntegrationTest
|
||||
extends
|
||||
AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
protected Person person;
|
||||
|
||||
protected PersonDao personDao;
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] { "config/testContext.xml" };
|
||||
}
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
super.onSetUp();
|
||||
person = new Person();
|
||||
person.setCountry("Sweden");
|
||||
person.setCompany("company1");
|
||||
person.setFullName("Some Person");
|
||||
person.setLastName("Person");
|
||||
person
|
||||
.setDescription("Sweden, Company1, Some Person");
|
||||
person.setPhone("+46 555-123456");
|
||||
}
|
||||
|
||||
protected void onTearDown() throws Exception {
|
||||
super.onTearDown();
|
||||
person = null;
|
||||
personDao = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Having a single test method test create, update and delete is not exactly
|
||||
* the ideal way of testing, since they depend on each other. A better way
|
||||
* would be to separate the tests and load a test fixture before each
|
||||
* operation, in order to guarantee the expected state every time. See the
|
||||
* ldaptemplate-person sample for the correct way to do this.
|
||||
*/
|
||||
public void testCreateUpdateDelete() {
|
||||
try {
|
||||
person.setFullName("Another Person");
|
||||
personDao.create(person);
|
||||
personDao.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
// if we got here, create succeeded
|
||||
|
||||
person
|
||||
.setDescription("Another description");
|
||||
personDao.update(person);
|
||||
Person result = personDao
|
||||
.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
assertEquals(
|
||||
"Another description", result
|
||||
.getDescription());
|
||||
} finally {
|
||||
personDao.delete(person);
|
||||
try {
|
||||
personDao.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
fail("NameNotFoundException (when using Spring LDAP) or RuntimeException (when using traditional) expected");
|
||||
} catch (NameNotFoundException expected) {
|
||||
// expected
|
||||
} catch (RuntimeException expected) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetAllPersonNames() {
|
||||
List result = personDao.getAllPersonNames();
|
||||
assertEquals(2, result.size());
|
||||
String first = (String) result.get(0);
|
||||
assertEquals("Some Person", first);
|
||||
}
|
||||
|
||||
public void testFindAll() {
|
||||
List result = personDao.findAll();
|
||||
assertEquals(2, result.size());
|
||||
Person first = (Person) result.get(0);
|
||||
assertEquals("Some Person", first
|
||||
.getFullName());
|
||||
}
|
||||
|
||||
public void testFindByPrimaryKey() {
|
||||
Person result = personDao.findByPrimaryKey(
|
||||
"Sweden", "company1", "Some Person");
|
||||
assertEquals(person, result);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import org.springframework.ldap.samples.article.dao.PersonDaoImpl;
|
||||
|
||||
/**
|
||||
* Integration tests for the PersonDaoImpl class.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PersonDaoImplIntegrationTest extends
|
||||
AbstractPersonDaoIntegrationTest {
|
||||
|
||||
public void setPersonDao(
|
||||
PersonDaoImpl personDao) {
|
||||
this.personDao = personDao;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
/**
|
||||
* Integration tests for the TraditionalPersonDaoImpl class.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class TraditionalPersonDaoImplIntegrationTest
|
||||
extends AbstractPersonDaoIntegrationTest {
|
||||
|
||||
public void setPersonDao(
|
||||
TraditionalPersonDaoImpl personDao) {
|
||||
this.personDao = personDao;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
urls=ldap://127.0.0.1:18882
|
||||
userDn=uid=admin,ou=system
|
||||
password=secret
|
||||
base=dc=jayway,dc=se
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="classpath:/config/ldap.properties" />
|
||||
</bean>
|
||||
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="/setup_data.ldif" />
|
||||
<property name="port" value="18882" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="personDao"
|
||||
class="org.springframework.ldap.samples.article.dao.PersonDaoImpl">
|
||||
<property name="ldapTemplate" ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
<bean id="traditionalPersonDao"
|
||||
class="org.springframework.ldap.samples.article.dao.TraditionalPersonDaoImpl">
|
||||
<property name="url" value="ldap://localhost:18882" />
|
||||
<property name="base" value="dc=jayway,dc=se" />
|
||||
<property name="userDn" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,35 +0,0 @@
|
||||
dn: c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: country
|
||||
c: Sweden
|
||||
description: The country of Sweden
|
||||
|
||||
dn: ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: company1
|
||||
description: First company in Sweden
|
||||
|
||||
dn: cn=Some Person,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person
|
||||
userPassword: password
|
||||
cn: Some Person
|
||||
sn: Person
|
||||
description: Sweden, Company1, Some Person
|
||||
telephoneNumber: +46 555-123456
|
||||
|
||||
dn: cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person2
|
||||
userPassword: password
|
||||
cn: Some Person2
|
||||
sn: Person2
|
||||
description: Sweden, Company1, Some Person2
|
||||
telephoneNumber: +46 555-654321
|
||||
4
samples/article/.gitignore
vendored
4
samples/article/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
target
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.0.5.v200805211800]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
</configs>
|
||||
<configSets>
|
||||
</configSets>
|
||||
</beansProjectDescription>
|
||||
@@ -1,20 +0,0 @@
|
||||
Sample application demonstrating how to do the most basic stuff in Spring LDAP.
|
||||
A very simple dao implementation is provided in
|
||||
org.springframework.ldap.samples.article.dao.PersonDaoImpl
|
||||
It demonstrates some basic operations using Spring LDAP. For reference purposes,
|
||||
a corresponding implementation using ordinary Java LDAP/JNDI implementation is
|
||||
available in TraditionalPersonDaoImpl.
|
||||
|
||||
How to use:
|
||||
-----------
|
||||
The project is in a Maven build structure. Make sure you have installed the samples-utils artifact, as this will be
|
||||
needed for this project to work.
|
||||
|
||||
'mvn jetty:run' will start up a web server demonstrating the capabilities. The web application will be available
|
||||
under http://localhost:8080/spring-ldap-person-article/
|
||||
|
||||
'mvn eclipse:eclipse' will construct an Eclipse project for you to use. Import that project into Eclipse using
|
||||
File/Import/Existing Project, and select this directory.
|
||||
|
||||
'mvn test' will run some integration tests that require the LDAP server to be running. It's recommended to run
|
||||
'mvn jetty:run' from another terminal window before 'mvn test'.
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
|
||||
|
||||
/**
|
||||
* Data Access Object interface for the Person entity.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public interface PersonDao {
|
||||
void create(Person person);
|
||||
|
||||
void update(Person person);
|
||||
|
||||
void delete(Person person);
|
||||
|
||||
List getAllPersonNames();
|
||||
|
||||
List findAll();
|
||||
|
||||
Person findByPrimaryKey(String country,
|
||||
String company, String fullname);
|
||||
}
|
||||
@@ -1,377 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.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.samples.article.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 that of {@link PersonDaoImpl}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class TraditionalPersonDaoImpl 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 getAllPersonNames() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 findAll() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 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 env = new Hashtable();
|
||||
return createContext(env);
|
||||
}
|
||||
|
||||
private DirContext createAuthenticatedContext() {
|
||||
Hashtable env = new Hashtable();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.domain;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* Simple class representing a single person.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class Person {
|
||||
private String fullName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String description;
|
||||
|
||||
private String country;
|
||||
|
||||
private String company;
|
||||
|
||||
private String phone;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return EqualsBuilder.reflectionEquals(
|
||||
this, obj);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return HashCodeBuilder
|
||||
.reflectionHashCode(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ToStringBuilder.reflectionToString(
|
||||
this, ToStringStyle.MULTI_LINE_STYLE);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<body>
|
||||
This document is the API specification for the Spring LDAP Article sample.
|
||||
</body>
|
||||
@@ -1,7 +0,0 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
log4j.logger.org.apache.directory=ERROR
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="/WEB-INF/ldap.properties" />
|
||||
</bean>
|
||||
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="/WEB-INF/setup_data.ldif" />
|
||||
<property name="port" value="18880" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTemplate"
|
||||
class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTreeBuilder"
|
||||
class="org.springframework.ldap.samples.utils.LdapTreeBuilder">
|
||||
<constructor-arg ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
<bean id="personDao"
|
||||
class="org.springframework.ldap.samples.article.dao.PersonDaoImpl">
|
||||
<property name="ldapTemplate" ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<context:component-scan
|
||||
base-package="org.springframework.ldap.samples.article.web" />
|
||||
|
||||
<bean
|
||||
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
|
||||
|
||||
<property name="prefix" value="/WEB-INF/jsp/" />
|
||||
<property name="suffix" value=".jsp" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,20 +0,0 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<html>
|
||||
<body>
|
||||
<a href="showTree.do">Back</a>
|
||||
<p>
|
||||
|
||||
Full name: ${person.fullName}
|
||||
<br>
|
||||
LastName: ${person.lastName}
|
||||
<br>
|
||||
Description: ${person.description}
|
||||
<br>
|
||||
Country: ${person.country}
|
||||
<br>
|
||||
Company: ${person.company}
|
||||
<br>
|
||||
Phone: ${person.phone}
|
||||
<br>
|
||||
</p>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<html>
|
||||
<body>
|
||||
<h2>Operations</h2>
|
||||
<h3>Clicking a link below performs the described operation which will be reflected in the LDAP tree below</h3>
|
||||
<a href="addPerson.do">Add new test person 'John Doe'</a> (only works once)<br>
|
||||
<a href="updatePhoneNumber.do">Add a '0' to the phone number of test person</a> (only works if the person has been created)<br>
|
||||
<a href="removePerson.do">Remove test person</a><br>
|
||||
<p>
|
||||
<h2>Tree contents</h2>
|
||||
<h3>Click a person row to see the attribute values (country and company rows do not have additional info)</h3>
|
||||
<c:forEach var="row" items="${rows}">
|
||||
${row}
|
||||
</c:forEach>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,35 +0,0 @@
|
||||
dn: c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: country
|
||||
c: Sweden
|
||||
description: The country of Sweden
|
||||
|
||||
dn: ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: company1
|
||||
description: First company in Sweden
|
||||
|
||||
dn: cn=Some Person,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person
|
||||
userPassword: password
|
||||
cn: Some Person
|
||||
sn: Person
|
||||
description: Sweden, Company1, Some Person
|
||||
telephoneNumber: +46 555-123456
|
||||
|
||||
dn: cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person2
|
||||
userPassword: password
|
||||
cn: Some Person2
|
||||
sn: Person2
|
||||
description: Sweden, Company1, Some Person2
|
||||
telephoneNumber: +46 555-654321
|
||||
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta HTTP-EQUIV="REFRESH" content="0; url=showTree.do">
|
||||
</head>
|
||||
</html>
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ldap.NameNotFoundException;
|
||||
import org.springframework.ldap.samples.article.dao.PersonDao;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
|
||||
/**
|
||||
* Abstract base class for PersonDao integration tests.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public abstract class AbstractPersonDaoIntegrationTest
|
||||
extends
|
||||
AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
protected Person person;
|
||||
|
||||
protected PersonDao personDao;
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] { "config/testContext.xml" };
|
||||
}
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
super.onSetUp();
|
||||
person = new Person();
|
||||
person.setCountry("Sweden");
|
||||
person.setCompany("company1");
|
||||
person.setFullName("Some Person");
|
||||
person.setLastName("Person");
|
||||
person
|
||||
.setDescription("Sweden, Company1, Some Person");
|
||||
person.setPhone("+46 555-123456");
|
||||
}
|
||||
|
||||
protected void onTearDown() throws Exception {
|
||||
super.onTearDown();
|
||||
person = null;
|
||||
personDao = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Having a single test method test create, update and delete is not exactly
|
||||
* the ideal way of testing, since they depend on each other. A better way
|
||||
* would be to separate the tests and load a test fixture before each
|
||||
* operation, in order to guarantee the expected state every time. See the
|
||||
* ldaptemplate-person sample for the correct way to do this.
|
||||
*/
|
||||
public void testCreateUpdateDelete() {
|
||||
try {
|
||||
person.setFullName("Another Person");
|
||||
personDao.create(person);
|
||||
personDao.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
// if we got here, create succeeded
|
||||
|
||||
person
|
||||
.setDescription("Another description");
|
||||
personDao.update(person);
|
||||
Person result = personDao
|
||||
.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
assertEquals(
|
||||
"Another description", result
|
||||
.getDescription());
|
||||
} finally {
|
||||
personDao.delete(person);
|
||||
try {
|
||||
personDao.findByPrimaryKey(
|
||||
"Sweden", "company1",
|
||||
"Another Person");
|
||||
fail("NameNotFoundException (when using Spring LDAP) or RuntimeException (when using traditional) expected");
|
||||
} catch (NameNotFoundException expected) {
|
||||
// expected
|
||||
} catch (RuntimeException expected) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetAllPersonNames() {
|
||||
List result = personDao.getAllPersonNames();
|
||||
assertEquals(2, result.size());
|
||||
String first = (String) result.get(0);
|
||||
assertEquals("Some Person", first);
|
||||
}
|
||||
|
||||
public void testFindAll() {
|
||||
List result = personDao.findAll();
|
||||
assertEquals(2, result.size());
|
||||
Person first = (Person) result.get(0);
|
||||
assertEquals("Some Person", first
|
||||
.getFullName());
|
||||
}
|
||||
|
||||
public void testFindByPrimaryKey() {
|
||||
Person result = personDao.findByPrimaryKey(
|
||||
"Sweden", "company1", "Some Person");
|
||||
assertEquals(person, result);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
import org.springframework.ldap.samples.article.dao.PersonDaoImpl;
|
||||
|
||||
/**
|
||||
* Integration tests for the PersonDaoImpl class.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PersonDaoImplIntegrationTest extends
|
||||
AbstractPersonDaoIntegrationTest {
|
||||
|
||||
public void setPersonDao(
|
||||
PersonDaoImpl personDao) {
|
||||
this.personDao = personDao;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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.samples.article.dao;
|
||||
|
||||
/**
|
||||
* Integration tests for the TraditionalPersonDaoImpl class.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class TraditionalPersonDaoImplIntegrationTest
|
||||
extends AbstractPersonDaoIntegrationTest {
|
||||
|
||||
public void setPersonDao(
|
||||
TraditionalPersonDaoImpl personDao) {
|
||||
this.personDao = personDao;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
dn: c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: country
|
||||
c: Sweden
|
||||
description: The country of Sweden
|
||||
|
||||
dn: ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: company1
|
||||
description: First company in Sweden
|
||||
|
||||
dn: cn=Some Person,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person
|
||||
userPassword: password
|
||||
cn: Some Person
|
||||
sn: Person
|
||||
description: Sweden, Company1, Some Person
|
||||
telephoneNumber: +46 555-123456
|
||||
|
||||
dn: cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person2
|
||||
userPassword: password
|
||||
cn: Some Person2
|
||||
sn: Person2
|
||||
description: Sweden, Company1, Some Person2
|
||||
telephoneNumber: +46 555-654321
|
||||
4
samples/demos/demo-tiger/.gitignore
vendored
4
samples/demos/demo-tiger/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
target
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.0.6.v200806241357]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
<config>src/test/resources/config/testContext.xml</config>
|
||||
</configs>
|
||||
<configSets>
|
||||
<configSet>
|
||||
<name><![CDATA[web]]></name>
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
<incomplete>false</incomplete>
|
||||
<configs>
|
||||
</configs>
|
||||
</configSet>
|
||||
</configSets>
|
||||
</beansProjectDescription>
|
||||
@@ -1,12 +0,0 @@
|
||||
apply from: JAVA_SCRIPT
|
||||
|
||||
description = "Example code for demonstrating the process of refactoring from plain JNDI to Spring LDAP (Java 5)."
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-ldap-test'),
|
||||
project(':spring-ldap-core-tiger'),
|
||||
"org.springframework:spring-context:$springVersion"
|
||||
|
||||
testCompile "org.springframework:spring-test:$springVersion",
|
||||
"junit:junit:$junitVersion"
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
Demo application to be used for demonstrating how to convert a legacy JNDI-based
|
||||
dao implementation written in Java 1.4 to instead use Spring LDAP. For reference
|
||||
purposes, a corresponding implementation using ordinary Java LDAP/JNDI
|
||||
implementation is available in TraditionalPersonDaoImpl.
|
||||
|
||||
How to use:
|
||||
-----------
|
||||
'mvn test' will start up an LDAP server before running the integration tests that
|
||||
verify the dao implementation.
|
||||
|
||||
'mvn eclipse:eclipse' will construct an Eclipse project for you to use. Import
|
||||
that project into Eclipse using File/Import/Existing Project, and select this
|
||||
directory.
|
||||
|
||||
You can start converting the org.springframework.ldap.demo.dao.PersonDaoImpl class.
|
||||
The original traditional implementation, as well as a "solution", is available in
|
||||
the org.springframework.ldap.demo.solution package. Run the tests after you have
|
||||
converted a method.
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.List;
|
||||
|
||||
import org.springframework.ldap.demo.domain.Person;
|
||||
|
||||
/**
|
||||
* Data Access Object interface for the Person entity.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public interface PersonDao {
|
||||
void create(Person person);
|
||||
|
||||
void update(Person person);
|
||||
|
||||
void delete(Person person);
|
||||
|
||||
List<String> getAllPersonNames();
|
||||
|
||||
List<Person> findAll();
|
||||
|
||||
Person findByPrimaryKey(String country, String company, String fullname);
|
||||
}
|
||||
@@ -1,344 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* 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.domain;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringStyle;
|
||||
|
||||
/**
|
||||
* Simple class representing a single person.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class Person {
|
||||
private String fullName;
|
||||
|
||||
private String lastName;
|
||||
|
||||
private String description;
|
||||
|
||||
private String country;
|
||||
|
||||
private String company;
|
||||
|
||||
private String phone;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return EqualsBuilder.reflectionEquals(
|
||||
this, obj);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return HashCodeBuilder
|
||||
.reflectionHashCode(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ToStringBuilder.reflectionToString(
|
||||
this, ToStringStyle.MULTI_LINE_STYLE);
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* 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.solution;
|
||||
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.ldap.core.simple.AbstractParameterizedContextMapper;
|
||||
import org.springframework.ldap.core.simple.SimpleLdapTemplate;
|
||||
import org.springframework.ldap.demo.dao.PersonDao;
|
||||
import org.springframework.ldap.demo.domain.Person;
|
||||
import org.springframework.ldap.support.LdapNameBuilder;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
|
||||
import javax.naming.Name;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Spring LDAP implementation of PersonDao. This implementation uses many Spring
|
||||
* LDAP features, such as the {@link DirContextAdapter},
|
||||
* {@link AbstractParameterizedContextMapper}, and {@link SimpleLdapTemplate}. The purpose is to
|
||||
* contrast this implementation with that of {@link TraditionalPersonDaoImpl}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PersonDaoImpl implements PersonDao {
|
||||
|
||||
private static final class PersonContextMapper extends
|
||||
AbstractParameterizedContextMapper<Person> {
|
||||
@Override
|
||||
protected Person doMapFromContext(DirContextOperations ctx) {
|
||||
Person person = new Person();
|
||||
person.setFullName(ctx.getStringAttribute("cn"));
|
||||
person.setLastName(ctx.getStringAttribute("sn"));
|
||||
person.setDescription(ctx.getStringAttribute("description"));
|
||||
person.setPhone(ctx.getStringAttribute("telephoneNumber"));
|
||||
|
||||
Name dn = ctx.getDn();
|
||||
person.setCountry(LdapUtils.getStringValue(dn, "c"));
|
||||
person.setCompany(LdapUtils.getStringValue(dn, "ou"));
|
||||
return person;
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleLdapTemplate ldapTemplate;
|
||||
|
||||
public void setLdapTemplate(SimpleLdapTemplate ldapTemplate) {
|
||||
this.ldapTemplate = ldapTemplate;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#create(Person)
|
||||
*/
|
||||
public void create(Person person) {
|
||||
DirContextOperations ctx = new DirContextAdapter(buildDn(person));
|
||||
mapToContext(person, ctx);
|
||||
ldapTemplate.bind(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#update(Person)
|
||||
*/
|
||||
public void update(Person person) {
|
||||
DirContextOperations ctx = ldapTemplate.lookupContext(buildDn(person));
|
||||
mapToContext(person, ctx);
|
||||
ldapTemplate.modifyAttributes(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#delete(Person)
|
||||
*/
|
||||
public void delete(Person person) {
|
||||
ldapTemplate.unbind(buildDn(person));
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#getAllPersonNames()
|
||||
*/
|
||||
public List<String> getAllPersonNames() {
|
||||
return ldapTemplate.search("", "(objectclass=person)",
|
||||
new AbstractParameterizedContextMapper<String>() {
|
||||
@Override
|
||||
protected String doMapFromContext(DirContextOperations ctx) {
|
||||
return ctx.getStringAttribute("cn");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findAll()
|
||||
*/
|
||||
public List<Person> findAll() {
|
||||
return ldapTemplate.search("", "(objectclass=person)",
|
||||
new PersonContextMapper());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findByPrimaryKey(java.lang.String, java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Person findByPrimaryKey(String country, String company,
|
||||
String fullname) {
|
||||
Name dn = buildDn(country, company, fullname);
|
||||
return (Person) ldapTemplate.lookup(dn, new PersonContextMapper());
|
||||
}
|
||||
|
||||
private Name buildDn(Person person) {
|
||||
return buildDn(person.getCountry(), person.getCompany(), person
|
||||
.getFullName());
|
||||
}
|
||||
|
||||
private Name buildDn(String country, String company, String fullname) {
|
||||
return LdapNameBuilder.newInstance()
|
||||
.add("c", country)
|
||||
.add("ou", company)
|
||||
.add("cn", fullname)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void mapToContext(Person person, DirContextOperations ctx) {
|
||||
ctx.setAttributeValues("objectclass", new String[] { "top", "person" });
|
||||
ctx.setAttributeValue("cn", person.getFullName());
|
||||
ctx.setAttributeValue("sn", person.getLastName());
|
||||
ctx.setAttributeValue("description", person.getDescription());
|
||||
ctx.setAttributeValue("telephoneNumber", person.getPhone());
|
||||
}
|
||||
}
|
||||
@@ -1,344 +0,0 @@
|
||||
/*
|
||||
* 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.solution;
|
||||
|
||||
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 TraditionalPersonDaoImpl 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;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<body>
|
||||
This document is the API specification for the Spring LDAP Article sample.
|
||||
</body>
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* 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 static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.ldap.NameNotFoundException;
|
||||
import org.springframework.ldap.demo.domain.Person;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
|
||||
/**
|
||||
* Integration tests for the PersonDao class.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
@ContextConfiguration(locations = { "/config/testContext.xml" })
|
||||
public class PersonDaoIntegrationTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
private Person person;
|
||||
|
||||
@Autowired
|
||||
private PersonDao personDao;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
person = new Person();
|
||||
person.setCountry("Sweden");
|
||||
person.setCompany("company1");
|
||||
person.setFullName("Some Person");
|
||||
person.setLastName("Person");
|
||||
person.setDescription("Sweden, Company1, Some Person");
|
||||
person.setPhone("+46 555-123456");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
person = null;
|
||||
personDao = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Having a single test method test create, update and delete is not exactly
|
||||
* the ideal way of testing, since they depend on each other. A better way
|
||||
* would be to separate the tests and load a test fixture before each
|
||||
* operation, in order to guarantee the expected state every time.
|
||||
*/
|
||||
@Test
|
||||
public void testCreateUpdateDelete() {
|
||||
try {
|
||||
person.setFullName("Another Person");
|
||||
personDao.create(person);
|
||||
personDao.findByPrimaryKey("Sweden", "company1", "Another Person");
|
||||
// if we got here, create succeeded
|
||||
|
||||
person.setDescription("Another description");
|
||||
personDao.update(person);
|
||||
Person result = personDao.findByPrimaryKey("Sweden", "company1",
|
||||
"Another Person");
|
||||
assertEquals("Another description", result.getDescription());
|
||||
} finally {
|
||||
personDao.delete(person);
|
||||
try {
|
||||
personDao.findByPrimaryKey("Sweden", "company1",
|
||||
"Another Person");
|
||||
fail("NameNotFoundException (when using Spring LDAP) or RuntimeException (when using traditional) expected");
|
||||
} catch (NameNotFoundException expected) {
|
||||
// expected
|
||||
} catch (RuntimeException expected) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllPersonNames() {
|
||||
List<String> result = personDao.getAllPersonNames();
|
||||
assertEquals(2, result.size());
|
||||
String first = (String) result.get(0);
|
||||
assertEquals("Some Person", first);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindAll() {
|
||||
List<Person> result = personDao.findAll();
|
||||
assertEquals(2, result.size());
|
||||
Person first = (Person) result.get(0);
|
||||
assertEquals("Some Person", first.getFullName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindByPrimaryKey() {
|
||||
Person result = personDao.findByPrimaryKey("Sweden", "company1",
|
||||
"Some Person");
|
||||
assertEquals(person, result);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
urls=ldap://127.0.0.1:18884
|
||||
userDn=uid=admin,ou=system
|
||||
password=secret
|
||||
base=dc=jayway,dc=se
|
||||
@@ -1,35 +0,0 @@
|
||||
dn: c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: country
|
||||
c: Sweden
|
||||
description: The country of Sweden
|
||||
|
||||
dn: ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: company1
|
||||
description: First company in Sweden
|
||||
|
||||
dn: cn=Some Person,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person
|
||||
userPassword: password
|
||||
cn: Some Person
|
||||
sn: Person
|
||||
description: Sweden, Company1, Some Person
|
||||
telephoneNumber: +46 555-123456
|
||||
|
||||
dn: cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person2
|
||||
userPassword: password
|
||||
cn: Some Person2
|
||||
sn: Person2
|
||||
description: Sweden, Company1, Some Person2
|
||||
telephoneNumber: +46 555-654321
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="classpath:/config/ldap.properties" />
|
||||
</bean>
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="/config/setup_data.ldif" />
|
||||
<property name="port" value="18884" />
|
||||
</bean>
|
||||
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
<bean id="personDao" class="org.springframework.ldap.demo.dao.PersonDaoImpl">
|
||||
<property name="base" value="dc=jayway,dc=se" />
|
||||
<property name="url" value="ldap://localhost:18884" />
|
||||
<property name="userDn" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,7 +0,0 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
log4j.logger.org.apache.directory=ERROR
|
||||
4
samples/demos/demo/.gitignore
vendored
4
samples/demos/demo/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
target
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.0.6.v200806241357]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
<config>src/test/resources/config/testContext.xml</config>
|
||||
</configs>
|
||||
<configSets>
|
||||
<configSet>
|
||||
<name><![CDATA[web]]></name>
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
<incomplete>false</incomplete>
|
||||
<configs>
|
||||
</configs>
|
||||
</configSet>
|
||||
</configSets>
|
||||
</beansProjectDescription>
|
||||
@@ -1,12 +0,0 @@
|
||||
apply from: JAVA_SCRIPT
|
||||
|
||||
description = "Example code for demonstrating the process of refactoring from plain JNDI to Spring LDAP (Java 1.4)."
|
||||
|
||||
dependencies {
|
||||
compile project(':spring-ldap-test'),
|
||||
project(':spring-ldap-core'),
|
||||
"org.springframework:spring-context:$springVersion"
|
||||
|
||||
testCompile "org.springframework:spring-test:$springVersion",
|
||||
"junit:junit:$junitVersion"
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
Demo application to be used for demonstrating how to convert a legacy JNDI-based
|
||||
dao implementation written in Java 1.4 to use Spring LDAP, focussing on the Java5
|
||||
support in Spring LDAP. For reference purposes, a corresponding implementation
|
||||
using ordinary Java LDAP/JNDI implementation is available in TraditionalPersonDaoImpl.
|
||||
|
||||
How to use:
|
||||
-----------
|
||||
'mvn test' will start up an LDAP server before running the integration tests that
|
||||
verify the dao implementation.
|
||||
|
||||
'mvn eclipse:eclipse' will construct an Eclipse project for you to use. Import
|
||||
that project into Eclipse using File/Import/Existing Project, and select this
|
||||
directory.
|
||||
|
||||
You can start converting the org.springframework.ldap.demo.dao.PersonDaoImpl class.
|
||||
The original traditional implementation, as well as a "solution", is available in
|
||||
the org.springframework.ldap.demo.solution package. Run the tests after you have
|
||||
converted a method.
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.List;
|
||||
|
||||
import org.springframework.ldap.demo.domain.Person;
|
||||
|
||||
/**
|
||||
* Data Access Object interface for the Person entity.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public interface PersonDao {
|
||||
void create(Person person);
|
||||
|
||||
void update(Person person);
|
||||
|
||||
void delete(Person person);
|
||||
|
||||
List getAllPersonNames();
|
||||
|
||||
List findAll();
|
||||
|
||||
Person findByPrimaryKey(String country, String company, String fullname);
|
||||
}
|
||||
@@ -1,343 +0,0 @@
|
||||
/*
|
||||
* 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.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 getAllPersonNames() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 findAll() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 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 hashtable = new Hashtable();
|
||||
Hashtable env = hashtable;
|
||||
return createContext(env);
|
||||
}
|
||||
|
||||
private DirContext createAuthenticatedContext() {
|
||||
Hashtable env = new Hashtable();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* 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.solution;
|
||||
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.ldap.core.LdapTemplate;
|
||||
import org.springframework.ldap.core.support.AbstractContextMapper;
|
||||
import org.springframework.ldap.demo.dao.PersonDao;
|
||||
import org.springframework.ldap.demo.domain.Person;
|
||||
import org.springframework.ldap.support.LdapNameBuilder;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
|
||||
import javax.naming.Name;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Spring LDAP implementation of PersonDao. This implementation uses many Spring
|
||||
* LDAP features, such as the {@link DirContextAdapter},
|
||||
* {@link AbstractContextMapper}, and {@link LdapTemplate}. The purpose is to
|
||||
* contrast this implementation with that of {@link TraditionalPersonDaoImpl}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PersonDaoImpl implements PersonDao {
|
||||
|
||||
private static final class PersonContextMapper extends
|
||||
AbstractContextMapper {
|
||||
protected Object doMapFromContext(DirContextOperations ctx) {
|
||||
Person person = new Person();
|
||||
person.setFullName(ctx.getStringAttribute("cn"));
|
||||
person.setLastName(ctx.getStringAttribute("sn"));
|
||||
person.setDescription(ctx.getStringAttribute("description"));
|
||||
person.setPhone(ctx.getStringAttribute("telephoneNumber"));
|
||||
|
||||
Name dn = ctx.getDn();
|
||||
person.setCountry(LdapUtils.getStringValue(dn, "c"));
|
||||
person.setCompany(LdapUtils.getStringValue(dn, "ou"));
|
||||
return person;
|
||||
}
|
||||
}
|
||||
|
||||
private LdapTemplate ldapTemplate;
|
||||
|
||||
public void setLdapTemplate(LdapTemplate ldapTemplate) {
|
||||
this.ldapTemplate = ldapTemplate;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#create(Person)
|
||||
*/
|
||||
public void create(Person person) {
|
||||
DirContextOperations ctx = new DirContextAdapter(buildDn(person));
|
||||
mapToContext(person, ctx);
|
||||
ldapTemplate.bind(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#update(Person)
|
||||
*/
|
||||
public void update(Person person) {
|
||||
DirContextOperations ctx = ldapTemplate.lookupContext(buildDn(person));
|
||||
mapToContext(person, ctx);
|
||||
ldapTemplate.modifyAttributes(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#delete(Person)
|
||||
*/
|
||||
public void delete(Person person) {
|
||||
ldapTemplate.unbind(buildDn(person));
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#getAllPersonNames()
|
||||
*/
|
||||
public List getAllPersonNames() {
|
||||
return ldapTemplate.search("", "(objectclass=person)",
|
||||
new AbstractContextMapper() {
|
||||
protected Object doMapFromContext(DirContextOperations ctx) {
|
||||
return ctx.getStringAttribute("cn");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findAll()
|
||||
*/
|
||||
public List findAll() {
|
||||
return ldapTemplate.search("", "(objectclass=person)",
|
||||
new PersonContextMapper());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findByPrimaryKey(java.lang.String, java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
public Person findByPrimaryKey(String country, String company,
|
||||
String fullname) {
|
||||
Name dn = buildDn(country, company, fullname);
|
||||
return (Person) ldapTemplate.lookup(dn, new PersonContextMapper());
|
||||
}
|
||||
|
||||
private Name buildDn(Person person) {
|
||||
return buildDn(person.getCountry(), person.getCompany(), person
|
||||
.getFullName());
|
||||
}
|
||||
|
||||
private Name buildDn(String country, String company, String fullname) {
|
||||
return LdapNameBuilder.newInstance()
|
||||
.add("c", country)
|
||||
.add("ou", company)
|
||||
.add("cn", fullname)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void mapToContext(Person person, DirContextOperations ctx) {
|
||||
ctx.setAttributeValues("objectclass", new String[] { "top", "person" });
|
||||
ctx.setAttributeValue("cn", person.getFullName());
|
||||
ctx.setAttributeValue("sn", person.getLastName());
|
||||
ctx.setAttributeValue("description", person.getDescription());
|
||||
ctx.setAttributeValue("telephoneNumber", person.getPhone());
|
||||
}
|
||||
}
|
||||
@@ -1,344 +0,0 @@
|
||||
/*
|
||||
* 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.solution;
|
||||
|
||||
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 TraditionalPersonDaoImpl 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 getAllPersonNames() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 findAll() {
|
||||
DirContext ctx = createAnonymousContext();
|
||||
|
||||
LinkedList list = new LinkedList();
|
||||
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 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 hashtable = new Hashtable();
|
||||
Hashtable env = hashtable;
|
||||
return createContext(env);
|
||||
}
|
||||
|
||||
private DirContext createAuthenticatedContext() {
|
||||
Hashtable env = new Hashtable();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="classpath:/config/ldap.properties" />
|
||||
</bean>
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="/config/setup_data.ldif" />
|
||||
<property name="port" value="18883" />
|
||||
</bean>
|
||||
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
<bean id="personDao" class="org.springframework.ldap.demo.dao.PersonDaoImpl">
|
||||
<property name="url" value="ldap://127.0.0.1:18883" />
|
||||
<property name="base" value="dc=jayway,dc=se" />
|
||||
<property name="userDn" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,3 +0,0 @@
|
||||
<body>
|
||||
This document is the API specification for the Spring LDAP Article sample.
|
||||
</body>
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* 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.List;
|
||||
|
||||
import org.springframework.ldap.NameNotFoundException;
|
||||
import org.springframework.ldap.demo.domain.Person;
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
|
||||
/**
|
||||
* Integration tests for the PersonDao class.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PersonDaoIntegrationTest extends
|
||||
AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
private Person person;
|
||||
|
||||
private PersonDao personDao;
|
||||
|
||||
public void setPersonDao(PersonDao personDao) {
|
||||
this.personDao = personDao;
|
||||
}
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] { "/config/testContext.xml" };
|
||||
}
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
super.onSetUp();
|
||||
person = new Person();
|
||||
person.setCountry("Sweden");
|
||||
person.setCompany("company1");
|
||||
person.setFullName("Some Person");
|
||||
person.setLastName("Person");
|
||||
person.setDescription("Sweden, Company1, Some Person");
|
||||
person.setPhone("+46 555-123456");
|
||||
}
|
||||
|
||||
protected void onTearDown() throws Exception {
|
||||
super.onTearDown();
|
||||
person = null;
|
||||
personDao = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Having a single test method test create, update and delete is not exactly
|
||||
* the ideal way of testing, since they depend on each other. A better way
|
||||
* would be to separate the tests and load a test fixture before each
|
||||
* operation, in order to guarantee the expected state every time.
|
||||
*/
|
||||
public void testCreateUpdateDelete() {
|
||||
try {
|
||||
person.setFullName("Another Person");
|
||||
personDao.create(person);
|
||||
personDao.findByPrimaryKey("Sweden", "company1", "Another Person");
|
||||
// if we got here, create succeeded
|
||||
|
||||
person.setDescription("Another description");
|
||||
personDao.update(person);
|
||||
Person result = personDao.findByPrimaryKey("Sweden", "company1",
|
||||
"Another Person");
|
||||
assertEquals("Another description", result.getDescription());
|
||||
} finally {
|
||||
personDao.delete(person);
|
||||
try {
|
||||
personDao.findByPrimaryKey("Sweden", "company1",
|
||||
"Another Person");
|
||||
fail("NameNotFoundException (when using Spring LDAP) or RuntimeException (when using traditional) expected");
|
||||
} catch (NameNotFoundException expected) {
|
||||
// expected
|
||||
} catch (RuntimeException expected) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetAllPersonNames() {
|
||||
List result = personDao.getAllPersonNames();
|
||||
assertEquals(2, result.size());
|
||||
String first = (String) result.get(0);
|
||||
assertEquals("Some Person", first);
|
||||
}
|
||||
|
||||
public void testFindAll() {
|
||||
List result = personDao.findAll();
|
||||
assertEquals(2, result.size());
|
||||
Person first = (Person) result.get(0);
|
||||
assertEquals("Some Person", first.getFullName());
|
||||
}
|
||||
|
||||
public void testFindByPrimaryKey() {
|
||||
Person result = personDao.findByPrimaryKey("Sweden", "company1",
|
||||
"Some Person");
|
||||
assertEquals(person, result);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
urls=ldap://127.0.0.1:18883
|
||||
userDn=uid=admin,ou=system
|
||||
password=secret
|
||||
base=dc=jayway,dc=se
|
||||
@@ -1,35 +0,0 @@
|
||||
dn: c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: country
|
||||
c: Sweden
|
||||
description: The country of Sweden
|
||||
|
||||
dn: ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: organizationalUnit
|
||||
ou: company1
|
||||
description: First company in Sweden
|
||||
|
||||
dn: cn=Some Person,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person
|
||||
userPassword: password
|
||||
cn: Some Person
|
||||
sn: Person
|
||||
description: Sweden, Company1, Some Person
|
||||
telephoneNumber: +46 555-123456
|
||||
|
||||
dn: cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: inetOrgPerson
|
||||
uid: some.person2
|
||||
userPassword: password
|
||||
cn: Some Person2
|
||||
sn: Person2
|
||||
description: Sweden, Company1, Some Person2
|
||||
telephoneNumber: +46 555-654321
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
<bean id="placeholderConfig"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="location" value="classpath:/config/ldap.properties" />
|
||||
</bean>
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="/config/setup_data.ldif" />
|
||||
<property name="port" value="18883" />
|
||||
</bean>
|
||||
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
<bean id="personDao" class="org.springframework.ldap.demo.dao.PersonDaoImpl">
|
||||
<property name="base" value="dc=jayway,dc=se" />
|
||||
<property name="url" value="ldap://localhost:18883" />
|
||||
<property name="userDn" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,7 +0,0 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
log4j.logger.org.apache.directory=ERROR
|
||||
@@ -1 +0,0 @@
|
||||
Demo applications for demonstrating conversion of legacy JNDI to Spring LDAP.
|
||||
9
samples/plain/readme.txt
Normal file
9
samples/plain/readme.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Sample application demonstrating how to do the most basic stuff in Spring LDAP.
|
||||
A very simple dao implementation is provided in org.springframework.ldap.samples.plain.dao.PersonDaoImpl
|
||||
It demonstrates some basic operations using Spring LDAP.
|
||||
|
||||
The core Spring application context of the sample is defined in resources/applicationContext.xml.
|
||||
This ApplicationContext will start an in-process Apache Directory Server instance, automatically populated
|
||||
with some test data. The data will be reset every time the application is restarted.
|
||||
|
||||
To run the example, do 'gradle jettyRun', and then navigate to http://localhost:8080/spring-ldap-plain-sample
|
||||
@@ -13,12 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ldap.samples.article.dao;
|
||||
package org.springframework.ldap.samples.plain.dao;
|
||||
|
||||
import org.springframework.ldap.samples.plain.domain.Person;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
|
||||
|
||||
/**
|
||||
* Data Access Object interface for the Person entity.
|
||||
@@ -33,10 +33,9 @@ public interface PersonDao {
|
||||
|
||||
void delete(Person person);
|
||||
|
||||
List getAllPersonNames();
|
||||
List<String> getAllPersonNames();
|
||||
|
||||
List findAll();
|
||||
List<Person> findAll();
|
||||
|
||||
Person findByPrimaryKey(String country,
|
||||
String company, String fullname);
|
||||
Person findByPrimaryKey(String country, String company, String fullname);
|
||||
}
|
||||
@@ -13,14 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ldap.samples.article.dao;
|
||||
package org.springframework.ldap.samples.plain.dao;
|
||||
|
||||
import org.springframework.ldap.core.AttributesMapper;
|
||||
import org.springframework.ldap.core.ContextMapper;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.ldap.core.LdapTemplate;
|
||||
import org.springframework.ldap.core.support.AbstractContextMapper;
|
||||
import org.springframework.ldap.filter.EqualsFilter;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.ldap.samples.plain.domain.Person;
|
||||
import org.springframework.ldap.support.LdapNameBuilder;
|
||||
import org.springframework.ldap.support.LdapUtils;
|
||||
|
||||
@@ -32,12 +34,9 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Default implementation of PersonDao. This implementation uses
|
||||
* DirContextAdapter for managing attribute values. It has been specified in the
|
||||
* Spring Context that the DirObjectFactory should be used when creating objects
|
||||
* from contexts, which defaults to creating DirContextAdapter objects. This
|
||||
* means that we can use a ContextMapper to map from the found contexts to our
|
||||
* domain objects. This is especially useful since we in this case have
|
||||
* properties in our domain objects that depend on parts of the DN.
|
||||
* DirContextAdapter for managing attribute values. We use a ContextMapper
|
||||
* to map from the found contexts to our domain objects. This is especially useful
|
||||
* since we in this case have properties in our domain objects that depend on parts of the DN.
|
||||
*
|
||||
* We could have worked with Attributes and an AttributesMapper implementation
|
||||
* instead, but working with Attributes is a bore and also, working with
|
||||
@@ -52,9 +51,7 @@ public class PersonDaoImpl implements PersonDao {
|
||||
|
||||
private LdapTemplate ldapTemplate;
|
||||
|
||||
/*
|
||||
* @see PersonDao#create(Person)
|
||||
*/
|
||||
@Override
|
||||
public void create(Person person) {
|
||||
Name dn = buildDn(person);
|
||||
DirContextAdapter context = new DirContextAdapter(dn);
|
||||
@@ -62,9 +59,7 @@ public class PersonDaoImpl implements PersonDao {
|
||||
ldapTemplate.bind(dn, context, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#update(Person)
|
||||
*/
|
||||
@Override
|
||||
public void update(Person person) {
|
||||
Name dn = buildDn(person);
|
||||
DirContextAdapter context = (DirContextAdapter) ldapTemplate.lookup(dn);
|
||||
@@ -72,44 +67,31 @@ public class PersonDaoImpl implements PersonDao {
|
||||
ldapTemplate.modifyAttributes(dn, context.getModificationItems());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#delete(Person)
|
||||
*/
|
||||
@Override
|
||||
public void delete(Person person) {
|
||||
ldapTemplate.unbind(buildDn(person));
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#getAllPersonNames()
|
||||
*/
|
||||
public List getAllPersonNames() {
|
||||
@Override
|
||||
public List<String> getAllPersonNames() {
|
||||
EqualsFilter filter = new EqualsFilter("objectclass", "person");
|
||||
return ldapTemplate.search(LdapUtils.emptyLdapName(), filter.encode(), new AttributesMapper() {
|
||||
public Object mapFromAttributes(Attributes attrs) throws NamingException {
|
||||
return attrs.get("cn").get();
|
||||
return ldapTemplate.search(LdapUtils.emptyLdapName(), filter.encode(), new AttributesMapper<String>() {
|
||||
public String mapFromAttributes(Attributes attrs) throws NamingException {
|
||||
return attrs.get("cn").get().toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findAll()
|
||||
*/
|
||||
public List findAll() {
|
||||
@Override
|
||||
public List<Person> findAll() {
|
||||
EqualsFilter filter = new EqualsFilter("objectclass", "person");
|
||||
return ldapTemplate.search(LdapUtils.emptyLdapName(), filter.encode(), getContextMapper());
|
||||
return ldapTemplate.search(LdapUtils.emptyLdapName(), filter.encode(), PERSON_CONTEXT_MAPPER);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see PersonDao#findByPrimaryKey(java.lang.String, java.lang.String,
|
||||
* java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Person findByPrimaryKey(String country, String company, String fullname) {
|
||||
LdapName dn = buildDn(country, company, fullname);
|
||||
return (Person) ldapTemplate.lookup(dn, getContextMapper());
|
||||
}
|
||||
|
||||
private ContextMapper getContextMapper() {
|
||||
return new PersonContextMapper();
|
||||
return ldapTemplate.lookup(dn, PERSON_CONTEXT_MAPPER);
|
||||
}
|
||||
|
||||
private LdapName buildDn(Person person) {
|
||||
@@ -137,16 +119,13 @@ public class PersonDaoImpl implements PersonDao {
|
||||
* of the form <code>cn=[fullname],ou=[company],c=[country]</code>, so
|
||||
* the values of these attributes must be extracted from the DN. For this,
|
||||
* we use the LdapName along with utility methods in LdapUtils.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
private static class PersonContextMapper implements ContextMapper {
|
||||
|
||||
public Object mapFromContext(Object ctx) {
|
||||
DirContextAdapter context = (DirContextAdapter) ctx;
|
||||
LdapName dn = LdapUtils.newLdapName(context.getDn());
|
||||
private final static ContextMapper<Person> PERSON_CONTEXT_MAPPER = new AbstractContextMapper<Person>() {
|
||||
@Override
|
||||
public Person doMapFromContext(DirContextOperations context) {
|
||||
Person person = new Person();
|
||||
|
||||
LdapName dn = LdapUtils.newLdapName(context.getDn());
|
||||
person.setCountry(LdapUtils.getStringValue(dn, 0));
|
||||
person.setCompany(LdapUtils.getStringValue(dn, 1));
|
||||
person.setFullName(context.getStringAttribute("cn"));
|
||||
@@ -156,7 +135,7 @@ public class PersonDaoImpl implements PersonDao {
|
||||
|
||||
return person;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void setLdapTemplate(LdapTemplate ldapTemplate) {
|
||||
this.ldapTemplate = ldapTemplate;
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ldap.demo.domain;
|
||||
package org.springframework.ldap.samples.plain.domain;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.springframework.ldap.samples.article.web;
|
||||
package org.springframework.ldap.samples.plain.web;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.ldap.samples.article.dao.PersonDao;
|
||||
import org.springframework.ldap.samples.article.domain.Person;
|
||||
import org.springframework.ldap.samples.plain.dao.PersonDao;
|
||||
import org.springframework.ldap.samples.plain.domain.Person;
|
||||
import org.springframework.ldap.samples.utils.HtmlRowLdapTreeVisitor;
|
||||
import org.springframework.ldap.samples.utils.LdapTree;
|
||||
import org.springframework.ldap.samples.utils.LdapTreeBuilder;
|
||||
@@ -45,28 +45,28 @@ public class DefaultController {
|
||||
}
|
||||
|
||||
@RequestMapping("/addPerson.do")
|
||||
public ModelAndView addPerson() {
|
||||
public String addPerson() {
|
||||
Person person = getPerson();
|
||||
|
||||
personDao.create(person);
|
||||
return showTree();
|
||||
return "redirect:/showTree.do";
|
||||
}
|
||||
|
||||
@RequestMapping("/updatePhoneNumber.do")
|
||||
public ModelAndView updatePhoneNumber() {
|
||||
public String updatePhoneNumber() {
|
||||
Person person = personDao.findByPrimaryKey("Sweden", "company1", "John Doe");
|
||||
person.setPhone(StringUtils.join(new String[] { person.getPhone(), "0" }));
|
||||
|
||||
personDao.update(person);
|
||||
return showTree();
|
||||
return "redirect:/showTree.do";
|
||||
}
|
||||
|
||||
@RequestMapping("/removePerson.do")
|
||||
public ModelAndView removePerson() {
|
||||
public String removePerson() {
|
||||
Person person = getPerson();
|
||||
|
||||
personDao.delete(person);
|
||||
return showTree();
|
||||
return "redirect:/showTree.do";
|
||||
}
|
||||
|
||||
@RequestMapping("/showPerson.do")
|
||||
3
samples/plain/src/main/java/overview.html
Normal file
3
samples/plain/src/main/java/overview.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
Plain example of Spring LDAP usage.
|
||||
</body>
|
||||
52
samples/plain/src/main/resources/applicationContext.xml
Normal file
52
samples/plain/src/main/resources/applicationContext.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<context:property-placeholder location="classpath:/ldap.properties" />
|
||||
|
||||
<!--
|
||||
This is for test and demo purposes only - the TestContextSourceFactoryBean starts an in-process
|
||||
Apache Directory Server instance and populates it with data from the specified LDIF file.
|
||||
|
||||
A real-world application would use a DirContextSource instead.
|
||||
-->
|
||||
<bean id="contextSource"
|
||||
class="org.springframework.ldap.test.TestContextSourceFactoryBean">
|
||||
<property name="defaultPartitionSuffix" value="dc=jayway,dc=se" />
|
||||
<property name="defaultPartitionName" value="jayway" />
|
||||
<property name="principal" value="${userDn}" />
|
||||
<property name="password" value="${password}" />
|
||||
<property name="ldifFile" value="classpath:/setup_data.ldif" />
|
||||
<property name="port" value="18880" />
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
Below is an example of a ContextSource definition as it would look in a real application, connecting
|
||||
against an external LDAP server.
|
||||
|
||||
<bean class="org.springframework.ldap.core.support.LdapContextSource" id="contextSource">
|
||||
<property name="url" value="ldap://ldap.example.com" />
|
||||
<property name="userDn" value="cn=admin,dc=261consulting,dc=com"/>
|
||||
<property name="password" value="secret"/>
|
||||
<property name="base" value="dc=261consulting,dc=com" />
|
||||
</bean>
|
||||
-->
|
||||
|
||||
<bean id="ldapTemplate"
|
||||
class="org.springframework.ldap.core.LdapTemplate">
|
||||
<constructor-arg ref="contextSource" />
|
||||
</bean>
|
||||
|
||||
<bean id="ldapTreeBuilder"
|
||||
class="org.springframework.ldap.samples.utils.LdapTreeBuilder">
|
||||
<constructor-arg ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
<bean id="personDao"
|
||||
class="org.springframework.ldap.samples.plain.dao.PersonDaoImpl">
|
||||
<property name="ldapTemplate" ref="ldapTemplate" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user