This commit is contained in:
11
build-spring-ldap/.project
Normal file
11
build-spring-ldap/.project
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>build-spring-ldap</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
233
build-spring-ldap/build.xml
Normal file
233
build-spring-ldap/build.xml
Normal file
@@ -0,0 +1,233 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
=======================================================================
|
||||
A master build file for creating a release of spring-ldap
|
||||
=======================================================================
|
||||
-->
|
||||
<project name="build-spring-ldap" default="release" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
|
||||
|
||||
<!-- Load local and user build preferences -->
|
||||
<property file="build.properties"/>
|
||||
<property file="project.properties"/>
|
||||
<property file="${user.home}/build.properties"/>
|
||||
|
||||
<!-- try to load ivy here from local lib dir, in case the user has not already dropped
|
||||
it into ant's lib dir (note that the latter copy will always take precedence).
|
||||
We will not fail as long as local lib dir exists (it may be empty) and
|
||||
ivy is in at least one of ant's lib dir or the local lib dir. -->
|
||||
<path id="ivy.lib.path">
|
||||
<fileset dir="${common.build.dir}/lib" includes="*.jar"/>
|
||||
</path>
|
||||
<taskdef resource="fr/jayasoft/ivy/ant/antlib.xml"
|
||||
uri="antlib:fr.jayasoft.ivy.ant" classpathref="ivy.lib.path"/>
|
||||
|
||||
<!-- simplistic pattern for zipping up sources -->
|
||||
<selector id="project.source.zip.includes">
|
||||
<or>
|
||||
<filename name="common-build/**" />
|
||||
<filename name="repository/**" />
|
||||
<and>
|
||||
<or>
|
||||
<filename name="build-spring-ldap/**"/>
|
||||
<filename name="spring-ldap/**"/>
|
||||
<filename name="spring-ldap-person/**"/>
|
||||
<filename name="spring-ldap-article/**"/>
|
||||
</or>
|
||||
<and>
|
||||
<filename name="*/target/**" negate="true"/>
|
||||
<filename name="*/build.properties" negate="true"/>
|
||||
<filename name="*/lib/**" negate="true"/>
|
||||
</and>
|
||||
<and>
|
||||
<filename name="*/*/*/target/**" negate="true"/>
|
||||
<filename name="*/*/*/build.properties" negate="true"/>
|
||||
<filename name="*/*/*/lib/**" negate="true"/>
|
||||
</and>
|
||||
</and>
|
||||
</or>
|
||||
</selector>
|
||||
|
||||
<!--
|
||||
targets: displays all targets suitable for developer use
|
||||
-->
|
||||
<target name="targets">
|
||||
<echo>
|
||||
|
||||
Master build for spring-ldap main and sample jars.
|
||||
|
||||
Please execute
|
||||
build -projecthelp
|
||||
|
||||
to see a list of all relevant targets.
|
||||
The default target is 'main'
|
||||
</echo>
|
||||
</target>
|
||||
|
||||
<!--
|
||||
init: initializes some common settings
|
||||
-->
|
||||
<target name="init" unless="init.done" depends="init.pre, init.post">
|
||||
</target>
|
||||
|
||||
<target name="init.pre" >
|
||||
|
||||
<!-- ivy will determine the right order to build web flow main and samples -->
|
||||
|
||||
<property name="ivy.conf.dir" value="${common.build.dir}" />
|
||||
<ivy:configure file="${ivy.conf.dir}/ivyconf.xml" />
|
||||
|
||||
<ivy:buildlist reference="modules">
|
||||
<fileset dir="..">
|
||||
<include name="spring-ldap-article/build.xml"/>
|
||||
<include name="spring-ldap-person/build.xml"/>
|
||||
<include name="spring-ldap/build.xml"/>
|
||||
</fileset>
|
||||
</ivy:buildlist>
|
||||
|
||||
<tstamp>
|
||||
<format property="build.timestamp" pattern="yyyyMMddHHmmss"/>
|
||||
</tstamp>
|
||||
<tstamp>
|
||||
<format property="TSTAMPCOL" pattern="hh:mm"/>
|
||||
</tstamp>
|
||||
|
||||
<!-- default the release version (used in release archive zips) to the current timestamp -->
|
||||
<property name="release.version" value="${build.timestamp}"/>
|
||||
|
||||
<!-- root of build hierarchy -->
|
||||
<property name="target.dir" value="${basedir}/target"/>
|
||||
|
||||
<!-- directory for release zips -->
|
||||
<property name="target.release.dir" value="${target.dir}/release"/>
|
||||
|
||||
<!-- directory for release zips -->
|
||||
<property name="release.bin.zip"
|
||||
value="spring-ldap-bin-${release.version}.zip"/>
|
||||
<property name="release.bin.deps.zip"
|
||||
value="spring-ldap-bin-with-dependencies-${release.version}.zip"/>
|
||||
<property name="release.buildable.zip"
|
||||
value="spring-ldap-buildable-${release.version}.zip"/>
|
||||
|
||||
<property name="zip.toplevel.dir" value="spring-ldap-${release.version}"/>
|
||||
|
||||
<echo message='user.dir = "${user.dir}"' />
|
||||
<echo message='ant.file = "${ant.file}"' />
|
||||
<echo message='ant.java.version = "${ant.java.version}"' />
|
||||
<echo message='release.version = "${release.version}"' />
|
||||
|
||||
</target>
|
||||
|
||||
<target name="init.post" >
|
||||
<property name="projects" value="modules"/>
|
||||
<property name="projects.names" refid="modules"/>
|
||||
|
||||
<property name="init.done" value="true"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="init"
|
||||
description="Cleans all build output files from all projects">
|
||||
<echo>projects=${projects}</echo>
|
||||
<echo>projects.names=${projects.names}</echo>
|
||||
<subant target="clean" inheritall="false">
|
||||
<buildpath refid="${projects}"/>
|
||||
</subant>
|
||||
</target>
|
||||
|
||||
<target name="clean-all" depends="init"
|
||||
description="Cleans all build output files from all projects, and also retrieved libs">
|
||||
<echo>projects=${projects}</echo>
|
||||
<subant target="clean-all" inheritall="false">
|
||||
<buildpath refid="${projects}"/>
|
||||
</subant>
|
||||
</target>
|
||||
|
||||
<target name="publish" depends="init"
|
||||
description="Calls publish targets on each project">
|
||||
<echo>projects=${projects}</echo>
|
||||
<subant target="publish" inheritall="false">
|
||||
<buildpath refid="${projects}"/>
|
||||
</subant>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="init"
|
||||
description="Calls dist targets on each project">
|
||||
<echo>projects=${projects}</echo>
|
||||
<subant target="dist" inheritall="false">
|
||||
<buildpath refid="${projects}"/>
|
||||
</subant>
|
||||
</target>
|
||||
|
||||
<target name="tests" depends="init"
|
||||
description="Calls test targets on each project">
|
||||
<echo>projects=${projects}</echo>
|
||||
<subant target="tests" inheritall="false">
|
||||
<buildpath refid="${projects}"/>
|
||||
</subant>
|
||||
</target>
|
||||
|
||||
<target name="javadoc" depends="init"
|
||||
description="Calls javadoc targets on each project">
|
||||
<echo>projects=${projects}</echo>
|
||||
<subant target="javadoc" inheritall="false">
|
||||
<buildpath refid="${projects}"/>
|
||||
</subant>
|
||||
</target>
|
||||
|
||||
<target name="release"
|
||||
depends="dist, javadoc, gen-release-bins, gen-release-bins-with-deps, gen-buildable-zip"
|
||||
description="Generate release zips">
|
||||
</target>
|
||||
|
||||
<target name="gen-release-bins" depends="init"
|
||||
description="Generate bin zips/tarballs">
|
||||
|
||||
<mkdir dir="${target.release.dir}"/>
|
||||
<delete file="${target.release.dir}/${release.bin.zip}"/>
|
||||
|
||||
<zip zipfile="${target.release.dir}/${release.bin.zip}">
|
||||
<zipfileset file="../spring-ldap/readme.txt" prefix="${zip.toplevel.dir}"/>
|
||||
<zipfileset file="../spring-ldap/license.txt" prefix="${zip.toplevel.dir}"/>
|
||||
<zipfileset dir="../spring-ldap/target/dist/jars" prefix="${zip.toplevel.dir}/dist"/>
|
||||
<zipfileset dir="../spring-ldap/target/dist/ivys" prefix="${zip.toplevel.dir}/dist/ivys"/>
|
||||
<zipfileset dir="../spring-ldap/docs/reference/target/html_single" prefix="${zip.toplevel.dir}/doc/reference/html_single"/>
|
||||
<zipfileset file="../spring-ldap/docs/reference/target/pdf/spring-ldap-reference.pdf" prefix="${zip.toplevel.dir}/doc/reference/pdf"/>
|
||||
<zipfileset dir="../spring-ldap/target/javadocs" prefix="${zip.toplevel.dir}/doc/api"/>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="gen-release-bins-with-deps" depends="init"
|
||||
description="Generate bin zips/tarballs with all dependencies">
|
||||
|
||||
<mkdir dir="${target.release.dir}"/>
|
||||
<delete file="${target.release.dir}/${release.bin.deps.zip}"/>
|
||||
|
||||
<zip zipfile="${target.release.dir}/${release.bin.deps.zip}">
|
||||
<zipfileset file="../spring-ldap/readme.txt" prefix="${zip.toplevel.dir}"/>
|
||||
<zipfileset file="../spring-ldap/license.txt" prefix="${zip.toplevel.dir}"/>
|
||||
<zipfileset dir="../spring-ldap/target/dist/jars" prefix="${zip.toplevel.dir}/dist"/>
|
||||
<zipfileset dir="../spring-ldap/target/dist/ivys" prefix="${zip.toplevel.dir}/dist/ivys"/>
|
||||
<zipfileset dir="../spring-ldap/docs/reference/target/html_single" prefix="${zip.toplevel.dir}/doc/reference/html_single"/>
|
||||
<zipfileset file="../spring-ldap/docs/reference/target/pdf/spring-ldap-reference.pdf" prefix="${zip.toplevel.dir}/doc/reference/pdf"/>
|
||||
<zipfileset dir="../spring-ldap/target/javadocs" prefix="${zip.toplevel.dir}/doc/api"/>
|
||||
<zipfileset dir="../spring-ldap/lib/global" prefix="${zip.toplevel.dir}/lib"/>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="gen-buildable-zip" depends="init"
|
||||
description="Generate archive with buildable sources">
|
||||
|
||||
<mkdir dir="${target.release.dir}"/>
|
||||
<delete file="${target.release.dir}/${release.buildable.zip}"/>
|
||||
|
||||
<zip zipfile="${target.release.dir}/${release.buildable.zip}">
|
||||
<zipfileset dir=".." prefix="spring-ldap">
|
||||
<selector refid="project.source.zip.includes"/>
|
||||
</zipfileset>
|
||||
<zipfileset file="../spring-ldap/readme.txt"/>
|
||||
<zipfileset file="../spring-ldap/license.txt"/>
|
||||
<zipfileset dir="../../common-build" prefix="common-build"/>
|
||||
<zipfileset dir="../../repository" prefix="repository"/>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
64
build-spring-ldap/checklist_release.txt
Normal file
64
build-spring-ldap/checklist_release.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
build-spring-ldap
|
||||
=================
|
||||
|
||||
* Update release number in project.properties
|
||||
|
||||
release.version=1.1
|
||||
|
||||
spring-ldap
|
||||
===========
|
||||
|
||||
* Update release number in project.properties
|
||||
|
||||
project.base.version=1.1
|
||||
project.version=${project.base.version}
|
||||
ivy.status=release
|
||||
|
||||
* Update release number in reference manual (docs/reference/src/index.xml)
|
||||
|
||||
<bookinfo>
|
||||
<title>Spring LDAP</title>
|
||||
<subtitle>Reference Documentation</subtitle>
|
||||
<releaseinfo>Version 1.1</releaseinfo>
|
||||
|
||||
* Update release number in readme.txt
|
||||
|
||||
Spring-LDAP 1.1 (Aug 2006)
|
||||
|
||||
General
|
||||
=======
|
||||
|
||||
* Update changelog with changes, including upgraded libraries
|
||||
|
||||
* Synchronize and commit changes, including .* files
|
||||
|
||||
* Run clean-all from build-spring-ldap
|
||||
|
||||
* Clean integration-repo
|
||||
|
||||
* Clean Ivy cache
|
||||
|
||||
* Run all tests, including integration tests
|
||||
|
||||
* Run the sample spring-ldap-person in a web container
|
||||
|
||||
* Run the sample spring-ldap-article integration tests
|
||||
|
||||
* Run doc-all from spring-ldap
|
||||
|
||||
* Run release from build-spring-ldap
|
||||
|
||||
* Run jdiff from spring-ldap
|
||||
|
||||
* Add Maven pom file for the new release to top directory.
|
||||
|
||||
After release
|
||||
=============
|
||||
|
||||
* Store source for new release in build-spring-ldap/spring-ldap-<rel>
|
||||
(used in future jdiff runs)
|
||||
|
||||
* Tag release like this:
|
||||
1. Open a svn repo browser, eg Eclipse
|
||||
2. Create a new directory: spring-projects/tags/spring-ldap-<rel>
|
||||
3. Copy repository, common-build and spring-ldap to that directory
|
||||
2201
build-spring-ldap/jdiff/lib/2000/10/XMLSchema
Normal file
2201
build-spring-ldap/jdiff/lib/2000/10/XMLSchema
Normal file
File diff suppressed because it is too large
Load Diff
31
build-spring-ldap/jdiff/lib/2000/10/XMLSchema-instance
Normal file
31
build-spring-ldap/jdiff/lib/2000/10/XMLSchema-instance
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE xs:schema SYSTEM "XMLSchema.dtd" [
|
||||
<!ENTITY % p 'xs:'>
|
||||
<!ENTITY % s ':xs'>
|
||||
<!ATTLIST xs:documentation xmlns CDATA #IMPLIED>
|
||||
]>
|
||||
<xs:schema targetNamespace="http://www.w3.org/2000/10/XMLSchema-instance"
|
||||
xmlns:xs="http://www.w3.org/2000/10/XMLSchema">
|
||||
<xs:annotation>
|
||||
<xs:documentation xmlns="">
|
||||
<h1>XML Schema instance namespace</h1>
|
||||
<p>See <a href="http://www.w3.org/TR/xmlschema-1/">The XML Schema draft recommendation</a> for an introduction</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<address><a href="mailto:ht@tux.w3.org">Henry S. Thompson</a></address>
|
||||
$Date: 2001/11/16 06:19:40 $<br />
|
||||
$Id: XMLSchema-instance,v 1.1 2001/11/16 06:19:40 mdoar Exp $
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:attribute name="type">
|
||||
<xs:annotation>
|
||||
<xs:documentation>No definitions are provided here, as
|
||||
this schema is never used as such</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
|
||||
<xs:attribute name="null"/>
|
||||
<xs:attribute name="schemaLocation"/>
|
||||
<xs:attribute name="noNamespaceSchemaLocation"/>
|
||||
</xs:schema>
|
||||
2441
build-spring-ldap/jdiff/lib/2001/XMLSchema
Normal file
2441
build-spring-ldap/jdiff/lib/2001/XMLSchema
Normal file
File diff suppressed because it is too large
Load Diff
38
build-spring-ldap/jdiff/lib/2001/XMLSchema-instance
Normal file
38
build-spring-ldap/jdiff/lib/2001/XMLSchema-instance
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE xs:schema SYSTEM "XMLSchema.dtd" [
|
||||
<!ATTLIST xs:documentation xmlns CDATA #IMPLIED>
|
||||
<!ELEMENT p ANY>
|
||||
<!ELEMENT a ANY>
|
||||
<!ATTLIST a href CDATA #IMPLIED>
|
||||
<!ELEMENT hr ANY>
|
||||
<!ELEMENT h1 ANY>
|
||||
<!ELEMENT br ANY>
|
||||
]>
|
||||
<xs:schema targetNamespace="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://www.w3.org/1999/xhtml">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
<h1>XML Schema instance namespace</h1>
|
||||
<p>See <a href="http://www.w3.org/TR/xmlschema-1/">the XML Schema
|
||||
Recommendation</a> for an introduction</p>
|
||||
|
||||
|
||||
<hr />
|
||||
$Date: 2002/01/09 20:32:53 $<br />
|
||||
$Id: XMLSchema-instance,v 1.1 2002/01/09 20:32:53 mdoar Exp $
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:annotation>
|
||||
<xs:documentation><p>This schema should never be used as such:
|
||||
<a href="http://www.w3.org/TR/xmlschema-1/#no-xsi">the XML
|
||||
Schema Recommendation</a> forbids the declaration of
|
||||
attributes in this namespace</p>
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
|
||||
<xs:attribute name="nil"/>
|
||||
<xs:attribute name="type"/>
|
||||
<xs:attribute name="schemaLocation"/>
|
||||
<xs:attribute name="noNamespaceSchemaLocation"/>
|
||||
</xs:schema>
|
||||
9
build-spring-ldap/jdiff/lib/Null.java
Normal file
9
build-spring-ldap/jdiff/lib/Null.java
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* This class is used only as a "null" argument for Javadoc when comparing
|
||||
* two API files. Javadoc has to have a package, .java or .class file as an
|
||||
* argument, even though JDiff doesn't use it.
|
||||
*/
|
||||
public class Null {
|
||||
public Null() {
|
||||
}
|
||||
}
|
||||
BIN
build-spring-ldap/jdiff/lib/ant.jar
Normal file
BIN
build-spring-ldap/jdiff/lib/ant.jar
Normal file
Binary file not shown.
BIN
build-spring-ldap/jdiff/lib/antjdiff.jar
Normal file
BIN
build-spring-ldap/jdiff/lib/antjdiff.jar
Normal file
Binary file not shown.
BIN
build-spring-ldap/jdiff/lib/background.gif
Normal file
BIN
build-spring-ldap/jdiff/lib/background.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 559 B |
BIN
build-spring-ldap/jdiff/lib/black.gif
Normal file
BIN
build-spring-ldap/jdiff/lib/black.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 799 B |
BIN
build-spring-ldap/jdiff/lib/classdoc.jar
Normal file
BIN
build-spring-ldap/jdiff/lib/classdoc.jar
Normal file
Binary file not shown.
BIN
build-spring-ldap/jdiff/lib/jdiff.jar
Normal file
BIN
build-spring-ldap/jdiff/lib/jdiff.jar
Normal file
Binary file not shown.
BIN
build-spring-ldap/jdiff/lib/jdiff_logo.gif
Normal file
BIN
build-spring-ldap/jdiff/lib/jdiff_logo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
build-spring-ldap/jdiff/lib/new.gif
Normal file
BIN
build-spring-ldap/jdiff/lib/new.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 B |
BIN
build-spring-ldap/jdiff/lib/xerces.jar
Normal file
BIN
build-spring-ldap/jdiff/lib/xerces.jar
Normal file
Binary file not shown.
5
build-spring-ldap/project.properties
Normal file
5
build-spring-ldap/project.properties
Normal file
@@ -0,0 +1,5 @@
|
||||
# configurable property values, may be locally overriden by a build.properties file
|
||||
release.version=1.1.2
|
||||
|
||||
# The location of the common build system
|
||||
common.build.dir=${basedir}/../common-build
|
||||
16
build-spring-ldap/readme.txt
Normal file
16
build-spring-ldap/readme.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
This is where the master build to create releases of spring-ldap resides.
|
||||
|
||||
To build a new release:
|
||||
|
||||
1. If you have ivy installed, make sure it is version 1.4 or higher.
|
||||
(check your ANT_HOME/lib for ivy-xxx.jar - if it is too old a version,
|
||||
remove it or replace it with the one in ../common-build/lib).
|
||||
|
||||
2. Update project.properties to contain the new release version, if necessary.
|
||||
|
||||
3. From this directory, run:
|
||||
ant release
|
||||
The release archive will be created and placed in:
|
||||
target/release
|
||||
|
||||
Questions? See http://www.springframework.org/ldap
|
||||
11
build-spring-ldap/release-toc.txt
Normal file
11
build-spring-ldap/release-toc.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Spring-LDAP
|
||||
|
||||
Release archive table of contents
|
||||
---------------------------------------------------
|
||||
* common-build - contains the ant 1.6 "common build system" used by all spring-ldap projects to compile/build/test
|
||||
* spring-ldap/build-spring-ldap - contains master build files to produce this release archive
|
||||
* spring-ldap/spring-ldap - contains project sources
|
||||
* spring-ldap/spring-ldap-person - contains a sample web project.
|
||||
* spring-ldap/spring-ldap-article - contains source code for an article published on java.net.
|
||||
|
||||
See the readme.txt within the above directories for additional information.
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
|
||||
/**
|
||||
* Exception that indicates that an invalid or missing Attribute has been
|
||||
* supplied to an LDAP operation.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class AttributesIntegrityViolationException extends
|
||||
DataIntegrityViolationException {
|
||||
|
||||
private static final long serialVersionUID = -6368616096960202571L;
|
||||
|
||||
public AttributesIntegrityViolationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public AttributesIntegrityViolationException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
|
||||
/**
|
||||
* An interface used by LdapTemplate for mapping LDAP Attributes to beans.
|
||||
* Implementions of this interface perform the actual work of extracting
|
||||
* results, but need not worry about exception handling. NamingExceptions will
|
||||
* be caught and handled correctly by the LdapTemplate class.
|
||||
* <p>
|
||||
* Typically used in LdapTemplate's search methods. AttributeMapper objects are
|
||||
* typically stateless and thus reusable; they are ideal for implementing
|
||||
* attribute-mapping logic in one place.
|
||||
* <p>
|
||||
* Alternatively, consider using a {@link ContextMapper} in stead.
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate#search(Name, String,
|
||||
* AttributesMapper)
|
||||
* @see ContextMapper
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface AttributesMapper {
|
||||
/**
|
||||
* Map Attributes to an object. The supplied attributes are the attributes
|
||||
* from a single SearchResult.
|
||||
*
|
||||
* @param attributes
|
||||
* attributes from a SearchResult.
|
||||
* @return an object built from the attributes.
|
||||
* @throws NamingException if any error occurs mapping the attributes
|
||||
*/
|
||||
public Object mapFromAttributes(Attributes attributes)
|
||||
throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
/**
|
||||
* An AuthenticationSource is responsible for providing the principal and
|
||||
* credentials to be used when creating a new context.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public interface AuthenticationSource {
|
||||
/**
|
||||
* Get the principal to use when creating an authenticated context.
|
||||
*
|
||||
* @return the principal (userName).
|
||||
*/
|
||||
public String getPrincipal();
|
||||
|
||||
/**
|
||||
* Get the credentials to use when creating an authenticated context.
|
||||
*
|
||||
* @return the credentials (userName).
|
||||
*/
|
||||
public String getCredentials();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that an invalid value has been supplied to an LDAP
|
||||
* operation. This could be an invalid filter or dn.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class BadLdapGrammarException extends
|
||||
InvalidDataAccessResourceUsageException {
|
||||
|
||||
private static final long serialVersionUID = 961612585331409470L;
|
||||
|
||||
public BadLdapGrammarException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public BadLdapGrammarException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
|
||||
/**
|
||||
* A NameClassPairCallbackHandler to collect all results in an internal List.
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public abstract class CollectingNameClassPairCallbackHandler implements
|
||||
NameClassPairCallbackHandler {
|
||||
|
||||
private List list = new LinkedList();
|
||||
|
||||
/**
|
||||
* Get the assembled list.
|
||||
*
|
||||
* @return the list of all assembled objects.
|
||||
*/
|
||||
public List getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass on the supplied NameClassPair to
|
||||
* {@link #getObjectFromNameClassPair(NameClassPair)} and add the result to
|
||||
* the internal list.
|
||||
*/
|
||||
public void handleNameClassPair(NameClassPair nameClassPair) {
|
||||
list.add(getObjectFromNameClassPair(nameClassPair));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a NameClassPair and transform it to an Object of the desired type
|
||||
* and with data from the NameClassPair.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* a NameClassPair from a search operation.
|
||||
* @return an object constructed from the data in the NameClassPair.
|
||||
*/
|
||||
public abstract Object getObjectFromNameClassPair(
|
||||
NameClassPair nameClassPair);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
/**
|
||||
* Helper interface to be used by Dao implementations for assembling to and from
|
||||
* context. Useful if we have assembler classes responsible for mapping to and
|
||||
* from a specific entry.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface ContextAssembler extends ContextMapper {
|
||||
/**
|
||||
* Map the supplied object to the specified context.
|
||||
*
|
||||
* @param obj
|
||||
* the object to read data from.
|
||||
* @param ctx
|
||||
* the context to map to.
|
||||
*/
|
||||
public void mapToContext(Object obj, Object ctx);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface for delegating an actual operation to be performed on an
|
||||
* DirContext. For searches, use {@link org.springframework.ldap.SearchExecutor} in
|
||||
* stead. A typical usage of this interface could be e.g.:
|
||||
*
|
||||
* <pre>
|
||||
* ContextExecutor executor = new ContextExecutor(){
|
||||
* public Object executeWithContext(DirContext ctx) throws NamingException{
|
||||
* return ctx.lookup(dn);
|
||||
* }
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate#executeReadOnly(ContextExecutor)
|
||||
* @see org.springframework.ldap.LdapTemplate#executeReadWrite(ContextExecutor)
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface ContextExecutor {
|
||||
/**
|
||||
* Perform any operation on the context.
|
||||
*
|
||||
* @param ctx
|
||||
* the DirContext to perform the operation on.
|
||||
* @return any object resulting from the operation - might be null.
|
||||
* @throws NamingException
|
||||
* if the operation resulted in one.
|
||||
*/
|
||||
public Object executeWithContext(DirContext ctx) throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.directory.SearchResult;
|
||||
|
||||
import org.springframework.ldap.support.DefaultDirObjectFactory;
|
||||
import org.springframework.ldap.support.DirContextAdapter;
|
||||
|
||||
/**
|
||||
* An interface used by LdapTemplate to map LDAP Contexts to beans. Responsible
|
||||
* for mapping from LDAP Contexts to beans. When a DirObjectFactory is set on
|
||||
* the ContextSource, the objects returned from <code>search</code> and
|
||||
* <code>listBindings</code> operations are automatically transformed to
|
||||
* DirContext objects (when using the {@link DefaultDirObjectFactory}, you get
|
||||
* a {@link DirContextAdapter} object). This object will then be passed to the
|
||||
* ContextMapper implementation for transformation to the desired bean.
|
||||
* <p>
|
||||
* ContextMapper implementations are typically stateless and thus reusable; they
|
||||
* are ideal for implementing mapping logic in one place.
|
||||
* <p>
|
||||
* Alternatively, consider using an {@link AttributesMapper} in stead.
|
||||
*
|
||||
* @see LdapTemplate#search(Name, String,
|
||||
* ContextMapper)
|
||||
* @see LdapTemplate#listBindings(Name, ContextMapper)
|
||||
* @see LdapTemplate#lookup(Name, ContextMapper)
|
||||
* @see AttributesMapper
|
||||
* @see DefaultDirObjectFactory
|
||||
* @see DirContextAdapter
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface ContextMapper {
|
||||
/**
|
||||
* Map a single LDAP Context to an object. The supplied Object
|
||||
* <code>ctx</code> is the object from a single {@link SearchResult},
|
||||
* {@link Binding}, or a lookup operation.
|
||||
*
|
||||
* @param ctx
|
||||
* the context to map to an object.
|
||||
* @return an object built from the data in the context.
|
||||
*/
|
||||
public Object mapFromContext(Object ctx);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
* Interface used to retrieve and authenticate LDAP contexts.
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface ContextSource {
|
||||
|
||||
/**
|
||||
* Gets a read-only DirContext. The returned DirContext must be possible to
|
||||
* perform read-only operations on.
|
||||
*
|
||||
* @return A DirContext instance, never null.
|
||||
* @throws DataAccessException
|
||||
* if some error occurs creating an DirContext.
|
||||
*/
|
||||
public DirContext getReadOnlyContext() throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Gets a read-write DirContext.
|
||||
*
|
||||
* @return A DirContext instance, never null.
|
||||
* @throws DataAccessException
|
||||
* if some error occurs creating an DirContext.
|
||||
*/
|
||||
public DirContext getReadWriteContext() throws DataAccessException;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* The default NameClassPairMapper implementation. This implementation simply
|
||||
* takes the Name string from the supplied NameClassPair and returns it as
|
||||
* result.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class DefaultNameClassPairMapper implements NameClassPairMapper {
|
||||
|
||||
/**
|
||||
* Gets the Name from the supplied NameClassPair and returns it as the
|
||||
* result.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* the NameClassPair to transform.
|
||||
* @return the Name string from the NameClassPair.
|
||||
*/
|
||||
public Object mapFromNameClassPair(NameClassPair nameClassPair)
|
||||
throws NamingException {
|
||||
|
||||
return nameClassPair.getName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.CommunicationException;
|
||||
import javax.naming.ContextNotEmptyException;
|
||||
import javax.naming.LimitExceededException;
|
||||
import javax.naming.NameAlreadyBoundException;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.InvalidAttributesException;
|
||||
import javax.naming.directory.InvalidSearchControlsException;
|
||||
import javax.naming.directory.InvalidSearchFilterException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
/**
|
||||
* The default implementation of NamingExceptionTranslator.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class DefaultNamingExceptionTranslator implements
|
||||
NamingExceptionTranslator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.NamingExceptionTranslator#translate(java.lang.String,
|
||||
* java.lang.String, java.lang.String, javax.naming.NamingException)
|
||||
*/
|
||||
public DataAccessException translate(NamingException namingException) {
|
||||
|
||||
if (namingException instanceof NameNotFoundException) {
|
||||
return new EntryNotFoundException("Entry not found",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof InvalidSearchFilterException) {
|
||||
return new BadLdapGrammarException("Invalid search filter",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof InvalidSearchControlsException) {
|
||||
return new InvalidDataAccessApiUsageException(
|
||||
"Invalid search controls supplied by internal API",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof NameAlreadyBoundException) {
|
||||
return new DataIntegrityViolationException("Name already bound",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof ContextNotEmptyException) {
|
||||
return new DataIntegrityViolationException(
|
||||
"The context needs to be empty in order to be removed",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof InvalidAttributesException) {
|
||||
return new AttributesIntegrityViolationException(
|
||||
"Invalid attributes", namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof LimitExceededException) {
|
||||
return new SearchLimitExceededException("Too many objects found",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof CommunicationException) {
|
||||
throw new DataRetrievalFailureException(
|
||||
"Unable to communicate with LDAP server", namingException);
|
||||
}
|
||||
|
||||
// Fallback - other type of NamingException encountered.
|
||||
return new UncategorizedLdapException("Operation failed",
|
||||
namingException);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface to be called in search by LdapTemplate before and after the actual
|
||||
* search and enumeration traversal.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public interface DirContextProcessor {
|
||||
/**
|
||||
* Perform pre-processing on the supplied DirContext.
|
||||
*
|
||||
* @param ctx
|
||||
* the DirContext instance.
|
||||
* @throws NamingException
|
||||
* if thrown by the underlying operation.
|
||||
*/
|
||||
public void preProcess(DirContext ctx) throws NamingException;
|
||||
|
||||
/**
|
||||
* Perform post-processing on the supplied DirContext.
|
||||
*
|
||||
* @param ctx
|
||||
* the DirContext instance.
|
||||
* @throws NamingException
|
||||
* if thrown by the underlying operation.
|
||||
*/
|
||||
public void postProcess(DirContext ctx) throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
/**
|
||||
* Represents that an entry could not be found.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class EntryNotFoundException extends DataRetrievalFailureException {
|
||||
|
||||
private static final long serialVersionUID = -1268390922996332424L;
|
||||
|
||||
public EntryNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public EntryNotFoundException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
|
||||
/**
|
||||
* Callback interface used by LdapTemplate's search, list and listBindings
|
||||
* methods. Implementations of this interface perform the actual work of
|
||||
* extracting results from a single NameClassPair (a NameClassPair,
|
||||
* Binding or SearchResult depending on the search operation) returned by an
|
||||
* LDAP seach operation, such as search(), list(), and listBindings().
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface NameClassPairCallbackHandler {
|
||||
/**
|
||||
* Handle one entry. This method will be called once for each entry returned
|
||||
* by a search or list.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* the NameClassPair returned from the NamingEnumeration.
|
||||
*/
|
||||
public void handleNameClassPair(NameClassPair nameClassPair);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* Responsible for mapping NameClassPair objects to beans.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface NameClassPairMapper {
|
||||
/**
|
||||
* Map NameClassPair to an Object. The supplied NameClassPair is one of the
|
||||
* results from a search operation (search, list or listBindings). Depending
|
||||
* on which search operation is being performed, the NameClassPair might be
|
||||
* a SearchResult, Binding or NameClassPair.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* NameClassPair from a search operation.
|
||||
* @return and Object built from the NameClassPair.
|
||||
* @throws NamingException
|
||||
* if one is encountered in the operation.
|
||||
*/
|
||||
public Object mapFromNameClassPair(NameClassPair nameClassPair)
|
||||
throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by classes that can translate between
|
||||
* NamingExceptions and DataAccessExceptions.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public interface NamingExceptionTranslator {
|
||||
/**
|
||||
* Translate the given NamingException into a generic data access exception.
|
||||
* @param namingException
|
||||
* the offending NamingException.
|
||||
*
|
||||
* @return the DataAccessException to throw.
|
||||
*/
|
||||
public DataAccessException translate(NamingException namingException);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface for delegating an actual search operation. The typical
|
||||
* implementation of executeSearch would be something like:
|
||||
*
|
||||
* <pre>
|
||||
* SearchExecutor executor = new SearchExecutor(){
|
||||
* public NamingEnumeration executeSearch(DirContext ctx) throws NamingException{
|
||||
* return ctx.search(dn, filter, searchControls);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate#search(SearchExecutor,
|
||||
* NameClassPairCallbackHandler)
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface SearchExecutor {
|
||||
/**
|
||||
* Execute the actual search.
|
||||
*
|
||||
* @param ctx
|
||||
* the DirContext on which to work.
|
||||
* @return the NamingEnumeration resulting from the search operation.
|
||||
* @throws NamingException
|
||||
* if the search results in one.
|
||||
*/
|
||||
public NamingEnumeration executeSearch(DirContext ctx)
|
||||
throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
/**
|
||||
* Indicates that the search limit was exceeded in a search.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class SearchLimitExceededException extends DataRetrievalFailureException {
|
||||
private static final long serialVersionUID = 6899885947075235580L;
|
||||
|
||||
public SearchLimitExceededException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public SearchLimitExceededException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.UncategorizedDataAccessException;
|
||||
|
||||
/**
|
||||
* Indicates that an unknown NamingException has occurred.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class UncategorizedLdapException extends
|
||||
UncategorizedDataAccessException {
|
||||
|
||||
private static final long serialVersionUID = -3319936235493869823L;
|
||||
|
||||
public UncategorizedLdapException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
The core package of the Spring-LDAP library.
|
||||
</body>
|
||||
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.JdkVersion;
|
||||
import org.springframework.ldap.AuthenticationSource;
|
||||
import org.springframework.ldap.ContextSource;
|
||||
import org.springframework.ldap.DefaultNamingExceptionTranslator;
|
||||
import org.springframework.ldap.NamingExceptionTranslator;
|
||||
|
||||
/**
|
||||
* Abstract implementation of the ContextSource interface. By default, returns
|
||||
* an authenticated DirContext implementation for both read-only and read-write
|
||||
* operations. To have an anonymous environment created for read-only
|
||||
* operations, set the anonymousReadOnly property to <code>true</code>.
|
||||
* <p>
|
||||
* Implementing classes need to implement
|
||||
* {@link #getDirContextInstance(Hashtable)} to create a DirContext instance of
|
||||
* the desired type.
|
||||
* <p>
|
||||
* If an AuthenticationSource is set, this will be used for getting user name
|
||||
* and password for each new connection, otherwise a default one will be created
|
||||
* using the specified userName and password.
|
||||
* <p>
|
||||
* <b>Note:</b> When using implementations of this class outside of a Spring
|
||||
* Context it is necessary to call {@link #afterPropertiesSet()} when all
|
||||
* properties are set, in order to finish up initialization.
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate
|
||||
* @see org.springframework.ldap.support.DefaultDirObjectFactory
|
||||
* @see org.springframework.ldap.support.LdapContextSource
|
||||
* @see org.springframework.ldap.support.DirContextSource
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
* @author Adam Skogman
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public abstract class AbstractContextSource implements ContextSource,
|
||||
InitializingBean {
|
||||
|
||||
private static final Class DEFAULT_CONTEXT_FACTORY = com.sun.jndi.ldap.LdapCtxFactory.class;
|
||||
|
||||
private static final Class DEFAULT_DIR_OBJECT_FACTORY = DefaultDirObjectFactory.class;
|
||||
|
||||
private Class dirObjectFactory = DEFAULT_DIR_OBJECT_FACTORY;
|
||||
|
||||
private Class contextFactory = DEFAULT_CONTEXT_FACTORY;
|
||||
|
||||
private DistinguishedName base;
|
||||
|
||||
protected String userName = "";
|
||||
|
||||
protected String password = "";
|
||||
|
||||
private String[] urls;
|
||||
|
||||
private boolean pooled = true;
|
||||
|
||||
private Hashtable baseEnv = new Hashtable();
|
||||
|
||||
private Hashtable anonymousEnv;
|
||||
|
||||
private AuthenticationSource authenticationSource;
|
||||
|
||||
private boolean cacheEnvironmentProperties = true;
|
||||
|
||||
private boolean anonymousReadOnly = false;
|
||||
|
||||
private NamingExceptionTranslator exceptionTranslator = new DefaultNamingExceptionTranslator();
|
||||
|
||||
private static final Log log = LogFactory.getLog(LdapContextSource.class);
|
||||
|
||||
public static final String SUN_LDAP_POOLING_FLAG = "com.sun.jndi.ldap.connect.pool";
|
||||
|
||||
private static final String JDK_142 = "1.4.2";
|
||||
|
||||
public DirContext getReadOnlyContext() {
|
||||
if (!anonymousReadOnly) {
|
||||
return createContext(getAuthenticatedEnv());
|
||||
} else {
|
||||
return createContext(getAnonymousEnv());
|
||||
}
|
||||
}
|
||||
|
||||
public DirContext getReadWriteContext() {
|
||||
return createContext(getAuthenticatedEnv());
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of setting the environment up to be authenticated.
|
||||
* Override in subclass if necessary. This is needed for Active Directory
|
||||
* connectivity, for example.
|
||||
*
|
||||
* @param env
|
||||
* the environment to modify.
|
||||
*/
|
||||
protected void setupAuthenticatedEnvironment(Hashtable env) {
|
||||
env
|
||||
.put(Context.SECURITY_PRINCIPAL, authenticationSource
|
||||
.getPrincipal());
|
||||
log.debug("Principal: '" + userName + "'");
|
||||
env.put(Context.SECURITY_CREDENTIALS, authenticationSource
|
||||
.getCredentials());
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the context and swallow any exceptions.
|
||||
*
|
||||
* @param ctx
|
||||
* the DirContext to close.
|
||||
*/
|
||||
private void closeContext(DirContext ctx) {
|
||||
if (ctx != null) {
|
||||
try {
|
||||
ctx.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble a valid url String from all registered urls to add as
|
||||
* PROVIDER_URL to the environment.
|
||||
*
|
||||
* @param ldapUrls
|
||||
* all individual url Strings.
|
||||
* @return the full url String
|
||||
*/
|
||||
protected String assembleProviderUrlString(String[] ldapUrls) {
|
||||
StringBuffer providerUrlBuffer = new StringBuffer(1024);
|
||||
for (int i = 0; i < ldapUrls.length; i++) {
|
||||
providerUrlBuffer.append(ldapUrls[i]);
|
||||
if (base != null) {
|
||||
if (!ldapUrls[i].endsWith("/")) {
|
||||
providerUrlBuffer.append("/");
|
||||
}
|
||||
providerUrlBuffer.append(base.toUrl());
|
||||
}
|
||||
providerUrlBuffer.append(' ');
|
||||
}
|
||||
return providerUrlBuffer.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base suffix from which all operations should origin. If a base
|
||||
* suffix is set, you will not have to (and, indeed, should not) specify the
|
||||
* full distinguished names in the operations performed.
|
||||
*
|
||||
* @param base
|
||||
* the base suffix.
|
||||
*/
|
||||
public void setBase(String base) {
|
||||
this.base = new DistinguishedName(base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DirContext using the supplied environment.
|
||||
*
|
||||
* @param environment
|
||||
* the Ldap environment to use when creating the DirContext.
|
||||
* @return a new DirContext implpementation initialized with the supplied
|
||||
* environment.
|
||||
*/
|
||||
DirContext createContext(Hashtable environment) {
|
||||
DirContext ctx = null;
|
||||
|
||||
try {
|
||||
ctx = getDirContextInstance(environment);
|
||||
|
||||
if (log.isInfoEnabled()) {
|
||||
Hashtable ctxEnv = ctx.getEnvironment();
|
||||
String ldapUrl = (String) ctxEnv.get(Context.PROVIDER_URL);
|
||||
log.debug("Got Ldap context on server '" + ldapUrl + "'");
|
||||
}
|
||||
|
||||
return ctx;
|
||||
} catch (NamingException e) {
|
||||
closeContext(ctx);
|
||||
throw getExceptionTranslator().translate(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the context factory. Default is com.sun.jndi.ldap.LdapCtxFactory.
|
||||
*
|
||||
* @param contextFactory
|
||||
* the context factory used when creating Contexts.
|
||||
*/
|
||||
public void setContextFactory(Class contextFactory) {
|
||||
this.contextFactory = contextFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the DirObjectFactory to use. Default is
|
||||
* {@link DefaultDirObjectFactory}. The specified class needs to be an
|
||||
* implementation of javax.naming.spi.DirObjectFactory. <b>Note: </b>Setting
|
||||
* this value to null may have cause connection leaks when using
|
||||
* ContextMapper methods in LdapTemplate.
|
||||
*
|
||||
* @param dirObjectFactory
|
||||
* the DirObjectFactory to be used. Null means that no
|
||||
* DirObjectFactory will be used.
|
||||
*/
|
||||
public void setDirObjectFactory(Class dirObjectFactory) {
|
||||
this.dirObjectFactory = dirObjectFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that all necessary data is set and that there is no compatibility
|
||||
* issues, after which the instance is initialized. Note that you need to
|
||||
* call this method explicitly after setting all desired properties if using
|
||||
* the class outside of a Spring Context.
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (ArrayUtils.isEmpty(urls)) {
|
||||
throw new IllegalArgumentException(
|
||||
"At least one server url must be set");
|
||||
}
|
||||
|
||||
if (base != null && getJdkVersion().compareTo(JDK_142) < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Base path is not supported for JDK versions < 1.4.2");
|
||||
}
|
||||
|
||||
if (authenticationSource == null) {
|
||||
log.debug("AuthenticationSource not set - "
|
||||
+ "using default implementation");
|
||||
if (StringUtils.isBlank(userName)) {
|
||||
log
|
||||
.warn("Property 'userName' not set - "
|
||||
+ "anonymous context will be used for read-write operations");
|
||||
} else if (StringUtils.isBlank(password)) {
|
||||
log.warn("Property 'password' not set - "
|
||||
+ "blank password will be used");
|
||||
}
|
||||
authenticationSource = new SimpleAuthenticationSource();
|
||||
}
|
||||
|
||||
if (cacheEnvironmentProperties) {
|
||||
anonymousEnv = setupAnonymousEnv();
|
||||
}
|
||||
}
|
||||
|
||||
private Hashtable setupAnonymousEnv() {
|
||||
if (pooled) {
|
||||
baseEnv.put(SUN_LDAP_POOLING_FLAG, "true");
|
||||
log.debug("Using LDAP pooling.");
|
||||
} else {
|
||||
log.debug("Not using LDAP pooling");
|
||||
}
|
||||
|
||||
Hashtable env = new Hashtable(baseEnv);
|
||||
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory.getName());
|
||||
env.put(Context.PROVIDER_URL, assembleProviderUrlString(urls));
|
||||
|
||||
if (dirObjectFactory != null) {
|
||||
env.put(Context.OBJECT_FACTORIES, dirObjectFactory.getName());
|
||||
}
|
||||
|
||||
if (base != null) {
|
||||
// Save the base path for use in the DefaultDirObjectFactory.
|
||||
env.put(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY, base);
|
||||
}
|
||||
|
||||
log.debug("Trying provider Urls: " + assembleProviderUrlString(urls));
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password (credentials) to use for getting authenticated contexts.
|
||||
*
|
||||
* @param password
|
||||
* the password.
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user name (principal) to use for getting authenticated contexts.
|
||||
*
|
||||
* @param userName
|
||||
* the user name.
|
||||
*/
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the urls of the LDAP servers. Use this method if several servers are
|
||||
* required.
|
||||
*
|
||||
* @param urls
|
||||
* the urls of all servers.
|
||||
*/
|
||||
public void setUrls(String[] urls) {
|
||||
this.urls = urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the url of the LDAP server. Utility method if only one server is
|
||||
* used.
|
||||
*
|
||||
* @param url
|
||||
* the url of the LDAP server.
|
||||
*/
|
||||
public void setUrl(String url) {
|
||||
this.urls = new String[] { url };
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the pooling flag should be set. Default is true.
|
||||
*
|
||||
* @param pooled
|
||||
* whether Contexts should be pooled.
|
||||
*/
|
||||
public void setPooled(boolean pooled) {
|
||||
this.pooled = pooled;
|
||||
}
|
||||
|
||||
/**
|
||||
* If any custom environment properties are needed, these can be set using
|
||||
* this method.
|
||||
*
|
||||
* @param baseEnvironmentProperties
|
||||
*/
|
||||
public void setBaseEnvironmentProperties(Map baseEnvironmentProperties) {
|
||||
this.baseEnv = new Hashtable(baseEnvironmentProperties);
|
||||
}
|
||||
|
||||
String getJdkVersion() {
|
||||
return JdkVersion.getJavaVersion();
|
||||
}
|
||||
|
||||
protected Hashtable getAnonymousEnv() {
|
||||
if (cacheEnvironmentProperties) {
|
||||
return anonymousEnv;
|
||||
} else {
|
||||
return setupAnonymousEnv();
|
||||
}
|
||||
}
|
||||
|
||||
protected Hashtable getAuthenticatedEnv() {
|
||||
// The authenticated environment should always be rebuilt.
|
||||
Hashtable env = new Hashtable(getAnonymousEnv());
|
||||
setupAuthenticatedEnvironment(env);
|
||||
return env;
|
||||
}
|
||||
|
||||
public void setAuthenticationSource(
|
||||
AuthenticationSource authenticationProvider) {
|
||||
this.authenticationSource = authenticationProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether environment properties should be cached between requsts for
|
||||
* anonymous environment. Default is true; setting this property to false
|
||||
* causes the environment Hashmap to be rebuilt from the current property
|
||||
* settings of this instance between each request for an anonymous
|
||||
* environment.
|
||||
*
|
||||
* @param cacheEnvironmentProperties
|
||||
* true causes that the anonymous environment properties should
|
||||
* be cached, false causes the Hashmap to be rebuilt for each
|
||||
* request.
|
||||
*/
|
||||
public void setCacheEnvironmentProperties(boolean cacheEnvironmentProperties) {
|
||||
this.cacheEnvironmentProperties = cacheEnvironmentProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether an anonymous environment should be used for read-only
|
||||
* operations. Default is <code>false</code>.
|
||||
*
|
||||
* @param anonymousReadOnly
|
||||
* <code>true</code> if and anonymous environment should be
|
||||
* used for read-only operations, <code>false</code> otherwise.
|
||||
*/
|
||||
public void setAnonymousReadOnly(boolean anonymousReadOnly) {
|
||||
this.anonymousReadOnly = anonymousReadOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NamingExceptionTranslator to be used by this instance. By
|
||||
* default, a {@link DefaultNamingExceptionTranslator} will be used.
|
||||
*
|
||||
* @param exceptionTranslator
|
||||
* the NamingExceptionTranslator to use.
|
||||
*/
|
||||
public void setExceptionTranslator(
|
||||
NamingExceptionTranslator exceptionTranslator) {
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NamingExceptionTranslator used by this instance.
|
||||
*
|
||||
* @return the NamingExceptionTranslator.
|
||||
*/
|
||||
public NamingExceptionTranslator getExceptionTranslator() {
|
||||
return exceptionTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement in subclass to create a DirContext of the desired type (e.g.
|
||||
* InitialDirContext or InitialLdapContext).
|
||||
*
|
||||
* @param environment
|
||||
* the environment to use when creating the instance.
|
||||
* @return a new DirContext instance.
|
||||
* @throws NamingException
|
||||
* if one is encountered when creating the instance.
|
||||
*/
|
||||
protected abstract DirContext getDirContextInstance(Hashtable environment)
|
||||
throws NamingException;
|
||||
|
||||
class SimpleAuthenticationSource implements AuthenticationSource {
|
||||
|
||||
public String getPrincipal() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public String getCredentials() {
|
||||
return password;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String[] getUrls() {
|
||||
return urls;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.springframework.ldap.support;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
import org.springframework.ldap.DirContextProcessor;
|
||||
|
||||
/**
|
||||
* Manages a sequence of DirContextProcessor instances. Applies
|
||||
* {@link #preProcess(DirContext)} and {@link #postProcess(DirContext)}
|
||||
* respectively in sequence on the managed objects.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class AggregateDirContextProcessor implements DirContextProcessor {
|
||||
|
||||
private List dirContextProcessors = new LinkedList();
|
||||
|
||||
/**
|
||||
* Add the supplied DirContextProcessor to the list of managed objects.
|
||||
*
|
||||
* @param processor
|
||||
* the DirContextpProcessor to add.
|
||||
*/
|
||||
public void addDirContextProcessor(DirContextProcessor processor) {
|
||||
dirContextProcessors.add(processor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of managed DirContextProcessors.
|
||||
*
|
||||
* @return the managed list of {@link DirContextProcessor} instances.
|
||||
*/
|
||||
public List getDirContextProcessors() {
|
||||
return dirContextProcessors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of managed {@link DirContextProcessor} instances.
|
||||
*
|
||||
* @param dirContextProcessors
|
||||
* the list of {@link DirContextProcessor} instances to set.
|
||||
*/
|
||||
public void setDirContextProcessors(List dirContextProcessors) {
|
||||
this.dirContextProcessors = dirContextProcessors;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.ldap.DirContextProcessor#preProcess(javax.naming.directory.DirContext)
|
||||
*/
|
||||
public void preProcess(DirContext ctx) throws NamingException {
|
||||
for (Iterator iter = dirContextProcessors.iterator(); iter.hasNext();) {
|
||||
DirContextProcessor processor = (DirContextProcessor) iter.next();
|
||||
processor.preProcess(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.ldap.DirContextProcessor#postProcess(javax.naming.directory.DirContext)
|
||||
*/
|
||||
public void postProcess(DirContext ctx) throws NamingException {
|
||||
for (Iterator iter = dirContextProcessors.iterator(); iter.hasNext();) {
|
||||
DirContextProcessor processor = (DirContextProcessor) iter.next();
|
||||
processor.postProcess(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import javax.naming.directory.ModificationItem;
|
||||
|
||||
/**
|
||||
* Indicates that the implementor is capable of keeping track of any attribute
|
||||
* modifications and return them as ModificationItems.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public interface AttributeModificationsAware {
|
||||
|
||||
/**
|
||||
* Creates an array of which attributes have been changed or added or removed.
|
||||
*
|
||||
* @return an array of modification items
|
||||
*/
|
||||
public ModificationItem[] getModificationItems();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
|
||||
import org.springframework.ldap.NameClassPairCallbackHandler;
|
||||
|
||||
/**
|
||||
* A NameClassPairCallbackHandler for counting all returned entries.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class CountNameClassPairCallbackHandler implements
|
||||
NameClassPairCallbackHandler {
|
||||
|
||||
private int noOfRows = 0;
|
||||
|
||||
/**
|
||||
* Get the number of rows that was returned by the search.
|
||||
*
|
||||
* @return the number of entries that have been handled.
|
||||
*/
|
||||
public int getNoOfRows() {
|
||||
return noOfRows;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.SearchResultCallbackHandler#handleSearchResult(javax.naming.directory.SearchResult)
|
||||
*/
|
||||
public void handleNameClassPair(NameClassPair nameClassPair) {
|
||||
noOfRows++;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.spi.DirObjectFactory;
|
||||
|
||||
/**
|
||||
* Default implementation of the DirObjectFactory interface. Creates a
|
||||
* DirContextAdapter from the supplied arguments.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class DefaultDirObjectFactory implements DirObjectFactory {
|
||||
/**
|
||||
* Key to use in the ContextSource implementation to store the value of the
|
||||
* base path suffix, if any, in the Ldap Environment.
|
||||
*/
|
||||
public static final String JNDI_ENV_BASE_PATH_KEY = "org.springframework.ldap.base.path";
|
||||
|
||||
/**
|
||||
* Creates a DirContextAdapter from the supplied arguments.
|
||||
*
|
||||
* @param obj
|
||||
* @param name
|
||||
* @param nameCtx
|
||||
* @param environment
|
||||
* @param attrs
|
||||
* @return a new DirContextAdapter from the attributes and name.
|
||||
* @throws Exception
|
||||
*/
|
||||
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
|
||||
Hashtable environment, Attributes attrs) throws Exception {
|
||||
|
||||
try {
|
||||
DirContextAdapter dirContextAdapter = new DirContextAdapter(attrs,
|
||||
name, (Name) environment.get(JNDI_ENV_BASE_PATH_KEY));
|
||||
dirContextAdapter.setUpdateMode(true);
|
||||
|
||||
return dirContextAdapter;
|
||||
} finally {
|
||||
// It seems that the object supplied to the obj parameter is a
|
||||
// DirContext instance with reference to the same Ldap connection as
|
||||
// the original context. Since it is not the same instance (that's
|
||||
// the nameCtx parameter) this one really needs to be closed in
|
||||
// order to correctly clean up and return the connection to the pool
|
||||
// when we're finished with the surrounding operation.
|
||||
if (obj instanceof Context) {
|
||||
Context ctx = (Context) obj;
|
||||
try {
|
||||
ctx.close();
|
||||
} catch (Exception e) {
|
||||
// Never mind this
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null.
|
||||
*
|
||||
* @param obj
|
||||
* @param name
|
||||
* @param nameCtx
|
||||
* @param environment
|
||||
* @return null.
|
||||
* @throws Exception
|
||||
*/
|
||||
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
|
||||
Hashtable environment) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
/**
|
||||
* A factory for creating DnParser instances. The actual implementation of
|
||||
* DnParser is generated using javacc and should not be constructed directly.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class DefaultDnParserFactory {
|
||||
/**
|
||||
* Create a new DnParser instance.
|
||||
*
|
||||
* @param string
|
||||
* the DN String to be parsed.
|
||||
* @return a new DnParser instance for parsing the supplied DN string.
|
||||
*/
|
||||
public static DnParser createDnParser(String string) {
|
||||
return new DnParserImpl(new StringReader(string));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface for DirContextAdapter to simplify mock testing.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface DirContextOperations extends DirContext,
|
||||
AttributeModificationsAware {
|
||||
|
||||
/**
|
||||
* Gets the update mode. The update mode should be <code>true</code> for a
|
||||
* new entry and <code>true</code> for an existing entry that is being
|
||||
* updated.
|
||||
*
|
||||
* @return update mode
|
||||
*/
|
||||
public boolean isUpdateMode();
|
||||
|
||||
/**
|
||||
* Creates a String array of the names of the attributes which have been
|
||||
* changed.
|
||||
*
|
||||
* If this is a new entry, all set entries will be in the list. If this is
|
||||
* an updated entry, only changed and removed entries will be in the array.
|
||||
*
|
||||
* @return Array of String
|
||||
*/
|
||||
public String[] getNamesOfModifiedAttributes();
|
||||
|
||||
/**
|
||||
* Get the value of a String attribute.
|
||||
*
|
||||
* @param name
|
||||
* name of the attribute.
|
||||
* @return the value of the attribute.
|
||||
*/
|
||||
public String getStringAttribute(String name);
|
||||
|
||||
/**
|
||||
* Get the value of an Object attribute.
|
||||
*
|
||||
* @param name
|
||||
* name of the attribute.
|
||||
* @return the attribute value as an object if it exists, or
|
||||
* <code>null</code> otherwise.
|
||||
*/
|
||||
public Object getObjectAttribute(String name);
|
||||
|
||||
/**
|
||||
* Set the with the name <code>name</code> to the <code>value</code>.
|
||||
*
|
||||
* @param name
|
||||
* name of the attribute.
|
||||
* @param value
|
||||
* value to set the attribute to.
|
||||
*/
|
||||
public void setAttributeValue(String name, Object value);
|
||||
|
||||
/**
|
||||
* Sets a multivalue attribute, disregarding the order of the values.
|
||||
*
|
||||
* If value is null or value.length == 0 then the attribute will be removed.
|
||||
*
|
||||
* If update mode, changes will be made only if the array has more or less
|
||||
* objects or if one or more object has changed. Reordering the objects will
|
||||
* not cause an update.
|
||||
*
|
||||
* @param name
|
||||
* The id of the attribute.
|
||||
* @param values
|
||||
* Attribute values.
|
||||
*/
|
||||
public void setAttributeValues(String name, Object[] values);
|
||||
|
||||
/**
|
||||
* Sets a multivalue attribute.
|
||||
*
|
||||
* If value is null or value.length == 0 then the attribute will be removed.
|
||||
*
|
||||
* If update mode, changes will be made if the array has more or less
|
||||
* objects or if one or more string has changed.
|
||||
*
|
||||
* Reordering the objects will only cause an update if orderMatters is set
|
||||
* to true.
|
||||
*
|
||||
* @param name
|
||||
* The id of the attribute.
|
||||
* @param values
|
||||
* Attribute values.
|
||||
* @param orderMatters
|
||||
* If <code>true</code>, it will be changed even if data was
|
||||
* just reordered.
|
||||
*/
|
||||
public void setAttributeValues(String name, Object[] values,
|
||||
boolean orderMatters);
|
||||
|
||||
/**
|
||||
* Update the attributes. This will mean that the getters
|
||||
* (getStringAttribute methods) will return the updated values. Remove the
|
||||
* attributes to be updated.
|
||||
*/
|
||||
public void update();
|
||||
|
||||
/**
|
||||
* Get all values of a String attribute.
|
||||
*
|
||||
* @param name
|
||||
* name of the attribute.
|
||||
*
|
||||
* @return all registered values of the attribute.
|
||||
*/
|
||||
public String[] getStringAttributes(String name);
|
||||
|
||||
/**
|
||||
* Get all String values of the attribute as a SortedSet.
|
||||
*
|
||||
* @param name
|
||||
* name of the attribute.
|
||||
* @return a SortedSet containing all values of the attribute.
|
||||
*/
|
||||
public SortedSet getAttributeSortedStringSet(String name);
|
||||
|
||||
/**
|
||||
* Returns DN, without the base path.
|
||||
*
|
||||
* @return The distinguished name of the current context.
|
||||
*
|
||||
* @see DirContextAdapter#getNameInNamespace()
|
||||
*/
|
||||
public Name getDn();
|
||||
|
||||
/**
|
||||
* Set the dn of this entry.
|
||||
*
|
||||
* @param dn
|
||||
* the dn.
|
||||
*/
|
||||
public void setDn(Name dn);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
|
||||
/**
|
||||
* ContextSource implementation which creates InitialDirContext instances, for
|
||||
* LDAPv2 compatibility. For configuration information, see
|
||||
* {@link org.springframework.ldap.support.AbstractContextSource AbstractContextSource}.
|
||||
*
|
||||
* @see org.springframework.ldap.support.AbstractContextSource
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class DirContextSource extends AbstractContextSource {
|
||||
|
||||
/**
|
||||
* Create a new InitialDirContext instance.
|
||||
*
|
||||
* @param environment
|
||||
* the environment to use when creating the context.
|
||||
* @return a new InitialDirContext implementation.
|
||||
*/
|
||||
protected DirContext getDirContextInstance(Hashtable environment)
|
||||
throws NamingException {
|
||||
return new InitialDirContext(environment);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,629 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import javax.naming.CompositeName;
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.Name;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.ldap.BadLdapGrammarException;
|
||||
import org.springframework.ldap.util.ListComparator;
|
||||
|
||||
/**
|
||||
* Default implementation of a Name corresponding to an LDAP path. A
|
||||
* DistinguishedName implementation is included in JDK1.5 (LdapName), but not in
|
||||
* prior releases.
|
||||
*
|
||||
* An DistinguishedName is particularly useful when building or modifying an
|
||||
* Ldap path dynamically, as escaping will be taken care of.
|
||||
*
|
||||
* A path is split into several names. The Name interface specifies that the
|
||||
* most significant part be in position 0, i.e.
|
||||
*
|
||||
* The path: uid=adam.skogman, ou=People, ou=EU Name[0]: ou=EU Name[1]:
|
||||
* ou=People Name[2]: uid=adam.skogman
|
||||
* <p>
|
||||
* Useful for parsing and building LDAP paths.
|
||||
*
|
||||
* <pre>
|
||||
* DistinguishedName path = new DistinguishedName();
|
||||
* path.addLast("cn", entry.getUid());
|
||||
* path.addLast("ou", "users");
|
||||
* path.append(new DistinguishedName(helpdesk.getSomeSuffix()));
|
||||
* String dn = path.toString();
|
||||
* </pre>
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class DistinguishedName implements Name {
|
||||
private static final long serialVersionUID = 3514344371999042586L;
|
||||
|
||||
/**
|
||||
* An empty, unmodifiable DistinguishedName.
|
||||
*/
|
||||
public static final DistinguishedName EMPTY_PATH = new DistinguishedName(
|
||||
Collections.EMPTY_LIST);
|
||||
|
||||
private List names;
|
||||
|
||||
/**
|
||||
* Construct a new DistinguishedName with no components.
|
||||
*/
|
||||
public DistinguishedName() {
|
||||
names = new LinkedList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new DistinguishedName from a String.
|
||||
*
|
||||
* @param path
|
||||
* a String corresponding to a (syntactically) valid LDAP path.
|
||||
*/
|
||||
public DistinguishedName(String path) {
|
||||
if (StringUtils.isBlank(path)) {
|
||||
names = new LinkedList();
|
||||
} else {
|
||||
parse(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new DistinguishedName from the supplied List of LdapRdn
|
||||
* objects.
|
||||
*
|
||||
* @param list
|
||||
* the components that this instance will consist of.
|
||||
*/
|
||||
public DistinguishedName(List list) {
|
||||
this.names = list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new DistinguishedName from the supplied Name. The parts of
|
||||
* the supplied Name must be syntactically correct LdapRdns.
|
||||
*
|
||||
* @param name
|
||||
* the Name to construct a new DistinguishedName from.
|
||||
*/
|
||||
public DistinguishedName(Name name) {
|
||||
names = new LinkedList();
|
||||
for (int i = 0; i < name.size(); i++) {
|
||||
names.add(new LdapRdn(name.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the supplied String and make this instance represent the
|
||||
* corresponding distinguished name.
|
||||
*
|
||||
* @param path
|
||||
* the LDAP path to parse.
|
||||
*/
|
||||
protected void parse(String path) {
|
||||
DnParser parser = DefaultDnParserFactory
|
||||
.createDnParser(unmangleCompositeName(path));
|
||||
DistinguishedName dn;
|
||||
try {
|
||||
dn = parser.dn();
|
||||
} catch (ParseException e) {
|
||||
throw new BadLdapGrammarException("Failed to parse DN", e);
|
||||
} catch (TokenMgrError e) {
|
||||
throw new BadLdapGrammarException("Failed to parse DN", e);
|
||||
}
|
||||
this.names = dn.names;
|
||||
}
|
||||
|
||||
/**
|
||||
* If path is surrounded by quotes, strip them. JNDI considers forward slash
|
||||
* ('/') special, but LDAP doesn't. {@link CompositeName#toString()} tends
|
||||
* to mangle a Name with a slash by surrounding it with quotes ('"').
|
||||
*
|
||||
* @param path
|
||||
* Path to check and possibly strip.
|
||||
* @return A String with the possibly stripped path.
|
||||
*/
|
||||
private String unmangleCompositeName(String path) {
|
||||
String tempPath;
|
||||
// Check if CompositeName has mangled the name with quotes
|
||||
if (path.startsWith("\"") && path.endsWith("\"")) {
|
||||
tempPath = path.substring(1, path.length() - 1);
|
||||
} else {
|
||||
tempPath = path;
|
||||
}
|
||||
return tempPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the LdapRdn at a specified position.
|
||||
*
|
||||
* @param index
|
||||
* the LdapRdn to retrieve.
|
||||
* @return the LdapRdn at the requested position.
|
||||
*/
|
||||
public LdapRdn getLdapRdn(int index) {
|
||||
return (LdapRdn) names.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name list.
|
||||
*
|
||||
* @return the list of LdapRdns that this DistinguishedName consists of.
|
||||
*/
|
||||
public List getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the String representation of this DistinguishedName.
|
||||
*
|
||||
* @return a syntactically correct, escaped String representation of the
|
||||
* DistinguishedName.
|
||||
*/
|
||||
public String toString() {
|
||||
return encode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a complete LDAP path, ldap encoded, useful as a DN.
|
||||
*
|
||||
* Always uses lowercase, always separates with ", " i.e. comma and a space.
|
||||
*
|
||||
* @return the LDAP path.
|
||||
*/
|
||||
public String encode() {
|
||||
|
||||
// empty path
|
||||
if (names.size() == 0)
|
||||
return "";
|
||||
|
||||
StringBuffer buffer = new StringBuffer(256);
|
||||
|
||||
ListIterator i = names.listIterator(names.size());
|
||||
while (i.hasPrevious()) {
|
||||
LdapRdn rdn = (LdapRdn) i.previous();
|
||||
buffer.append(rdn.getLdapEncoded());
|
||||
|
||||
// add comma, except in last iteration
|
||||
if (i.hasPrevious())
|
||||
buffer.append(", ");
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a complete LDAP path, ldap and url encoded. Separates only with
|
||||
* ",".
|
||||
*
|
||||
* @return the LDAP path, for use in an url.
|
||||
*/
|
||||
public String toUrl() {
|
||||
StringBuffer buffer = new StringBuffer(256);
|
||||
|
||||
for (int i = names.size() - 1; i >= 0; i--) {
|
||||
LdapRdn n = (LdapRdn) names.get(i);
|
||||
buffer.append(n.encodeUrl());
|
||||
if (i > 0) {
|
||||
buffer.append(",");
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a ldap path contains another path.
|
||||
*
|
||||
* @param path
|
||||
* the path to check.
|
||||
* @return true if the supplied path is conained in this instance, false
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean contains(DistinguishedName path) {
|
||||
|
||||
List shortlist = path.getNames();
|
||||
|
||||
// this path must be at least as long
|
||||
if (getNames().size() < shortlist.size())
|
||||
return false;
|
||||
|
||||
// must have names
|
||||
if (shortlist.size() == 0)
|
||||
return false;
|
||||
|
||||
Iterator longiter = getNames().iterator();
|
||||
Iterator shortiter = shortlist.iterator();
|
||||
|
||||
LdapRdn longname = (LdapRdn) longiter.next();
|
||||
LdapRdn shortname = (LdapRdn) shortiter.next();
|
||||
|
||||
// find first match
|
||||
while (!longname.equals(shortname) && longiter.hasNext()) {
|
||||
longname = (LdapRdn) longiter.next();
|
||||
}
|
||||
|
||||
// Done?
|
||||
if (!shortiter.hasNext() && longname.equals(shortname))
|
||||
return true;
|
||||
if (!longiter.hasNext())
|
||||
return false;
|
||||
|
||||
// compare
|
||||
while (longname.equals(shortname) && longiter.hasNext()
|
||||
&& shortiter.hasNext()) {
|
||||
longname = (LdapRdn) longiter.next();
|
||||
shortname = (LdapRdn) shortiter.next();
|
||||
}
|
||||
|
||||
// Done
|
||||
if (!shortiter.hasNext() && longname.equals(shortname))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a LDAP path first
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
public void append(DistinguishedName path) {
|
||||
getNames().addAll(path.getNames());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a LDAP path first
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
public void prepend(DistinguishedName path) {
|
||||
ListIterator i = path.getNames().listIterator(path.getNames().size());
|
||||
while (i.hasPrevious()) {
|
||||
names.add(0, i.previous());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the first part of this DistinguishedName.
|
||||
*
|
||||
* @return the removed entry.
|
||||
*/
|
||||
public LdapRdn removeFirst() {
|
||||
return (LdapRdn) names.remove(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the supplied path from the beginning of this DistinguishedName if
|
||||
* this instance starts with <path>. Useful for stripping base path suffix
|
||||
* from a DistinguishedName.
|
||||
*
|
||||
* @param path
|
||||
* the path to remove from the beginning of this instance.
|
||||
*/
|
||||
public void removeFirst(Name path) {
|
||||
if (path != null && this.startsWith(path)) {
|
||||
for (int i = 0; i < path.size(); i++)
|
||||
this.removeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
public Object clone() {
|
||||
|
||||
// just duplicate the list, the rdns are immutable.
|
||||
LinkedList list = new LinkedList(getNames());
|
||||
|
||||
return new DistinguishedName(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
// A subclass with identical values should NOT be considered equal.
|
||||
// EqualsBuilder in commons-lang cannot handle subclasses correctly.
|
||||
if (obj == null || obj.getClass() != this.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DistinguishedName name = (DistinguishedName) obj;
|
||||
|
||||
// compare the lists
|
||||
return getNames().equals(name.getNames());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return this.getClass().hashCode() ^ getNames().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this instance to another object. Note that the comparison is done
|
||||
* in order of significance, so the most significant Rdn is compared first,
|
||||
* then the second and so on.
|
||||
*
|
||||
* @see javax.naming.Name#compareTo(java.lang.Object)
|
||||
*/
|
||||
public int compareTo(Object obj) {
|
||||
DistinguishedName that = (DistinguishedName) obj;
|
||||
ListComparator comparator = new ListComparator();
|
||||
return comparator.compare(this.names, that.names);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return names.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return names.size() == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#getAll()
|
||||
*/
|
||||
public Enumeration getAll() {
|
||||
LinkedList strings = new LinkedList();
|
||||
for (Iterator iter = names.iterator(); iter.hasNext();) {
|
||||
LdapRdn rdn = (LdapRdn) iter.next();
|
||||
strings.add(rdn.getLdapEncoded());
|
||||
}
|
||||
|
||||
return Collections.enumeration(strings);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#get(int)
|
||||
*/
|
||||
public String get(int index) {
|
||||
LdapRdn rdn = (LdapRdn) names.get(index);
|
||||
return rdn.getLdapEncoded();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#getPrefix(int)
|
||||
*/
|
||||
public Name getPrefix(int index) {
|
||||
LinkedList newNames = new LinkedList();
|
||||
for (int i = 0; i < index; i++) {
|
||||
newNames.add(names.get(i));
|
||||
}
|
||||
|
||||
return new DistinguishedName(newNames);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#getSuffix(int)
|
||||
*/
|
||||
public Name getSuffix(int index) {
|
||||
if (index > names.size()) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
LinkedList newNames = new LinkedList();
|
||||
for (int i = index; i < names.size(); i++) {
|
||||
newNames.add(names.get(i));
|
||||
}
|
||||
|
||||
return new DistinguishedName(newNames);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#startsWith(javax.naming.Name)
|
||||
*/
|
||||
public boolean startsWith(Name name) {
|
||||
if (name.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DistinguishedName start = null;
|
||||
if (name instanceof DistinguishedName) {
|
||||
start = (DistinguishedName) name;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (start.size() > this.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator longiter = names.iterator();
|
||||
Iterator shortiter = start.getNames().iterator();
|
||||
|
||||
while (shortiter.hasNext()) {
|
||||
Object longname = longiter.next();
|
||||
Object shortname = shortiter.next();
|
||||
|
||||
if (!longname.equals(shortname)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All names in shortiter matched.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this ldap path ends with a certian path.
|
||||
*
|
||||
* If the argument path is empty (no names in path) this methid will return
|
||||
* false.
|
||||
*
|
||||
* @param name
|
||||
* The suffix to check for
|
||||
*
|
||||
*/
|
||||
public boolean endsWith(Name name) {
|
||||
DistinguishedName path = null;
|
||||
if (name instanceof DistinguishedName) {
|
||||
path = (DistinguishedName) name;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
List shortlist = path.getNames();
|
||||
|
||||
// this path must be at least as long
|
||||
if (getNames().size() < shortlist.size())
|
||||
return false;
|
||||
|
||||
// must have names
|
||||
if (shortlist.size() == 0)
|
||||
return false;
|
||||
|
||||
ListIterator longiter = getNames().listIterator(getNames().size());
|
||||
ListIterator shortiter = shortlist.listIterator(shortlist.size());
|
||||
|
||||
while (shortiter.hasPrevious()) {
|
||||
LdapRdn longname = (LdapRdn) longiter.previous();
|
||||
LdapRdn shortname = (LdapRdn) shortiter.previous();
|
||||
|
||||
if (!longname.equals(shortname))
|
||||
return false;
|
||||
}
|
||||
|
||||
// if short list ended, all were equal
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#addAll(javax.naming.Name)
|
||||
*/
|
||||
public Name addAll(Name name) throws InvalidNameException {
|
||||
return addAll(names.size(), name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#addAll(int, javax.naming.Name)
|
||||
*/
|
||||
public Name addAll(int arg0, Name name) throws InvalidNameException {
|
||||
DistinguishedName distinguishedName = null;
|
||||
try {
|
||||
distinguishedName = (DistinguishedName) name;
|
||||
} catch (ClassCastException e) {
|
||||
throw new InvalidNameException("Invalid name type");
|
||||
}
|
||||
|
||||
names.addAll(arg0, distinguishedName.getNames());
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#add(java.lang.String)
|
||||
*/
|
||||
public Name add(String string) throws InvalidNameException {
|
||||
return add(names.size(), string);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#add(int, java.lang.String)
|
||||
*/
|
||||
public Name add(int index, String string) throws InvalidNameException {
|
||||
try {
|
||||
names.add(index, new LdapRdn(string));
|
||||
} catch (BadLdapGrammarException e) {
|
||||
throw new InvalidNameException("Failed to parse rdn '" + string
|
||||
+ "'");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see javax.naming.Name#remove(int)
|
||||
*/
|
||||
public Object remove(int arg0) throws InvalidNameException {
|
||||
LdapRdn rdn = (LdapRdn) names.remove(arg0);
|
||||
return rdn.getLdapEncoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the ldast part of this DistinguishedName.
|
||||
*
|
||||
* @return the removed LdapRdn.
|
||||
*/
|
||||
public LdapRdn removeLast() {
|
||||
return (LdapRdn) names.remove(names.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new LdapRdn using the supplied key and value.
|
||||
*
|
||||
* @param key
|
||||
* the key of the LdapRdn.
|
||||
* @param value
|
||||
* the value of the LdapRdn.
|
||||
*/
|
||||
public void add(String key, String value) {
|
||||
names.add(new LdapRdn(key, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the supplied LdapRdn last in the list of Rdns.
|
||||
*
|
||||
* @param rdn
|
||||
* the LdapRdn to add.
|
||||
*/
|
||||
public void add(LdapRdn rdn) {
|
||||
names.add(rdn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the supplied LdapRdn att the specified index.
|
||||
*
|
||||
* @param idx
|
||||
* the index at which to add the LdapRdn.
|
||||
* @param rdn
|
||||
* the LdapRdn to add.
|
||||
*/
|
||||
public void add(int idx, LdapRdn rdn) {
|
||||
names.add(idx, rdn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
|
||||
/**
|
||||
* A parser for RFC2253-compliant Distinguished Names.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public interface DnParser {
|
||||
/**
|
||||
* Parse a full Distinguished Name.
|
||||
*
|
||||
* @return the DistinguishedName corresponding to the parsed stream.
|
||||
*/
|
||||
public DistinguishedName dn() throws ParseException;
|
||||
|
||||
/**
|
||||
* Parse a Relative Distinguished Name.
|
||||
*
|
||||
* @return the next rdn on the stream.
|
||||
*/
|
||||
public LdapRdn rdn() throws ParseException;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.ldap.ControlFactory;
|
||||
import javax.naming.ldap.InitialLdapContext;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
|
||||
import com.sun.jndi.ldap.ctl.ResponseControlFactory;
|
||||
|
||||
/**
|
||||
* ContextSource implementation which creates an <code>InitialLdapContext</code>
|
||||
* instance. For configuration information, see
|
||||
* {@link org.springframework.ldap.support.AbstractContextSource AbstractContextSource}.
|
||||
*
|
||||
* @see org.springframework.ldap.support.AbstractContextSource
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
* @author Adam Skogman
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class LdapContextSource extends AbstractContextSource {
|
||||
|
||||
private static final Class DEFAULT_RESPONSE_CONTROL_FACTORY = ResponseControlFactory.class;
|
||||
|
||||
private Class responseControlFactory = DEFAULT_RESPONSE_CONTROL_FACTORY;
|
||||
|
||||
protected Hashtable getAnonymousEnv() {
|
||||
Hashtable env = super.getAnonymousEnv();
|
||||
env
|
||||
.put(LdapContext.CONTROL_FACTORIES, responseControlFactory
|
||||
.getName() + ".trasig");
|
||||
return env;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.ldap.support.AbstractContextSource#getDirContextInstance(java.util.Hashtable)
|
||||
*/
|
||||
protected DirContext getDirContextInstance(Hashtable environment)
|
||||
throws NamingException {
|
||||
return new InitialLdapContext(environment, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ResponseControlFactory to use. Default is
|
||||
* {@link com.sun.jndi.ldap.ctl.ResponseControlFactory}. The specified
|
||||
* class needs to be an implementation of
|
||||
* {@link javax.naming.ldap.ControlFactory}.
|
||||
*
|
||||
* @param responseControlFactory
|
||||
* the ResponseControlFactory to be used. Null means reset to the
|
||||
* default.
|
||||
*/
|
||||
public void setResponseControlFactory(Class responseControlFactory) {
|
||||
if (responseControlFactory == null) {
|
||||
this.responseControlFactory = DEFAULT_RESPONSE_CONTROL_FACTORY;
|
||||
} else if (ControlFactory.class
|
||||
.isAssignableFrom(responseControlFactory)) {
|
||||
this.responseControlFactory = responseControlFactory;
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid ReponseControlFactory: " + responseControlFactory
|
||||
+ " is not an implementation of "
|
||||
+ ControlFactory.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current ResponseControlFactory.
|
||||
*/
|
||||
Class getResponseControlFactory() {
|
||||
return responseControlFactory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.ldap.BadLdapGrammarException;
|
||||
|
||||
/**
|
||||
* Helper class to encode and decode ldap names and values.
|
||||
*
|
||||
* @author Adam Skogman
|
||||
*/
|
||||
public class LdapEncoder {
|
||||
|
||||
static private String[] nameEscapeTable = new String[96];
|
||||
|
||||
static private String[] filterEscapeTable = new String['\\' + 1];
|
||||
|
||||
/**
|
||||
* Pattern for matching escaped ldap name values.
|
||||
*
|
||||
* Double escaping: \ -> \\ (in pattern) -> \\\\ (in java string literal)
|
||||
*
|
||||
* Group 1: Hex escapes = \XX -> \p{XDigit}{2} Group 2: Ordinary escapes =
|
||||
* \x -> \. Group 3: Anything but \ [^\\]
|
||||
*
|
||||
* Note that the \ is not part of the match.
|
||||
*/
|
||||
static private final Pattern VALUE_DECODE_PATTERN = Pattern
|
||||
.compile("(?:\\\\(\\p{XDigit}{2}))|(?:\\\\(.))|([^\\\\])");
|
||||
|
||||
static {
|
||||
|
||||
// Name encoding table -------------------------------------
|
||||
|
||||
// all below 0x20 (control chars)
|
||||
for (char c = 0; c < ' '; c++) {
|
||||
nameEscapeTable[c] = "\\" + toTwoCharHex(c);
|
||||
}
|
||||
|
||||
nameEscapeTable['#'] = "\\#";
|
||||
nameEscapeTable[','] = "\\,";
|
||||
nameEscapeTable[';'] = "\\;";
|
||||
nameEscapeTable['='] = "\\=";
|
||||
nameEscapeTable['+'] = "\\+";
|
||||
nameEscapeTable['<'] = "\\<";
|
||||
nameEscapeTable['>'] = "\\>";
|
||||
// nameEscapeTable['\''] = "\\";
|
||||
nameEscapeTable['\"'] = "\\\"";
|
||||
// nameEscapeTable['/'] = "\\" + toTwoCharHex('/');
|
||||
nameEscapeTable['\\'] = "\\\\";
|
||||
|
||||
// Filter encoding table -------------------------------------
|
||||
|
||||
// fill with char itself
|
||||
for (char c = 0; c < filterEscapeTable.length; c++) {
|
||||
filterEscapeTable[c] = String.valueOf(c);
|
||||
}
|
||||
|
||||
// escapes (RFC2254)
|
||||
filterEscapeTable['*'] = "\\2a";
|
||||
filterEscapeTable['('] = "\\28";
|
||||
filterEscapeTable[')'] = "\\29";
|
||||
filterEscapeTable['\\'] = "\\5c";
|
||||
filterEscapeTable[0] = "\\00";
|
||||
|
||||
}
|
||||
|
||||
static protected String toTwoCharHex(char c) {
|
||||
|
||||
String raw = Integer.toHexString(c).toUpperCase();
|
||||
|
||||
if (raw.length() > 1)
|
||||
return raw;
|
||||
else
|
||||
return "0" + raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* All static methods
|
||||
*/
|
||||
private LdapEncoder() {
|
||||
}
|
||||
|
||||
static public String filterEncode(String value) {
|
||||
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
// make buffer roomy
|
||||
StringBuffer encodedValue = new StringBuffer(value.length() * 2);
|
||||
|
||||
int length = value.length();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
char c = value.charAt(i);
|
||||
|
||||
if (c < filterEscapeTable.length) {
|
||||
encodedValue.append(filterEscapeTable[c]);
|
||||
} else {
|
||||
// default: add the char
|
||||
encodedValue.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return encodedValue.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* LDAP Encodes a value for use with a DN. Escapes for LDAP, not JNDI!
|
||||
*
|
||||
* <br/>Escapes:<br/> ' ' [space] - "\ " [if first or last] <br/> '#'
|
||||
* [hash] - "\#" <br/> ',' [comma] - "\," <br/> ';' [semicolon] - "\;" <br/> '=
|
||||
* [equals] - "\=" <br/> '+' [plus] - "\+" <br/> '<' [less than] -
|
||||
* "\<" <br/> '>' [greater than] - "\>" <br/> '"' [double quote] -
|
||||
* "\"" <br/> '\' [backslash] - "\\" <br/>
|
||||
*
|
||||
* @param value
|
||||
* @return The escaped value
|
||||
*/
|
||||
static public String nameEncode(String value) {
|
||||
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
// make buffer roomy
|
||||
StringBuffer encodedValue = new StringBuffer(value.length() * 2);
|
||||
|
||||
int length = value.length();
|
||||
int last = length - 1;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
char c = value.charAt(i);
|
||||
|
||||
// space first or last
|
||||
if (c == ' ' && (i == 0 || i == last)) {
|
||||
encodedValue.append("\\ ");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c < nameEscapeTable.length) {
|
||||
// check in table for escapes
|
||||
String esc = nameEscapeTable[c];
|
||||
|
||||
if (esc != null) {
|
||||
encodedValue.append(esc);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// default: add the char
|
||||
encodedValue.append(c);
|
||||
}
|
||||
|
||||
return encodedValue.toString();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a value. Converts escaped chars to ordinary chars.
|
||||
*
|
||||
* @param value
|
||||
* Trimmed value, so no leading an trailing blanks, except an
|
||||
* escaped space last.
|
||||
* @return The decoded value as a string.
|
||||
* @throws BadLdapGrammarException
|
||||
*/
|
||||
static public String nameDecode(String value)
|
||||
throws BadLdapGrammarException {
|
||||
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
// make buffer same size
|
||||
StringBuffer decoded = new StringBuffer(value.length());
|
||||
|
||||
Matcher matcher = VALUE_DECODE_PATTERN.matcher(value);
|
||||
|
||||
int end = 0;
|
||||
|
||||
while (matcher.find()) {
|
||||
end = matcher.end();
|
||||
// group 1
|
||||
if (matcher.group(1) != null) {
|
||||
// parse as hex = base 16
|
||||
try {
|
||||
char c = (char) Integer.parseInt(matcher.group(1), 16);
|
||||
decoded.append(c);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new BadLdapGrammarException(
|
||||
"Escaped hex value Could not be parsed. Found '\\"
|
||||
+ matcher.group(1) + "'");
|
||||
}
|
||||
} else if (matcher.group(2) != null) {
|
||||
// just add, we stripped away the \
|
||||
decoded.append(matcher.group(2));
|
||||
} else if (matcher.group(3) != null) {
|
||||
// just add
|
||||
decoded.append(matcher.group(3));
|
||||
}
|
||||
|
||||
}
|
||||
// end is match + +1 so it should be same as length, i.e.
|
||||
// last + 1
|
||||
if (end < value.length()) {
|
||||
throw new BadLdapGrammarException(
|
||||
"RDN could not be parsed fully, remaining '"
|
||||
+ StringUtils.substring(value, end) + "'");
|
||||
}
|
||||
|
||||
return decoded.toString();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ldap.BadLdapGrammarException;
|
||||
import org.springframework.ldap.util.ListComparator;
|
||||
|
||||
/**
|
||||
* Datatype for a LDAP name, a part of a path.
|
||||
*
|
||||
* The name: uid=adam.skogman Key: uid Value: adam.skogman
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class LdapRdn implements Serializable, Comparable {
|
||||
private static final long serialVersionUID = 5681397547245228750L;
|
||||
|
||||
private List components = new LinkedList();
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public LdapRdn() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the supplied string and construct this instance accordingly.
|
||||
*
|
||||
* @param string
|
||||
* the string to parse.
|
||||
*/
|
||||
public LdapRdn(String string) {
|
||||
DnParser parser = DefaultDnParserFactory.createDnParser(string);
|
||||
LdapRdn rdn;
|
||||
try {
|
||||
rdn = parser.rdn();
|
||||
} catch (ParseException e) {
|
||||
throw new BadLdapGrammarException("Failed to parse Rdn", e);
|
||||
} catch (TokenMgrError e) {
|
||||
throw new BadLdapGrammarException("Failed to parse Rdn", e);
|
||||
}
|
||||
this.components = rdn.components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an LdapRdn using the supplied key and value.
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public LdapRdn(String key, String value) {
|
||||
components.add(new LdapRdnComponent(key, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an LdapRdnComponent to this LdapRdn.
|
||||
*
|
||||
* @param rdnComponent
|
||||
* the LdapRdnComponent to add.s
|
||||
*/
|
||||
public void addComponent(LdapRdnComponent rdnComponent) {
|
||||
components.add(rdnComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all components in this LdapRdn.
|
||||
*
|
||||
* @return the List of all LdapRdnComponents composing this LdapRdn.
|
||||
*/
|
||||
public List getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first LdapRdnComponent of this LdapRdn.
|
||||
*
|
||||
* @return The first LdapRdnComponent of this LdapRdn.
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if no components have been added.
|
||||
*/
|
||||
public LdapRdnComponent getComponent() {
|
||||
return (LdapRdnComponent) components.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the LdapRdnComponent at index <code>idx</code>.
|
||||
*
|
||||
* @param idx
|
||||
* the 0-based index of the component to get.
|
||||
* @return the LdapRdnComponent at indet <code>idx</code>.
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if no component exists at index <code>idx</code>.
|
||||
*/
|
||||
public LdapRdnComponent getComponent(int idx) {
|
||||
return (LdapRdnComponent) components.get(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a properly rfc2253-encoded String representation to this LdapRdn.
|
||||
*
|
||||
* @return an encoded String corresponding to this LdapRdn.
|
||||
*/
|
||||
public String getLdapEncoded() {
|
||||
if (components.size() == 0) {
|
||||
throw new IndexOutOfBoundsException("No components in Rdn.");
|
||||
}
|
||||
StringBuffer sb = new StringBuffer(100);
|
||||
for (Iterator iter = components.iterator(); iter.hasNext();) {
|
||||
LdapRdnComponent component = (LdapRdnComponent) iter.next();
|
||||
sb.append(component.encodeLdap());
|
||||
if (iter.hasNext()) {
|
||||
sb.append("+");
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a String representation of this LdapRdn for use in urls.
|
||||
*
|
||||
* @return a String representation of this LdapRdn for use in urls.
|
||||
*/
|
||||
public String encodeUrl() {
|
||||
StringBuffer sb = new StringBuffer(100);
|
||||
for (Iterator iter = components.iterator(); iter.hasNext();) {
|
||||
LdapRdnComponent component = (LdapRdnComponent) iter.next();
|
||||
sb.append(component.encodeUrl());
|
||||
if (iter.hasNext()) {
|
||||
sb.append("+");
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this LdapRdn to another object.
|
||||
*
|
||||
* @param obj
|
||||
* the object to compare to.
|
||||
* @throws ClassCastException
|
||||
* if the supplied object is not an LdapRdn instance.
|
||||
*/
|
||||
public int compareTo(Object obj) {
|
||||
LdapRdn that = (LdapRdn) obj;
|
||||
Comparator comparator = new ListComparator();
|
||||
return comparator.compare(this.components, that.components);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || obj.getClass() != this.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LdapRdn that = (LdapRdn) obj;
|
||||
return this.getComponents().equals(that.getComponents());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return this.getClass().hashCode() ^ getComponents().hashCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return getLdapEncoded();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
/**
|
||||
* Represents part of an LdapRdn. As specified in RFC2253 an LdapRdn may be
|
||||
* composed of several attributes, separated by "+". An
|
||||
* LdapRdnComponent represents one of these attributes.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class LdapRdnComponent implements Comparable {
|
||||
public static final boolean DONT_DECODE_VALUE = false;
|
||||
|
||||
private String key;
|
||||
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* Constructs an LdapRdnComponent without decoding the value.
|
||||
*
|
||||
* @param key
|
||||
* the Atttribute name.
|
||||
* @param value
|
||||
* the Attribute value.
|
||||
*/
|
||||
public LdapRdnComponent(String key, String value) {
|
||||
this(key, value, DONT_DECODE_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an LdapRdnComponent, optionally decoding the value.
|
||||
*
|
||||
* @param key
|
||||
* the Atttribute name.
|
||||
* @param value
|
||||
* the Attribute value.
|
||||
* @param decodeValue
|
||||
* if <code>true</code> the value is decoded (typically used
|
||||
* when a DN is parsed from a String), otherwise the value is
|
||||
* used as specified.
|
||||
*/
|
||||
public LdapRdnComponent(String key, String value, boolean decodeValue) {
|
||||
Validate.notEmpty(key, "Key must not be empty");
|
||||
Validate.notEmpty(value, "Value must not be empty");
|
||||
|
||||
this.key = StringUtils.lowerCase(key);
|
||||
if (decodeValue) {
|
||||
this.value = LdapEncoder.nameDecode(value);
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode key and value to ldap
|
||||
*
|
||||
* @return The ldap encoded rdn
|
||||
*/
|
||||
protected String encodeLdap() {
|
||||
StringBuffer buff = new StringBuffer(key.length() + value.length() * 2);
|
||||
|
||||
buff.append(key);
|
||||
buff.append('=');
|
||||
buff.append(LdapEncoder.nameEncode(value));
|
||||
|
||||
return buff.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return getLdapEncoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The LdapRdn as a string where the value is LDAP-encoded.
|
||||
*/
|
||||
public String getLdapEncoded() {
|
||||
return encodeLdap();
|
||||
}
|
||||
|
||||
public String encodeUrl() {
|
||||
// Use the URI class to properly URL encode the value.
|
||||
try {
|
||||
URI valueUri = new URI(null, null, value, null);
|
||||
return key + "=" + valueUri.toString();
|
||||
} catch (URISyntaxException e) {
|
||||
// This should really never happen...
|
||||
return key + "=" + "value";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return key.hashCode() ^ value.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj != null && obj.getClass() == LdapRdnComponent.class) {
|
||||
LdapRdnComponent that = (LdapRdnComponent) obj;
|
||||
return StringUtils.equalsIgnoreCase(this.key, that.key)
|
||||
&& StringUtils.equalsIgnoreCase(this.value, that.value);
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this instance to the supplied object.
|
||||
*
|
||||
* @param obj
|
||||
* the object to compare to.
|
||||
* @throws ClassCastException
|
||||
* if the object is not possible to cast to an LdapRdnComponent.
|
||||
*/
|
||||
public int compareTo(Object obj) {
|
||||
LdapRdnComponent that = (LdapRdnComponent) obj;
|
||||
return this.toString().compareTo(that.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.authentication;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.AuthenticationSource;
|
||||
|
||||
|
||||
/**
|
||||
* An AuthenticationSource to retrieve authentication information stored in
|
||||
* Acegi's SecurityContextHolder. Use Acegi's LdapAuthenticationProvider have a
|
||||
* LdapUserDetails object placed in the authentication.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class AcegiAuthenticationSource implements AuthenticationSource {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(AcegiAuthenticationSource.class);
|
||||
|
||||
/**
|
||||
* Get the principals of the logged in user, in this case the distinguished
|
||||
* name.
|
||||
*
|
||||
* @return the distinguished name of the logged in user.
|
||||
*/
|
||||
public String getPrincipal() {
|
||||
Authentication authentication = SecurityContextHolder.getContext()
|
||||
.getAuthentication();
|
||||
if (authentication != null) {
|
||||
Object principal = authentication.getPrincipal();
|
||||
if (!(principal instanceof LdapUserDetails)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The principal property of the authentication object -"
|
||||
+ "needs to be a LdapUserDetails.");
|
||||
} else {
|
||||
LdapUserDetails details = (LdapUserDetails) principal;
|
||||
return details.getDn();
|
||||
}
|
||||
} else {
|
||||
log.warn("No Authentication object set in SecurityContext - "
|
||||
+ "returning empty String as Principal");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.ldap.AuthenticationSource#getCredentials()
|
||||
*/
|
||||
public String getCredentials() {
|
||||
Authentication authentication = SecurityContextHolder.getContext()
|
||||
.getAuthentication();
|
||||
|
||||
if (authentication != null) {
|
||||
return (String) authentication.getCredentials();
|
||||
} else {
|
||||
log.warn("No Authentication object set in SecurityContext - "
|
||||
+ "returning empty String as Credentials");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.authentication;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.ldap.AuthenticationSource;
|
||||
|
||||
/**
|
||||
* Decorator on AuthenticationSource to have default authentication information
|
||||
* be returned should the target return empty principal and credentials. Useful
|
||||
* in combination with {@link AcegiAuthenticationSource} if users are to be
|
||||
* allowed to read some information even though they are not logged in.
|
||||
* <p>
|
||||
* <b>Note:</b> The <code>defaultUser</code> should be an non-privileged
|
||||
* user. This is important as this is the one that will be used when no user is
|
||||
* logged in (i.e. empty principal is returned from the target
|
||||
* AuthenticationSource).
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class DefaultValuesAuthenticationSourceDecorator implements
|
||||
AuthenticationSource, InitializingBean {
|
||||
|
||||
private AuthenticationSource target;
|
||||
|
||||
private String defaultUser;
|
||||
|
||||
private String defaultPassword;
|
||||
|
||||
/**
|
||||
* Constructor for bean usage.
|
||||
*/
|
||||
public DefaultValuesAuthenticationSourceDecorator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to setup instance directly.
|
||||
*
|
||||
* @param target
|
||||
* the target AuthenticationSource.
|
||||
* @param defaultUser
|
||||
* dn of the user to use when the target returns an empty
|
||||
* principal.
|
||||
* @param defaultPassword
|
||||
* password of the user to use when the target returns an empty
|
||||
* principal.
|
||||
*/
|
||||
public DefaultValuesAuthenticationSourceDecorator(
|
||||
AuthenticationSource target, String defaultUser,
|
||||
String defaultPassword) {
|
||||
this.target = target;
|
||||
this.defaultUser = defaultUser;
|
||||
this.defaultPassword = defaultPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the target's principal is not empty; if not, the credentials
|
||||
* from the target is returned - otherwise return the
|
||||
* <code>defaultPassword</code>.
|
||||
*
|
||||
* @return the target's password if the target's principal is not empty, the
|
||||
* <code>defaultPassword</code> otherwise.
|
||||
*/
|
||||
public String getCredentials() {
|
||||
if (StringUtils.isNotEmpty(target.getPrincipal())) {
|
||||
return target.getCredentials();
|
||||
} else {
|
||||
return defaultPassword;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the target's principal is not empty; if not, this is returned -
|
||||
* otherwise return the <code>defaultUser</code>.
|
||||
*
|
||||
* @return the target's principal if it is not empty, the
|
||||
* <code>defaultUser</code> otherwise.
|
||||
*/
|
||||
public String getPrincipal() {
|
||||
String principal = target.getPrincipal();
|
||||
if (StringUtils.isNotEmpty(principal)) {
|
||||
return principal;
|
||||
} else {
|
||||
return defaultUser;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password of the default user.
|
||||
*
|
||||
* @param defaultPassword
|
||||
* the password of the default user.
|
||||
*/
|
||||
public void setDefaultPassword(String defaultPassword) {
|
||||
this.defaultPassword = defaultPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default user DN. This should be a non-privileged user, since it
|
||||
* will be used when no authentication information is returned from the
|
||||
* target.
|
||||
*
|
||||
* @param defaultUser
|
||||
* DN of the default user.
|
||||
*/
|
||||
public void setDefaultUser(String defaultUser) {
|
||||
this.defaultUser = defaultUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the target AuthenticationSource.
|
||||
*
|
||||
* @param target
|
||||
* the target AuthenticationSource.
|
||||
*/
|
||||
public void setTarget(AuthenticationSource target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property 'target' must be set.'");
|
||||
}
|
||||
|
||||
if (defaultUser == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property 'defaultUser' must be set.'");
|
||||
}
|
||||
|
||||
if (defaultPassword == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property 'defaultPassword' must be set.'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
Support classes for custom authentication.
|
||||
</body>
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.control;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.ldap.Control;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.ldap.DirContextProcessor;
|
||||
|
||||
/**
|
||||
* Abstract superclass with responsibility to apply a single RequestControl on
|
||||
* an LdapContext, preserving any existing controls. Subclasses should implement
|
||||
* {@link DirContextProcessor#postProcess(DirContext)} and template method
|
||||
* {@link #createRequestControl()}.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public abstract class AbstractRequestControlDirContextProcessor implements
|
||||
DirContextProcessor {
|
||||
protected Log log = LogFactory
|
||||
.getLog(AbstractRequestControlDirContextProcessor.class);
|
||||
|
||||
/**
|
||||
* Get the existing RequestControls from the LdapContext, call
|
||||
* {@link #createRequestControl()} to get a new instance, build a new array
|
||||
* of Controls and set it on the LdapContext.
|
||||
* <p>
|
||||
* The {@link Control} feature is specific for LDAP v3 and thus applies only
|
||||
* to {@link LdapContext}. However, the generic DirContextProcessor
|
||||
* mechanism used for calling <code>preProcess</code> and
|
||||
* <code>postProcess</code> uses DirContext, since it also works for LDAP
|
||||
* v2. This is the reason that DirContext has to be cast into LdapContext.
|
||||
*
|
||||
* @param ctx
|
||||
* an LdapContext instance.
|
||||
* @throws NamingException
|
||||
* @throws IllegalArgumentException
|
||||
* if the supplied DirContext is not an LdapContext.
|
||||
*/
|
||||
public void preProcess(DirContext ctx) throws NamingException {
|
||||
LdapContext ldapContext;
|
||||
if (ctx instanceof LdapContext) {
|
||||
ldapContext = (LdapContext) ctx;
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Request Control operations require LDAPv3 - "
|
||||
+ "Context must be of type LdapContext");
|
||||
}
|
||||
|
||||
Control[] requestControls = ldapContext.getRequestControls();
|
||||
Control newControl = createRequestControl();
|
||||
|
||||
Control[] newControls = new Control[requestControls.length + 1];
|
||||
for (int i = 0; i < requestControls.length; i++) {
|
||||
newControls[i] = requestControls[i];
|
||||
}
|
||||
|
||||
// Add the new Control at the end of the array.
|
||||
newControls[newControls.length - 1] = newControl;
|
||||
|
||||
ldapContext.setRequestControls(newControls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of the appropriate RequestControl.
|
||||
*
|
||||
* @return the new instance.
|
||||
*/
|
||||
public abstract Control createRequestControl();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.control;
|
||||
|
||||
import com.sun.jndi.ldap.ctl.PagedResultsControl;
|
||||
|
||||
/**
|
||||
* Wrapper class for the cookie returned when using the
|
||||
* {@link PagedResultsControl}.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PagedResultsCookie {
|
||||
|
||||
private byte[] cookie;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param cookie
|
||||
* the cookie returned by a PagedResultsResponseControl.
|
||||
*/
|
||||
public PagedResultsCookie(byte[] cookie) {
|
||||
this.cookie = cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cookie.
|
||||
*
|
||||
* @return the cookie.
|
||||
*/
|
||||
public byte[] getCookie() {
|
||||
return cookie;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.control;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.ldap.Control;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
|
||||
import org.springframework.ldap.UncategorizedLdapException;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.sun.jndi.ldap.ctl.PagedResultsControl;
|
||||
import com.sun.jndi.ldap.ctl.PagedResultsResponseControl;
|
||||
|
||||
/**
|
||||
* DirContextProcessor implementation for managing the paged results.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class PagedResultsRequestControl extends
|
||||
AbstractRequestControlDirContextProcessor {
|
||||
|
||||
private static final Class DEFAULT_RESPONSE_CONTROL = PagedResultsResponseControl.class;
|
||||
|
||||
private static final boolean CRITICAL_CONTROL = true;
|
||||
|
||||
private static final String JAVA5_RESPONSE_CONTROL = "javax.naming.ldap.PagedResultsResponseControl";
|
||||
|
||||
private int pageSize;
|
||||
|
||||
private PagedResultsCookie cookie;
|
||||
|
||||
private int resultSize;
|
||||
|
||||
private Class responseControlClass = DEFAULT_RESPONSE_CONTROL;
|
||||
|
||||
private Class fallbackResponseControlClass;
|
||||
|
||||
private Class currentResponseControlClass;
|
||||
|
||||
public PagedResultsRequestControl(int pageSize) {
|
||||
this(pageSize, null);
|
||||
}
|
||||
|
||||
public PagedResultsRequestControl(int pageSize, PagedResultsCookie cookie) {
|
||||
this.pageSize = pageSize;
|
||||
this.cookie = cookie;
|
||||
fallbackResponseControlClass = loadFallbackResponseControlClass();
|
||||
}
|
||||
|
||||
public PagedResultsCookie getCookie() {
|
||||
return cookie;
|
||||
}
|
||||
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public int getResultSize() {
|
||||
return resultSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class of the expected ResponseControl for the paged results
|
||||
* response. The default is {@link PagedResultsResponseControl}.
|
||||
*
|
||||
* @param responseControlClass
|
||||
* Class of the expected response control.
|
||||
*/
|
||||
public void setResponseControlClass(Class responseControlClass) {
|
||||
this.responseControlClass = responseControlClass;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.ldap.support.control.AbstractRequestControlDirContextProcessor#createRequestControl()
|
||||
*/
|
||||
public Control createRequestControl() {
|
||||
try {
|
||||
if (cookie != null) {
|
||||
return new PagedResultsControl(pageSize, cookie.getCookie(),
|
||||
CRITICAL_CONTROL);
|
||||
} else {
|
||||
return new PagedResultsControl(pageSize);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncategorizedLdapException(
|
||||
"Error creating PagedResultsControl", e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.ldap.DirContextProcessor#postProcess(javax.naming.directory.DirContext)
|
||||
*/
|
||||
public void postProcess(DirContext ctx) throws NamingException {
|
||||
// initialize from property
|
||||
currentResponseControlClass = responseControlClass;
|
||||
|
||||
LdapContext ldapContext = (LdapContext) ctx;
|
||||
Control[] responseControls = ldapContext.getResponseControls();
|
||||
|
||||
// Go through response controls and get info, regardless of class
|
||||
for (int i = 0; i < responseControls.length; i++) {
|
||||
Control responseControl = responseControls[i];
|
||||
|
||||
// check for match, try fallback otherwise
|
||||
if (isPagedResultsResponseControl(responseControl)) {
|
||||
Object control = responseControl;
|
||||
byte[] result = (byte[]) invokeMethod("getCookie",
|
||||
currentResponseControlClass, control);
|
||||
this.cookie = new PagedResultsCookie(result);
|
||||
Integer wrapper = (Integer) invokeMethod("getResultSize",
|
||||
currentResponseControlClass, control);
|
||||
this.resultSize = wrapper.intValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given control matches a paged results response control. Try
|
||||
* the fallback class from Java5 if there is no match. Set the
|
||||
* {@link #currentResponseControlClass} to the fallback if it matches.
|
||||
*
|
||||
* @param responseControl
|
||||
* the control to check for a match
|
||||
* @return whether the control is a paged results response control
|
||||
*/
|
||||
private boolean isPagedResultsResponseControl(Control responseControl) {
|
||||
if (responseControl.getClass().isAssignableFrom(
|
||||
currentResponseControlClass)) {
|
||||
return true;
|
||||
}
|
||||
if (fallbackResponseControlClass != null
|
||||
&& responseControl.getClass().isAssignableFrom(
|
||||
fallbackResponseControlClass)) {
|
||||
currentResponseControlClass = fallbackResponseControlClass;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Class loadFallbackResponseControlClass() {
|
||||
Class fallbackResponseControlClass = null;
|
||||
try {
|
||||
fallbackResponseControlClass = Class
|
||||
.forName(JAVA5_RESPONSE_CONTROL);
|
||||
} catch (ClassNotFoundException e) {
|
||||
log.debug("Could not load Java5 response control class "
|
||||
+ JAVA5_RESPONSE_CONTROL);
|
||||
}
|
||||
return fallbackResponseControlClass;
|
||||
}
|
||||
|
||||
private Object invokeMethod(String method, Class clazz, Object control) {
|
||||
// For Spring 2.0 ReflectionUtils could be used for all of this, but
|
||||
// since we still want to support the 1.2 branch we do it manually and
|
||||
// only use the stuff present in 1.2.8.
|
||||
Method actualMethod = null;
|
||||
Object retval = null;
|
||||
try {
|
||||
actualMethod = clazz.getMethod(method, new Class[0]);
|
||||
} catch (SecurityException e) {
|
||||
ReflectionUtils.handleReflectionException(e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
ReflectionUtils.handleReflectionException(e);
|
||||
}
|
||||
|
||||
try {
|
||||
retval = actualMethod.invoke(control, new Object[0]);
|
||||
} catch (IllegalArgumentException e) {
|
||||
ReflectionUtils.handleReflectionException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
ReflectionUtils.handleReflectionException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
ReflectionUtils.handleReflectionException(e);
|
||||
}
|
||||
|
||||
// Retval will be set unless an exception has been thrown.
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
Support classes for custom request control context processors.
|
||||
</body>
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
/**
|
||||
* Convenience class that implements most of the methods in the Filter
|
||||
* interface.
|
||||
*
|
||||
* @author Adam Skogman
|
||||
*/
|
||||
public abstract class AbstractFilter implements Filter {
|
||||
|
||||
protected AbstractFilter() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the query with LDAP encoding to a stringbuffer
|
||||
*
|
||||
* @param buff
|
||||
* The stringbuffer
|
||||
* @return The very same stringbuffer
|
||||
*/
|
||||
public abstract StringBuffer encode(StringBuffer buff);
|
||||
|
||||
/**
|
||||
* Encodes the filter to a string using the (@link #encode(StringBuffer)
|
||||
* method.
|
||||
*
|
||||
* @return The encoded filter
|
||||
*/
|
||||
public String encode() {
|
||||
StringBuffer buff = new StringBuffer(256);
|
||||
buff = encode(buff);
|
||||
return buff.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return encode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
/**
|
||||
* A filter for a logical AND. E.g.:
|
||||
*
|
||||
* <pre>
|
||||
* AndFilter filter = new AndFilter();
|
||||
* filter.and(new EqualsFilter("objectclass", "person");
|
||||
* filter.and(new EqualsFilter("cn", "Some CN");
|
||||
* System.out.println(filter.ecode());
|
||||
* </pre>
|
||||
*
|
||||
* would result in: <code>(&(objectclass=person)(cn=Some CN))</code>
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.EqualsFilter
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class AndFilter extends BinaryLogicalFilter {
|
||||
|
||||
private static final String AMPERSAND = "&";
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.BinaryLogicalFilter#getLogicalOperator()
|
||||
*/
|
||||
protected String getLogicalOperator() {
|
||||
return AMPERSAND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a query to the and expression
|
||||
*
|
||||
* @param query
|
||||
* The query to and with the rest of the and:ed queries.
|
||||
* @return This LdapAndQuery
|
||||
*/
|
||||
public AndFilter and(Filter query) {
|
||||
queryList.add(query);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
|
||||
/**
|
||||
* Abstract superclass for binary logical operations, that is "and"
|
||||
* and "or" operations.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public abstract class BinaryLogicalFilter extends AbstractFilter {
|
||||
|
||||
protected List queryList = new LinkedList();
|
||||
|
||||
/**
|
||||
* @see org.springframework.ldap.support.filter.Filter#encode(java.lang.StringBuffer)
|
||||
*/
|
||||
public StringBuffer encode(StringBuffer buff) {
|
||||
if (queryList.size() <= 0) {
|
||||
|
||||
// only output query if contains anything
|
||||
return buff;
|
||||
|
||||
} else if (queryList.size() == 1) {
|
||||
|
||||
// don't add the &
|
||||
Filter query = (Filter) queryList.get(0);
|
||||
return query.encode(buff);
|
||||
|
||||
} else {
|
||||
buff.append("(" + getLogicalOperator());
|
||||
|
||||
for (Iterator i = queryList.iterator(); i.hasNext();) {
|
||||
Filter query = (Filter) i.next();
|
||||
buff = query.encode(buff);
|
||||
}
|
||||
|
||||
buff.append(")");
|
||||
|
||||
return buff;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this in subclass to return the logical operator, for example
|
||||
* &qout;&&qout;.
|
||||
*
|
||||
* @return the logical operator.
|
||||
*/
|
||||
protected abstract String getLogicalOperator();
|
||||
|
||||
/**
|
||||
* Compares each filter in turn
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.Filter#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof BinaryLogicalFilter
|
||||
&& this.getClass() == obj.getClass()) {
|
||||
return EqualsBuilder.reflectionEquals(this, obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes all contained data
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.Filter#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return HashCodeBuilder.reflectionHashCode(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.springframework.ldap.support.LdapEncoder;
|
||||
|
||||
/**
|
||||
* Abstract superclass for filters to compare values.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public abstract class CompareFilter extends AbstractFilter {
|
||||
|
||||
private final String attribute;
|
||||
|
||||
private final String value;
|
||||
|
||||
private final String encodedValue;
|
||||
|
||||
public CompareFilter(String attribute, String value) {
|
||||
this.attribute = attribute;
|
||||
this.value = value;
|
||||
this.encodedValue = encodeValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* For testing purposes.
|
||||
*
|
||||
* @return the encoded value.
|
||||
*/
|
||||
String getEncodedValue() {
|
||||
return encodedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to perform special encoding in subclass.
|
||||
*
|
||||
* @param value
|
||||
* the value to encode.
|
||||
* @return properly escaped value.
|
||||
*/
|
||||
protected String encodeValue(String value) {
|
||||
return LdapEncoder.filterEncode(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor for int values.
|
||||
*
|
||||
* @param attribute
|
||||
* @param value
|
||||
*/
|
||||
public CompareFilter(String attribute, int value) {
|
||||
this.attribute = attribute;
|
||||
this.value = String.valueOf(value);
|
||||
this.encodedValue = LdapEncoder.filterEncode(this.value);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.ldap.support.filter.AbstractFilter#encode(java.lang.StringBuffer)
|
||||
*/
|
||||
public StringBuffer encode(StringBuffer buff) {
|
||||
buff.append('(');
|
||||
buff.append(attribute).append(getCompareString()).append(encodedValue);
|
||||
buff.append(')');
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares key and value before encoding.
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.Filter#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof CompareFilter && o.getClass() == this.getClass()) {
|
||||
CompareFilter that = (CompareFilter) o;
|
||||
EqualsBuilder builder = new EqualsBuilder();
|
||||
builder.append(this.attribute, that.attribute);
|
||||
builder.append(this.value, that.value);
|
||||
return builder.isEquals();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the hash code for the attribute and the value.
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.Filter#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
HashCodeBuilder builder = new HashCodeBuilder();
|
||||
builder.append(attribute);
|
||||
builder.append(value);
|
||||
return builder.toHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method in subclass to return a String representing the
|
||||
* operator. The {@link EqualsFilter#getCompareString()} would for example
|
||||
* return an equals sign, "=".
|
||||
*
|
||||
* @return the String to use as operator in the comparison for the specific
|
||||
* subclass.
|
||||
*/
|
||||
protected abstract String getCompareString();
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
|
||||
/**
|
||||
* A filter for 'equals'. The following code:
|
||||
*
|
||||
* <pre>
|
||||
* EqualsFilter filter = new EqualsFilter("cn", "Some CN");
|
||||
* System.out.println(filter.ecode());
|
||||
* </pre>
|
||||
*
|
||||
* would result in:
|
||||
* <pre>(cn=Some CN)</pre>
|
||||
*
|
||||
* @author Adam Skogman
|
||||
*/
|
||||
public class EqualsFilter extends CompareFilter {
|
||||
|
||||
private static final String EQUALS_SIGN = "=";
|
||||
|
||||
public EqualsFilter(String attribute, String value) {
|
||||
super(attribute, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor for int values.
|
||||
*
|
||||
* @param attribute Name of attribute in filter.
|
||||
* @param value The value of the attribute in the filter.
|
||||
*/
|
||||
public EqualsFilter(String attribute, int value) {
|
||||
super(attribute, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.springframework.ldap.support.filter.CompareFilter#getCompareString()
|
||||
*/
|
||||
protected String getCompareString() {
|
||||
return EQUALS_SIGN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
/**
|
||||
* Common interface for filters.
|
||||
*
|
||||
* @author Adam Skogman
|
||||
*/
|
||||
public interface Filter {
|
||||
|
||||
/**
|
||||
* Encodes the filter to a string using the (@link #encode(StringBuffer)
|
||||
* method.
|
||||
*
|
||||
* @return The encoded filter
|
||||
*/
|
||||
public String encode();
|
||||
|
||||
/**
|
||||
* Prints the query with LDAP encoding to a stringbuffer
|
||||
*
|
||||
* @param buff
|
||||
* The stringbuffer
|
||||
* @return The very same stringbuffer
|
||||
*/
|
||||
public StringBuffer encode(StringBuffer buff);
|
||||
|
||||
/**
|
||||
* All filters must implement equals.
|
||||
*
|
||||
* @param o
|
||||
* @return <code>true</code> if the objects are equal.
|
||||
*/
|
||||
public boolean equals(Object o);
|
||||
|
||||
/**
|
||||
* All filters must implement hashCode()
|
||||
*
|
||||
* @return hascode
|
||||
*/
|
||||
public int hashCode();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
/**
|
||||
* A filter to compare >=. LDAP RFC does not allow > comparison. The following
|
||||
* code:
|
||||
*
|
||||
* <pre>
|
||||
* GreaterThanOrEqualsFilter filter = new GreaterThanOrEqualsFilter("cn",
|
||||
* "Some CN");
|
||||
* System.out.println(filter.ecode());
|
||||
* </pre>
|
||||
*
|
||||
* would result in:
|
||||
*
|
||||
* <pre>
|
||||
* (cn>=Some CN)
|
||||
* </pre>
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class GreaterThanOrEqualsFilter extends CompareFilter {
|
||||
|
||||
private static final String GREATER_THAN_OR_EQUALS = ">=";
|
||||
|
||||
public GreaterThanOrEqualsFilter(String attribute, String value) {
|
||||
super(attribute, value);
|
||||
}
|
||||
|
||||
public GreaterThanOrEqualsFilter(String attribute, int value) {
|
||||
super(attribute, value);
|
||||
}
|
||||
|
||||
protected String getCompareString() {
|
||||
return GREATER_THAN_OR_EQUALS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
/**
|
||||
* A filter to compare <=. LDAP RFC does not allow < comparison. The following
|
||||
* code:
|
||||
*
|
||||
* <pre>
|
||||
* LessThanOrEqualsFilter filter = new LessThanOrEqualsFilter("cn", "Some CN");
|
||||
* System.out.println(filter.ecode());
|
||||
* </pre>
|
||||
*
|
||||
* would result in:
|
||||
*
|
||||
* <pre>
|
||||
* (cn<=Some CN)
|
||||
* </pre>
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class LessThanOrEqualsFilter extends CompareFilter {
|
||||
|
||||
private static final String LESS_THAN_OR_EQUALS = "<=";
|
||||
|
||||
public LessThanOrEqualsFilter(String attribute, String value) {
|
||||
super(attribute, value);
|
||||
}
|
||||
|
||||
public LessThanOrEqualsFilter(String attribute, int value) {
|
||||
super(attribute, value);
|
||||
}
|
||||
|
||||
protected String getCompareString() {
|
||||
return LESS_THAN_OR_EQUALS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
import org.springframework.ldap.support.LdapEncoder;
|
||||
|
||||
/**
|
||||
* This filter allows the user to specify wildcards (*) by not escaping them in
|
||||
* the filter. The following code:
|
||||
*
|
||||
* <pre>
|
||||
* LikeFilter filter = new LikeFilter("cn", "foo*");
|
||||
* System.out.println(filter.ecode());
|
||||
* </pre>
|
||||
*
|
||||
* would result in:
|
||||
*
|
||||
* <pre>
|
||||
* (cn=foo*)
|
||||
* </pre>
|
||||
*
|
||||
* @author Anders Henja
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class LikeFilter extends EqualsFilter {
|
||||
|
||||
public LikeFilter(String attribute, String value) {
|
||||
super(attribute, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a value according to the rules for this filter.
|
||||
*
|
||||
* @param value
|
||||
* Value to encode.
|
||||
* @return Encoded value.
|
||||
*/
|
||||
protected String encodeValue(String value) {
|
||||
// just return if blank string
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String[] substrings = value.split("\\*", -2);
|
||||
|
||||
if (substrings.length == 1) {
|
||||
return LdapEncoder.filterEncode(substrings[0]);
|
||||
}
|
||||
|
||||
StringBuffer buff = new StringBuffer();
|
||||
for (int i = 0; i < substrings.length; i++) {
|
||||
buff.append(LdapEncoder.filterEncode(substrings[i]));
|
||||
if (i < substrings.length - 1) {
|
||||
buff.append("*");
|
||||
} else {
|
||||
if (substrings[i].equals("")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buff.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
/**
|
||||
* A filter for 'not'. The following code:
|
||||
*
|
||||
* <pre>
|
||||
* Filter filter = new NotFilter(new EqualsFilter("cn", "foo");
|
||||
* System.out.println(filter.ecode());
|
||||
* </pre>
|
||||
*
|
||||
* would result in:
|
||||
*
|
||||
* <pre>(!(cn=foo))</pre>
|
||||
*
|
||||
* @author Adam Skogman
|
||||
*/
|
||||
public class NotFilter extends AbstractFilter {
|
||||
|
||||
private final Filter filter;
|
||||
|
||||
static private final int HASH = "!".hashCode();
|
||||
|
||||
/**
|
||||
* Create a filter that negates the outcome of the given <code>filter</code>.
|
||||
*
|
||||
* @param filter
|
||||
* The filter that should be negated.
|
||||
*/
|
||||
public NotFilter(Filter filter) {
|
||||
Validate.notNull(filter);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.ldap.support.filter.Filter#encode(java.lang.StringBuffer)
|
||||
*/
|
||||
public StringBuffer encode(StringBuffer buff) {
|
||||
|
||||
buff.append("(!");
|
||||
filter.encode(buff);
|
||||
buff.append(')');
|
||||
|
||||
return buff;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares key and value before encoding
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.Filter#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o instanceof NotFilter && o.getClass() == this.getClass()) {
|
||||
NotFilter f = (NotFilter) o;
|
||||
return this.filter.equals(f.filter);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* hash attribute and value
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.Filter#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return HASH ^ filter.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
/**
|
||||
* Filter for logical OR.
|
||||
*
|
||||
* <pre>
|
||||
* AndFilter filter = new AndFilter();
|
||||
* filter.or(new EqualsFilter("objectclass", "person");
|
||||
* filter.or(new EqualsFilter("objectclass", "organizationalUnit");
|
||||
* System.out.println(filter.ecode());
|
||||
* </pre>
|
||||
*
|
||||
* would result in:
|
||||
* <code>(|(objectclass=person)(objectclass=organizationalUnit))</code>
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class OrFilter extends BinaryLogicalFilter {
|
||||
|
||||
private static final String PIPE_SIGN = "|";
|
||||
|
||||
/**
|
||||
* Add a query to the OR expression
|
||||
*
|
||||
* @param query
|
||||
* The query to or with the rest of the or:ed queries.
|
||||
* @return This LdapOrQuery
|
||||
*/
|
||||
public OrFilter or(Filter query) {
|
||||
queryList.add(query);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.support.filter.BinaryLogicalFilter#getLogicalOperator()
|
||||
*/
|
||||
protected String getLogicalOperator() {
|
||||
return PIPE_SIGN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.support.filter;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.ldap.support.LdapEncoder;
|
||||
|
||||
/**
|
||||
* This filter automatically converts all whitespace to wildcards (*). The
|
||||
* following code:
|
||||
*
|
||||
* <pre>
|
||||
* WhitespaceWildcardsFilter filter = new WhitespaceWildcardsFilter("cn",
|
||||
* "Some CN");
|
||||
* System.out.println(filter.ecode());
|
||||
* </pre>
|
||||
*
|
||||
* would result in: <code>(cn=*Some*CN*)</code>
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class WhitespaceWildcardsFilter extends EqualsFilter {
|
||||
private static Pattern starReplacePattern = Pattern.compile("\\s+");
|
||||
|
||||
public WhitespaceWildcardsFilter(String attribute, String value) {
|
||||
super(attribute, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a value according to the rules for this filter.
|
||||
*
|
||||
* @param value
|
||||
* Value to encode.
|
||||
* @return Encoded value.
|
||||
*/
|
||||
protected String encodeValue(String value) {
|
||||
|
||||
// blank string means just ONE star
|
||||
if (StringUtils.isBlank(value)) {
|
||||
return "*";
|
||||
}
|
||||
|
||||
// trim value, we will add in stars first and last anywhay
|
||||
value = value.trim();
|
||||
|
||||
// filter encode so that any stars etc. are preserved
|
||||
String filterEncoded = LdapEncoder.filterEncode(value);
|
||||
|
||||
// Now replace all whitespace with stars
|
||||
Matcher m = starReplacePattern.matcher(filterEncoded);
|
||||
|
||||
// possibly 2 longer (stars at ends)
|
||||
StringBuffer buff = new StringBuffer(value.length() + 2);
|
||||
|
||||
buff.append('*');
|
||||
|
||||
while (m.find()) {
|
||||
m.appendReplacement(buff, "*");
|
||||
}
|
||||
m.appendTail(buff);
|
||||
|
||||
buff.append('*');
|
||||
|
||||
return buff.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<body>
|
||||
Utility classes for dynamically building LDAP
|
||||
filters. Filters can be nested and wrapped around each other:
|
||||
<pre>
|
||||
AndFilter andFilter = new AndFilter();
|
||||
andFilter.and(new EqualsFilter("objectclass", "person");
|
||||
andFilter.and(new EqualsFilter("cn", "Some CN");
|
||||
OrFilter orFilter = new OrFilter();
|
||||
orFilter.or(andFilter);
|
||||
orFilter.or(new EqualsFilter("objectclass", "organizationalUnit));
|
||||
System.out.println(orFilter.encode());
|
||||
</pre>
|
||||
would result in:
|
||||
|
||||
<pre>(|(&(objectclass=person)(cn=Some CN))(objectclass=organizationalUnit))</pre>
|
||||
</body>
|
||||
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
Support classes for Spring-LDAP.
|
||||
</body>
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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.util;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Comparator for comparing lists of Comparable objects.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class ListComparator implements Comparator {
|
||||
|
||||
/**
|
||||
* Compare two lists of Comparable objects.
|
||||
*
|
||||
* @param o1
|
||||
* the first object to be compared.
|
||||
* @param o2
|
||||
* the second object to be compared.
|
||||
* @throws ClassCastException
|
||||
* if either of the lists contains an object that is not
|
||||
* Comparable.
|
||||
*/
|
||||
public int compare(Object o1, Object o2) {
|
||||
List list1 = (List) o1;
|
||||
List list2 = (List) o2;
|
||||
|
||||
for (int i = 0; i < list1.size(); i++) {
|
||||
if (list2.size() > i) {
|
||||
Comparable component1 = (Comparable) list1.get(i);
|
||||
Comparable component2 = (Comparable) list2.get(i);
|
||||
int componentsCompared = component1.compareTo(component2);
|
||||
if (componentsCompared != 0) {
|
||||
return componentsCompared;
|
||||
}
|
||||
} else {
|
||||
// First instance has more components, so that instance is
|
||||
// greater.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// All components so far are equal - if the other instance has
|
||||
// more components it is greater otherwise they are equal.
|
||||
if (list2.size() > list1.size()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
Internal utility classes.
|
||||
</body>
|
||||
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
This document is the API specification for the Spring LDAP Framework.
|
||||
</body>
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
|
||||
/**
|
||||
* Exception that indicates that an invalid or missing Attribute has been
|
||||
* supplied to an LDAP operation.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class AttributesIntegrityViolationException extends
|
||||
DataIntegrityViolationException {
|
||||
|
||||
private static final long serialVersionUID = -6368616096960202571L;
|
||||
|
||||
public AttributesIntegrityViolationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public AttributesIntegrityViolationException(String msg, Throwable t) {
|
||||
super(msg, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
|
||||
/**
|
||||
* An interface used by LdapTemplate for mapping LDAP Attributes to beans.
|
||||
* Implementions of this interface perform the actual work of extracting
|
||||
* results, but need not worry about exception handling. NamingExceptions will
|
||||
* be caught and handled correctly by the LdapTemplate class.
|
||||
* <p>
|
||||
* Typically used in LdapTemplate's search methods. AttributeMapper objects are
|
||||
* typically stateless and thus reusable; they are ideal for implementing
|
||||
* attribute-mapping logic in one place.
|
||||
* <p>
|
||||
* Alternatively, consider using a {@link ContextMapper} in stead.
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate#search(Name, String,
|
||||
* AttributesMapper)
|
||||
* @see ContextMapper
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface AttributesMapper {
|
||||
/**
|
||||
* Map Attributes to an object. The supplied attributes are the attributes
|
||||
* from a single SearchResult.
|
||||
*
|
||||
* @param attributes
|
||||
* attributes from a SearchResult.
|
||||
* @return an object built from the attributes.
|
||||
* @throws NamingException if any error occurs mapping the attributes
|
||||
*/
|
||||
public Object mapFromAttributes(Attributes attributes)
|
||||
throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
/**
|
||||
* An AuthenticationSource is responsible for providing the principal and
|
||||
* credentials to be used when creating a new context.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public interface AuthenticationSource {
|
||||
/**
|
||||
* Get the principal to use when creating an authenticated context.
|
||||
*
|
||||
* @return the principal (userName).
|
||||
*/
|
||||
public String getPrincipal();
|
||||
|
||||
/**
|
||||
* Get the credentials to use when creating an authenticated context.
|
||||
*
|
||||
* @return the credentials (userName).
|
||||
*/
|
||||
public String getCredentials();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that an invalid value has been supplied to an LDAP
|
||||
* operation. This could be an invalid filter or dn.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class BadLdapGrammarException extends
|
||||
InvalidDataAccessResourceUsageException {
|
||||
|
||||
private static final long serialVersionUID = 961612585331409470L;
|
||||
|
||||
public BadLdapGrammarException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public BadLdapGrammarException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
|
||||
/**
|
||||
* A NameClassPairCallbackHandler to collect all results in an internal List.
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public abstract class CollectingNameClassPairCallbackHandler implements
|
||||
NameClassPairCallbackHandler {
|
||||
|
||||
private List list = new LinkedList();
|
||||
|
||||
/**
|
||||
* Get the assembled list.
|
||||
*
|
||||
* @return the list of all assembled objects.
|
||||
*/
|
||||
public List getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass on the supplied NameClassPair to
|
||||
* {@link #getObjectFromNameClassPair(NameClassPair)} and add the result to
|
||||
* the internal list.
|
||||
*/
|
||||
public void handleNameClassPair(NameClassPair nameClassPair) {
|
||||
list.add(getObjectFromNameClassPair(nameClassPair));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a NameClassPair and transform it to an Object of the desired type
|
||||
* and with data from the NameClassPair.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* a NameClassPair from a search operation.
|
||||
* @return an object constructed from the data in the NameClassPair.
|
||||
*/
|
||||
public abstract Object getObjectFromNameClassPair(
|
||||
NameClassPair nameClassPair);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
/**
|
||||
* Helper interface to be used by Dao implementations for assembling to and from
|
||||
* context. Useful if we have assembler classes responsible for mapping to and
|
||||
* from a specific entry.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface ContextAssembler extends ContextMapper {
|
||||
/**
|
||||
* Map the supplied object to the specified context.
|
||||
*
|
||||
* @param obj
|
||||
* the object to read data from.
|
||||
* @param ctx
|
||||
* the context to map to.
|
||||
*/
|
||||
public void mapToContext(Object obj, Object ctx);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface for delegating an actual operation to be performed on an
|
||||
* DirContext. For searches, use {@link org.springframework.ldap.SearchExecutor} in
|
||||
* stead. A typical usage of this interface could be e.g.:
|
||||
*
|
||||
* <pre>
|
||||
* ContextExecutor executor = new ContextExecutor(){
|
||||
* public Object executeWithContext(DirContext ctx) throws NamingException{
|
||||
* return ctx.lookup(dn);
|
||||
* }
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate#executeReadOnly(ContextExecutor)
|
||||
* @see org.springframework.ldap.LdapTemplate#executeReadWrite(ContextExecutor)
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface ContextExecutor {
|
||||
/**
|
||||
* Perform any operation on the context.
|
||||
*
|
||||
* @param ctx
|
||||
* the DirContext to perform the operation on.
|
||||
* @return any object resulting from the operation - might be null.
|
||||
* @throws NamingException
|
||||
* if the operation resulted in one.
|
||||
*/
|
||||
public Object executeWithContext(DirContext ctx) throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.directory.SearchResult;
|
||||
|
||||
import org.springframework.ldap.support.DefaultDirObjectFactory;
|
||||
import org.springframework.ldap.support.DirContextAdapter;
|
||||
|
||||
/**
|
||||
* An interface used by LdapTemplate to map LDAP Contexts to beans. Responsible
|
||||
* for mapping from LDAP Contexts to beans. When a DirObjectFactory is set on
|
||||
* the ContextSource, the objects returned from <code>search</code> and
|
||||
* <code>listBindings</code> operations are automatically transformed to
|
||||
* DirContext objects (when using the {@link DefaultDirObjectFactory}, you get
|
||||
* a {@link DirContextAdapter} object). This object will then be passed to the
|
||||
* ContextMapper implementation for transformation to the desired bean.
|
||||
* <p>
|
||||
* ContextMapper implementations are typically stateless and thus reusable; they
|
||||
* are ideal for implementing mapping logic in one place.
|
||||
* <p>
|
||||
* Alternatively, consider using an {@link AttributesMapper} in stead.
|
||||
*
|
||||
* @see LdapTemplate#search(Name, String,
|
||||
* ContextMapper)
|
||||
* @see LdapTemplate#listBindings(Name, ContextMapper)
|
||||
* @see LdapTemplate#lookup(Name, ContextMapper)
|
||||
* @see AttributesMapper
|
||||
* @see DefaultDirObjectFactory
|
||||
* @see DirContextAdapter
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface ContextMapper {
|
||||
/**
|
||||
* Map a single LDAP Context to an object. The supplied Object
|
||||
* <code>ctx</code> is the object from a single {@link SearchResult},
|
||||
* {@link Binding}, or a lookup operation.
|
||||
*
|
||||
* @param ctx
|
||||
* the context to map to an object.
|
||||
* @return an object built from the data in the context.
|
||||
*/
|
||||
public Object mapFromContext(Object ctx);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
* Interface used to retrieve and authenticate LDAP contexts.
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface ContextSource {
|
||||
|
||||
/**
|
||||
* Gets a read-only DirContext. The returned DirContext must be possible to
|
||||
* perform read-only operations on.
|
||||
*
|
||||
* @return A DirContext instance, never null.
|
||||
* @throws DataAccessException
|
||||
* if some error occurs creating an DirContext.
|
||||
*/
|
||||
public DirContext getReadOnlyContext() throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Gets a read-write DirContext.
|
||||
*
|
||||
* @return A DirContext instance, never null.
|
||||
* @throws DataAccessException
|
||||
* if some error occurs creating an DirContext.
|
||||
*/
|
||||
public DirContext getReadWriteContext() throws DataAccessException;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* The default NameClassPairMapper implementation. This implementation simply
|
||||
* takes the Name string from the supplied NameClassPair and returns it as
|
||||
* result.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class DefaultNameClassPairMapper implements NameClassPairMapper {
|
||||
|
||||
/**
|
||||
* Gets the Name from the supplied NameClassPair and returns it as the
|
||||
* result.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* the NameClassPair to transform.
|
||||
* @return the Name string from the NameClassPair.
|
||||
*/
|
||||
public Object mapFromNameClassPair(NameClassPair nameClassPair)
|
||||
throws NamingException {
|
||||
|
||||
return nameClassPair.getName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.CommunicationException;
|
||||
import javax.naming.ContextNotEmptyException;
|
||||
import javax.naming.LimitExceededException;
|
||||
import javax.naming.NameAlreadyBoundException;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.InvalidAttributesException;
|
||||
import javax.naming.directory.InvalidSearchControlsException;
|
||||
import javax.naming.directory.InvalidSearchFilterException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
/**
|
||||
* The default implementation of NamingExceptionTranslator.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class DefaultNamingExceptionTranslator implements
|
||||
NamingExceptionTranslator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.ldap.NamingExceptionTranslator#translate(java.lang.String,
|
||||
* java.lang.String, java.lang.String, javax.naming.NamingException)
|
||||
*/
|
||||
public DataAccessException translate(NamingException namingException) {
|
||||
|
||||
if (namingException instanceof NameNotFoundException) {
|
||||
return new EntryNotFoundException("Entry not found",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof InvalidSearchFilterException) {
|
||||
return new BadLdapGrammarException("Invalid search filter",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof InvalidSearchControlsException) {
|
||||
return new InvalidDataAccessApiUsageException(
|
||||
"Invalid search controls supplied by internal API",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof NameAlreadyBoundException) {
|
||||
return new DataIntegrityViolationException("Name already bound",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof ContextNotEmptyException) {
|
||||
return new DataIntegrityViolationException(
|
||||
"The context needs to be empty in order to be removed",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof InvalidAttributesException) {
|
||||
return new AttributesIntegrityViolationException(
|
||||
"Invalid attributes", namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof LimitExceededException) {
|
||||
return new SearchLimitExceededException("Too many objects found",
|
||||
namingException);
|
||||
}
|
||||
|
||||
if (namingException instanceof CommunicationException) {
|
||||
throw new DataRetrievalFailureException(
|
||||
"Unable to communicate with LDAP server", namingException);
|
||||
}
|
||||
|
||||
// Fallback - other type of NamingException encountered.
|
||||
return new UncategorizedLdapException("Operation failed",
|
||||
namingException);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
/**
|
||||
* Represents that an entry could not be found.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public class EntryNotFoundException extends DataRetrievalFailureException {
|
||||
|
||||
private static final long serialVersionUID = -1268390922996332424L;
|
||||
|
||||
public EntryNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public EntryNotFoundException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
|
||||
/**
|
||||
* Callback interface used by LdapTemplate's search, list and listBindings
|
||||
* methods. Implementations of this interface perform the actual work of
|
||||
* extracting results from a single NameClassPair (a NameClassPair,
|
||||
* Binding or SearchResult depending on the search operation) returned by an
|
||||
* LDAP seach operation, such as search(), list(), and listBindings().
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface NameClassPairCallbackHandler {
|
||||
/**
|
||||
* Handle one entry. This method will be called once for each entry returned
|
||||
* by a search or list.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* the NameClassPair returned from the NamingEnumeration.
|
||||
*/
|
||||
public void handleNameClassPair(NameClassPair nameClassPair);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* Responsible for mapping NameClassPair objects to beans.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface NameClassPairMapper {
|
||||
/**
|
||||
* Map NameClassPair to an Object. The supplied NameClassPair is one of the
|
||||
* results from a search operation (search, list or listBindings). Depending
|
||||
* on which search operation is being performed, the NameClassPair might be
|
||||
* a SearchResult, Binding or NameClassPair.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* NameClassPair from a search operation.
|
||||
* @return and Object built from the NameClassPair.
|
||||
* @throws NamingException
|
||||
* if one is encountered in the operation.
|
||||
*/
|
||||
public Object mapFromNameClassPair(NameClassPair nameClassPair)
|
||||
throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by classes that can translate between
|
||||
* NamingExceptions and DataAccessExceptions.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public interface NamingExceptionTranslator {
|
||||
/**
|
||||
* Translate the given NamingException into a generic data access exception.
|
||||
* @param namingException
|
||||
* the offending NamingException.
|
||||
*
|
||||
* @return the DataAccessException to throw.
|
||||
*/
|
||||
public DataAccessException translate(NamingException namingException);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface for delegating an actual search operation. The typical
|
||||
* implementation of executeSearch would be something like:
|
||||
*
|
||||
* <pre>
|
||||
* SearchExecutor executor = new SearchExecutor(){
|
||||
* public NamingEnumeration executeSearch(DirContext ctx) throws NamingException{
|
||||
* return ctx.search(dn, filter, searchControls);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see org.springframework.ldap.LdapTemplate#search(SearchExecutor,
|
||||
* NameClassPairCallbackHandler)
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*/
|
||||
public interface SearchExecutor {
|
||||
/**
|
||||
* Execute the actual search.
|
||||
*
|
||||
* @param ctx
|
||||
* the DirContext on which to work.
|
||||
* @return the NamingEnumeration resulting from the search operation.
|
||||
* @throws NamingException
|
||||
* if the search results in one.
|
||||
*/
|
||||
public NamingEnumeration executeSearch(DirContext ctx)
|
||||
throws NamingException;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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;
|
||||
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
/**
|
||||
* Indicates that the search limit was exceeded in a search.
|
||||
*
|
||||
* @author Mattias Arthursson
|
||||
*
|
||||
*/
|
||||
public class SearchLimitExceededException extends DataRetrievalFailureException {
|
||||
private static final long serialVersionUID = 6899885947075235580L;
|
||||
|
||||
public SearchLimitExceededException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public SearchLimitExceededException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user