Removed unused stuff and changed Exception type in AbstractCompensatingTransactionManagerDelegate to avoid package cycle.

This commit is contained in:
Mattias Arthursson
2008-10-23 17:06:27 +00:00
parent 2f60f6618f
commit 363773ce9a
96 changed files with 56 additions and 5286 deletions

View File

@@ -1,41 +0,0 @@
In order to build the spring-ldap-person sample, you need to build spring-ldap first.
% cd spring-ldap
% ant dist
You will most likely get this error, if you haven't installed [url=https://javacc.dev.java.net/]JavaCC[/url] and pointed out to Ant where it is:
[code]
BUILD FAILED
... JavaCC home must be a valid directory.
[/code]
You install JavaCC say in /javacc-4.0 and put this in a spring-ldap/build.properties:
[code]
javacc.home.dir=/javacc-4.0
[/code]
Try building spring-ldap again:
% ant dist
If that succeeds, you'll get a snapshot build installed in your integration repo:
% ls ../integration-repo/artifacts/org.springframework/spring-ldap/
1.2.1-SNAPSHOT-20071206091603
ivy-1.2.1-SNAPSHOT-20071206091603.xml
ivy-1.2.1-SNAPSHOT-20071206091603.xml.md5
ivy-1.2.1-SNAPSHOT-20071206091603.xml.sha1
Next, you can build spring-ldap-person:
% cd ../spring-ldap-person
% ant
If that succeeds, you'll get a war in target/artifacts:
% ls target/artifacts/war
ldap-person.war
Deploy that in Tomcat and see how it goes.

View File

@@ -1,91 +0,0 @@
<?xml version="1.0"?>
<project name="spring-ldap" default="dist">
<property file="build.properties" />
<property file="project.properties" />
<property file="${common.build.dir}/build.properties" />
<property file="${common.build.dir}/project.properties" />
<property file="${user.home}/build.properties" />
<property name="project.title" value="Spring LDAP" />
<property name="project.package" value="org.springframework.ldap" />
<property name="ldap.server" value="127.0.0.1" />
<property name="ldap.user" value="&quot;cn=Manager,dc=jayway,dc=se&quot;" />
<property name="ldap.password" value="secret" />
<!-- Cannot import common-targets since itest-targets already does -->
<import file="${basedir}/itest-openldap-targets.xml" />
<import file="${common.build.dir}/doc-targets.xml" />
<import file="${common.build.dir}/clover-targets.xml" />
<import file="${common.build.dir}/jdiff-targets.xml" />
<!-- extend common-build with source capability -->
<target name="build.prepare.make.config.dirs" depends="common-targets.build.prepare.make.config.dirs">
<mkdir dir="${lib.dir}/source" />
</target>
<!--
Overridden to create test report and run integration tests as well.
-->
<target name="tests" depends="tests-local,test-report,itests,itest-report" description="Runs all tests, first local then server (if any)" />
<!--
Overridden only to have the errorproperty and failureproperty attributes
added to the junit task.
-->
<!-- Runs the local unit tests. -->
<target name="tests-local" depends="tests.prepare" description="Run all local tests">
<!-- for the time being we just halt on failure, since these are
local tests and there is no server to shut down, etc. But if
we want to optionally run all tests and report on the whole
batch, then we need to set a failure property as in the server
tests. -->
<junit forkmode="perBatch" printsummary="yes" haltonfailure="no" haltonerror="no" dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed">
<jvmarg value="${unitvm}" />
<jvmarg value="-Djava.security.auth.login.config=${target.testclasses.dir}/auth.conf" />
<jvmarg value="${test.arguments}" />
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.testclasses.dir}" />
<pathelement location="${target.genclasses.dir}" />
<path refid="test.classpath" />
</classpath>
<formatter type="plain" />
<formatter type="xml" />
<batchtest fork="yes" todir="${target.testresults.dir}">
<fileset dir="${target.testclasses.dir}" includes="${test.includes}" excludes="${test.excludes}" />
</batchtest>
</junit>
</target>
<property name="target.testresults.html.dir" location="${target.testresults.dir}/html" />
<!-- Generate the unit test report -->
<target name="test-report" depends="build.prepare" description="Generate HTML report of unit test results">
<delete dir="${target.testresults.html.dir}" />
<mkdir dir="${target.testresults.html.dir}" />
<junitreport todir="${target.testresults.html.dir}">
<fileset dir="${target.testresults.dir}">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${target.testresults.html.dir}" />
</junitreport>
<echo>
Unit test report has been generated.
The HTML report is ${target.testresults.html.dir}/index.html
</echo>
<fail if="tests.failed" message="Unit tests failed" />
</target>
<target name="gen.main">
<property name="javacc.out.dir" location="${target.gen.java.dir}/org/springframework/ldap/core" />
<mkdir dir="${javacc.out.dir}" />
<javacc javacchome="${javacc.home.dir}" target="${src.javacc.dir}/DnParserImpl.jj" outputdirectory="${javacc.out.dir}" />
</target>
</project>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

View File

@@ -1,20 +0,0 @@
This project uses the 'DocBook XSL distribution' for HTML and PDF
generation of project reference documentation.
This project's build.xml file contains targets to generate the
project reference documentation.
To generate project documentation, execute one of the following
build targets:
* doc-all - generate documentation in all supported formats
* doc-pdf - generate the PDF documentation
* doc-html - generate the HTML documentation
* doc-htmlsingle - generate single page HTML documentation
* doc-clean - clean any output directories for docs
For generation to complete successfully, you must have first extracted
the .jar libraries contained in this archive:
- http://static.springframework.org/spring/files/docbook-reference-libs.zip
... to ${basedir}/docs/reference. If you have not yet done so, download this file
and unzip the contents of the archive into ${basedir}/docs/reference.

View File

@@ -1,385 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="basic">
<title>Basic Operations</title>
<sect1 id="basic-searches">
<title>Search and Lookup Using AttributesMapper</title>
<para>In this example we will use an <literal>AttributesMapper</literal>
to easily build a List of all common names of all person objects.</para>
<example>
<title>AttributesMapper that returns a single attribute</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
public void setLdapTemplate(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
public List getAllPersonNames() {
return ldapTemplate.search(
"", "(objectclass=person)",
<emphasis role="bold"> new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs)
throws NamingException {
return attrs.get("cn").get();
}
}</emphasis>);
}
}</programlisting>
</example>
<para>The inline implementation of <literal>AttributesMapper</literal>
just gets the desired attribute value from the
<literal>Attributes</literal> and returns it. Internally,
<literal>LdapTemplate</literal> iterates over all entries found, calling
the given <literal>AttributesMapper</literal> for each entry, and collects
the results in a list. The list is then returned by the
<literal>search</literal> method.</para>
<para>Note that the <literal>AttributesMapper</literal> implementation
could easily be modified to return a full <literal>Person</literal>
object:</para>
<example>
<title>AttributesMapper that returns a Person object</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
<emphasis role="bold"> private class PersonAttributesMapper implements AttributesMapper {
public Object mapFromAttributes(Attributes attrs) throws NamingException {
Person person = new Person();
person.setFullName((String)attrs.get("cn").get());
person.setLastName((String)attrs.get("sn").get());
person.setDescription((String)attrs.get("description").get());
return person;
}
}
</emphasis>
public List getAllPersons() {
return ldapTemplate.search("", "(objectclass=person)", <emphasis
role="bold">new PersonAttributesMapper()</emphasis>);
}
}</programlisting>
</example>
<para>If you have the distinguished name (<literal>dn</literal>) that
identifies an entry, you can retrieve the entry directly, without
searching for it. This is called a <emphasis>lookup</emphasis> in Java
LDAP. The following example shows how a lookup results in a Person
object:</para>
<example>
<title>A lookup resulting in a Person object</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public Person findPerson(String dn) {
return (Person) ldapTemplate.lookup(dn, new PersonAttributesMapper());
}
}</programlisting>
</example>
<para>This will look up the specified <literal>dn</literal> and pass the
found attributes to the supplied <literal>AttributesMapper</literal>, in
this case resulting in a <literal>Person</literal> object.</para>
</sect1>
<sect1 id="basic-filters">
<title>Building Dynamic Filters</title>
<para>We can build dynamic filters to use in searches, using the classes
from the <literal>org.springframework.ldap.filter</literal>
package. Let's say that we want the following filter:
<literal>(&amp;(objectclass=person)(sn=?))</literal>, where we want the
<literal>?</literal> to be replaced with the value of the parameter
<literal>lastName</literal>. This is how we do it using the filter support
classes:</para>
<example>
<title>Building a search filter dynamically</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public List getPersonNamesByLastName(String lastName) {
<emphasis role="bold"> AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "person"));
filter.and(new EqualsFilter("sn", lastName));
</emphasis> return ldapTemplate.search(
"", <emphasis role="bold">filter.encode()</emphasis>,
new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs)
throws NamingException {
return attrs.get("cn").get();
}
});
}
}</programlisting>
</example>
<para>To perform a wildcard search, it's possible to use the
<literal>WhitespaceWildcardsFilter</literal>:</para>
<example>
<title>Building a wildcard search filter</title>
<programlisting>AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "person"));
filter.and(new WhitespaceWildcardsFilter("cn", cn));</programlisting>
</example>
<para>
<note>
In addition to simplifying building of complex search filters,
the <literal>Filter</literal> classes also provide proper escaping
of any unsafe characters. This prevents &quot;ldap injection&quot;,
where a user might use such characters to inject unwanted operations
into your LDAP operations.
</note>
</para>
</sect1>
<sect1>
<title>Building Dynamic Distinguished Names</title>
<para>The standard <ulink
url="http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Name.html">Name</ulink>
interface represents a generic name, which is basically an ordered
sequence of components. The <literal>Name</literal> interface also
provides operations on that sequence; e.g., <literal>add</literal> or
<literal>remove</literal>. LdapTemplate provides an implementation of the
<literal>Name</literal> interface: <literal>DistinguishedName</literal>.
Using this class will greatly simplify building distinguished names,
especially considering the sometimes complex rules regarding escapings and
encodings. As with the <literal>Filter</literal> classes this helps preventing
potentially malicious data being injected into your LDAP operations.
</para>
<para>
The following example illustrates how
<literal>DistinguishedName</literal> can be used to dynamically construct
a distinguished name:</para>
<example>
<title>Building a distinguished name dynamically</title>
<programlisting>package com.example.dao;
import org.springframework.ldap.core.support.DistinguishedName;
import javax.naming.Name;
public class PersonDaoImpl implements PersonDao {
public static final String BASE_DN = "dc=example,dc=com";
...
protected Name buildDn(Person p) {
<emphasis role="bold"> DistinguishedName dn = new DistinguishedName(BASE_DN);
dn.add("c", p.getCountry());
dn.add("ou", p.getCompany());
dn.add("cn", p.getFullname());
</emphasis> return dn;
}
}</programlisting>
</example>
<para>Assuming that a Person has the following attributes:</para>
<informaltable>
<tgroup cols="2">
<tbody>
<row>
<entry><literal>country</literal></entry>
<entry>Sweden</entry>
</row>
<row>
<entry><literal>company</literal></entry>
<entry>Some Company</entry>
</row>
<row>
<entry><literal>fullname</literal></entry>
<entry>Some Person</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>The code above would then result in the following distinguished
name:</para>
<para><programlisting>cn=Some Person, ou=Some Company, c=Sweden, dc=example, dc=com</programlisting></para>
<para>In Java 5, there is an implementation of the Name interface: <ulink
url="http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/ldap/LdapName.html">LdapName</ulink>.
If you are in the Java 5 world, you might as well use
<literal>LdapName</literal>. However, you may still use
<literal>DistinguishedName</literal> if you so wish.</para>
</sect1>
<sect1 id="basic-binding-unbinding">
<title>Binding and Unbinding</title>
<sect2 id="basic-binding-data">
<title>Binding Data</title>
<para>Inserting data in Java LDAP is called binding. In order to do
that, a distinguished name that uniquely identifies the new entry is
required. The following example shows how data is bound using
LdapTemplate:</para>
<example>
<title>Binding data using Attributes</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void create(Person p) {
Name dn = buildDn(p);
<emphasis role="bold"> ldapTemplate.bind(dn, null, buildAttributes(p));
</emphasis> }
private Attributes buildAttributes(Person p) {
Attributes attrs = new BasicAttributes();
BasicAttribute ocattr = new BasicAttribute("objectclass");
ocattr.add("top");
ocattr.add("person");
attrs.put(ocattr);
attrs.put("cn", "Some Person");
attrs.put("sn", "Person");
return attrs;
}
}</programlisting>
</example>
<para>The Attributes building is--while dull and verbose--sufficient for
many purposes. It is, however, possible to simplify the binding
operation further, which will be described in <xref
linkend="dirobjectfactory" />.</para>
</sect2>
<sect2 id="basic-unbinding-data">
<title>Unbinding Data</title>
<para>Removing data in Java LDAP is called unbinding. A distinguished
name (dn) is required to identify the entry, just as in the binding
operation. The following example shows how data is unbound using
LdapTemplate:</para>
<example>
<title>Unbinding data</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void delete(Person p) {
Name dn = buildDn(p);
<emphasis role="bold"> ldapTemplate.unbind(dn);
</emphasis> }
}</programlisting>
</example>
</sect2>
</sect1>
<sect1 id="basic-modifying">
<title>Modifying</title>
<para>In Java LDAP, data can be modified in two ways: either using
<emphasis>rebind</emphasis> or
<emphasis>modifyAttributes</emphasis>.</para>
<sect2>
<title>Modifying using <literal>rebind</literal></title>
<para>A <literal>rebind</literal> is a very crude way to modify data.
It's basically an <literal>unbind</literal> followed by a
<literal>bind</literal>. It looks like this:</para>
<example>
<title>Modifying using rebind</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void update(Person p) {
Name dn = buildDn(p);
<emphasis role="bold"> ldapTemplate.rebind(dn, null, buildAttributes(p));
</emphasis> }
}</programlisting>
</example>
</sect2>
<sect2 id="modify-modifyAttributes">
<title>Modifying using <literal>modifyAttributes</literal></title>
<para>If only the modified attributes should be replaced, there is a
method called <literal>modifyAttributes</literal> that takes an array of
modifications:</para>
<example>
<title>Modifying using modifyAttributes</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void updateDescription(Person p) {
Name dn = buildDn(p);
Attribute attr = new BasicAttribute("description", p.getDescription())
ModificationItem item = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr);
<emphasis role="bold"> ldapTemplate.modifyAttributes(dn, new ModificationItem[] {item});
</emphasis> }
}</programlisting>
</example>
<para>Building <literal>Attributes</literal> and
<literal>ModificationItem</literal> arrays is a lot of work, but as you
will see in <xref linkend="dirobjectfactory" />, the update operations
can be simplified.</para>
</sect2>
</sect1>
<sect1 id="samples">
<title>Sample applications</title>
<para>It is recommended that you review the Spring LDAP sample
applications included in the release distribution for best-practice
illustrations of the features of this library. A description of each
sample is provided below:</para>
<para><orderedlist>
<listitem>
<para>spring-ldap-person - the sample demonstrating most
features.</para>
</listitem>
<listitem>
<para>spring-ldap-article - the sample application that was written
to accompany a <ulink
url="http://today.java.net/pub/a/today/2006/04/18/ldaptemplate-java-ldap-made-simple.html">java.net
article</ulink> about Spring LDAP.</para>
</listitem>
</orderedlist></para>
</sect1>
</chapter>

View File

@@ -1,259 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="configuration">
<title>Configuration</title>
<sect1 id="context-source-configuration">
<title>ContextSource Configuration</title>
<para>There are several properties in <literal>AbstractContextSource</literal>
(superclass of <literal>DirContextSource</literal> and <literal>LdapContextSource</literal>)
that can be used to modify its behaviour.</para>
<sect2 id="dir-context-url">
<title>LDAP Server URLs</title>
<para>The URL of the LDAP server is specified using the <literal>url</literal> property.
The URL should be in the format <literal>ldap://myserver.example.com:389</literal>.
For SSL access, use the <literal>ldaps</literal> protocol and the appropriate port, e.g.
<literal>ldaps://myserver.example.com:636</literal></para>
<para>It is possible to configure multiple alternate LDAP servers using the
<literal>urls</literal> property. In this case, supply all server urls in a String
array to the <literal>urls</literal> property.</para>
</sect2>
<sect2 id="dir-context-base">
<title>Base LDAP path</title>
<para>It is possible to specify the root context for all LDAP operations using the
<literal>base</literal> property of <literal>AbstractContextSource</literal>.
When a value has been specified to this property, all Distinguished Names supplied to and received from LDAP operations
will be relative to the LDAP path supplied. This can significantly simplify working against the LDAP
tree; however there are several occations when you will need to have access to the base path.
For more information on this, please refer to <xref linkend="base-context-configuration" /></para>
</sect2>
<sect2 id="dir-context-authentication">
<title>Authentication</title>
<para>Authenticated contexts are created for both read-only and
read-write operations by default. You specify
<literal>userDn</literal> and <literal>password</literal> of the LDAP
user to be used for authentication on the
<literal>ContextSource</literal>.</para>
<para><note>
<para>The <literal>userDn</literal> needs to be the full
Distinguished Name (DN) of the user.</para>
</note></para>
<para>Some LDAP server setups allow anonymous read-only access. If you
want to use anonymous Contexts for read-only operations, set the
<literal>anonymousReadOnly</literal> property to
<literal>true</literal>.<literal></literal></para>
<sect3>
<title>Custom Authentication Using Acegi</title>
<para>While the user name (i.e. user DN) and password used for
creating an authenticated <literal>Context</literal> are static by
default - the ones set on the <literal>ContextSource</literal> on
startup will be used throughout the lifetime of the
<literal>ContextSource</literal> - there are however several cases in
which this is not the desired behaviour. A common scenario is that the
principal and credentials of the current user should be used when
executing LDAP operations for that user. The default behaviour can be
modified by supplying a custom <literal>AuthenticationSource</literal>
implementation to the <literal>ContextSource</literal> on startup,
instead of explicitly specifying the <literal>userDn</literal> and
<literal>password</literal>. The
<literal>AuthenticationSource</literal> will be queried by the
<literal>ContextSource</literal> for principal and credentials each
time an authenticated <literal>Context</literal> is to be
created.</para>
<para>To use the authentication information of the currently logged in
user using <ulink url="http://acegisecurity.org/">Acegi
Security</ulink>, use the
<literal>AcegiAuthenticationSource</literal>:</para>
<example>
<title>The Spring bean definition for an
AcegiAuthenticationSource</title>
<programlisting>&lt;beans&gt;
...
&lt;bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource"&gt;
&lt;property name="url" value="ldap://localhost:389" /&gt;
&lt;property name="base" value="dc=example,dc=com" /&gt;
&lt;property name="authenticationSource" ref="acegiAuthenticationSource" /&gt;
&lt;/bean&gt;
&lt;bean id="acegiAuthenticationSource"
class="org.springframework.ldap.authentication.AcegiAuthenticationSource" /&gt;
...
&lt;/beans&gt;</programlisting>
</example>
<note>
<para>We don't specify any <literal>userDn</literal> or
<literal>password</literal> to our <literal>ContextSource</literal>
when using an <literal>AuthenticationSource</literal> - these
properties are needed only when the default behaviour is
used.</para>
</note>
<note>
<para>When using the <literal>AcegiAuthenticationSource</literal>
you need to use Acegi's
<literal>LdapAuthenticationProvider</literal> to authenticate the
users against LDAP.</para>
</note>
</sect3>
<sect3>
<title>Default Authentication</title>
<para>When using <literal>AcegiAuthenticationSource</literal>,
authenticated contexts will only be possible to create once the user
is logged in using Acegi. To use default authentication information
when no user is logged in, use the
<literal>DefaultValuesAuthenticationSourceDecorator</literal>:</para>
<example>
<title>Configuring a
DefaultValuesAuthenticationSourceDecorator</title>
<programlisting>&lt;beans&gt;
...
&lt;bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource"&gt;
&lt;property name="url" value="ldap://localhost:389" /&gt;
&lt;property name="base" value="dc=example,dc=com" /&gt;
&lt;property name="authenticationSource" ref="authenticationSource" /&gt;
&lt;/bean&gt;
&lt;bean id="authenticationSource"
class="org.springframework.ldap.authentication.DefaultValuesAuthenticationSourceDecorator"&gt;
&lt;property name="target" ref="acegiAuthenticationSource" /&gt;
&lt;property name="defaultUser" value="cn=myDefaultUser" /&gt;
&lt;property name="defaultPassword" value="pass" /&gt;
&lt;/bean&gt;
&lt;bean id="acegiAuthenticationSource"
class="org.springframework.ldap.authentication.AcegiAuthenticationSource" /&gt;
...
&lt;/beans&gt;</programlisting>
</example>
</sect3>
</sect2>
<sect2 id="context-source-pooling">
<title>Pooling</title>
<para>LDAP connection pooling can be turned on/off using the
<literal>pooled</literal> flag. Default is <literal>true</literal>. The
configuration of LDAP connection pooling is managed using
<literal>System</literal> properties, so this needs to be handled
manually. Details of pooling configuration can be found <ulink
url="http://java.sun.com/products/jndi/tutorial/ldap/connect/config.html">here</ulink>.</para>
</sect2>
<sect2 id="context-source-advanced">
<title>Advanced ContextSource Configuration</title>
<sect3 id="context-source-context-factory">
<title>Alternate ContextFactory</title>
<para>It is possible to configure the <literal>ContextFactory</literal> that the
<literal>ContextSource</literal> is to use when creating Contexts using the
<literal>contextFactory</literal> property. The default value is
<literal>com.sun.jndi.ldap.LdapCtxFactory</literal>.</para>
</sect3>
<sect3 id="context-source-object-factory">
<title>Custom DirObjectFactory</title>
<para>As described in <xref linkend="dirobjectfactory" />, a <literal>DirObjectFactory</literal>
can be used to translate the <literal>Attributes</literal> of found Contexts
to a more useful <literal>DirContext</literal> implementation. This can be
configured using the <literal>dirObjectFactory</literal> property. You can use
this property if you have your own, custom <literal>DirObjectFactory</literal> implementation.</para>
<para>The default value is <literal>DefaultDirObjectFactory</literal>.</para>
</sect3>
<sect3 id="context-source-custom-env-properties">
<title>Custom DirContext Environment Properties</title>
<para>In some cases the user might want to specify additional environment setup properties
in addition to the ones directly configurable from <literal>AbstractContextSource</literal>.
Such properties should be set in a <literal>Map</literal> and supplied to
the <literal>baseEnvironmentProperties</literal> property.</para>
</sect3>
</sect2>
</sect1>
<sect1 id="ldap-template-configuration">
<title>LdapTemplate Configuration</title>
<sect2 id="ldap-template-ignore-partial-result">
<title>Ignoring PartialResultExceptions</title>
<para>Some Active Directory (AD) servers are unable to automatically following
referrals, which often leads to a <literal>PartialResultException</literal> being
thrown in searches. You can specify that <literal>PartialResultException</literal>
is to be ignored by setting the <literal>ignorePartialResultException</literal>
property to <literal>true</literal>.
<note>This causes all referrals to be ignored, and no notice will be given that
a <literal>PartialResultException</literal> has been encountered.
There is currently no way of manually following referrals using LdapTemplate.</note></para>
</sect2>
</sect1>
<sect1 id="base-context-configuration">
<title>Obtaining a reference to the base LDAP path</title>
<para>As described above, a base LDAP path may be supplied to the <literal>ContextSource</literal>,
specifying the root in the LDAP tree to which all operations will be relative. This means that
you will only be working with relative distinguished names throughout your system, which is
typically rather handy. There are however some cases in which you will need to have access
to the base path in order to be able to construct full DNs, relative to the actual root of the LDAP tree.
One example would be when working with LDAP groups (e.g. <literal>groupOfNames</literal> objectclass),
in which case each group member attribute value will need to be the full DN of the referenced member.</para>
<para>For that reason, Spring LDAP has a mechanism by which any Spring controlled bean may be supplied
the base path on startup. For beans to be notified of the base path, two things need to be in place:
First of all, the bean that wants the base path reference needs to implement the
<literal>BaseLdapPathAware</literal> interface. Secondly, a <literal>BaseLdapPathBeanPostProcessor</literal>
needs to be defined in the application context</para>
<example>
<title>Implementing <literal>BaseLdapPathAware</literal></title>
<programlisting>package com.example.service;
public class PersonService implements PersonService, <emphasis role="bold">BaseLdapPathAware</emphasis> {
...
<emphasis role="bold">private DistinguishedName basePath;
public void setBaseLdapPath(DistinguishedName basePath) {
this.basePath = basePath;
}</emphasis>
...
private DistinguishedName getFullPersonDn(Person person) {
return new DistinguishedName(<emphasis role="bold">basePath</emphasis>).append(person.getDn());
}
...
}</programlisting>
</example>
<example>
<title>Specifying a <literal>BaseLdapPathBeanPostProcessor</literal> in your <literal>ApplicationContext</literal></title>
<programlisting>&lt;beans&gt;
...
&lt;bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource"&gt;
&lt;property name="url" value="ldap://localhost:389" /&gt;
&lt;property name="base" value="dc=example,dc=com" /&gt;
&lt;property name="acegiAuthenticationSource" ref="authenticationSource" /&gt;
&lt;/bean&gt;
...
<emphasis role="bold">&lt;bean class="org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor" /&gt;</emphasis>
&lt;/beans&gt;
</programlisting>
</example>
<para>The default behaviour of the <literal>BaseLdapPathBeanPostProcessor</literal> is to use the base path of the single
defined <literal>BaseLdapPathSource</literal> (<literal>AbstractContextSource</literal> )in the <literal>ApplicationContext</literal>.
If more than one <literal>BaseLdapPathSource</literal> is defined, you will need to specify which one to use with the
<literal>baseLdapPathSourceName</literal> property.</para>
</sect1>
</chapter>

View File

@@ -1,200 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="processor">
<title>Processing the DirContext</title>
<sect1 id="processor-overview">
<title>Custom DirContext Pre/Postprocessing</title>
<para>In some situations, one would like to perform operations on the
<literal>DirContext</literal> before and after the search operation. The
interface that is used for this is called
<literal>DirContextProcessor</literal>:</para>
<informalexample>
<programlisting>public interface DirContextProcessor {
public void preProcess(DirContext ctx) throws NamingException;
public void postProcess(DirContext ctx) throws NamingException;
}</programlisting>
</informalexample>
<para>The <literal>LdapTemplate</literal> class has a search method that
takes a <literal>DirContextProcessor</literal>:</para>
<informalexample>
<programlisting>public void search(SearchExecutor se, NameClassPairCallbackHandler handler,
DirContextProcessor processor) throws DataAccessException;</programlisting>
</informalexample>
<para>Before the search operation, the <literal>preProcess</literal>
method is called on the given <literal>DirContextProcessor</literal>
instance. After the search has been executed and the resulting
<literal>NamingEnumeration</literal> has been processed, the
<literal>postProcess</literal> method is called. This enables a user to
perform operations on the <literal>DirContext</literal> to be used in the
search, and to check the <literal>DirContext</literal> when the search has
been performed. This can be very useful for example when handling request
and response controls.</para>
<para>There are also a few convenience methods for those that don't need a
custom <literal>SearchExecutor</literal>:</para>
<informalexample>
<programlisting>public void search(Name base, String filter,
SearchControls controls, NameClassPairCallbackHandler handler, DirContextProcessor processor)
public void search(String base, String filter,
SearchControls controls, NameClassPairCallbackHandler handler, DirContextProcessor processor)
public void search(Name base, String filter,
SearchControls controls, AttributesMapper mapper, DirContextProcessor processor)
public void search(String base, String filter,
SearchControls controls, AttributesMapper mapper, DirContextProcessor processor)
public void search(Name base, String filter,
SearchControls controls, ContextMapper mapper, DirContextProcessor processor)
public void search(String base, String filter,
SearchControls controls, ContextMapper mapper, DirContextProcessor processor)</programlisting>
</informalexample>
</sect1>
<sect1 id="processor-others">
<title>Implementing a Request Control DirContextProcessor</title>
<para>The LDAPv3 protocol uses Controls to send and receive additional
data to affect the behavior of predefined operations. In order to simplify
the implementation of a request control
<literal>DirContextProcessor</literal>, Spring LDAP provides the base
class <literal>AbstractRequestControlDirContextProcessor</literal>. This
class handles the retrieval of the current request controls from the
<literal>LdapContext</literal>, calls a template method for creating a
request control, and adds it to the <literal>LdapContext</literal>. All
you have to do in the subclass is to implement the template method
<literal>createRequestControl</literal>, and of course the
<literal>postProcess</literal> method for performing whatever you need to
do after the search.</para>
<informalexample>
<programlisting>public abstract class AbstractRequestControlDirContextProcessor implements
DirContextProcessor {
public void preProcess(DirContext ctx) throws NamingException {
...
}
public abstract Control createRequestControl();
}</programlisting>
<para>A typical <literal>DirContextProcessor</literal> will be similar to the following:</para>
</informalexample>
<example>
<title>A request control DirContextProcessor implementation</title>
<programlisting>package com.example.control;
public class MyCoolRequestControl extends AbstractRequestControlDirContextProcessor {
private static final boolean CRITICAL_CONTROL = true;
private MyCoolCookie cookie;
...
public MyCoolCookie getCookie() {
return cookie;
}
public Control createRequestControl() {
return new SomeCoolControl(cookie.getCookie(), CRITICAL_CONTROL);
}
public void postProcess(DirContext ctx) throws NamingException {
LdapContext ldapContext = (LdapContext) ctx;
Control[] responseControls = ldapContext.getResponseControls();
for (int i = 0; i &lt; responseControls.length; i++) {
if (responseControls[i] instanceof SomeCoolResponseControl) {
SomeCoolResponseControl control = (SomeCoolResponseControl) responseControls[i];
this.cookie = new MyCoolCookie(control.getCookie());
}
}
}
}</programlisting>
</example>
<note>
<para>Make sure you use <literal>LdapContextSource</literal> when you
use Controls. The <literal><ulink
url="http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/ldap/Control.html">Control</ulink></literal>
interface is specific for LDAPv3 and requires that
<literal>LdapContext</literal> is used instead of
<literal>DirContext</literal>. If an
<literal>AbstractRequestControlDirContextProcessor</literal> subclass is
called with an argument that is not an <literal>LdapContext</literal>,
it will throw an <literal>IllegalArgumentException</literal>.</para>
</note>
</sect1>
<sect1>
<title>Paged Search Results</title>
<para>Some searches may return large numbers of results. When there is no
easy way to filter out a smaller amount, it would be convenient to have
the server return only a certain number of results each time it is called.
This is known as <emphasis>paged search results</emphasis>. Each "page" of
the result could then be displayed at the time, with links to the next and
previous page. Without this functionality, the client must either manually
limit the search result into pages, or retrieve the whole result and then
chop it into pages of suitable size. The former would be rather
complicated, and the latter would be consuming unnecessary amounts of
memory.</para>
<para>Some LDAP servers have support for the
<literal>PagedResultsControl</literal>, which requests that the results of
a search operation are returned by the LDAP server in pages of a specified
size. The user controls the rate at which the pages are returned, simply
by the rate at which the searches are called. However, the user must keep
track of a <emphasis>cookie</emphasis> between the calls. The server uses
this cookie to keep track of where it left off the previous time it was
called with a paged results request.</para>
<para>Spring LDAP provides support for paged results by leveraging the
concept for pre- and postprocessing of an <literal>LdapContext</literal> that was discussed
in the previous sections. It does so by providing two classes:
<literal>PagedResultsRequestControl</literal> and
<literal>PagedResultsCookie</literal>. The
<literal>PagedResultsRequestControl</literal> class creates a
<literal>PagedResultsControl</literal> with the requested page size and
adds it to the <literal>LdapContext</literal>. After the search, it gets
the <literal>PagedResultsResponseControl</literal> and retrieves two
pieces of information from it: the estimated total result size and a
cookie. This cookie is a byte array containing information that the server
needs the next time it is called with a
<literal>PagedResultsControl</literal>. In order to make it easy to store
this cookie between searches, Spring LDAP provides the wrapper class
<literal>PagedResultsCookie</literal>.</para>
<para>Below is an example of how the paged search results functionality may
be used:</para>
<example>
<title>Paged results using <literal>PagedResultsRequestControl</literal></title>
<programlisting>public PagedResult getAllPersons(PagedResultsCookie cookie) {
PagedResultsRequestControl control = new PagedResultsRequestControl(PAGE_SIZE, cookie);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
List persons = ldapTemplate.search("", "objectclass=person", searchControls, control);
return new PagedResult(persons, control.getCookie());
}</programlisting>
</example>
<para>In the first call to this method, <literal>null</literal> will be supplied as
the cookie parameter. On subsequent calls the client will need to supply the cookie from
the last search (returned wrapped in the <literal>PagedResult</literal>) each time the
method is called. When the actual cookie is <literal>null</literal> (i.e.
<literal>pagedResult.getCookie().getCookie()</literal> returns <literal>null</literal>),
the last batch has been returned from the search.</para>
</sect1>
</chapter>

View File

@@ -1,341 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="dirobjectfactory">
<title>Simpler Attribute Access and Manipulation with DirContextAdapter</title>
<sect1 id="dirobjectfactory-intro">
<title>Introduction</title>
<para>A little-known--and probably underestimated--feature of the Java
LDAP API is the ability to register a <literal>DirObjectFactory</literal>
to automatically create objects from found contexts. One of the reasons
why it is seldom used is that you will need an implementation of
<literal>DirObjectFactory</literal> that creates instances of a meaningful
implementation of <literal>DirContext</literal>. The Spring LDAP library
provides the missing pieces: a default implementation of
<literal>DirContext</literal> called <literal>DirContextAdapter</literal>,
and a corresponding implementation of <literal>DirObjectFactory</literal>
called <literal>DefaultDirObjectFactory</literal>. Used together with
<literal>DefaultDirObjectFactory</literal>, the
<literal>DirContextAdapter</literal> can be a very powerful tool.</para>
</sect1>
<sect1>
<title>Search and Lookup Using ContextMapper</title>
<para>The <literal>DefaultDirObjectFactory</literal> is registered with
the <literal>ContextSource</literal> by default, which means that whenever
a context is found in the LDAP tree, its <literal>Attributes</literal> and
Distinguished Name (DN) will be used to construct a
<literal>DirContextAdapter</literal>. This enables us to use a
<literal>ContextMapper</literal> instead of an
<literal>AttributesMapper</literal> to transform found values:</para>
<example>
<title>Searching using a ContextMapper</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
...
<emphasis role="bold">private static class PersonContextMapper implements ContextMapper {
public Object mapFromContext(Object ctx) {
DirContextAdapter context = (DirContextAdapter)ctx;
Person p = new Person();
p.setFullName(context.getStringAttribute("cn"));
p.setLastName(context.getStringAttribute("sn"));
p.setDescription(context.getStringAttribute("description"));
return p;
}
}</emphasis>
public Person findByPrimaryKey(
String name, String company, String country) {
Name dn = buildDn(name, company, country);
return ldapTemplate.lookup(dn, <emphasis role="bold">new PersonContextMapper()</emphasis>);
}
}</programlisting>
</example>
<para>The above code shows that it is possible to retrieve the attributes
directly by name, without having to go through the
<literal>Attributes</literal> and <literal>BasicAttribute</literal>
classes. This is particularly useful when working with multi-value attributes. Extracting values from
multi-value attributes normally requires looping through a <literal>NamingEnumeration</literal> of
attribute values returned from the <literal>Attributes</literal> implementation. The
<literal>DirContextAdapter</literal> can do this for you, using the <literal>getStringAttributes()</literal>
or <literal>getObjectAttributes()</literal> methods:</para>
<example>
<title>Getting multi-value attribute values using <literal>getStringAttributes()</literal></title>
<programlisting>private static class PersonContextMapper implements ContextMapper {
public Object mapFromContext(Object ctx) {
DirContextAdapter context = (DirContextAdapter)ctx;
Person p = new Person();
p.setFullName(context.getStringAttribute("cn"));
p.setLastName(context.getStringAttribute("sn"));
p.setDescription(context.getStringAttribute("description"));
// The roleNames property of Person is an String array
<emphasis role="bold">p.setRoleNames(context.getStringAttributes("roleNames"));</emphasis>
return p;
}
}
</programlisting>
</example>
<sect2>
<title>The AbstractContextMapper</title>
<para>Spring LDAP provides an abstract base implementation of <literal>ContextMapper</literal>,
<literal>AbstractContextMapper</literal>. This automatically takes care of the casting of the supplied
<literal>Object</literal> parameter to <literal>DirContexOperations</literal>.
The <literal>PersonContextMapper</literal> above can thus be re-written as follows:
</para>
<example>
<title>Using an AbstractContextMapper</title>
<programlisting>
private static class PersonContextMapper <emphasis role="bold">extends AbstractContextMapper</emphasis> {
public Object <emphasis role="bold">doMapFromContext</emphasis>(DirContextOperations ctx) {
Person p = new Person();
p.setFullName(context.getStringAttribute("cn"));
p.setLastName(context.getStringAttribute("sn"));
p.setDescription(context.getStringAttribute("description"));
return p;
}
}
</programlisting>
</example>
</sect2>
</sect1>
<sect1>
<title>Binding and Modifying Using DirContextAdapter</title>
<para>While very useful when extracting attribute values, <literal>DirContextAdapter</literal> is even more
powerful for hiding attribute details when binding and modifying data.</para>
<sect2>
<title>Binding</title>
<para>This is an example of an improved implementation of the create DAO
method. Compare it with the previous implementation in <xref
linkend="basic-binding-data" />.</para>
<example id="example-binding-contextmapper">
<title>Binding using <literal>DirContextAdapter</literal></title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
...
public void create(Person p) {
Name dn = buildDn(p);
DirContextAdapter context = new DirContextAdapter(dn);
<emphasis role="bold">context.setAttributeValues("objectclass", new String[] {"top", "person"});
context.setAttributeValue("cn", p.getFullname());
context.setAttributeValue("sn", p.getLastname());
context.setAttributeValue("description", p.getDescription());</emphasis>
ldapTemplate.bind(dn, context, null);
}
}</programlisting>
</example>
<para>Note that we use the <literal>DirContextAdapter</literal> instance
as the second parameter to bind, which should be a <literal>Context</literal>.
The third parameter is <literal>null</literal>, since we're not using any
<literal>Attributes</literal>.</para>
<para>Also note the use of the <literal>setAttributeValues()</literal> method when setting the
<literal>objectclass</literal> attribute values. The <literal>objectclass</literal> attribute is
multi-value, and similar to the troubles of extracting muti-value attribute data, building multi-value
attributes is tedious and verbose work. Using the <literal>setAttributeValues()</literal> mehtod you can
have <literal>DirContextAdapter</literal> handle that work for you.</para>
</sect2>
<sect2>
<title>Modifying</title>
<para>The code for a <literal>rebind</literal> would be pretty much
identical to <xref linkend="example-binding-contextmapper" />, except
that the method called would be <literal>rebind</literal>. As we saw in
<xref linkend="modify-modifyAttributes"/> a more correct approach would be to
build a <literal>ModificationItem</literal> array containing the actual
modifications you want to do. This would require you to determine the actual
modifications compared to the data present in the LDAP tree. Again, this
is something that <literal>DirContextAdapter</literal> can help you with; the
<literal>DirContextAdapter</literal> has the ability to keep track of
its modified attributes. The following example takes advantage of this
feature:</para>
<example>
<title>Modifying using <literal>DirContextAdapter</literal></title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
...
public void update(Person p) {
Name dn = buildDn(p);
<emphasis role="bold">DirContextOperations context = ldapTemplate.lookupContext(dn);</emphasis>
context.setAttributeValues("objectclass", new String[] {"top", "person"});
context.setAttributeValue("cn", p.getFullname());
context.setAttributeValue("sn", p.getLastname());
context.setAttributeValue("description", p.getDescription());
<emphasis role="bold">ldapTemplate.modifyAttributes(context);</emphasis>
}
}</programlisting>
</example>
<para>When no mapper is passed to a <literal>ldapTemplate.lookup()</literal> operation,
the result will be a <literal>DirContextAdapter</literal> instance.
While the <literal>lookup</literal> method returns an <literal>Object</literal>, the convenience
method <literal>lookupContext</literal> method automatically casts the return value to
a <literal>DirContextOperations</literal> (the interface that <literal>DirContextAdapter</literal> implements.</para>
<para>The observant reader will see that we have duplicated code in the
<literal>create</literal> and <literal>update</literal> methods. This
code maps from a domain object to a context. It can be extracted to a
separate method:</para>
<example>
<title>Binding and modifying using DirContextAdapter</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
...
public void create(Person p) {
Name dn = buildDn(p);
DirContextAdapter context = new DirContextAdapter(dn);
mapToContext(p, context);
ldapTemplate.bind(dn, context, null);
}
public void update(Person p) {
Name dn = buildDn(p);
DirContextOperations context = ldapTemplate.lookupContext(dn);
mapToContext(person, context);
ldapTemplate.modifyAttributes(context);
}
protected void mapToContext (Person p, DirContextOperations context) {
context.setAttributeValues("objectclass", new String[] {"top", "person"});
context.setAttributeValue("cn", p.getFullName());
context.setAttributeValue("sn", p.getLastName());
context.setAttributeValue("description", p.getDescription());
}
}</programlisting>
</example>
</sect2>
</sect1>
<sect1>
<title>A Complete PersonDao Class</title>
<para>To illustrate the power of Spring LDAP, here is a complete Person
DAO implementation for LDAP in just 68 lines:</para>
<example>
<title>A complete PersonDao class</title>
<programlisting>package com.example.dao;
import java.util.List;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.support.DistinguishedName;
import org.springframework.ldap.filter.EqualsFilter;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
public void setLdapTemplate(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
public void create(Person person) {
DirContextAdapter context = new DirContextAdapter();
mapToContext(person, context);
ldapTemplate.bind(buildDn(person), context, null);
}
public void update(Person person) {
Name dn = buildDn(person);
DirContextOperations context = ldapTemplate.lookupContext(dn);
mapToContext(person, context);
ldapTemplate.modifyAttributes(context);
}
public void delete(Person person) {
ldapTemplate.unbind(buildDn(person));
}
public Person findByPrimaryKey(String name, String company, String country) {
Name dn = buildDn(name, company, country);
return (Person) ldapTemplate.lookup(dn, getContextMapper());
}
public List findAll() {
EqualsFilter filter = new EqualsFilter("objectclass", "person");
return ldapTemplate.search(DistinguishedName.EMPTY_PATH, filter.encode(), getContextMapper());
}
protected ContextMapper getContextMapper() {
return new PersonContextMapper();
}
protected Name buildDn(Person person) {
return buildDn(person.getFullname(), person.getCompany(), person.getCountry());
}
protected Name buildDn(String fullname, String company, String country) {
DistinguishedName dn = new DistinguishedName();
dn.add("c", country);
dn.add("ou", company);
dn.add("cn", fullname);
return dn;
}
protected void mapToContext(Person person, DirContextOperations context) {
context.setAttributeValues("objectclass", new String[] {"top", "person"});
context.setAttributeValue("cn", person.getFullName());
context.setAttributeValue("sn", person.getLastName());
context.setAttributeValue("description", person.getDescription());
}
private static class PersonContextMapper extends AbstractContextMapper {
public Object doMapFromContext(DirContextOperations context) {
Person person = new Person();
person.setFullName(context.getStringAttribute("cn"));
person.setLastName(context.getStringAttribute("sn"));
person.setDescription(context.getStringAttribute("description"));
return person;
}
}
}</programlisting>
</example>
<note>
<para>In several cases the Distinguished Name (DN) of an object is
constructed using properties of the object. E.g. in the above example,
the country, company and full name of the <literal>Person</literal> are
used in the DN, which means that updating any of these properties will
actually require moving the entry in the LDAP tree using the
<literal>rename()</literal> operation in addition to updating the
<literal>Attribute</literal> values. Since this is highly implementation
specific this is something you'll need to keep track of yourself -
either by disallowing the user to change these properties or performing
the <literal>rename()</literal> operation in your
<literal>update()</literal> method if needed.</para>
</note>
</sect1>
</chapter>

View File

@@ -1,148 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="executors">
<title>Adding Missing Overloaded API Methods</title>
<sect1 id="executors-search">
<title>Implementing Custom Search Methods</title>
<para>While <literal>LdapTemplate</literal> contains several overloaded
versions of the most common operations in <literal>DirContext</literal>,
we have not provided an alternative for each and every method signature,
mostly because there are so many of them. We have, however, provided a
means to call whichever <literal>DirContext</literal> method you want
and still get the benefits that LdapTemplate provides.</para>
<para>Let's say that you want to call the following <literal>DirContext</literal>
method:</para>
<programlisting>NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls ctls)</programlisting>
<para>There is no corresponding overloaded method in LdapTemplate. The way to solve
this is to use a custom <literal>SearchExecutor</literal> implementation:</para>
<informalexample>
<programlisting>public interface SearchExecutor {
public NamingEnumeration executeSearch(DirContext ctx) throws NamingException;
}</programlisting>
</informalexample>
<para>In your custom executor, you have access to a <literal>DirContext</literal>
object, which you use to call the method you want. You then provide a handler
that is responsible for mapping attributes and collecting the results. You can
for example use one of the available implementations of
<literal>CollectingNameClassPairCallbackHandler</literal>, which will collect
the mapped results in an internal list. In order to
actually execute the search, you call the <literal>search</literal>
method in LdapTemplate that takes an executor and a handler as arguments. Finally,
you return whatever your handler has collected.</para>
<example>
<title>A custom search method using SearchExecutor and
AttributesMapper</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
...
public List search(final Name base, final String filter, final String[] params,
final SearchControls ctls) {
<emphasis role="bold">SearchExecutor executor = new SearchExecutor() {
public NamingEnumeration executeSearch(DirContext ctx) {
return ctx.search(base, filter, params, ctls);
}
}</emphasis>;
CollectingNameClassPairCallbackHandler handler =
new AttributesMapperCallbackHandler(new PersonAttributesMapper());
ldapTemplate.search(<emphasis role="bold">executor</emphasis>, handler);
return handler.getList();
}
}</programlisting>
</example>
<para>If you prefer the <literal>ContextMapper</literal> to the
<literal>AttributesMapper</literal>, this is what it would look
like:</para>
<example>
<title>A custom search method using SearchExecutor and
ContextMapper</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
...
public List search(final Name base, final String filter, final String[] params,
final SearchControls ctls) {
SearchExecutor executor = new SearchExecutor() {
public NamingEnumeration executeSearch(DirContext ctx) {
return ctx.search(base, filter, params, ctls);
}
};
CollectingNameClassPairCallbackHandler handler =
<emphasis role="bold">new ContextMapperCallbackHandler(new PersonContextMapper())</emphasis>;
ldapTemplate.search(executor, handler);
return handler.getList();
}
}</programlisting>
</example>
<note>
<para>When using the
<literal>ContextMapperCallbackHandler</literal> you must
make sure that you have called
<literal>setReturningObjFlag(true)</literal> on your
<literal>SearchControls</literal> instance.</para>
</note>
</sect1>
<sect1 id="executors-others">
<title>Implementing Other Custom Context Methods</title>
<para>In the same manner as for custom <literal>search</literal> methods,
you can actually execute any method in <literal>DirContext</literal> by
using a <literal>ContextExecutor</literal>.</para>
<informalexample>
<programlisting>public interface ContextExecutor {
public Object executeWithContext(DirContext ctx) throws NamingException;
}</programlisting>
<para>When implementing a custom <literal>ContextExecutor</literal>, you
can choose between using the <literal>executeReadOnly()</literal> or the
<literal>executeReadWrite()</literal> method. Let's say that we want to
call this method:</para>
</informalexample>
<programlisting>Object lookupLink(Name name)</programlisting>
<para>It's available in <literal>DirContext</literal>, but there is no
matching method in <literal>LdapTemplate</literal>. It's a lookup method,
so it should be read-only. We can implement it like this:</para>
<example>
<title>A custom DirContext method using ContextExecutor</title>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
...
public Object lookupLink(final Name name) {
ContextExecutor executor = new ContextExecutor() {
public Object executeWithContext(DirContext ctx) {
return ctx.lookupLink(name);
}
};
return ldapTemplate.executeReadOnly(executor);
}
}</programlisting>
<para>In the same manner you can execute a read-write operation using
the <literal>executeReadWrite()</literal> method.</para>
</example>
</sect1>
</chapter>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,64 +0,0 @@
<?xml version='1.0' encoding="iso-8859-1"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"../lib/docbook-dtd/docbookx.dtd"
[
<!ENTITY preface SYSTEM "preface.xml">
<!ENTITY overview SYSTEM "overview.xml">
<!ENTITY basic SYSTEM "basic.xml">
<!ENTITY dirobjectfactory SYSTEM "dirobjectfactory.xml">
<!ENTITY executors SYSTEM "executors.xml">
<!ENTITY contextprocessor SYSTEM "contextprocessor.xml">
<!ENTITY transactions SYSTEM "transactions.xml">
<!ENTITY simple SYSTEM "simple.xml">
<!ENTITY configuration SYSTEM "configuration.xml">
<!ENTITY pooling SYSTEM "pooling.xml">
]>
<book>
<bookinfo>
<title>Spring LDAP</title>
<subtitle>Reference Documentation</subtitle>
<releaseinfo>Version 1.2.1</releaseinfo>
<pubdate>December 2007</pubdate>
<authorgroup>
<author>
<firstname>Mattias</firstname>
<surname>Arthursson</surname>
</author>
<author>
<firstname>Ulrik</firstname>
<surname>Sandberg</surname>
</author>
<author>
<firstname>Eric</firstname>
<surname>Dalquist</surname>
</author>
</authorgroup>
<legalnotice>
<para>
Copies of this document may be made for your own use and
for distribution to others, provided that you do not
charge any fee for such copies and further provided that
each copy contains this Copyright Notice, whether
distributed in print or electronically.
</para>
</legalnotice>
</bookinfo>
<toc />
&preface;
&overview;
&basic;
&dirobjectfactory;
&transactions;
&executors;
&contextprocessor;
&simple;
&configuration;
&pooling;
</book>

View File

@@ -1,417 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="introduction">
<title>Introduction</title>
<sect1 id="introduction-overview">
<title>Overview</title>
<para>Spring-LDAP (<ulink
url="http://www.springframework.org/ldap">http://www.springframework.org/ldap</ulink>)
is a library for simpler LDAP programming in Java, built on the same
principles as the <ulink
url="http://static.springframework.org/spring/docs/current/api/org/springframework/jdbc/core/JdbcTemplate.html">JdbcTemplate</ulink>
in Spring JDBC. It completely eliminates the need to worry about creating
and closing <literal>LdapContext</literal> and looping through
<literal>NamingEnumeration</literal>. It also provides a more
comprehensive unchecked Exception hierarchy, built on Spring's
<literal>DataAccessException</literal>. As a bonus, it also contains
classes for dynamically building LDAP filters and DNs (Distinguished
Names), LDAP attribute management, and client-side LDAP transaction management.</para>
<para>Consider, for example, a method that should search some storage for
all persons and return their names in a list. Using JDBC, we would create
a <emphasis>connection</emphasis> and execute a <emphasis>query</emphasis>
using a <emphasis>statement</emphasis>. We would then loop over the
<emphasis>result set</emphasis> and retrieve the
<emphasis>column</emphasis> we want, adding it to a list. In contrast,
using Java LDAP, we would create a <emphasis>context</emphasis> and
perform a <emphasis>search</emphasis> using a <emphasis>search
filter</emphasis>. We would then loop over the resulting <emphasis>naming
enumeration</emphasis> and retrieve the <emphasis>attribute</emphasis> we
want, adding it to a list.</para>
<para>The traditional way of implementing this person name search method
in Java LDAP looks like this, where the code marked as bold actually
performs tasks related to the business purpose of the method:</para>
<informalexample>
<programlisting>package com.example.dao;
public class TraditionalPersonDaoImpl implements PersonDao {
public List getAllPersonNames() {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/dc=example,dc=com");
DirContext ctx;
try {
ctx = new InitialDirContext(env);
} catch (NamingException e) {
throw new RuntimeException(e);
}
LinkedList list = new LinkedList();
NamingEnumeration results = null;
try {
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
results = ctx.<emphasis role="bold">search("", "(objectclass=person)"</emphasis>, controls);
while (results.hasMore()) {
SearchResult searchResult = (SearchResult) results.next();
Attributes attributes = searchResult.getAttributes();
<emphasis role="bold">Attribute attr = attributes.get("cn");
String cn = (String) attr.get();
list.add(cn);</emphasis>
}
} catch (NameNotFoundException e) {
// The base context was not found.
// Just clean up and exit.
} catch (NamingException e) {
throw new RuntimeException(e);
} finally {
if (results != null) {
try {
results.close();
} catch (Exception e) {
// Never mind this.
}
}
if (ctx != null) {
try {
ctx.close();
} catch (Exception e) {
// Never mind this.
}
}
}
<emphasis role="bold">return list;</emphasis>
}
}</programlisting>
</informalexample>
<para>By using the Spring LDAP classes <literal>AttributesMapper</literal>
and <literal>LdapTemplate</literal>, we get the exact same functionality
with the following code:</para>
<informalexample>
<programlisting>package com.example.dao;
public class PersonDaoImpl implements PersonDao {
private LdapTemplate ldapTemplate;
public void setLdapTemplate(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
public List getAllPersonNames() {
return ldapTemplate.<emphasis role="bold">search(
"", "(objectclass=person)"</emphasis>,
new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs)
throws NamingException {
<emphasis role="bold">return attrs.get("cn").get();</emphasis>
}
});
}
}</programlisting>
</informalexample>
<para>The amount of boiler-plate code is significantly less than in the
traditional example. The <literal>LdapTemplate</literal> version of the
search method performs the search, maps the attributes to a string using
the given <literal>AttributesMapper</literal>, collects the strings in an
internal list, and finally returns the list.</para>
<para>Note that the <literal>PersonDaoImpl</literal> code simply assumes
that it has an <literal>LdapTemplate</literal> instance, rather than
looking one up somewhere. It provides a set method for this purpose. There
is nothing Spring-specific about this "Inversion of Control". Anyone that
can create an instance of <literal>PersonDaoImpl</literal> can also set
the <literal>LdapTemplate</literal> on it. However, Spring provides a very
flexible and easy way of <ulink
url="http://static.springframework.org/spring/docs/current/reference/beans.html">achieving
this</ulink>. The Spring container can be told to wire up an instance of
<literal>LdapTemplate</literal> with its required dependencies and inject
it into the <literal>PersonDao</literal> instance. This wiring can be
defined in various ways, but the most common is through XML:</para>
<informalexample>
<programlisting>&lt;beans&gt;
&lt;bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource"&gt;
&lt;property name="url" value="ldap://localhost:389" /&gt;
&lt;property name="base" value="dc=example,dc=com" /&gt;
&lt;property name="userDn" value="cn=Manager" /&gt;
&lt;property name="password" value="secret" /&gt;
&lt;/bean&gt;
&lt;bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"&gt;
&lt;constructor-arg ref="contextSource" /&gt;
&lt;/bean&gt;
&lt;bean id="personDao" class="com.example.dao.PersonDaoImpl"&gt;
&lt;property name="ldapTemplate" ref="ldapTemplate" /&gt;
&lt;/bean&gt;
&lt;/beans&gt;</programlisting>
</informalexample>
</sect1>
<sect1 id="introduction-packaging">
<title>Packaging overview</title>
<para>At a minimum, to use Spring LDAP you need:</para>
<itemizedlist spacing="compact">
<listitem>
<para><emphasis>spring-ldap</emphasis> (the Spring LDAP library)</para>
</listitem>
<listitem>
<para><emphasis>spring-core</emphasis> (miscellaneous utility classes used internally by
the framework)</para>
</listitem>
<listitem>
<para><emphasis>spring-beans</emphasis> (contains interfaces and classes for manipulating
Java beans)</para>
</listitem>
<listitem>
<para><emphasis>commons-logging</emphasis> (a simple logging facade, used
internally)</para>
</listitem>
<listitem>
<para><emphasis>commons-lang</emphasis> (misc utilities, used internally)</para>
</listitem>
</itemizedlist>
<para>In addition to the required dependencies the following optional dependencies
are required for certain functionality:</para>
<itemizedlist>
<listitem>
<para><emphasis>acegi-security</emphasis> (For Acegi security integration using <literal>AcegiAuthenticationSource</literal>)</para>
</listitem>
<listitem>
<para><emphasis>spring-context</emphasis> (If your application is wired up using the Spring Application Context -
adds the ability for application objects to obtain resources using a consistent API. Definitely needed if you are
planning on using the BaseLdapPathBeanPostProcessor.)</para>
</listitem>
<listitem>
<para><emphasis>spring-dao</emphasis> (If you are planning to use the client side compensating transaction support)</para>
</listitem>
<listitem>
<para><emphasis>spring-jdbc</emphasis> (If you are planning to use the client side compensating transaction support)</para>
</listitem>
<listitem>
<para><emphasis>ldapbp</emphasis> (Sun LDAP Booster Pack - if you will use the LDAP v3 Server controls integration)</para>
</listitem>
<listitem>
<para><emphasis>commons-pool</emphasis> (If you are planning to use the pooling functionality)</para>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="introduction-package-structure">
<title>Package structure</title>
<para>This section provides an overview of the logical package structure
of the Spring LDAP codebase. The dependencies for each package are clearly
noted. A package dependency noted as <emphasis>(optional)</emphasis> means
that the dependency is needed to compile the package but is optionally
needed at runtime (depending on your use of the package). For example, use
of Spring LDAP together with Acegi Security entails use of the
<literal>org.acegisecurity</literal> package.</para>
<figure>
<title>Spring LDAP package structure</title>
<mediaobject>
<imageobject>
<imagedata fileref="images/package-dependencies.png" format="png" />
</imageobject>
</mediaobject>
</figure>
<sect2 id="transaction.compensating">
<title>org.springframework.transaction.compensating</title>
<para>The <emphasis>transaction.compensating</emphasis> package contains
the generic compensating transaction support. This is not LDAP-specific
or JNDI-specific in any way.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: commons-logging</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap">
<title>org.springframework.ldap</title>
<para>The <emphasis>ldap</emphasis> package contains the exceptions of
the library. These exceptions form an unchecked hierarchy that mirrors
the NamingException hierarchy.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: spring-core</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.core">
<title>org.springframework.ldap.core</title>
<para>The <emphasis>ldap.core</emphasis> package contains the central
abstractions of the library. These abstractions include
AuthenticationSource, ContextSource, DirContextProcessor, and
NameClassPairCallbackHandler. This package also contains the central
class LdapTemplate, plus various mappers and executors.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap, ldap.support, spring-beans,
commons-lang, commons-logging</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.core.support">
<title>org.springframework.ldap.core.support</title>
<para>The <emphasis>ldap.core.support</emphasis> package contains
supporting implementations of some of the core interfaces.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap.core, ldap.support, spring-core,
spring-beans, spring-context (optional), commons-lang, commons-logging</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.support">
<title>org.springframework.ldap.support</title>
<para>The <emphasis>ldap.support</emphasis> package contains supporting
utilities, like the exception translation mechanism.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap, spring-core, commons-logging</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.authentication">
<title>org.springframework.ldap.authentication</title>
<para>The <emphasis>ldap.authentication</emphasis> package contains an
implementation of the AuthenticationSource interface that can be used
with <ulink url="http://www.acegisecurity.org/">Acegi Security</ulink>,
as well as related helper classes.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap.core, acegi-security (optional),
spring-beans, commons-lang, commons-logging</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.control">
<title>org.springframework.ldap.control</title>
<para>The <emphasis>ldap.control</emphasis> package contains an abstract
implementation of the DirContextProcessor interface that can be used as
a basis for processing RequestControls and ResponseControls. There is
also a concrete implementation that handles paged search results. The
<ulink url="http://java.sun.com/products/jndi/">LDAP Booster
Pack</ulink> is used to get support for controls.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap, ldap.core, LDAP booster pack (optional), spring-core,
commons-lang, commons-logging</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.filter">
<title>org.springframework.ldap.filter</title>
<para>The <emphasis>ldap.filter</emphasis> package contains the Filter
abstraction and several implementations of it.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap.core, commons-lang</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.transaction.compensating">
<title>org.springframework.ldap.transaction.compensating</title>
<para>The <emphasis>ldap.transaction.compensating</emphasis> package contains the
core LDAP-specific implementation of compensating transactions.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap, ldap.core, transaction.compensating,
spring-core, commons-lang, commons-logging</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.transaction.compensating.manager">
<title>org.springframework.ldap.transaction.compensating.manager</title>
<para>The <emphasis>ldap.transaction.compensating.manager</emphasis> package contains the
core implementation classes for client-side compensating transactions.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap, ldap.core, ldap.transaction.compensating,
ldap.transaction.compensating.support, transaction.compensating,
spring-dao (optional), spring-jdbc (optional), commons-logging</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="ldap.transaction.compensating.support">
<title>org.springframework.ldap.transaction.compensating.support</title>
<para>The <emphasis>ldap.transaction.compensating.support</emphasis> package contains
useful helper classes for client-side compensating transactions.</para>
<itemizedlist spacing="compact">
<listitem>
<para>Dependencies: ldap.core, ldap.transaction.compensating</para>
</listitem>
</itemizedlist>
</sect2>
<para>For the exact list of jar dependencies, see the Spring LDAP <ulink
url="http://jayasoft.org/ivy">Ivy</ulink> dependency manager descriptor
located within the Spring LDAP distribution at
<literal>spring-ldap/ivy.xml</literal></para>
</sect1>
<sect1 id="introduction-support">
<title>Support</title>
<para>Spring LDAP 1.2.1 is supported on Spring 1.2.8 or later, including
2.0.x.</para>
<para>The community support forum is located at <ulink
url="http://forum.springframework.org">http://forum.springframework.org</ulink>,
and the project web page is <ulink
url="http://www.springframework.org/ldap">http://www.springframework.org/ldap</ulink>.</para>
</sect1>
</chapter>

View File

@@ -1,550 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="pooling">
<title>Pooling Support</title>
<sect1 id="pooling-intro">
<title>Introduction</title>
<para>
Pooling LDAP connections helps mitigate the overhead of
creating a new LDAP connection for each LDAP interaction.
While
<ulink
url="http://java.sun.com/products/jndi/tutorial/ldap/connect/pool.html">
Java LDAP pooling support
</ulink>
exists it is limited in its configuration options and
features, such as connection validation and pool
maintenance. Spring LDAP provides support for detailed pool
configuration on a per-
<literal>ContextSource</literal>
basis.
</para>
<para>
Pooling support is provided by
<literal>PoolingContextSource</literal>
which can wrap any
<literal>ContextSource</literal>
and pool both read-only and read-write
<literal>DirContext</literal>
objects.
<ulink url="http://commons.apache.org/pool/index.html">
Jakarta Commons-Pool
</ulink>
is used to provide the underlying pool implementation.
</para>
</sect1>
<sect1 id="pooling-validation">
<title>DirContext Validation</title>
<para>
Validation of pooled connections is the primary motivation
for using a custom pooling library versus the JDK provided
LDAP pooling functionality. Validation allows pooled
<literal>DirContext</literal>
connections to be checked to ensure they are still properly
connected and configured when checking them out of the pool,
in to the pool or while idle in the pool
</para>
<para>
The
<literal>DirContextValidator</literal>
interface is used by the
<literal>PoolingContextSource</literal>
for validation and
<literal>DefaultDirContextValidator</literal>
is provided as the default validation implementation.
<literal>DefaultDirContextValidator</literal>
does a
<literal>
DirContext.search(String, String, SearchControls)
</literal>
, with an empty name, a filter of
<literal>"objectclass=*"</literal>
and
<literal>SearchControls</literal>
set to limit a single result with the only the objectclass
attribute and a 500ms timeout. If the returned
<literal>NamingEnumeration</literal>
has results the
<literal>DirContext</literal>
passes validation, if no results are returned or an
exception is thrown the
<literal>DirContext</literal>
fails validation. The
<literal>DefaultDirContextValidator</literal>
should work with no configuration changes on most LDAP
servers and provide the fastest way to validate the
<literal>DirContext</literal>
.
</para>
</sect1>
<sect1 id="pooling-properties">
<title>Pool Properties</title>
<para>
The following properties are available on the
<literal>PoolingContextSource</literal>
for configuration of the DirContext pool. The
<literal>contextSource</literal>
property must be set and the
<literal>dirContextValidator</literal>
property must be set if validation is enabled, all other
properties are optional.
</para>
<table frame="all">
<title>Pooling Configuration Properties</title>
<tgroup align="left" cols="3" colsep="1" rowsep="1">
<colspec colname="c1" />
<colspec colname="c2" />
<colspec colname="c3" />
<thead>
<row>
<entry>Parameter</entry>
<entry>Default</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<literal>contextSource</literal>
</entry>
<entry>
<literal>null</literal>
</entry>
<entry>
The
<literal>ContextSource</literal>
implementation to get
<literal>DirContext</literal>
s from to populate the pool.
</entry>
</row>
<row>
<entry>
<literal>dirContextValidator</literal>
</entry>
<entry>
<literal>null</literal>
</entry>
<entry>
The
<literal>DirContextValidator</literal>
implementation to use when validating
connections. This is required if
<literal>testOnBorrow</literal>
,
<literal>testOnReturn</literal>
, or
<literal>testWhileIdle</literal>
options are set to
<literal>true</literal>
.
</entry>
</row>
<row>
<entry>
<literal>maxActive</literal>
</entry>
<entry>
<literal>8</literal>
</entry>
<entry>
The maximum number of active connections of
each type (read-only|read-write) that can be
allocated from this pool at the same time,
or non-positive for no limit.
</entry>
</row>
<row>
<entry>
<literal>maxTotal</literal>
</entry>
<entry>
<literal>-1</literal>
</entry>
<entry>
The overall maximum number of active
connections (for all types) that can be
allocated from this pool at the same time,
or non-positive for no limit.
</entry>
</row>
<row>
<entry>
<literal>maxIdle</literal>
</entry>
<entry>
<literal>8</literal>
</entry>
<entry>
The maximum number of active connections of
each type (read-only|read-write) that can
remain idle in the pool, without extra ones
being released, or non-positive for no
limit.
</entry>
</row>
<row>
<entry>
<literal>minIdle</literal>
</entry>
<entry>
<literal>0</literal>
</entry>
<entry>
The minimum number of active connections of
each type (read-only|read-write) that can
remain idle in the pool, without extra ones
being created, or zero to create none.
</entry>
</row>
<row>
<entry>
<literal>maxWait</literal>
</entry>
<entry>
<literal>-1</literal>
</entry>
<entry>
The maximum number of milliseconds that the
pool will wait (when there are no available
connections) for a connection to be returned
before throwing an exception, or
non-positive to wait indefinitely.
</entry>
</row>
<row>
<entry>
<literal>whenExhaustedAction</literal>
</entry>
<entry>
<literal>1</literal> (BLOCK)
</entry>
<entry>
Specifies the behaviour when the pool is
exhausted.
<itemizedlist>
<listitem>
<para>
The
FAIL (<literal>0</literal>)
option will throw a
<literal>
NoSuchElementException
</literal>
when the pool is exhausted.
</para>
</listitem>
<listitem>
<para>
The
BLOCK (<literal>1</literal>)
option will wait until a new
object is available. If
<literal>maxWait</literal>
is positive a
<literal>
NoSuchElementException
</literal>
is thrown if no new object is
available after the
<literal>maxWait</literal>
time expires.
</para>
</listitem>
<listitem>
<para>
The
GROW (<literal>2</literal>)
option will create and return a
new object (essentially making
<literal>maxActive</literal>
meaningless).
</para>
</listitem>
</itemizedlist>
</entry>
</row>
<row>
<entry>
<literal>testOnBorrow</literal>
</entry>
<entry>
<literal>false</literal>
</entry>
<entry>
The indication of whether objects will be
validated before being borrowed from the
pool. If the object fails to validate, it
will be dropped from the pool, and an
attempt to borrow another will be made.
</entry>
</row>
<row>
<entry>
<literal>testOnReturn</literal>
</entry>
<entry>
<literal>false</literal>
</entry>
<entry>
The indication of whether objects will be
validated before being returned to the pool.
</entry>
</row>
<row>
<entry>
<literal>testWhileIdle</literal>
</entry>
<entry>
<literal>false</literal>
</entry>
<entry>
The indication of whether objects will be
validated by the idle object evictor (if
any). If an object fails to validate, it
will be dropped from the pool.
</entry>
</row>
<row>
<entry>
<literal>
timeBetweenEvictionRunsMillis
</literal>
</entry>
<entry>
<literal>-1</literal>
</entry>
<entry>
The number of milliseconds to sleep between
runs of the idle object evictor thread. When
non-positive, no idle object evictor thread
will be run.
</entry>
</row>
<row>
<entry>
<literal>numTestsPerEvictionRun</literal>
</entry>
<entry>
<literal>3</literal>
</entry>
<entry>
The number of objects to examine during each
run of the idle object evictor thread (if
any).
</entry>
</row>
<row>
<entry>
<literal>
minEvictableIdleTimeMillis
</literal>
</entry>
<entry>
<literal>1000 * 60 * 30</literal>
</entry>
<entry>
The minimum amount of time an object may sit
idle in the pool before it is eligible for
eviction by the idle object evictor (if
any).
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="pooling-configuration">
<title>Configuration</title>
<para>
Configuring pooling should look very familiar if you're used
to Jakarta Commons-Pool or Commons-DBCP. You will first
create a normal
<literal>ContextSource</literal>
then wrap it in a
<literal>PoolingContextSource</literal>
.
<informalexample>
<programlisting><![CDATA[
<beans>
...
<bean id="contextSource" class="org.springframework.ldap.pool.factory.PoolingContextSource">
<property name="contextSource" ref="contextSourceTarget" />
</bean>
<bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://localhost:389" />
<property name="base" value="dc=example,dc=com" />
<property name="userDn" value="cn=Manager" />
<property name="password" value="secret" />
<property name="pooled" value="false"/>
</bean>
...
</beans>
]]></programlisting>
</informalexample>
In a real world example you would probably configure the
pool options and enable connection validation; the above
serves as an example to demonstrate the general idea.
<note>
<para>
Ensure that the
<literal>pooled</literal>
property is set to
<literal>false</literal>
on any
<literal>ContextSource</literal>
that will be wrapped in a
<literal>PoolingContextSource</literal>
. The
<literal>PoolingContextSource</literal>
must be able to create new connections when needed
and if
<literal>pooled</literal>
is set to
<literal>true</literal>
that may not be possible.
</para>
</note>
<note>
<para>
You'll notice that the actual
<literal>ContextSource</literal>
gets an id with a "Target" suffix. The bean you will
actually refer to is the
<literal>PoolingContextSource</literal>
that wraps the target
<literal>contextSource</literal>
</para>
</note>
</para>
<sect2 id="pooling-advanced-configuration">
<title>Validation Configuration</title>
<para>
Adding validation and a few pool configuration tweaks to
the above example is straight forward. Inject a
<literal>DirContextValidator</literal>
and set when validation should occur and the pool is
ready to go.
<informalexample>
<programlisting><![CDATA[
<beans>
...
<bean id="contextSource" class="org.springframework.ldap.pool.factory.PoolingContextSource">
<property name="contextSource" ref="contextSourceTarget" />
<property name="dirContextValidator" ref="dirContextValidator" />
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
</bean>
<bean id="dirContextValidator"
class="org.springframework.ldap.pool.validation.DefaultDirContextValidator" />
<bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://localhost:389" />
<property name="base" value="dc=example,dc=com" />
<property name="userDn" value="cn=Manager" />
<property name="password" value="secret" />
<property name="pooled" value="false"/>
</bean>
...
</beans>
]]></programlisting>
</informalexample>
The above example will test each
<literal>DirContext</literal>
before it is passed to the client application and test
<literal>DirContext</literal>
s that have been sitting idle in the pool.
</para>
</sect2>
</sect1>
<sect1 id="pooling-issues">
<title>Known Issues</title>
<sect2 id="pooling-custom-auth-issue">
<title>Custom Authentication</title>
<para>
The <literal>PoolingContextSource</literal> assumes that all
<literal>DirContext</literal> objects retrieved from
<literal>ContextSource.getReadOnlyContext()</literal> will have
the same environment and likewise that all
<literal>DirContext</literal> objects retrieved from
<literal>ContextSource.getReadWriteContext()</literal> will
have the same environment. This means that wrapping a
<literal>LdapContextSource</literal> configured with an
<literal>AuthenticationSource</literal> in a
<literal>PoolingContextSource</literal> will not function
as expected. The pool would be populated using the credentials
of the first user and unless new connections were needed
subsequent context requests would not be filled for the user
specified by the <literal>AuthenticationSource</literal> for
the requesting thread.
</para>
</sect2>
</sect1>
</chapter>

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<preface id="preface">
<title>Preface</title>
<para>
The Java Naming and Directory Interface (JNDI) is for LDAP programming
what Java Database Connectivity (JDBC) is for SQL programming. There are
several similarities between JDBC and JNDI/LDAP (Java LDAP). Despite
being two completely different APIs with different pros and cons, they
share a number of less flattering characteristics:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>They require extensive plumbing code, even to perform the simplest of tasks.</para>
</listitem>
<listitem>
<para>All resources need to be correctly closed, no matter what happens.</para>
</listitem>
<listitem>
<para>Exception handling is difficult.</para>
</listitem>
</itemizedlist>
<para>
The above points often lead to massive code duplication in common usages
of the APIs. As we all know, code duplication is one of the worst code smells.
All in all, it boils down to this: JDBC and LDAP programming in Java are both
incredibly dull and repetitive.
</para>
<para>
Spring JDBC, a part of the Spring framework, provides excellent utilities for
simplifying SQL programming. We need a similar framework for Java LDAP programming.
</para>
</preface>

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="simple">
<title>Java 5 Support</title>
<sect1 id="simple-ldap-template">
<title>SimpleLdapTemplate</title>
<para>As of version 1.3 Spring LDAP includes the spring-ldap-core-tiger.jar distributable, which adds
a thin layer of Java 5 functionality on top of Spring LDAP.</para>
<para>The <literal>SimpleLdapTemplate</literal> class adds search and lookup methods that take a
<literal>ParameterizedContextMapper</literal>, adding generics support to these methods.</para>
<para><literal>ParametrizedContextMapper</literal> is a typed version of <literal>ContextMapper</literal>,
which simplifies working with searches and lookups:
<example>
<title>Using <literal>ParameterizedContextMapper</literal></title>
<programlisting>public List&lt;Person&gt; getAllPersons(){
return simpleLdapTemplate.search("", "(objectclass=person)",
new <emphasis role="bold">ParameterizedContextMapper&lt;Person&gt;</emphasis>() {
public <emphasis role="bold">Person</emphasis> mapFromContext(Object ctx) {
DirContextAdapter adapter = (DirContextAdapter) ctx;
Person person = new Person();
// Fill the domain object with data from the DirContextAdapter
return person;
}
};
}
</programlisting>
</example>
</para>
</sect1>
</chapter>

View File

@@ -1,223 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="transactions">
<title>Transaction Support</title>
<sect1 id="transactions-intro">
<title>Introduction</title>
<para>Programmers used to working with relational databases coming to the LDAP
world often express surprise to the fact that there is no notion of transactions.
It is not specified in the protocol, and thus no servers support it.
Recognizing that this may be a major problem, Spring LDAP provides support for client-side,
compensating transactions on LDAP resources.</para>
<para>LDAP transaction support is provided by <literal>ContextSourceTransactionManager</literal>, a
<literal>PlatformTransactionManager</literal> implementation that manages Spring transaction
support for LDAP operations. Along with its collaborators it keeps track of the LDAP operations
performed in a transaction, making record of the state before each operation and taking steps to
restore the initial state should the transaction need to be rolled back.</para>
<para>In addition to the actual transaction management, Spring LDAP transaction support also
makes sure that the same <literal>DirContext</literal> instance will be used throughout the same transaction,
i.e. the <literal>DirContext</literal> will not actually be closed until the transaction is finished,
allowing for more efficient resources usage.</para>
<para>
<note>It is important to note that while the approach used by Spring LDAP to provide transaction support
is sufficient for many cases it is by no means &quot;real&quot; transactions in the traditional sense.
The server is completely unaware of the transactions, so e.g. if the connection is broken there will
be no hope to rollback the transaction. While this should be carefully considered it should also be noted
that the alternative will be to operate without any transaction support whatsoever; this is pretty much
as good as it gets.</note>
<note>The client side transaction support will add some overhead in addition to the work required
by the original operations. While this overhead should not be something to worry about in most cases,
if your application will not perform several LDAP operations within the same
transaction (e.g. a <literal>modifyAttributes</literal> followed by a <literal>rebind</literal>), or
if transaction synchronization with a JDBC data source is not required (see below) there will be nothing to gain
by using the LDAP transaction support.</note>
</para>
</sect1>
<sect1 id="transactions-configuration">
<title>Configuration</title>
<para>
Configuring Spring LDAP transactions should look very familiar if you're used to configuring Spring transactions.
You will create a <literal>TransactionManager</literal> instance and wrap your target object using a
<literal>TransactionProxyFactoryBean</literal>. In addition to this, you will also need to wrap your
<literal>ContextSource</literal> in a <literal>TransactionAwareContextSourceProxy</literal>.
<informalexample>
<programlisting>&lt;beans&gt;
...
&lt;bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource"&gt;
&lt;property name="url" value="ldap://localhost:389" /&gt;
&lt;property name="base" value="dc=example,dc=com" /&gt;
&lt;property name="userDn" value="cn=Manager" /&gt;
&lt;property name="password" value="secret" /&gt;
&lt;/bean&gt;
&lt;bean id="contextSource"
class="org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy"&gt;
&lt;constructor-arg ref="contextSourceTarget" /&gt;
&lt;/bean&gt;
&lt;bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"&gt;
&lt;constructor-arg ref="contextSource" /&gt;
&lt;/bean&gt;
&lt;bean id="transactionManager"
class="org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager"&gt;
&lt;constructor-arg ref="contextSource" /&gt;
&lt;/bean&gt;
&lt;bean id="myDataAccessObjectTarget" class="com.example.MyDataAccessObject"&gt;
&lt;property name="ldapTemplate" ref="ldapTemplate" /&gt;
&lt;/bean&gt;
&lt;bean id="myDataAccessObject"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;
&lt;property name="transactionManager" ref="transactionManager" /&gt;
&lt;property name="target" ref="myDataAccessObjectTarget" /&gt;
&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="*"&gt;PROPAGATION_REQUIRES_NEW&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
&lt;/bean&gt;
...</programlisting>
</informalexample>
In a real world example you would probably apply the transactions on the service object level
rather than the DAO level; the above serves as an example to demonstrate the general idea.
<note>You'll notice that the actual <literal>ContextSource</literal> and DAO instances get ids with a
&quot;Target&quot; suffix. The beans you will actually refer to are the Proxies that are created
around the targets; <literal>contextSource</literal> and <literal>myDataAccessObject</literal></note>
</para>
</sect1>
<sect1 id="jdbc-transaction-integration">
<title>JDBC Transaction Integration</title>
<para>A common use case when working against LDAP is that some of the data is stored in the LDAP tree, but
other data is stored in a relational database. In this case, transaction support becomes even more important,
since the update of the different resources should be synchronized.</para>
<para>While actual XA transactions is not supported, support is provided to conceptually wrap JDBC and LDAP
access within the same transaction using the <literal>ContextSourceAndDataSourceTransactionManager</literal>.
A <literal>DataSource</literal> and a <literal>ContextSource</literal> is supplied to the
<literal>ContextSourceAndDataSourceTransactionManager</literal>, which will then manage the two transactions,
virtually as if they were one. When performing a commit, the JDBC part of the operation will always
be performed first, allowing both transactions to be rolled back should the JDBC commit fail. The JDBC
part of the transaction is managed exactly as in <literal>DataSourceTransactionManager</literal>, except that
nested transactions is not supported.
<note>Once again it should be noted that the provided support is all client side. The wrapped transaction is not
an XA transaction. No two-phase as such commit is performed, as the LDAP server will be unable to vote on its outcome.
Once again, however, for the majority of cases the supplied support will be sufficient.</note></para>
</sect1>
<sect1 id="jdbc-transaction-integration">
<title>Hibernate Transaction Integration</title>
<para>If Hibernate is used for relational database persistence, transansaction integration can be achieved using
<literal>ContextSourceAndHibernateTransactionManager</literal>. The general idea is exactly the same
as for JDBC integration, only integratino is made against an underlying <literal>HibernateTransactionManager</literal>
rather than a <literal>DataSourceTransactionManager</literal>.</para>
</sect1>
<sect1 id="compensating-transactions-explained">
<title>LDAP Compensating Transactions Explained</title>
<para>Spring LDAP manages compensating transactions by making record of the state in the LDAP tree
before each modifying operation (<literal>bind</literal>, <literal>unbind</literal>, <literal>rebind</literal>,
<literal>modifyAttributes</literal>, and <literal>rename</literal>).</para>
<para>This enables the system
to perform compensating operations should the transaction need to be rolled back. In many cases the
compensating operation is pretty straightforward. E.g. the compensating rollback operation for a
<literal>bind</literal> operation will quite obviously be to unbind the entry. Other operations however require
a different, more complicated approach because of some particular characteristics of LDAP databases. Specifically,
it is not always possible to get the values of all <literal>Attributes</literal> of an entry, making the above
strategy insufficient for e.g. an <literal>unbind</literal> operation.</para>
<para>This is why each modifying operation performed within a Spring LDAP managed transaction is internally
split up in four distinct operations - a recording operation, a preparation operation, a commit operation,
and a rollback operation. The specifics for each LDAP operation is described in the table below:</para>
<table frame="all">
<tgroup cols='5' align='left' colsep='1' rowsep='1'>
<colspec colname="c1" />
<colspec colname="c2" />
<colspec colname="c3" />
<colspec colname="c4" />
<colspec colname="c5" />
<thead>
<row>
<entry>LDAP Operation</entry>
<entry>Recording</entry>
<entry>Preparation</entry>
<entry>Commit</entry>
<entry>Rollback</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>bind</literal></entry>
<entry>Make record of the DN of the entry to bind.</entry>
<entry>Bind the entry.</entry>
<entry>No operation.</entry>
<entry>Unbind the entry using the recorded DN.</entry>
</row>
<row>
<entry><literal>rename</literal></entry>
<entry>Make record of the original and target DN.</entry>
<entry>Rename the entry.</entry>
<entry>No operation.</entry>
<entry>Rename the entry back to its original DN.</entry>
</row>
<row>
<entry><literal>unbind</literal></entry>
<entry>Make record of the original DN and calculate a temporary DN.</entry>
<entry>Rename the entry to the temporary location.</entry>
<entry>Unbind the temporary entry.</entry>
<entry>Rename the entry from the temporary location back to its original DN.</entry>
</row>
<row>
<entry><literal>rebind</literal></entry>
<entry>Make record of the original DN and the new <literal>Attributes</literal>, and calculate a temporary DN.</entry>
<entry>Rename the entry to a temporary location.</entry>
<entry>Bind the new <literal>Attributes</literal> at the original DN, and unbind the original entry
from its temporary location.</entry>
<entry>Rename the entry from the temporary location back to its original DN.</entry>
</row>
<row>
<entry><literal>modifyAttributes</literal></entry>
<entry>Make record of the DN of the entry to modify and calculate compensating <literal>ModificationItem</literal>s
for the modifications to be done.</entry>
<entry>Perform the <literal>modifyAttributes</literal> operation.</entry>
<entry>No operation.</entry>
<entry>Perform a <literal>modifyAttributes</literal> operation using the calculated compensating
<literal>ModificationItem</literal>s.</entry>
</row>
</tbody>
</tgroup>
</table>
<para>A more detailed description of the internal workings of the Spring LDAP transaction support is available in the
javadocs.</para>
<sect2 id="renaming-strategies">
<title>Renaming Strategies</title>
As described in the table above, the transaction management of some operations require the original entry affected
by the operation to be temporarily renamed before the actual modification can be made in the commit.
The manner in which the temporary DN of the entry is calculated is managed by a <literal>TempEntryRenamingStrategy</literal>
supplied to the <literal>ContextSourceTransactionManager</literal>. Two implementations are supplied with Spring LDAP,
but if specific behaviour is required a custom implementation can easily be implemented by the user. The
provided <literal>TempEntryRenamingStrategy</literal> implementations are:
<itemizedlist>
<listitem><para><literal>DefaultTempEntryRenamingStrategy</literal> (the default). Adds a suffix to the least significant
part of the entry DN. E.g. for the DN <literal>cn=john doe, ou=users</literal>, this strategy would return the
temporary DN <literal>cn=john doe_temp, ou=users</literal>. The suffix is configurable using the <literal>tempSuffix</literal>
property</para></listitem>
<listitem><para><literal>DifferentSubtreeTempEntryRenamingStrategy</literal>. Takes the least significant part of the DN
and appends a subtree DN to this. This makes all temporary entries be placed at a specific location in the LDAP tree.
The temporary subtree DN is configured using the <literal>subtreeNode</literal> property. E.g., if
<literal>subtreeNode</literal> is <literal>ou=tempEntries</literal> and the original DN of the entry is
<literal>cn=john doe, ou=users</literal>, the temporary DN will be <literal>cn=john doe, ou=tempEntries</literal>.
Note that the configured subtree node needs to be present in the LDAP tree.</para></listitem>
</itemizedlist>
<note>
There are some situations where the <literal>DefaultTempEntryRenamingStrategy</literal> will not work. E.g. if your are planning
to do recursive deletes you'll need to use <literal>DifferentSubtreeTempEntryRenamingStrategy</literal>. This is because
the recursive delete operation actually consists of a depth-first delete of each node in the sub tree individually.
Since it is not allowed to rename an entry that has any children, and <literal>DefaultTempEntryRenamingStrategy</literal> would
leave each node in the same subtree (with a different name) in stead of actually removing it, this operation would fail.
When in doubt, use <literal>DifferentSubtreeTempEntryRenamingStrategy</literal>.
</note>
</sect2>
</sect1>
</chapter>

View File

@@ -1,475 +0,0 @@
<?xml version="1.0"?>
<!--
This is the XSL FO (PDF) stylesheet for the Spring reference
documentation.
Thanks are due to Christian Bauer of the Hibernate project
team for writing the original stylesheet upon which this one
is based.
-->
<!DOCTYPE xsl:stylesheet [
<!ENTITY db_xsl_path "../lib/docbook-xsl/">
<!ENTITY admon_gfx_path "images/admons/">
<!ENTITY copyright "&#xA9;">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns="http://www.w3.org/TR/xhtml1/transitional"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="#default">
<xsl:import href="&db_xsl_path;/fo/docbook.xsl"/>
<!--###################################################
Custom Title Page
################################################### -->
<xsl:template name="book.titlepage.recto">
<fo:block>
<fo:table table-layout="fixed" width="175mm">
<fo:table-column column-width="175mm"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell text-align="center">
<fo:block>
<fo:external-graphic src="file:images/logo.png"/>
</fo:block>
<fo:block font-family="Helvetica" font-size="22pt" padding-before="10mm">
<xsl:value-of select="bookinfo/subtitle"/>
</fo:block>
<fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
<xsl:value-of select="bookinfo/releaseinfo"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell text-align="center">
<fo:block font-family="Helvetica" font-size="14pt" padding="10mm">
<xsl:value-of select="bookinfo/pubdate"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell text-align="center">
<fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
<xsl:text>Copyright &copyright; 2005-2006 </xsl:text>
<xsl:for-each select="bookinfo/authorgroup/author">
<xsl:if test="position() > 1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="firstname"/>
<xsl:text> </xsl:text>
<xsl:value-of select="surname"/>
</xsl:for-each>
</fo:block>
<fo:block font-family="Helvetica" font-size="10pt" padding="1mm">
<xsl:value-of select="bookinfo/legalnotice"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
</xsl:template>
<!-- Prevent blank pages in output -->
<xsl:template name="book.titlepage.before.verso">
</xsl:template>
<xsl:template name="book.titlepage.verso">
</xsl:template>
<xsl:template name="book.titlepage.separator">
</xsl:template>
<!--###################################################
Header
################################################### -->
<!-- More space in the center header for long text -->
<xsl:attribute-set name="header.content.properties">
<xsl:attribute name="font-family">
<xsl:value-of select="$body.font.family"/>
</xsl:attribute>
<xsl:attribute name="margin-left">-5em</xsl:attribute>
<xsl:attribute name="margin-right">-5em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Custom Footer
################################################### -->
<xsl:template name="footer.content">
<xsl:param name="pageclass" select="''" />
<xsl:param name="sequence" select="''" />
<xsl:param name="position" select="''" />
<xsl:param name="gentext-key" select="''" />
<xsl:variable name="Version">
<xsl:if test="//releaseinfo">
<xsl:text>Spring LDAP (</xsl:text><xsl:value-of select="//releaseinfo" /><xsl:text>)</xsl:text>
</xsl:if>
</xsl:variable>
<xsl:choose>
<xsl:when test="$sequence='blank'">
<xsl:if test="$position = 'center'">
<xsl:value-of select="$Version" />
</xsl:if>
</xsl:when>
<!-- for double sided printing, print page numbers on alternating sides (of the page) -->
<xsl:when test="$double.sided != 0">
<xsl:choose>
<xsl:when test="$sequence = 'even' and $position='left'">
<fo:page-number />
</xsl:when>
<xsl:when test="$sequence = 'odd' and $position='right'">
<fo:page-number />
</xsl:when>
<xsl:when test="$position='center'">
<xsl:value-of select="$Version" />
</xsl:when>
</xsl:choose>
</xsl:when>
<!-- for single sided printing, print all page numbers on the right (of the page) -->
<xsl:when test="$double.sided = 0">
<xsl:choose>
<xsl:when test="$position='center'">
<xsl:value-of select="$Version" />
</xsl:when>
<xsl:when test="$position='right'">
<fo:page-number />
</xsl:when>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>
<!--###################################################
Custom Toc Line
################################################### -->
<!-- The default DocBook XSL TOC printing is seriously broken... -->
<xsl:template name="toc.line">
<xsl:variable name="id">
<xsl:call-template name="object.id"/>
</xsl:variable>
<xsl:variable name="label">
<xsl:apply-templates select="." mode="label.markup"/>
</xsl:variable>
<!-- justify-end removed from block attributes (space problem in title.markup) -->
<fo:block end-indent="{$toc.indent.width}pt"
last-line-end-indent="-{$toc.indent.width}pt"
white-space-treatment="preserve"
text-align="left"
white-space-collapse="false">
<fo:inline keep-with-next.within-line="always">
<!-- print Chapters in bold style -->
<xsl:choose>
<xsl:when test="local-name(.) = 'chapter'">
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:when>
</xsl:choose>
<fo:basic-link internal-destination="{$id}">
<xsl:if test="$label != ''">
<xsl:copy-of select="$label"/>
<fo:inline white-space-treatment="preserve"
white-space-collapse="false">
<xsl:value-of select="$autotoc.label.separator"/>
</fo:inline>
</xsl:if>
<xsl:apply-templates select="." mode="title.markup"/>
</fo:basic-link>
</fo:inline>
<fo:inline keep-together.within-line="always">
<xsl:text> </xsl:text>
<fo:leader leader-pattern="dots"
leader-pattern-width="3pt"
leader-alignment="reference-area"
keep-with-next.within-line="always"/>
<xsl:text> </xsl:text>
<fo:basic-link internal-destination="{$id}">
<fo:page-number-citation ref-id="{$id}"/>
</fo:basic-link>
</fo:inline>
</fo:block>
</xsl:template>
<!--###################################################
Extensions
################################################### -->
<!-- These extensions are required for table printing and other stuff -->
<xsl:param name="use.extensions">1</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="callout.extensions">1</xsl:param>
<!-- FOP provide only PDF Bookmarks at the moment -->
<xsl:param name="fop.extensions">1</xsl:param>
<!--###################################################
Table Of Contents
################################################### -->
<!-- Generate the TOCs for named components only -->
<xsl:param name="generate.toc">
book toc
</xsl:param>
<!-- Show only Sections up to level 3 in the TOCs -->
<xsl:param name="toc.section.depth">2</xsl:param>
<!-- Dot and Whitespace as separator in TOC between Label and Title-->
<xsl:param name="autotoc.label.separator" select="'. '"/>
<!--###################################################
Paper & Page Size
################################################### -->
<!-- Paper type, no headers on blank pages, no double sided printing -->
<xsl:param name="paper.type" select="'A4'"/>
<xsl:param name="double.sided">0</xsl:param>
<xsl:param name="headers.on.blank.pages">0</xsl:param>
<xsl:param name="footers.on.blank.pages">0</xsl:param>
<!-- Space between paper border and content (chaotic stuff, don't touch) -->
<xsl:param name="page.margin.top">5mm</xsl:param>
<xsl:param name="region.before.extent">10mm</xsl:param>
<xsl:param name="body.margin.top">10mm</xsl:param>
<xsl:param name="body.margin.bottom">15mm</xsl:param>
<xsl:param name="region.after.extent">10mm</xsl:param>
<xsl:param name="page.margin.bottom">0mm</xsl:param>
<xsl:param name="page.margin.outer">18mm</xsl:param>
<xsl:param name="page.margin.inner">18mm</xsl:param>
<!-- No intendation of Titles -->
<xsl:param name="title.margin.left">0pc</xsl:param>
<!--###################################################
Fonts & Styles
################################################### -->
<!-- Left aligned text and no hyphenation -->
<xsl:param name="alignment">justify</xsl:param>
<xsl:param name="hyphenate">false</xsl:param>
<!-- Default Font size -->
<xsl:param name="body.font.master">11</xsl:param>
<xsl:param name="body.font.small">8</xsl:param>
<!-- Line height in body text -->
<xsl:param name="line-height">1.4</xsl:param>
<!-- Monospaced fonts are smaller than regular text -->
<xsl:attribute-set name="monospace.properties">
<xsl:attribute name="font-family">
<xsl:value-of select="$monospace.font.family"/>
</xsl:attribute>
<xsl:attribute name="font-size">0.8em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Tables
################################################### -->
<!-- The table width should be adapted to the paper size -->
<xsl:param name="default.table.width">17.4cm</xsl:param>
<!-- Some padding inside tables -->
<xsl:attribute-set name="table.cell.padding">
<xsl:attribute name="padding-left">4pt</xsl:attribute>
<xsl:attribute name="padding-right">4pt</xsl:attribute>
<xsl:attribute name="padding-top">4pt</xsl:attribute>
<xsl:attribute name="padding-bottom">4pt</xsl:attribute>
</xsl:attribute-set>
<!-- Only hairlines as frame and cell borders in tables -->
<xsl:param name="table.frame.border.thickness">0.1pt</xsl:param>
<xsl:param name="table.cell.border.thickness">0.1pt</xsl:param>
<!--###################################################
Labels
################################################### -->
<!-- Label Chapters and Sections (numbering) -->
<xsl:param name="chapter.autolabel">1</xsl:param>
<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="section.label.includes.component.label" select="1"/>
<!--###################################################
Titles
################################################### -->
<!-- Chapter title size -->
<xsl:attribute-set name="chapter.titlepage.recto.style">
<xsl:attribute name="text-align">left</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.8"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
</xsl:attribute-set>
<!-- Why is the font-size for chapters hardcoded in the XSL FO templates?
Let's remove it, so this sucker can use our attribute-set only... -->
<xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format"
xsl:use-attribute-sets="chapter.titlepage.recto.style">
<xsl:call-template name="component.title">
<xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/>
</xsl:call-template>
</fo:block>
</xsl:template>
<!-- Sections 1, 2 and 3 titles have a small bump factor and padding -->
<xsl:attribute-set name="section.title.level1.properties">
<xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.5"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level2.properties">
<xsl:attribute name="space-before.optimum">0.6em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.6em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.25"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="section.title.level3.properties">
<xsl:attribute name="space-before.optimum">0.4em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.4em</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master * 1.0"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<!-- Titles of formal objects (tables, examples, ...) -->
<xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
<xsl:attribute name="font-weight">bold</xsl:attribute>
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.master"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
<xsl:attribute name="hyphenate">false</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Programlistings
################################################### -->
<!-- Verbatim text formatting (programlistings) -->
<xsl:attribute-set name="monospace.verbatim.properties">
<xsl:attribute name="font-size">
<xsl:value-of select="$body.font.small * 1.0"/>
<xsl:text>pt</xsl:text>
</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="verbatim.properties">
<xsl:attribute name="space-before.minimum">1em</xsl:attribute>
<xsl:attribute name="space-before.optimum">1em</xsl:attribute>
<xsl:attribute name="space-before.maximum">1em</xsl:attribute>
<xsl:attribute name="border-color">#444444</xsl:attribute>
<xsl:attribute name="border-style">solid</xsl:attribute>
<xsl:attribute name="border-width">0.1pt</xsl:attribute>
<xsl:attribute name="padding-top">0.5em</xsl:attribute>
<xsl:attribute name="padding-left">0.5em</xsl:attribute>
<xsl:attribute name="padding-right">0.5em</xsl:attribute>
<xsl:attribute name="padding-bottom">0.5em</xsl:attribute>
<xsl:attribute name="margin-left">0.5em</xsl:attribute>
<xsl:attribute name="margin-right">0.5em</xsl:attribute>
</xsl:attribute-set>
<!-- Shade (background) programlistings -->
<xsl:param name="shade.verbatim">1</xsl:param>
<xsl:attribute-set name="shade.verbatim.style">
<xsl:attribute name="background-color">#F0F0F0</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
Callouts
################################################### -->
<!-- Use images for callouts instead of (1) (2) (3) -->
<xsl:param name="callout.graphics">0</xsl:param>
<xsl:param name="callout.unicode">1</xsl:param>
<!-- Place callout marks at this column in annotated areas -->
<xsl:param name="callout.defaultcolumn">90</xsl:param>
<!--###################################################
Admonitions
################################################### -->
<!-- Use nice graphics for admonitions -->
<xsl:param name="admon.graphics">'1'</xsl:param>
<xsl:param name="admon.graphics.path">&admon_gfx_path;</xsl:param>
<!--###################################################
Misc
################################################### -->
<!-- Placement of titles -->
<xsl:param name="formal.title.placement">
figure after
example before
equation before
table before
procedure before
</xsl:param>
<!-- Format Variable Lists as Blocks (prevents horizontal overflow) -->
<xsl:param name="variablelist.as.blocks">1</xsl:param>
<!-- The horrible list spacing problems -->
<xsl:attribute-set name="list.block.spacing">
<xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
<xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
<xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
<xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
</xsl:attribute-set>
<!--###################################################
colored and hyphenated links
################################################### -->
<xsl:template match="ulink">
<fo:basic-link external-destination="{@url}"
xsl:use-attribute-sets="xref.properties"
text-decoration="underline"
color="blue">
<xsl:choose>
<xsl:when test="count(child::node())=0">
<xsl:value-of select="@url"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</fo:basic-link>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,270 +0,0 @@
BODY {
text-align: justify;
margin-right: 2em;
margin-left: 2em;
}
A[accesskey^="p"] {
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
color: #003399;
}
A[accesskey^="u"] {
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
color: #003399;
}
A[accesskey^="h"] {
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
color: #003399;
}
A[accesskey^="n"] {
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
color: #003399;
}
A {
color: #003399;
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
}
A:active {
color: #003399;
}
A:visited {
color: #888888;
}
P {
font-family: Verdana, Arial;
}
DT {
font-family: Verdana, Arial;
font-size: 12px;
}
P, DL, DT, DD, BLOCKQUOTE {
color: #000000;
margin-bottom: 3px;
margin-top: 3px;
padding-top: 0px;
}
OL, UL, P {
margin-top: 6px;
margin-bottom: 6px;
}
P, BLOCKQUOTE {
font-size: 90%;
}
P.releaseinfo {
font-size: 100%;
font-weight: bold;
font-family: Verdana, Arial, helvetica, sans-serif;
padding-top: 10px;
}
P.pubdate {
font-size: 120%; font-weight: bold;
font-family: Verdana, Arial, helvetica, sans-serif;
}
td {
font-size: 80%;
}
TD, TH, SPAN {
color: #000000;
}
TD[width^="40%"] {
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
color: #003399;
}
TABLE[summary^="Navigation header"] tbody tr th[colspan^="3"] {
font-family: Verdana, Arial, helvetica, sans-serif;
}
BLOCKQUOTE {
margin-right: 0px;
}
H1, H2, H3, H4, H5, H6 {
color: #000000;
font-weight:500;
margin-top:0px;
padding-top:14px;
font-family: Verdana, Arial, helvetica, sans-serif;
margin-bottom: 0px;
}
H2.title {
font-weight:800;
margin-bottom: 8px;
}
H2.subtitle {
font-weight:800;
margin-bottom: 20px;
}
.firstname, .surname {
font-size: 12px;
font-family: Verdana, Arial, helvetica, sans-serif;
}
TABLE {
border-collapse: collapse;
border-spacing:0;
border: 1px thin black;
empty-cells: hide;
margin: 10px 0px 30px 50px;
width: 90%;
}
div.table {
margin: 30px 0 30 0;
border: 1px dashed gray;
padding: 10px;
}
div.table > p.title {
padding-left: 10px;
}
table[summary^="Navigation footer"] {
border-collapse: collapse;
border-spacing:0;
border: 1px thin black;
empty-cells: hide;
margin: 0px;
width: 100%;
}
table[summary^="Note"], table[summary^="Warning"], table[summary^="Tip"] {
border-collapse: collapse;
border-spacing:0;
border: 1px thin black;
empty-cells: hide;
margin: 10px 0 10 -20;
width: 100%;
}
TD {
padding: 4pt;
font-family: Verdana, Arial, helvetica, sans-serif;
}
div.warning TD {
text-align: justify;
}
H1 {
font-size: 150%;
}
H2 {
font-size: 110%;
}
H3 {
font-size: 100%; font-weight: bold;
}
H4 {
font-size: 90%; font-weight: bold;
}
H5 {
font-size: 90%; font-style: italic;
}
H6 {
font-size: 100%; font-style: italic;
}
TT {
font-size: 110%;
font-family: "Courier New", Courier, monospace;
color: #000000;
}
.navheader, .navfooter {
background-color: #e4eff3;
}
PRE {
font-size: 110%;
padding: 5px;
border-style: solid;
border-width: 1px;
border-color: #CCCCCC;
background-color: #F4F4F4;
}
UL, OL, LI {
list-style: disc;
}
HR {
width: 100%;
height: 1px;
background-color: #CCCCCC;
border-width: 0px;
padding: 0px;
color: #CCCCCC;
}
.variablelist {
padding-top: 10;
padding-bottom:10;
margin:0;
}
.term {
font-weight:bold;
}
.mediaobject {
padding-top: 30px;
padding-bottom: 30px;
}
.legalnotice {
font-family: Verdana, Arial, helvetica, sans-serif;
font-size: 12px;
font-style: italic;
}
.sidebar {
float: right;
margin: 10px 0px 10px 30px;
padding: 10px 20px 20px 20px;
width: 33%;
border: 1px solid black;
background-color: #F4F4F4;
font-size: 14px;
}
.programlisting * .classname {
font-size: 95%;
}
.programlisting * .interfacename {
font-size: 95%;
}
.programlisting * .literal {
font-size: 95%;
}
.property {
font-family: "Courier New", Courier, monospace;
}

View File

@@ -1,100 +0,0 @@
<?xml version="1.0"?>
<!--
This is the XSL HTML configuration file for the Spring
Reference Documentation.
-->
<!DOCTYPE xsl:stylesheet [
<!ENTITY db_xsl_path "../lib/docbook-xsl/">
<!ENTITY callout_gfx_path "images/callouts/">
<!ENTITY admon_gfx_path "images/admons/">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns="http://www.w3.org/TR/xhtml1/transitional"
exclude-result-prefixes="#default">
<xsl:import href="&db_xsl_path;/html/docbook.xsl"/>
<!--###################################################
HTML Settings
################################################### -->
<xsl:param name="html.stylesheet">../styles/html.css</xsl:param>
<!-- These extensions are required for table printing and other stuff -->
<xsl:param name="use.extensions">1</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="callout.extensions">1</xsl:param>
<xsl:param name="graphicsize.extension">0</xsl:param>
<!--###################################################
Table Of Contents
################################################### -->
<!-- Generate the TOCs for named components only -->
<xsl:param name="generate.toc">
book toc
</xsl:param>
<!-- Show only Sections up to level 3 in the TOCs -->
<xsl:param name="toc.section.depth">3</xsl:param>
<!--###################################################
Labels
################################################### -->
<!-- Label Chapters and Sections (numbering) -->
<xsl:param name="chapter.autolabel">1</xsl:param>
<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="section.label.includes.component.label" select="1"/>
<!--###################################################
Callouts
################################################### -->
<!-- Use images for callouts instead of (1) (2) (3) -->
<xsl:param name="callout.graphics">1</xsl:param>
<xsl:param name="callout.graphics.path">&callout_gfx_path;</xsl:param>
<!-- Place callout marks at this column in annotated areas -->
<xsl:param name="callout.defaultcolumn">90</xsl:param>
<!--###################################################
Admonitions
################################################### -->
<!-- Use nice graphics for admonitions -->
<xsl:param name="admon.graphics">'1'</xsl:param>
<xsl:param name="admon.graphics.path">&admon_gfx_path;</xsl:param>
<!--###################################################
Misc
################################################### -->
<!-- Placement of titles -->
<xsl:param name="formal.title.placement">
figure after
example before
equation before
table before
procedure before
</xsl:param>
<xsl:template match="author" mode="titlepage.mode">
<xsl:if test="name(preceding-sibling::*[1]) = 'author'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:call-template name="person.name" />
<xsl:apply-templates mode="titlepage.mode" select="./contrib" />
<xsl:apply-templates mode="titlepage.mode" select="./affiliation" />
</span>
</xsl:template>
<xsl:template match="authorgroup" mode="titlepage.mode">
<div class="{name(.)}">
<h2>Authors</h2>
<p/>
<xsl:apply-templates mode="titlepage.mode" />
</div>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,103 +0,0 @@
<?xml version="1.0" ?>
<!--
This is the XSL HTML configuration file for the Spring
Reference Documentation.
-->
<!DOCTYPE xsl:stylesheet [
<!ENTITY db_xsl_path "../lib/docbook-xsl/">
<!ENTITY callout_gfx_path "images/callouts/">
<!ENTITY admon_gfx_path "images/admons/">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns="http://www.w3.org/TR/xhtml1/transitional"
exclude-result-prefixes="#default">
<xsl:import href="&db_xsl_path;/html/chunk.xsl" />
<!--###################################################
HTML Settings
################################################### -->
<xsl:param name="chunk.section.depth">'5'</xsl:param>
<xsl:param name="use.id.as.filename">'1'</xsl:param>
<xsl:param name="html.stylesheet">../styles/html.css</xsl:param>
<!-- These extensions are required for table printing and other stuff -->
<xsl:param name="use.extensions">1</xsl:param>
<xsl:param name="tablecolumns.extension">0</xsl:param>
<xsl:param name="callout.extensions">1</xsl:param>
<xsl:param name="graphicsize.extension">0</xsl:param>
<!--###################################################
Table Of Contents
################################################### -->
<!-- Generate the TOCs for named components only -->
<xsl:param name="generate.toc">
book toc
</xsl:param>
<!-- Show only Sections up to level 3 in the TOCs -->
<xsl:param name="toc.section.depth">3</xsl:param>
<!--###################################################
Labels
################################################### -->
<!-- Label Chapters and Sections (numbering) -->
<xsl:param name="chapter.autolabel">1</xsl:param>
<xsl:param name="section.autolabel" select="1" />
<xsl:param name="section.label.includes.component.label" select="1" />
<!--###################################################
Callouts
################################################### -->
<!-- Use images for callouts instead of (1) (2) (3) -->
<xsl:param name="callout.graphics">1</xsl:param>
<xsl:param name="callout.graphics.path">&callout_gfx_path;</xsl:param>
<!-- Place callout marks at this column in annotated areas -->
<xsl:param name="callout.defaultcolumn">90</xsl:param>
<!--###################################################
Admonitions
################################################### -->
<!-- Use nice graphics for admonitions -->
<xsl:param name="admon.graphics">'1'</xsl:param>
<xsl:param name="admon.graphics.path">&admon_gfx_path;</xsl:param>
<!--###################################################
Misc
################################################### -->
<!-- Placement of titles -->
<xsl:param name="formal.title.placement">
figure after
example before
equation before
table before
procedure before
</xsl:param>
<xsl:template match="author" mode="titlepage.mode">
<xsl:if test="name(preceding-sibling::*[1]) = 'author'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:call-template name="person.name" />
<xsl:apply-templates mode="titlepage.mode" select="./contrib" />
<xsl:apply-templates mode="titlepage.mode" select="./affiliation" />
</span>
</xsl:template>
<xsl:template match="authorgroup" mode="titlepage.mode">
<div class="{name(.)}">
<h2>Authors</h2>
<p/>
<xsl:apply-templates mode="titlepage.mode" />
</div>
</xsl:template>
<!--###################################################
Headers and Footers
################################################### -->
<!-- lets have a Spring and I21 banner across the top of each page -->
<xsl:template name="user.header.navigation">
<div style="background-color:#31430f;border:none;height:110px;border:1px solid black;">
<a style="border:none;background: url();" href="http://www.springframework.org/" title="The Spring Framework">
<img style="border:none;" src="images/banner4.jpg"/>
</a>
<a style="border:none;background: url();" href="http://www.interface21.com/" title="Interface21 - Spring from the Source">
<img style="border:none;position:absolute;right:32px;" src="images/bannerR.gif"/>
</a>
</div>
</xsl:template>
<!-- no header navigation -->
<xsl:template name="header.navigation"/>
<xsl:param name="navig.showtitles">1</xsl:param>
</xsl:stylesheet>

View File

@@ -1,197 +0,0 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2006 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.
-->
<!--
Effects the transformation of taglib XML to DocBook XML.
Author: Rick Evans (based on Tim - katentim - Nolan's original stylesheet)
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan">
<xsl:output
method="xml"
indent="yes"
xalan:indent-amount="3"
omit-xml-declaration="no"/>
<xsl:param name="title"/>
<xsl:template match="taglib">
<xsl:element name="appendix">
<xsl:attribute name="id">
<xsl:value-of select="$title"/>
</xsl:attribute>
<xsl:element name="title"><xsl:value-of select="$title"/></xsl:element>
<xsl:element name="section">
<xsl:attribute name="id">
<xsl:value-of select="$title"/>
<xsl:text>-intro</xsl:text>
</xsl:attribute>
<xsl:element name="title"><xsl:text>Introduction</xsl:text></xsl:element>
</xsl:element>
<xsl:element name="para">
<xsl:text>This appendix describes the </xsl:text>
<xsl:element name="literal">
<xsl:value-of select="$title"/>
</xsl:element>
<xsl:text> tag library descriptor.</xsl:text>
</xsl:element>
<xsl:element name="itemizedlist">
<xsl:apply-templates select="tag" mode="mini-toc">
<xsl:sort select="name" order="ascending"/>
</xsl:apply-templates>
</xsl:element>
<xsl:apply-templates select="tag">
<xsl:sort select="name" order="ascending"/>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<xsl:template match="tag" mode="mini-toc">
<xsl:element name="listitem">
<xsl:element name="xref">
<xsl:attribute name="linkend">
<xsl:call-template name="generate.id">
<xsl:with-param name="id">
<xsl:value-of select="./name"/>
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="tag">
<xsl:element name="section">
<xsl:attribute name="id">
<xsl:call-template name="generate.id">
<xsl:with-param name="id">
<xsl:value-of select="./name"/>
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
<xsl:element name="title">
<xsl:text>The </xsl:text>
<xsl:element name="literal">
<xsl:value-of select="./name"/>
</xsl:element>
<xsl:text> tag</xsl:text>
</xsl:element>
<xsl:element name="para">
<xsl:value-of select="./description"/>
</xsl:element>
<xsl:element name="table">
<xsl:element name="title">
<xsl:text>Attributes</xsl:text>
</xsl:element>
<xsl:element name="tgroup">
<xsl:attribute name="cols">
<xsl:text>4</xsl:text>
</xsl:attribute>
<xsl:element name="colspec">
<xsl:attribute name="align">
<xsl:text>center</xsl:text>
</xsl:attribute>
</xsl:element>
<xsl:element name="colspec">
<xsl:attribute name="align">
<xsl:text>center</xsl:text>
</xsl:attribute>
</xsl:element>
<xsl:element name="colspec">
<xsl:attribute name="align">
<xsl:text>center</xsl:text>
</xsl:attribute>
</xsl:element>
<xsl:element name="colspec">
<xsl:attribute name="align">
<xsl:text>center</xsl:text>
</xsl:attribute>
</xsl:element>
<xsl:element name="thead">
<xsl:element name="row">
<xsl:element name="entry">
<xsl:attribute name="align">
<xsl:text>center</xsl:text>
</xsl:attribute>
<xsl:text>Attribute</xsl:text>
</xsl:element>
<xsl:element name="entry">
<xsl:attribute name="align">
<xsl:text>center</xsl:text>
</xsl:attribute>
<xsl:text>Required?</xsl:text>
</xsl:element>
<xsl:element name="entry">
<xsl:attribute name="align">
<xsl:text>center</xsl:text>
</xsl:attribute>
<xsl:text>Runtime Expression?</xsl:text>
</xsl:element>
<xsl:element name="entry">
<xsl:attribute name="align">
<xsl:text>center</xsl:text>
</xsl:attribute>
<xsl:text>Description</xsl:text>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="tbody">
<xsl:apply-templates select="attribute">
<xsl:sort select="name" order="ascending"/>
</xsl:apply-templates>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="attribute">
<xsl:element name="row">
<xsl:element name="entry">
<xsl:element name="para">
<xsl:value-of select="name"/>
</xsl:element>
</xsl:element>
<xsl:element name="entry">
<xsl:element name="para">
<xsl:value-of select="required"/>
</xsl:element>
</xsl:element>
<xsl:element name="entry">
<xsl:element name="para">
<xsl:value-of select="rtexprvalue"/>
</xsl:element>
</xsl:element>
<xsl:element name="entry">
<xsl:element name="para">
<xsl:value-of select="description"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template name="generate.id">
<xsl:param name="id"/>
<xsl:value-of select="$title"/>.<xsl:value-of select="$id"/>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,123 +0,0 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2006 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.
-->
<!--
Effects the transformation of the various Spring schema definitions to DocBook XML.
Author: Rick Evans
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xalan="http://xml.apache.org/xalan">
<xsl:output
method="xml"
indent="yes"
xalan:indent-amount="3"
omit-xml-declaration="no"/>
<xsl:param name="title"/>
<xsl:template match="xsd:schema">
<xsl:element name="appendix">
<xsl:attribute name="id">
<xsl:value-of select="$title"/>
</xsl:attribute>
<xsl:element name="title">
<xsl:element name="literal">
<xsl:value-of select="$title"/>
</xsl:element>
</xsl:element>
<xsl:element name="section">
<xsl:attribute name="id">
<xsl:value-of select="$title"/>
<xsl:text>-intro</xsl:text>
</xsl:attribute>
<xsl:element name="title">
<xsl:text>Introduction</xsl:text>
</xsl:element>
</xsl:element>
<xsl:element name="para">
<xsl:text>This appendix describes the </xsl:text>
<xsl:element name="literal">
<xsl:value-of select="$title"/>
</xsl:element>
<xsl:text> schema.</xsl:text>
</xsl:element>
<xsl:element name="itemizedlist">
<xsl:apply-templates select="xsd:element" mode="mini-toc">
<xsl:sort select="name" order="ascending"/>
</xsl:apply-templates>
</xsl:element>
<xsl:apply-templates select="xsd:element">
<xsl:sort select="name" order="ascending"/>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<!--
creates the elements of an <itemizedlist/> containing (hyper)links
to the actual content
-->
<xsl:template match="xsd:element" mode="mini-toc">
<xsl:element name="listitem">
<xsl:element name="xref">
<xsl:attribute name="linkend">
<xsl:call-template name="generate.id">
<xsl:with-param name="id">
<xsl:value-of select="@name"/>
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="xsd:element">
<xsl:element name="section">
<xsl:attribute name="id">
<xsl:call-template name="generate.id">
<xsl:with-param name="id">
<xsl:value-of select="@name"/>
</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
<xsl:element name="title">
<xsl:text>The </xsl:text>
<xsl:element name="literal">
<xsl:value-of select="@name"/>
</xsl:element>
<xsl:text> element</xsl:text>
</xsl:element>
<xsl:element name="para">
<xsl:text>[TODO : insert the description of the element here]</xsl:text>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template name="generate.id">
<xsl:param name="id"/>
<xsl:value-of select="$title"/>.<xsl:value-of select="$id"/>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,19 +0,0 @@
This project uses the 'DocBook XSL distribution' for HTML and PDF
generation of project upgrade documentation.
This project's build.xml file contains targets to generate the
project upgrade documentation.
To generate project documentation, execute one of the following
build targets:
* upgrade-all - generate documentation in all supported formats
* upgrade-pdf - generate the PDF documentation
* upgrade-html - generate the HTML documentation
* upgrade-clean - clean any output directories for docs
For generation to complete successfully, you must have first extracted
the .jar libraries contained in this archive:
- http://static.springframework.org/spring/files/docbook-reference-libs.zip
... to ${basedir}/docs/reference. If you have not yet done so, download this file
and unzip the contents of the archive into ${basedir}/docs/reference.

View File

@@ -1,460 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<article>
<title>Upgrade Guide</title>
<para>The base package for Spring LDAP is
<literal>org.springframework.ldap</literal>. In this document, we will refer
to this package as <literal>ldap</literal>.</para>
<sect1>
<title>Upgrading from 1.1.x to 1.2</title>
<para>In 1.2, there are a couple of major changes:</para>
<itemizedlist>
<listitem>
<para>Transaction support added</para>
</listitem>
<listitem>
<para>Exception hierarchy changed</para>
</listitem>
<listitem>
<para>Package structure changed</para>
</listitem>
</itemizedlist>
<para>The transaction support is entirely new and should not affect users of
previous releases.</para>
<para>The exception hierarchy was previously based on the Spring
<literal>DataAccessException</literal> hierarchy, but is now an unchecked
mirror of the JNDI <literal>NamingException</literal> hierarchy. The fact
that it is unchecked like <literal>DataAccessException</literal> makes
migration less troublesome. However, note that
<literal>ContextSource</literal> and its implementations now throw
<literal>org.springframework.ldap.NamingException</literal>, not
<literal>DataAccessException</literal>.</para>
<para>In release 1.1.x, there were two cyclic dependencies. The first one
was between <literal>ldap.support</literal> and
<literal>ldap.support.parser</literal>, while the other one was between
<literal>ldap</literal> and <literal>ldap.support</literal>. </para>
<para>The first cycle was easily solved by changing the generation of the
parser to generate code into <literal>ldap.support</literal> rather than
into a separate package.</para>
<para>The second cycle was slightly more complicated. To sort it out, some major
restructuring was needed, as documented in the following sections.</para>
<para>While the package restructuring is rather extensive, no classes have
changed names - this means that for the most cases a simple import resolve operation
(such as &quot;Ctrl+Shift-O&quot; in Eclipse) should sort things out.
You will still need to change the package names manually in your configuration files -
this should be a simple find/replace operation based on the information below.</para>
<sect2>
<title>Moved core classes from ldap to ldap.core</title>
<para>The core classes listed below were moved to a subpackage called
<literal>ldap.core</literal>.</para>
<para><informaltable>
<tgroup cols="3">
<colspec align="left" />
<thead>
<row>
<entry align="center">Class</entry>
<entry align="center">Before</entry>
<entry align="center">After</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>AttributesMapper</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>AuthenticationSource</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>CollectingNameClassPair- CallbackHandler</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>ContextAssembler</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>ContextExecutor</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>ContextMapper</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>ContextSource</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>DefaultNameClassPairMapper</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>DirContextProcessor</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>LdapOperations</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>LdapTemplate</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>NameClassPairCallbackHandler</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>NameClassPairMapper</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>SearchExecutor</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
</sect2>
<sect2>
<title>Moved subpackages of ldap.support to ldap</title>
<para>The various packages for authentication, controls and filters were
moved to the top level <literal>ldap</literal> package.</para>
<para><informaltable>
<tgroup cols="3">
<colspec align="center" />
<thead>
<row>
<entry align="center">Class</entry>
<entry align="center">Before</entry>
<entry align="center">After</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>*</literal></entry>
<entry><literal>ldap.support.authentication</literal></entry>
<entry><literal>ldap.authentication</literal></entry>
</row>
<row>
<entry><literal>*</literal></entry>
<entry><literal>ldap.support.control</literal></entry>
<entry><literal>ldap.control</literal></entry>
</row>
<row>
<entry><literal>*</literal></entry>
<entry><literal>ldap.support.filter</literal></entry>
<entry><literal>ldap.filter</literal></entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
</sect2>
<sect2>
<title>Moved most classes in ldap.support to ldap.core or
ldap.core.support</title>
<para>The classes in <literal>ldap.support</literal> that are directly
referenced from the core classes were moved to
<literal>ldap.core</literal>, while various support classes not directly
referenced were moved to <literal>ldap.core.support</literal>.</para>
<para><informaltable>
<tgroup cols="3">
<colspec align="left" />
<thead>
<row>
<entry align="center">Class</entry>
<entry align="center">Before</entry>
<entry align="center">After</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>AbstractContextSource</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core.support</literal></entry>
</row>
<row>
<entry><literal>AggregateDirContextProcessor</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core.support</literal></entry>
</row>
<row>
<entry><literal>AttributeModificationsAware</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>CountNameClassPair- CallbackHandler</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core.support</literal></entry>
</row>
<row>
<entry><literal>DefaultDirObjectFactory</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>DefaultDnParserFactory</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>DirContextAdapter</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>DirContextOperations</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>DirContextSource</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core.support</literal></entry>
</row>
<row>
<entry><literal>DistinguishedName</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>DnParser</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>LdapContextSource</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core.support</literal></entry>
</row>
<row>
<entry><literal>LdapEncoder</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>LdapRdn</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
<row>
<entry><literal>LdapRdnComponent</literal></entry>
<entry><literal>ldap.support</literal></entry>
<entry><literal>ldap.core</literal></entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
</sect2>
<sect2>
<title>Moved classes in ldap and ldap.util to ldap.support</title>
<para>The <literal>ldap.util</literal> package has been removed. The
classes in <literal>ldap.util</literal> were moved to
<literal>ldap.support</literal>. Also, the classes in
<literal>ldap</literal> related to exception translation were moved to
<literal>ldap.support</literal>.</para>
<note>
<para>The translation classes are deprecated. Instead, the static
method <literal>LdapUtils.convertLdapException</literal> should be
used.</para>
</note>
<para><informaltable>
<tgroup cols="3">
<colspec align="left" />
<thead>
<row>
<entry align="center">Class</entry>
<entry align="center">Before</entry>
<entry align="center">After</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>DefaultNamingExceptionTranslator</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.support</literal></entry>
</row>
<row>
<entry><literal>LdapUtils</literal></entry>
<entry><literal>-</literal></entry>
<entry><literal>ldap.support</literal></entry>
</row>
<row>
<entry><literal>ListComparator</literal></entry>
<entry><literal>ldap.util</literal></entry>
<entry><literal>ldap.support</literal></entry>
</row>
<row>
<entry><literal>NamingExceptionTranslator</literal></entry>
<entry><literal>ldap</literal></entry>
<entry><literal>ldap.support</literal></entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
</sect2>
</sect1>
</article>

View File

@@ -1,234 +0,0 @@
<?xml version="1.0"?>
<!--
Copyright 2005-2006 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.
- - -
Author: Ulrik Sandberg
- - -
-->
<!--
Note that in your build file, you can no longer import common-targets
or itest-targets, since this file already imports those files. If you do,
the hook targets here will not execute.
Your build file should look something like this:
<import file="${basedir}/itest-openldap-targets.xml" />
<import file="${common.build.dir}/doc-targets.xml" />
<import file="${common.build.dir}/clover-targets.xml" />
-->
<project name="itest-openldap-targets">
<property file="build.properties" />
<property file="project.properties" />
<property file="${common.build.dir}/build.properties" />
<property file="${common.build.dir}/project.properties" />
<property file="${user.home}/build.properties" />
<import file="${common.build.dir}/itest-targets.xml" />
<import file="${common.build.dir}/common-targets.xml" />
<!--
Custom properties for itest-openldap.
Cannot use project.properties, because common-build properties
must be loaded before these ones are set.
-->
<!-- itest-openldap sources -->
<property name="src.java.itest.openldap.dir" location="${src.dir}/itest-openldap/java" />
<!-- any generated java sources go here -->
<property name="target.gen.java.itest.openldap.dir" location="${target.dir}/gen-java-itest-openldap-src" />
<!-- where built itest-openldap class files and resources go -->
<property name="target.itest.openldap.classes.dir" location="${target.dir}/itest-openldap-classes" />
<!-- where itest-openldap results end up -->
<property name="target.itest.openldap.results.dir" location="${target.dir}/itest-openldap-reports" />
<!-- itest-openldap resources get copied into target itest-openldap classes dir with filtering -->
<property name="src.itest.openldap.resources.dir" location="${src.dir}/itest-openldap/resources" />
<!-- default wildcard for finding JUnit tests
the convention is that our JUnit test classes have XXXTests-style names -->
<property name="itest.openldap.includes" value="**/*ITest.class,**/*ITests.class" />
<!-- wildcards to exclude among JUnit tests -->
<property name="itest.openldap.includes" value="itest.openldap.excludes=**/Abstract*" />
<!-- jvm arguments we want tacked on to all integration tests -->
<!-- set fake default value, will not override existing setting -->
<property name="itest.openldap.arguments" value="-Dzzz456zzz" />
<!-- Hooking in an itest-openldap version of statics.test -->
<target name="statics.post" depends="itest-targets.statics.post">
<!-- copy everything from the source dir, except java files. Do not filter. Files
that need filtering should source from ${src.itest.openldap.resources.dir} -->
<copy todir="${target.itest.openldap.classes.dir}">
<fileset dir="${src.java.itest.openldap.dir}">
<exclude name="**/*.java" />
</fileset>
</copy>
<!-- copy test resource files if neccessary, filtering for non-binary types -->
<available file="${src.itest.openldap.resources.dir}" property="itest.openldap.resources.exists" />
<antcall target="copy.itest.openldap.resources" />
<!-- write out a test.properties file with common properties -->
<propertyfile file="${target.testclasses.dir}/test.properties" comment="Common unit/integration test properties">
<entry key="lastupdate" type="date" value="now" />
</propertyfile>
</target>
<!-- The itest-openldap version of copy.test.resources -->
<target name="copy.itest.openldap.resources" if="itest.openldap.resources.exists">
<copy todir="${target.itest.openldap.classes.dir}" filtering="on">
<fileset dir="${src.itest.openldap.resources.dir}">
<patternset refid="std.files.to.filter" />
</fileset>
<filterset>
<filtersfile file="${target.filter.file}" />
</filterset>
</copy>
<copy todir="${target.itest.openldap.classes.dir}">
<fileset dir="${src.itest.openldap.resources.dir}">
<patternset refid="std.files.not.to.filter" />
</fileset>
</copy>
</target>
<!-- Hooking in an itest-openldap version of compile.tests -->
<target name="compile.post" depends="itest-targets.compile.post,build.itest.openldap.prepare">
<echo>compiling itest-openldap sources</echo>
<javac destdir="${target.itest.openldap.classes.dir}" debug="${debug}" deprecation="${deprecation}" optimize="${optimize}" source="${javac.source}" target="${javac.target}">
<src path="${src.java.itest.openldap.dir}" />
<src path="${target.gen.java.itest.openldap.dir}" />
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.itestclasses.dir}" />
<path refid="test.classpath" />
</classpath>
</javac>
</target>
<!-- build.itest.openldap.prepare: Prepares the build directory for itests-openldap -->
<target name="build.itest.openldap.prepare" unless="build.itest.openldap.prepare.done">
<mkdir dir="${target.gen.java.itest.openldap.dir}" />
<mkdir dir="${target.itest.openldap.classes.dir}" />
<property name="build.itest.openldap.prepare.done" value="true" />
</target>
<!-- The itest-openldap version of tests.prepare -->
<target name="itests-openldap-prepare" depends="compile" unless="itests.openldap.prepare.done">
<mkdir dir="${target.itest.openldap.results.dir}" />
<delete>
<fileset dir="${target.itest.openldap.results.dir}" includes="**/*.txt,**/*.log" />
</delete>
<property name="itests.openldap.prepare.done" value="true" />
</target>
<!-- Runs the integration tests. -->
<target name="itests-openldap" depends="itests-openldap-prepare" description="Run all integration tests">
<!-- for the time being we just halt on failure, since these are
local tests and there is no external server to shut down, etc.
But if we want to optionally run all tests and report on the
whole batch, then we need to set a failure property. -->
<junit forkmode="perBatch" printsummary="yes" haltonfailure="no" haltonerror="no" dir="${basedir}" errorproperty="itests.openldap.failed" failureproperty="itests.openldap.failed">
<jvmarg value="${unitvm}" />
<jvmarg value="-Djava.security.auth.login.config=${target.itest.openldap.classes.dir}/auth.conf" />
<jvmarg value="${itest.openldap.arguments}" />
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.itestclasses.dir}" />
<pathelement location="${target.itest.openldap.classes.dir}" />
<pathelement location="${target.genclasses.dir}" />
<path refid="test.classpath" />
</classpath>
<formatter type="plain" />
<formatter type="xml" />
<batchtest fork="yes" todir="${target.itest.openldap.results.dir}">
<fileset dir="${target.itest.openldap.classes.dir}" includes="${itest.openldap.includes}" excludes="${itest.openldap.excludes}" />
</batchtest>
</junit>
</target>
<!-- runs one integration test -->
<target name="itest-openldap" depends="guard.itest-openldapclass,itests-openldap-prepare" description="Runs one integration test using the value of the itest.openldap.class property">
<junit forkmode="perBatch" printsummary="yes" haltonfailure="no" haltonerror="no">
<jvmarg value="${unitvm}" />
<jvmarg value="-Djava.security.auth.login.config=${target.itest.openldap.classes.dir}/auth.conf" />
<jvmarg value="${test.arguments}" />
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.itestclasses.dir}" />
<pathelement location="${target.itest.openldap.classes.dir}" />
<pathelement location="${target.genclasses.dir}" />
<path refid="test.classpath" />
</classpath>
<formatter type="plain" />
<formatter type="xml" />
<!-- the test case -->
<test name="${itest.openldap.class}" todir="${target.itest.openldap.results.dir}" />
</junit>
</target>
<target name="guard.itest-openldapclass" unless="itest.openldap.class">
<fail message="The target you are attempting to run requires the ${itest.openldap.class} property to be set, which doesn't appear to be" />
</target>
<!--
itest-openldap-example - a sample integration test
shows how to make a target to run just one specific integration test instead
of having to specify the class
It can get a lot more elaborate than this, with various properties being
set up, etc. Property files can be written out, etc.
<target name="itest.openldap.example" depends="init">
<antcall target="itest-openldap">
<param name="itest.openldap.class" value="com.mycompany.myproject.MyIntegrationTest"/>
</antcall>
</target>
-->
<property name="target.itest.openldap.results.html.dir" location="${target.itest.openldap.results.dir}/html" />
<!-- Generate the unit test report -->
<target name="itest-openldap-report" depends="build.prepare" description="Generate HTML report of integration test results">
<delete dir="${target.itest.openldap.results.html.dir}" />
<mkdir dir="${target.itest.openldap.results.html.dir}" />
<junitreport todir="${target.itest.openldap.results.html.dir}">
<fileset dir="${target.itest.openldap.results.dir}">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${target.itest.openldap.results.html.dir}" />
</junitreport>
<echo>
Integration test report has been generated.
The HTML report is ${target.itest.openldap.results.html.dir}/index.html
</echo>
<fail if="itests.openldap.failed" message="Integration tests towards OpenLDAP failed" />
</target>
</project>

View File

@@ -1,140 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.jayasoft.org/misc/ivy/samples/ivy.xsd">
<info organisation="org.springframework" module="spring-ldap" />
<configurations>
<conf name="default" extends="global" />
<conf name="global" visibility="private" />
<conf name="buildtime" visibility="private" />
<conf name="test" visibility="private" />
<conf name="source" visibility="public" />
</configurations>
<publications>
<artifact name="spring-ldap" type="jar" conf="default" />
<artifact name="spring-ldap-src" type="zip" conf="source" />
</publications>
<dependencies defaultconf="global->default">
<!-- global (core) dependencies -->
<dependency org="commons-logging" name="commons-logging"
rev="1.0.4" />
<dependency org="commons-lang" name="commons-lang" rev="2.3" />
<dependency org="commons-pool" name="commons-pool" rev="1.3" />
<dependency org="org.springframework" name="spring-beans"
rev="2.0.8" />
<dependency org="org.springframework" name="spring-core"
rev="2.0.8" />
<dependency org="org.springframework" name="spring-context"
rev="2.0.8" />
<dependency org="org.springframework" name="spring-dao"
rev="2.0.8" />
<dependency org="org.springframework" name="spring-jdbc"
rev="2.0.8" />
<dependency org="org.springframework" name="spring-src"
rev="2.0.8" conf="source->source">
<artifact name="spring-src" type="zip" />
</dependency>
<dependency org="com.sun" name="ldapbp" rev="1.0" />
<!-- build time only dependencies -->
<dependency org="org.acegisecurity" name="acegi-security"
rev="1.0.6" conf="buildtime->default" />
<dependency org="org.acegisecurity" name="acegi-security-src"
rev="1.0.6" conf="source->default">
<artifact name="acegi-security-src" type="zip" />
</dependency>
<!-- kind of nasty, acegi needs some 1.2.7 stuff, so we override with newer! -->
<dependency org="org.springframework" name="spring-remoting"
rev="2.0.8" conf="buildtime->default" />
<dependency org="org.springframework" name="spring-support"
rev="2.0.8" conf="buildtime->default" />
<dependency org="org.tigris" name="svnant" rev="1.0.0"
conf="buildtime->default">
<artifact name="svnant" type="jar" />
<artifact name="svnClientAdapter" type="jar" />
<artifact name="svnjavahl" type="jar" />
</dependency>
<!-- test time only dependencies -->
<dependency org="commons-collections" name="commons-collections"
rev="3.1" conf="test->default" />
<dependency org="com.cenqua.clover" name="clover" rev="1.3.12"
conf="test->default" />
<dependency org="org.springframework" name="spring-mock"
rev="2.0.8" conf="test->default" />
<dependency org="gsbase" name="gsbase" rev="2.0.1"
conf="test->default" />
<dependency org="junit" name="junit" rev="3.8.2"
conf="test->default" />
<dependency org="junit-addons" name="junit-addons" rev="1.4"
conf="test->default" />
<dependency org="junitperf" name="junitperf" rev="1.8"
conf="test->default" />
<dependency org="easymock" name="easymock" rev="1.2_Java1.3"
conf="test->default" />
<dependency org="ehcache" name="ehcache" rev="1.1"
conf="test->default" />
<dependency org="net.sf.ehcache" name="ehcache-constructs"
rev="0.6" conf="test->default" />
<dependency org="jexcelapi" name="jxl" rev="2.5.9"
conf="test->default" />
<dependency org="org.ddsteps" name="DDSteps" rev="1.1"
conf="test->default" />
<dependency org="cglib" name="cglib-nodep" rev="2.1_3"
conf="test->default" />
<dependency org="org.springframework" name="spring-aop"
rev="2.0.8" conf="test->default" />
<dependency org="aopalliance" name="aopalliance" rev="1.0"
conf="test->default" />
<dependency org="hsqldb" name="hsqldb" rev="1.8.0.7"
conf="test->default" />
<!-- Test dependencies for Apache Directory Server -->
<dependency org="org.apache.directory.server"
name="apacheds-core" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-core-shared" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-server-jndi" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-server-main" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-protocol-shared" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-protocol-changepw" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-protocol-kerberos" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-kerberos-shared" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-protocol-ldap" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.shared" name="shared-asn1"
rev="0.9.5.3" conf="test->default" />
<dependency org="org.apache.directory.shared"
name="shared-asn1-codec" rev="0.9.5.3" conf="test->default" />
<dependency org="org.apache.directory.shared" name="shared-ldap"
rev="0.9.5.3" conf="test->default" />
<dependency org="log4j" name="log4j" rev="1.2.9"
conf="test->default" />
<dependency org="antlr" name="antlr" rev="2.7.2"
conf="test->default" />
<dependency org="jdbm" name="jdbm" rev="1.0"
conf="test->default" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.0"
conf="test->default" />
<dependency org="org.apache.mina" name="mina-core" rev="1.0.0"
conf="test->default" />
<dependency org="org.apache.mina" name="mina-filter-ssl"
rev="1.0.0" conf="test->default" />
<!-- End test dependencies for Apache Directory Server -->
</dependencies>
</ivy-module>

View File

@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2006 Mattias Arthursson and Ulrik Sandberg
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.

View File

@@ -1,16 +0,0 @@
======================================================================
== NOTICE file corresponding to section 4 d of the Apache License, ==
== Version 2.0, for the Spring LDAP distribution. ==
======================================================================
This product includes software developed by
the Apache Software Foundation (http://www.apache.org).
The end-user documentation included with a redistribution, if any,
must include the following acknowledgement:
"This product includes software developed by the Spring LDAP
Project (http://www.springframework.org/ldap)."
Alternately, this acknowledgement may appear in the software itself,
if and wherever such third-party acknowledgements normally appear.

View File

@@ -1,17 +0,0 @@
# properties defined in this file are overridable by a local build.properties in this project dir
# The location of the common build system
common.build.dir=${basedir}/../common-build
src.javacc.dir=${basedir}/src/main/javacc
javacc.home.dir=c:/java/javacc-4.0
project.base.version=1.2.2-SNAPSHOT
#project.version=${project.base.version}
#ivy.status=release
javac.source=1.3
javac.target=1.3
# extend common-build with source capability
main.build.configs=global,buildtime,test,source

View File

@@ -1,87 +0,0 @@
Spring-LDAP 1.2 (Oct 2007)
-----------------------------
http://www.springframework.org/ldap
1. INTRODUCTION
Spring-LDAP is a library to simplify LDAP programming in Java, built on the same
principles as Spring Jdbc.
The LdapTemplate class encapsulates all the plumbing work involved in traditional LDAP
programming, such as creating, looping through NamingEnumerations, handling Exceptions
and cleaning up resources. This leaves the programmer to handle the important stuff -
where to find data (DNs and Filters) and what do do with it (map to and from domain
objects, bind, modify, unbind, etc.), in the same way that JdbcTemplate relieves the
programmer of all but the actual SQL and how the data maps to the domain model.
In addition to this, Spring-LDAP provides Exception translation from NamingExceptions
to an unchecked exception hirearchy, as well as several utilities for working with filters,
LDAP paths and Attributes.
As of version 1.2, support for client-side compensating transaction is provided, as well as
Java 5 generics support with the SimpleLdapTemplate.
2. RELEASE INFO
Spring LDAP requires J2SE 1.4 for running.
J2SE 1.4, and javacc version 4.0 is required for building the Spring LDAP distributables from source code.
J2EE 1.4 (Servlet 2.3, JSP 1.2) is required for running the example.
The Spring-LDAP release comes in three different distributables:
* spring-ldap-bin-x.x.zip
** readme.txt - this readme file.
** license.txt - terms and conditions for use, reproduction and distribution
** dist/spring-ldap-x.x.jar - the library
** dist/spring-ldap-src-x.x.zip - the source code of the library
** dist/ivys - ivy configuration
** doc/api - api javadoc documentation
** doc/reference - full project reference documentation
** doc/upgrade - Upgrade guide from 1.1.2
* spring-ldap-bin-with-dependencies-x.x.zip
** readme.txt - this readme file.
** license.txt - terms and conditions for use, reproduction and distribution
** dist/spring-ldap-x.x.jar - the library
** dist/spring-ldap-src-x.x.zip - the source code of the library
** dist/ivys - ivy configuration
** lib - all referenced libraries necessary to use spring-LDAP
** doc/api - api javadoc documentation
** doc/reference - full project reference documentation
** doc/upgrade - Upgrade guide from 1.1.2
The sources included in the distributables are for reference use only, however buildable
sources are available in svn on sourceforge on the following URLs:
Sources for this release (1.2 tag):
https://springframework.svn.sourceforge.net/svnroot/springframework/spring-ldap/tags/1.2
Latest sources (trunk):
https://springframework.svn.sourceforge.net/svnroot/springframework/spring-ldap/trunk
Nightly builds are available for download from:
http://static.springframework.org/downloads/nightly/snapshot-download.php?project=LDAP
Spring-LDAP is released under the terms of the Apache Software License (see license.txt).
3. DISTRIBUTION JAR FILES
The following distinct jar files are included in the distribution. This list
specifies the respective contents and third-party dependencies.
* spring-ldap-x.x.jar
- Contents: The Spring-LDAP library
- Dependencies: Commons Logging, Commons Lang, spring-beans,
spring-core, spring-context, spring-dao, ldapbp, commons-pool
* spring-ldap-tiger-x.x.jar
- Contents: The Spring-LDAP Java 5 support library
- Dependencies: Commons Logging, Commons Lang, spring-beans,
spring-core, spring-context, spring-dao, ldapbp, commons-pool
4. WHERE TO START
The distribution contains extensive JavaDoc documentation as well as full reference
documentation and a sample application illustrating different ways to use Spring-LDAP.
The Spring-LDAP homepage can be found at the following URL:
http://www.springframework.org/ldap
There you will find resources related to the project.

View File

@@ -17,8 +17,6 @@ package org.springframework.transaction.compensating.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
@@ -89,7 +87,7 @@ public abstract class AbstractCompensatingTransactionManagerDelegate {
TransactionSynchronizationManager.bindResource(getTransactionSynchronizationKey(), contextHolder);
}
}
catch (NamingException e) {
catch (Exception e) {
throw new CannotCreateTransactionException("Could not create DirContext instance for transaction", e);
}
}

View File

@@ -1,4 +1,4 @@
Spring-LDAP 1.2 (Oct 2007)
Spring-LDAP 1.3-RC1 (Oct 2008)
-----------------------------
http://www.springframework.org/ldap
@@ -21,38 +21,18 @@ LDAP paths and Attributes.
As of version 1.2, support for client-side compensating transaction is provided, as well as
Java 5 generics support with the SimpleLdapTemplate.
See changelog for detailed information on the thanges included in the current release.
2. RELEASE INFO
Spring LDAP requires J2SE 1.4 for running.
J2SE 1.4, and javacc version 4.0 is required for building the Spring LDAP distributables from source code.
Spring LDAP requires J2SE 1.4 and Spring 2.x for running.
J2SE 1.5, and javacc version 4.0 is required for building the Spring LDAP distributables from source code.
J2EE 1.4 (Servlet 2.3, JSP 1.2) is required for running the example.
The Spring-LDAP release comes in three different distributables:
* spring-ldap-bin-x.x.zip
** readme.txt - this readme file.
** license.txt - terms and conditions for use, reproduction and distribution
** dist/spring-ldap-x.x.jar - the library
** dist/spring-ldap-src-x.x.zip - the source code of the library
** dist/ivys - ivy configuration
** doc/api - api javadoc documentation
** doc/reference - full project reference documentation
** doc/upgrade - Upgrade guide from 1.1.2
* spring-ldap-bin-with-dependencies-x.x.zip
** readme.txt - this readme file.
** license.txt - terms and conditions for use, reproduction and distribution
** dist/spring-ldap-x.x.jar - the library
** dist/spring-ldap-src-x.x.zip - the source code of the library
** dist/ivys - ivy configuration
** lib - all referenced libraries necessary to use spring-LDAP
** doc/api - api javadoc documentation
** doc/reference - full project reference documentation
** doc/upgrade - Upgrade guide from 1.1.2
The sources included in the distributables are for reference use only, however buildable
sources are available in svn on sourceforge on the following URLs:
Sources for this release (1.2 tag):
https://springframework.svn.sourceforge.net/svnroot/springframework/spring-ldap/tags/1.2
Sources for this release (1.3-rc1 tag):
https://springframework.svn.sourceforge.net/svnroot/springframework/spring-ldap/tags/1.3-rc1
Latest sources (trunk):
https://springframework.svn.sourceforge.net/svnroot/springframework/spring-ldap/trunk
@@ -66,17 +46,58 @@ Spring-LDAP is released under the terms of the Apache Software License (see lice
The following distinct jar files are included in the distribution. This list
specifies the respective contents and third-party dependencies.
* spring-ldap-x.x.jar
* spring-ldap-core-x.x.jar
- Contents: The Spring-LDAP library
- Dependencies: Commons Logging, Commons Lang, spring-beans,
spring-core, spring-context, spring-dao, ldapbp, commons-pool
- Dependencies: Commons Logging, Commons Lang, Commons Pool, spring-beans,
spring-core, spring-context, spring-jdbc, spring-tx, ldapbp
* spring-ldap-tiger-x.x.jar
* spring-ldap-core-tiger-x.x.jar
- Contents: The Spring-LDAP Java 5 support library
- Dependencies: Commons Logging, Commons Lang, spring-beans,
spring-core, spring-context, spring-dao, ldapbp, commons-pool
- Dependencies: Commons Logging, Commons Lang, Commons Pool, spring-beans,
spring-core, spring-context, spring-jdbc, spring-tx, ldapbp
4. WHERE TO START
* spring-ldap-test-x.x.jar
- Contents: Support classes that helps LDAP withintegration testing.
- Dependencies: Commons Logging, Commons Lang, Commons Pool, spring-beans,
spring-core, spring-context, spring-jdbc, spring-tx, ldapbp
4. MAVEN USERS
All major releases of this library are available in the central maven repository. Note that the artifacts
have changed names between the 1.2.x and 1.3 releases:
spring-ldap is now spring-ldap-core
spring-ldap-tiger is now spring-ldap-core-tiger
Milestone releases (such as release candidates) are available from the spring framework milestone repo:
<repository>
<id>spring-milestone</id>
<name>Spring Portfolio Milestone Repository</name>
<url>http://s3.amazonaws.com/maven.springframework.org/milestone</url>
</repository>
This means that in order to use the latest release (1.3-rc1), you need to specify the
repository above and include the following dependencies:
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>1.3-rc1</version>
</dependency>
For java 1.5 support:
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core-tiger</artifactId>
<version>1.3-rc1</version>
</dependency>
Nighly builds are published to the snapshot repository:
<repository>
<id>spring-snapshot</id>
<name>Spring Portfolio Snapshot Repository</name>
<url>http://s3.amazonaws.com/maven.springframework.org/snapshot</url>
</repository>
5. WHERE TO START
The distribution contains extensive JavaDoc documentation as well as full reference
documentation and a sample application illustrating different ways to use Spring-LDAP.

View File

@@ -14,7 +14,6 @@
<include>org.springframework.ldap:spring-ldap-core</include>
<include>org.springframework.ldap:spring-ldap-core-tiger</include>
<include>org.springframework.ldap:spring-ldap-test</include>
<include>org.springframework.ldap:spring-ldap-acegi-support</include>
</includes>
<binaries>
<includeDependencies>false</includeDependencies>