Applied Eric's patch for pooling:

* bind/rebind/unbind support
* DirContextProxy implementation
* Removed email address from the javadocs
* Added pooling documentation
This commit is contained in:
Ulrik Sandberg
2007-11-28 23:21:21 +00:00
parent 28f6d2eae9
commit 2d1dced405
15 changed files with 3777 additions and 3209 deletions

View File

@@ -1,56 +1,64 @@
<?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">
]>
<book>
<bookinfo>
<title>Spring LDAP</title>
<subtitle>Reference Documentation</subtitle>
<releaseinfo>Version 1.2</releaseinfo>
<pubdate>October 2007</pubdate>
<authorgroup>
<author>
<firstname>Mattias</firstname>
<surname>Arthursson</surname>
</author>
<author>
<firstname>Ulrik</firstname>
<surname>Sandberg</surname>
</author>
</authorgroup>
<legalnotice>
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.
</legalnotice>
</bookinfo>
<toc />
&preface;
&overview;
&basic;
&dirobjectfactory;
&transactions;
&executors;
&contextprocessor;
&simple;
&configuration;
<?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

@@ -0,0 +1,524 @@
<?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 mitigated 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>
s.
<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>BLOCK</literal>
</entry>
<entry>
Specifies the behaviour when the pool is
exhausted.
<itemizedlist>
<listitem>
<para>
The
<literal>FAIL</literal>
option will throw a
<literal>
NoSuchElementException
</literal>
when the pool is exhausted.
</para>
</listitem>
<listitem>
<para>
The
<literal>GROW</literal>
option will create and return a
new object (essentially making
<literal>maxActive</literal>
meaningless).
</para>
</listitem>
<listitem>
<para>
The
<literal>BLOCK</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>
</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>
</chapter>

View File

@@ -66,6 +66,12 @@
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>ldapbp</artifactId>

View File

@@ -1,352 +1,358 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
/**
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DelegatingContext implements Context {
private KeyedObjectPool keyedObjectPool;
private Context delegateContext;
private final DirContextType dirContextType;
public DelegatingContext(KeyedObjectPool keyedObjectPool, Context delegateContext, DirContextType dirContextType) {
Validate.notNull(keyedObjectPool, "keyedObjectPool may not be null");
Validate.notNull(delegateContext, "delegateContext may not be null");
Validate.notNull(dirContextType, "dirContextType may not be null");
this.keyedObjectPool = keyedObjectPool;
this.delegateContext = delegateContext;
this.dirContextType = dirContextType;
}
//***** Helper Methods *****//
public Context getDelegateContext() {
return this.delegateContext;
}
public Context getInnermostDelegateContext() {
final Context delegateContext = this.getDelegateContext();
if (delegateContext instanceof DelegatingContext) {
return ((DelegatingContext)delegateContext).getInnermostDelegateContext();
}
else {
return delegateContext;
}
}
protected void assertOpen() throws NamingException {
if (this.delegateContext == null) {
throw new NamingException("Context is closed.");
}
}
//***** Object methods *****//
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Context)) {
return false;
}
final Context thisContext = this.getInnermostDelegateContext();
Context otherContext = (Context)obj;
if (otherContext instanceof DelegatingContext) {
otherContext = ((DelegatingContext)otherContext).getInnermostDelegateContext();
}
return thisContext == otherContext || (thisContext != null && thisContext.equals(otherContext));
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final Context context = this.getInnermostDelegateContext();
return (context != null ? context.hashCode() : 0);
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
final Context context = this.getInnermostDelegateContext();
return (context != null ? context.toString() : "Context is closed");
}
//***** Context Interface Delegates *****//
/**
* @see javax.naming.Context#addToEnvironment(java.lang.String, java.lang.Object)
*/
public Object addToEnvironment(String propName, Object propVal) throws NamingException {
throw new UnsupportedOperationException("Cannot call addToEnvironment on a pooled context");
}
/**
* @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object)
*/
public void bind(Name name, Object obj) throws NamingException {
throw new UnsupportedOperationException("Cannot call bind on a pooled context");
}
/**
* @see javax.naming.Context#bind(java.lang.String, java.lang.Object)
*/
public void bind(String name, Object obj) throws NamingException {
throw new UnsupportedOperationException("Cannot call bind on a pooled context");
}
/**
* @see javax.naming.Context#close()
*/
public void close() throws NamingException {
final Context context = this.getInnermostDelegateContext();
if (context == null) {
return;
}
//Get a local reference so the member can be nulled earlier
this.delegateContext = null;
//Return the object to the Pool and then null the pool reference
try {
this.keyedObjectPool.returnObject(this.dirContextType, context);
}
catch (Exception e) {
final NamingException namingException = new NamingException("Failed to return delegate Context to pool.");
namingException.setRootCause(e);
throw namingException;
}
finally {
this.keyedObjectPool = null;
}
}
/**
* @see javax.naming.Context#composeName(javax.naming.Name, javax.naming.Name)
*/
public Name composeName(Name name, Name prefix) throws NamingException {
this.assertOpen();
return this.getDelegateContext().composeName(name, prefix);
}
/**
* @see javax.naming.Context#composeName(java.lang.String, java.lang.String)
*/
public String composeName(String name, String prefix) throws NamingException {
this.assertOpen();
return this.getDelegateContext().composeName(name, prefix);
}
/**
* @see javax.naming.Context#createSubcontext(javax.naming.Name)
*/
public Context createSubcontext(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.Context#createSubcontext(java.lang.String)
*/
public Context createSubcontext(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.Context#destroySubcontext(javax.naming.Name)
*/
public void destroySubcontext(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.Context#destroySubcontext(java.lang.String)
*/
public void destroySubcontext(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.Context#getEnvironment()
*/
public Hashtable getEnvironment() throws NamingException {
this.assertOpen();
return this.getDelegateContext().getEnvironment();
}
/**
* @see javax.naming.Context#getNameInNamespace()
*/
public String getNameInNamespace() throws NamingException {
this.assertOpen();
return this.getDelegateContext().getNameInNamespace();
}
/**
* @see javax.naming.Context#getNameParser(javax.naming.Name)
*/
public NameParser getNameParser(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().getNameParser(name);
}
/**
* @see javax.naming.Context#getNameParser(java.lang.String)
*/
public NameParser getNameParser(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().getNameParser(name);
}
/**
* @see javax.naming.Context#list(javax.naming.Name)
*/
public NamingEnumeration list(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().list(name);
}
/**
* @see javax.naming.Context#list(java.lang.String)
*/
public NamingEnumeration list(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().list(name);
}
/**
* @see javax.naming.Context#listBindings(javax.naming.Name)
*/
public NamingEnumeration listBindings(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().listBindings(name);
}
/**
* @see javax.naming.Context#listBindings(java.lang.String)
*/
public NamingEnumeration listBindings(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().listBindings(name);
}
/**
* @see javax.naming.Context#lookup(javax.naming.Name)
*/
public Object lookup(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().lookup(name);
}
/**
* @see javax.naming.Context#lookup(java.lang.String)
*/
public Object lookup(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().lookup(name);
}
/**
* @see javax.naming.Context#lookupLink(javax.naming.Name)
*/
public Object lookupLink(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().lookupLink(name);
}
/**
* @see javax.naming.Context#lookupLink(java.lang.String)
*/
public Object lookupLink(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().lookupLink(name);
}
/**
* @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
*/
public void rebind(Name name, Object obj) throws NamingException {
throw new UnsupportedOperationException("Cannot call rebind on a pooled context");
}
/**
* @see javax.naming.Context#rebind(java.lang.String, java.lang.Object)
*/
public void rebind(String name, Object obj) throws NamingException {
throw new UnsupportedOperationException("Cannot call rebind on a pooled context");
}
/**
* @see javax.naming.Context#removeFromEnvironment(java.lang.String)
*/
public Object removeFromEnvironment(String propName) throws NamingException {
throw new UnsupportedOperationException("Cannot call removeFromEnvironment on a pooled context");
}
/**
* @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
*/
public void rename(Name oldName, Name newName) throws NamingException {
this.assertOpen();
this.getDelegateContext().rename(oldName, newName);
}
/**
* @see javax.naming.Context#rename(java.lang.String, java.lang.String)
*/
public void rename(String oldName, String newName) throws NamingException {
this.assertOpen();
this.getDelegateContext().rename(oldName, newName);
}
/**
* @see javax.naming.Context#unbind(javax.naming.Name)
*/
public void unbind(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call unbind on a pooled context");
}
/**
* @see javax.naming.Context#unbind(java.lang.String)
*/
public void unbind(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call unbind on a pooled context");
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
/**
* @author Eric Dalquist
*/
public class DelegatingContext implements Context {
private KeyedObjectPool keyedObjectPool;
private Context delegateContext;
private final DirContextType dirContextType;
public DelegatingContext(KeyedObjectPool keyedObjectPool, Context delegateContext, DirContextType dirContextType) {
Validate.notNull(keyedObjectPool, "keyedObjectPool may not be null");
Validate.notNull(delegateContext, "delegateContext may not be null");
Validate.notNull(dirContextType, "dirContextType may not be null");
this.keyedObjectPool = keyedObjectPool;
this.delegateContext = delegateContext;
this.dirContextType = dirContextType;
}
//***** Helper Methods *****//
public Context getDelegateContext() {
return this.delegateContext;
}
public Context getInnermostDelegateContext() {
final Context delegateContext = this.getDelegateContext();
if (delegateContext instanceof DelegatingContext) {
return ((DelegatingContext)delegateContext).getInnermostDelegateContext();
}
else {
return delegateContext;
}
}
protected void assertOpen() throws NamingException {
if (this.delegateContext == null) {
throw new NamingException("Context is closed.");
}
}
//***** Object methods *****//
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Context)) {
return false;
}
final Context thisContext = this.getInnermostDelegateContext();
Context otherContext = (Context)obj;
if (otherContext instanceof DelegatingContext) {
otherContext = ((DelegatingContext)otherContext).getInnermostDelegateContext();
}
return thisContext == otherContext || (thisContext != null && thisContext.equals(otherContext));
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final Context context = this.getInnermostDelegateContext();
return (context != null ? context.hashCode() : 0);
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
final Context context = this.getInnermostDelegateContext();
return (context != null ? context.toString() : "Context is closed");
}
//***** Context Interface Delegates *****//
/**
* @see javax.naming.Context#addToEnvironment(java.lang.String, java.lang.Object)
*/
public Object addToEnvironment(String propName, Object propVal) throws NamingException {
throw new UnsupportedOperationException("Cannot call addToEnvironment on a pooled context");
}
/**
* @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object)
*/
public void bind(Name name, Object obj) throws NamingException {
this.assertOpen();
this.getDelegateContext().bind(name, obj);
}
/**
* @see javax.naming.Context#bind(java.lang.String, java.lang.Object)
*/
public void bind(String name, Object obj) throws NamingException {
this.assertOpen();
this.getDelegateContext().bind(name, obj);
}
/**
* @see javax.naming.Context#close()
*/
public void close() throws NamingException {
final Context context = this.getInnermostDelegateContext();
if (context == null) {
return;
}
//Get a local reference so the member can be nulled earlier
this.delegateContext = null;
//Return the object to the Pool and then null the pool reference
try {
this.keyedObjectPool.returnObject(this.dirContextType, context);
}
catch (Exception e) {
final NamingException namingException = new NamingException("Failed to return delegate Context to pool.");
namingException.setRootCause(e);
throw namingException;
}
finally {
this.keyedObjectPool = null;
}
}
/**
* @see javax.naming.Context#composeName(javax.naming.Name, javax.naming.Name)
*/
public Name composeName(Name name, Name prefix) throws NamingException {
this.assertOpen();
return this.getDelegateContext().composeName(name, prefix);
}
/**
* @see javax.naming.Context#composeName(java.lang.String, java.lang.String)
*/
public String composeName(String name, String prefix) throws NamingException {
this.assertOpen();
return this.getDelegateContext().composeName(name, prefix);
}
/**
* @see javax.naming.Context#createSubcontext(javax.naming.Name)
*/
public Context createSubcontext(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.Context#createSubcontext(java.lang.String)
*/
public Context createSubcontext(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.Context#destroySubcontext(javax.naming.Name)
*/
public void destroySubcontext(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.Context#destroySubcontext(java.lang.String)
*/
public void destroySubcontext(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.Context#getEnvironment()
*/
public Hashtable getEnvironment() throws NamingException {
this.assertOpen();
return this.getDelegateContext().getEnvironment();
}
/**
* @see javax.naming.Context#getNameInNamespace()
*/
public String getNameInNamespace() throws NamingException {
this.assertOpen();
return this.getDelegateContext().getNameInNamespace();
}
/**
* @see javax.naming.Context#getNameParser(javax.naming.Name)
*/
public NameParser getNameParser(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().getNameParser(name);
}
/**
* @see javax.naming.Context#getNameParser(java.lang.String)
*/
public NameParser getNameParser(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().getNameParser(name);
}
/**
* @see javax.naming.Context#list(javax.naming.Name)
*/
public NamingEnumeration list(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().list(name);
}
/**
* @see javax.naming.Context#list(java.lang.String)
*/
public NamingEnumeration list(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().list(name);
}
/**
* @see javax.naming.Context#listBindings(javax.naming.Name)
*/
public NamingEnumeration listBindings(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().listBindings(name);
}
/**
* @see javax.naming.Context#listBindings(java.lang.String)
*/
public NamingEnumeration listBindings(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().listBindings(name);
}
/**
* @see javax.naming.Context#lookup(javax.naming.Name)
*/
public Object lookup(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().lookup(name);
}
/**
* @see javax.naming.Context#lookup(java.lang.String)
*/
public Object lookup(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().lookup(name);
}
/**
* @see javax.naming.Context#lookupLink(javax.naming.Name)
*/
public Object lookupLink(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().lookupLink(name);
}
/**
* @see javax.naming.Context#lookupLink(java.lang.String)
*/
public Object lookupLink(String name) throws NamingException {
this.assertOpen();
return this.getDelegateContext().lookupLink(name);
}
/**
* @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
*/
public void rebind(Name name, Object obj) throws NamingException {
this.assertOpen();
this.getDelegateContext().rebind(name, obj);
}
/**
* @see javax.naming.Context#rebind(java.lang.String, java.lang.Object)
*/
public void rebind(String name, Object obj) throws NamingException {
this.assertOpen();
this.getDelegateContext().rebind(name, obj);
}
/**
* @see javax.naming.Context#removeFromEnvironment(java.lang.String)
*/
public Object removeFromEnvironment(String propName) throws NamingException {
throw new UnsupportedOperationException("Cannot call removeFromEnvironment on a pooled context");
}
/**
* @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
*/
public void rename(Name oldName, Name newName) throws NamingException {
this.assertOpen();
this.getDelegateContext().rename(oldName, newName);
}
/**
* @see javax.naming.Context#rename(java.lang.String, java.lang.String)
*/
public void rename(String oldName, String newName) throws NamingException {
this.assertOpen();
this.getDelegateContext().rename(oldName, newName);
}
/**
* @see javax.naming.Context#unbind(javax.naming.Name)
*/
public void unbind(Name name) throws NamingException {
this.assertOpen();
this.getDelegateContext().unbind(name);
}
/**
* @see javax.naming.Context#unbind(java.lang.String)
*/
public void unbind(String name) throws NamingException {
this.assertOpen();
this.getDelegateContext().unbind(name);
}
}

View File

@@ -1,326 +1,341 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
/**
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DelegatingDirContext extends DelegatingContext implements DirContext {
private DirContext delegateDirContext;
public DelegatingDirContext(KeyedObjectPool keyedObjectPool, DirContext delegateDirContext, DirContextType dirContextType) {
super(keyedObjectPool, delegateDirContext, dirContextType);
Validate.notNull(delegateDirContext, "delegateDirContext may not be null");
this.delegateDirContext = delegateDirContext;
}
//***** Helper Methods *****//
public DirContext getDelegateDirContext() {
return this.delegateDirContext;
}
public Context getDelegateContext() {
return this.getDelegateDirContext();
}
public DirContext getInnermostDelegateDirContext() {
final DirContext delegateDirContext = this.getDelegateDirContext();
if (delegateDirContext instanceof DelegatingDirContext) {
return ((DelegatingDirContext)delegateDirContext).getInnermostDelegateDirContext();
}
else {
return delegateDirContext;
}
}
protected void assertOpen() throws NamingException {
if (this.delegateDirContext == null) {
throw new NamingException("DirContext is closed.");
}
super.assertOpen();
}
//***** Object methods *****//
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof DirContext)) {
return false;
}
final DirContext thisDirContext = this.getInnermostDelegateDirContext();
DirContext otherDirContext = (DirContext)obj;
if (otherDirContext instanceof DelegatingDirContext) {
otherDirContext = ((DelegatingDirContext)otherDirContext).getInnermostDelegateDirContext();
}
return thisDirContext == otherDirContext || (thisDirContext != null && thisDirContext.equals(otherDirContext));
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final DirContext context = this.getInnermostDelegateDirContext();
return (context != null ? context.hashCode() : 0);
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
final DirContext context = this.getInnermostDelegateDirContext();
return (context != null ? context.toString() : "DirContext is closed");
}
//***** DirContext Interface Delegates *****//
/**
* @see javax.naming.directory.DirContext#bind(javax.naming.Name, java.lang.Object, javax.naming.directory.Attributes)
*/
public void bind(Name name, Object obj, Attributes attrs) throws NamingException {
throw new UnsupportedOperationException("Cannot call bind on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#bind(java.lang.String, java.lang.Object, javax.naming.directory.Attributes)
*/
public void bind(String name, Object obj, Attributes attrs) throws NamingException {
throw new UnsupportedOperationException("Cannot call bind on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#createSubcontext(javax.naming.Name, javax.naming.directory.Attributes)
*/
public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#createSubcontext(java.lang.String, javax.naming.directory.Attributes)
*/
public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name, java.lang.String[])
*/
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().getAttributes(name, attrIds);
}
/**
* @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name)
*/
public Attributes getAttributes(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().getAttributes(name);
}
/**
* @see javax.naming.directory.DirContext#getAttributes(java.lang.String, java.lang.String[])
*/
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().getAttributes(name, attrIds);
}
/**
* @see javax.naming.directory.DirContext#getAttributes(java.lang.String)
*/
public Attributes getAttributes(String name) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().getAttributes(name);
}
/**
* @see javax.naming.directory.DirContext#getSchema(javax.naming.Name)
*/
public DirContext getSchema(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call getSchema on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#getSchema(java.lang.String)
*/
public DirContext getSchema(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call getSchema on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#getSchemaClassDefinition(javax.naming.Name)
*/
public DirContext getSchemaClassDefinition(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call getSchemaClassDefinition on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#getSchemaClassDefinition(java.lang.String)
*/
public DirContext getSchemaClassDefinition(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call getSchemaClassDefinition on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, int, javax.naming.directory.Attributes)
*/
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().modifyAttributes(name, mod_op, attrs);
}
/**
* @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, javax.naming.directory.ModificationItem[])
*/
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().modifyAttributes(name, mods);
}
/**
* @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, int, javax.naming.directory.Attributes)
*/
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().modifyAttributes(name, mod_op, attrs);
}
/**
* @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, javax.naming.directory.ModificationItem[])
*/
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().modifyAttributes(name, mods);
}
/**
* @see javax.naming.directory.DirContext#rebind(javax.naming.Name, java.lang.Object, javax.naming.directory.Attributes)
*/
public void rebind(Name name, Object obj, Attributes attrs) throws NamingException {
throw new UnsupportedOperationException("Cannot call rebind on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#rebind(java.lang.String, java.lang.Object, javax.naming.directory.Attributes)
*/
public void rebind(String name, Object obj, Attributes attrs) throws NamingException {
throw new UnsupportedOperationException("Cannot call rebind on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#search(javax.naming.Name, javax.naming.directory.Attributes, java.lang.String[])
*/
public NamingEnumeration search(Name name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, matchingAttributes, attributesToReturn);
}
/**
* @see javax.naming.directory.DirContext#search(javax.naming.Name, javax.naming.directory.Attributes)
*/
public NamingEnumeration search(Name name, Attributes matchingAttributes) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, matchingAttributes);
}
/**
* @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
*/
public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, filterExpr, filterArgs, cons);
}
/**
* @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, javax.naming.directory.SearchControls)
*/
public NamingEnumeration search(Name name, String filter, SearchControls cons) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, filter, cons);
}
/**
* @see javax.naming.directory.DirContext#search(java.lang.String, javax.naming.directory.Attributes, java.lang.String[])
*/
public NamingEnumeration search(String name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, matchingAttributes, attributesToReturn);
}
/**
* @see javax.naming.directory.DirContext#search(java.lang.String, javax.naming.directory.Attributes)
*/
public NamingEnumeration search(String name, Attributes matchingAttributes) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, matchingAttributes);
}
/**
* @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
*/
public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, filterExpr, filterArgs, cons);
}
/**
* @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, javax.naming.directory.SearchControls)
*/
public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, filter, cons);
}
/**
* @see edu.wisc.commons.lcp.pool.DelegatingContext#close()
*/
public void close() throws NamingException {
if (this.delegateDirContext == null) {
return;
}
super.close();
this.delegateDirContext = null;
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
import org.springframework.ldap.core.DirContextProxy;
/**
* @author Eric Dalquist
*/
public class DelegatingDirContext extends DelegatingContext implements DirContext, DirContextProxy {
private DirContext delegateDirContext;
public DelegatingDirContext(KeyedObjectPool keyedObjectPool, DirContext delegateDirContext, DirContextType dirContextType) {
super(keyedObjectPool, delegateDirContext, dirContextType);
Validate.notNull(delegateDirContext, "delegateDirContext may not be null");
this.delegateDirContext = delegateDirContext;
}
//***** Helper Methods *****//
public DirContext getDelegateDirContext() {
return this.delegateDirContext;
}
public Context getDelegateContext() {
return this.getDelegateDirContext();
}
public DirContext getInnermostDelegateDirContext() {
final DirContext delegateDirContext = this.getDelegateDirContext();
if (delegateDirContext instanceof DelegatingDirContext) {
return ((DelegatingDirContext)delegateDirContext).getInnermostDelegateDirContext();
}
else {
return delegateDirContext;
}
}
protected void assertOpen() throws NamingException {
if (this.delegateDirContext == null) {
throw new NamingException("DirContext is closed.");
}
super.assertOpen();
}
//***** Object methods *****//
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof DirContext)) {
return false;
}
final DirContext thisDirContext = this.getInnermostDelegateDirContext();
DirContext otherDirContext = (DirContext)obj;
if (otherDirContext instanceof DelegatingDirContext) {
otherDirContext = ((DelegatingDirContext)otherDirContext).getInnermostDelegateDirContext();
}
return thisDirContext == otherDirContext || (thisDirContext != null && thisDirContext.equals(otherDirContext));
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final DirContext context = this.getInnermostDelegateDirContext();
return (context != null ? context.hashCode() : 0);
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
final DirContext context = this.getInnermostDelegateDirContext();
return (context != null ? context.toString() : "DirContext is closed");
}
//***** DirContextProxy Interface Methods *****//
/* (non-Javadoc)
* @see org.springframework.ldap.core.DirContextProxy#getTargetContext()
*/
public DirContext getTargetContext() {
return this.delegateDirContext;
}
//***** DirContext Interface Delegates *****//
/**
* @see javax.naming.directory.DirContext#bind(javax.naming.Name, java.lang.Object, javax.naming.directory.Attributes)
*/
public void bind(Name name, Object obj, Attributes attrs) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().bind(name, obj, attrs);
}
/**
* @see javax.naming.directory.DirContext#bind(java.lang.String, java.lang.Object, javax.naming.directory.Attributes)
*/
public void bind(String name, Object obj, Attributes attrs) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().bind(name, obj, attrs);
}
/**
* @see javax.naming.directory.DirContext#createSubcontext(javax.naming.Name, javax.naming.directory.Attributes)
*/
public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#createSubcontext(java.lang.String, javax.naming.directory.Attributes)
*/
public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
throw new UnsupportedOperationException("Cannot call createSubcontext on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name, java.lang.String[])
*/
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().getAttributes(name, attrIds);
}
/**
* @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name)
*/
public Attributes getAttributes(Name name) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().getAttributes(name);
}
/**
* @see javax.naming.directory.DirContext#getAttributes(java.lang.String, java.lang.String[])
*/
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().getAttributes(name, attrIds);
}
/**
* @see javax.naming.directory.DirContext#getAttributes(java.lang.String)
*/
public Attributes getAttributes(String name) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().getAttributes(name);
}
/**
* @see javax.naming.directory.DirContext#getSchema(javax.naming.Name)
*/
public DirContext getSchema(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call getSchema on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#getSchema(java.lang.String)
*/
public DirContext getSchema(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call getSchema on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#getSchemaClassDefinition(javax.naming.Name)
*/
public DirContext getSchemaClassDefinition(Name name) throws NamingException {
throw new UnsupportedOperationException("Cannot call getSchemaClassDefinition on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#getSchemaClassDefinition(java.lang.String)
*/
public DirContext getSchemaClassDefinition(String name) throws NamingException {
throw new UnsupportedOperationException("Cannot call getSchemaClassDefinition on a pooled context");
}
/**
* @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, int, javax.naming.directory.Attributes)
*/
public void modifyAttributes(Name name, int mod_op, Attributes attrs) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().modifyAttributes(name, mod_op, attrs);
}
/**
* @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, javax.naming.directory.ModificationItem[])
*/
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().modifyAttributes(name, mods);
}
/**
* @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, int, javax.naming.directory.Attributes)
*/
public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().modifyAttributes(name, mod_op, attrs);
}
/**
* @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, javax.naming.directory.ModificationItem[])
*/
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().modifyAttributes(name, mods);
}
/**
* @see javax.naming.directory.DirContext#rebind(javax.naming.Name, java.lang.Object, javax.naming.directory.Attributes)
*/
public void rebind(Name name, Object obj, Attributes attrs) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().rebind(name, obj, attrs);
}
/**
* @see javax.naming.directory.DirContext#rebind(java.lang.String, java.lang.Object, javax.naming.directory.Attributes)
*/
public void rebind(String name, Object obj, Attributes attrs) throws NamingException {
this.assertOpen();
this.getDelegateDirContext().rebind(name, obj, attrs);
}
/**
* @see javax.naming.directory.DirContext#search(javax.naming.Name, javax.naming.directory.Attributes, java.lang.String[])
*/
public NamingEnumeration search(Name name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, matchingAttributes, attributesToReturn);
}
/**
* @see javax.naming.directory.DirContext#search(javax.naming.Name, javax.naming.directory.Attributes)
*/
public NamingEnumeration search(Name name, Attributes matchingAttributes) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, matchingAttributes);
}
/**
* @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
*/
public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, filterExpr, filterArgs, cons);
}
/**
* @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, javax.naming.directory.SearchControls)
*/
public NamingEnumeration search(Name name, String filter, SearchControls cons) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, filter, cons);
}
/**
* @see javax.naming.directory.DirContext#search(java.lang.String, javax.naming.directory.Attributes, java.lang.String[])
*/
public NamingEnumeration search(String name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, matchingAttributes, attributesToReturn);
}
/**
* @see javax.naming.directory.DirContext#search(java.lang.String, javax.naming.directory.Attributes)
*/
public NamingEnumeration search(String name, Attributes matchingAttributes) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, matchingAttributes);
}
/**
* @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
*/
public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, filterExpr, filterArgs, cons);
}
/**
* @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, javax.naming.directory.SearchControls)
*/
public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException {
this.assertOpen();
return this.getDelegateDirContext().search(name, filter, cons);
}
/**
* @see edu.wisc.commons.lcp.pool.DelegatingContext#close()
*/
public void close() throws NamingException {
if (this.delegateDirContext == null) {
return;
}
super.close();
this.delegateDirContext = null;
}
}

View File

@@ -1,179 +1,179 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.Control;
import javax.naming.ldap.ExtendedRequest;
import javax.naming.ldap.ExtendedResponse;
import javax.naming.ldap.LdapContext;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
/**
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DelegatingLdapContext extends DelegatingDirContext implements LdapContext {
private LdapContext delegateLdapContext;
public DelegatingLdapContext(KeyedObjectPool keyedObjectPool, LdapContext delegateLdapContext, DirContextType dirContextType) {
super(keyedObjectPool, delegateLdapContext, dirContextType);
Validate.notNull(delegateLdapContext, "delegateLdapContext may not be null");
this.delegateLdapContext = delegateLdapContext;
}
//***** Helper Methods *****//
public LdapContext getDelegateLdapContext() {
return this.delegateLdapContext;
}
// cannot return subtype in overriden method unless Java5
public DirContext getDelegateDirContext() {
return this.getDelegateLdapContext();
}
public LdapContext getInnermostDelegateLdapContext() {
final LdapContext delegateLdapContext = this.getDelegateLdapContext();
if (delegateLdapContext instanceof DelegatingLdapContext) {
return ((DelegatingLdapContext)delegateLdapContext).getInnermostDelegateLdapContext();
}
else {
return delegateLdapContext;
}
}
protected void assertOpen() throws NamingException {
if (this.delegateLdapContext == null) {
throw new NamingException("LdapContext is closed.");
}
super.assertOpen();
}
//***** Object methods *****//
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof LdapContext)) {
return false;
}
final LdapContext thisLdapContext = this.getInnermostDelegateLdapContext();
LdapContext otherLdapContext = (LdapContext)obj;
if (otherLdapContext instanceof DelegatingLdapContext) {
otherLdapContext = ((DelegatingLdapContext)otherLdapContext).getInnermostDelegateLdapContext();
}
return thisLdapContext == otherLdapContext || (thisLdapContext != null && thisLdapContext.equals(otherLdapContext));
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final LdapContext context = this.getInnermostDelegateLdapContext();
return (context != null ? context.hashCode() : 0);
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
final LdapContext context = this.getInnermostDelegateLdapContext();
return (context != null ? context.toString() : "LdapContext is closed");
}
//***** LdapContext Interface Delegates *****//
/**
* @see javax.naming.ldap.LdapContext#extendedOperation(javax.naming.ldap.ExtendedRequest)
*/
public ExtendedResponse extendedOperation(ExtendedRequest request) throws NamingException {
this.assertOpen();
return this.getDelegateLdapContext().extendedOperation(request);
}
/**
* @see javax.naming.ldap.LdapContext#getConnectControls()
*/
public Control[] getConnectControls() throws NamingException {
this.assertOpen();
return this.getDelegateLdapContext().getConnectControls();
}
/**
* @see javax.naming.ldap.LdapContext#getRequestControls()
*/
public Control[] getRequestControls() throws NamingException {
this.assertOpen();
return this.getDelegateLdapContext().getRequestControls();
}
/**
* @see javax.naming.ldap.LdapContext#getResponseControls()
*/
public Control[] getResponseControls() throws NamingException {
this.assertOpen();
return this.getDelegateLdapContext().getResponseControls();
}
/**
* @see javax.naming.ldap.LdapContext#newInstance(javax.naming.ldap.Control[])
*/
public LdapContext newInstance(Control[] requestControls) throws NamingException {
throw new UnsupportedOperationException("Cannot call newInstance on a pooled context");
}
/**
* @see javax.naming.ldap.LdapContext#reconnect(javax.naming.ldap.Control[])
*/
public void reconnect(Control[] connCtls) throws NamingException {
throw new UnsupportedOperationException("Cannot call reconnect on a pooled context");
}
/**
* @see javax.naming.ldap.LdapContext#setRequestControls(javax.naming.ldap.Control[])
*/
public void setRequestControls(Control[] requestControls) throws NamingException {
throw new UnsupportedOperationException("Cannot call setRequestControls on a pooled context");
}
/**
* @see edu.wisc.commons.lcp.pool.DelegatingContext#close()
*/
public void close() throws NamingException {
if (this.delegateLdapContext == null) {
return;
}
super.close();
this.delegateLdapContext = null;
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.Control;
import javax.naming.ldap.ExtendedRequest;
import javax.naming.ldap.ExtendedResponse;
import javax.naming.ldap.LdapContext;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
/**
* @author Eric Dalquist
*/
public class DelegatingLdapContext extends DelegatingDirContext implements LdapContext {
private LdapContext delegateLdapContext;
public DelegatingLdapContext(KeyedObjectPool keyedObjectPool, LdapContext delegateLdapContext, DirContextType dirContextType) {
super(keyedObjectPool, delegateLdapContext, dirContextType);
Validate.notNull(delegateLdapContext, "delegateLdapContext may not be null");
this.delegateLdapContext = delegateLdapContext;
}
//***** Helper Methods *****//
public LdapContext getDelegateLdapContext() {
return this.delegateLdapContext;
}
// cannot return subtype in overriden method unless Java5
public DirContext getDelegateDirContext() {
return this.getDelegateLdapContext();
}
public LdapContext getInnermostDelegateLdapContext() {
final LdapContext delegateLdapContext = this.getDelegateLdapContext();
if (delegateLdapContext instanceof DelegatingLdapContext) {
return ((DelegatingLdapContext)delegateLdapContext).getInnermostDelegateLdapContext();
}
else {
return delegateLdapContext;
}
}
protected void assertOpen() throws NamingException {
if (this.delegateLdapContext == null) {
throw new NamingException("LdapContext is closed.");
}
super.assertOpen();
}
//***** Object methods *****//
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof LdapContext)) {
return false;
}
final LdapContext thisLdapContext = this.getInnermostDelegateLdapContext();
LdapContext otherLdapContext = (LdapContext)obj;
if (otherLdapContext instanceof DelegatingLdapContext) {
otherLdapContext = ((DelegatingLdapContext)otherLdapContext).getInnermostDelegateLdapContext();
}
return thisLdapContext == otherLdapContext || (thisLdapContext != null && thisLdapContext.equals(otherLdapContext));
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final LdapContext context = this.getInnermostDelegateLdapContext();
return (context != null ? context.hashCode() : 0);
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
final LdapContext context = this.getInnermostDelegateLdapContext();
return (context != null ? context.toString() : "LdapContext is closed");
}
//***** LdapContext Interface Delegates *****//
/**
* @see javax.naming.ldap.LdapContext#extendedOperation(javax.naming.ldap.ExtendedRequest)
*/
public ExtendedResponse extendedOperation(ExtendedRequest request) throws NamingException {
this.assertOpen();
return this.getDelegateLdapContext().extendedOperation(request);
}
/**
* @see javax.naming.ldap.LdapContext#getConnectControls()
*/
public Control[] getConnectControls() throws NamingException {
this.assertOpen();
return this.getDelegateLdapContext().getConnectControls();
}
/**
* @see javax.naming.ldap.LdapContext#getRequestControls()
*/
public Control[] getRequestControls() throws NamingException {
this.assertOpen();
return this.getDelegateLdapContext().getRequestControls();
}
/**
* @see javax.naming.ldap.LdapContext#getResponseControls()
*/
public Control[] getResponseControls() throws NamingException {
this.assertOpen();
return this.getDelegateLdapContext().getResponseControls();
}
/**
* @see javax.naming.ldap.LdapContext#newInstance(javax.naming.ldap.Control[])
*/
public LdapContext newInstance(Control[] requestControls) throws NamingException {
throw new UnsupportedOperationException("Cannot call newInstance on a pooled context");
}
/**
* @see javax.naming.ldap.LdapContext#reconnect(javax.naming.ldap.Control[])
*/
public void reconnect(Control[] connCtls) throws NamingException {
throw new UnsupportedOperationException("Cannot call reconnect on a pooled context");
}
/**
* @see javax.naming.ldap.LdapContext#setRequestControls(javax.naming.ldap.Control[])
*/
public void setRequestControls(Control[] requestControls) throws NamingException {
throw new UnsupportedOperationException("Cannot call setRequestControls on a pooled context");
}
/**
* @see edu.wisc.commons.lcp.pool.DelegatingContext#close()
*/
public void close() throws NamingException {
if (this.delegateLdapContext == null) {
return;
}
super.close();
this.delegateLdapContext = null;
}
}

View File

@@ -1,52 +1,49 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.directory.DirContext;
import org.springframework.ldap.core.ContextSource;
/**
* An enum representing the two types of {@link DirContext}s that can be returned by a
* {@link ContextSource}.
*
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public final class DirContextType {
private String name;
private DirContextType(String name) {
this.name = name;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
return name;
}
/**
* The type of {@link DirContext} returned by {@link ContextSource#getReadOnlyContext()}
*/
public static final DirContextType READ_ONLY = new DirContextType("READ_ONLY");
/**
* The type of {@link DirContext} returned by {@link ContextSource#getReadWriteContext()}
*/
public static final DirContextType READ_WRITE = new DirContextType("READ_WRITE");
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
/**
* An enum representing the two types of {@link DirContext}s that can be returned by a
* {@link ContextSource}.
*
* @author Eric Dalquist
*/
public final class DirContextType {
private String name;
private DirContextType(String name) {
this.name = name;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
return name;
}
/**
* The type of {@link DirContext} returned by {@link ContextSource#getReadOnlyContext()}
*/
public static final DirContextType READ_ONLY = new DirContextType("READ_ONLY");
/**
* The type of {@link DirContext} returned by {@link ContextSource#getReadWriteContext()}
*/
public static final DirContextType READ_WRITE = new DirContextType("READ_WRITE");
}

View File

@@ -1,200 +1,201 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.factory;
import javax.naming.directory.DirContext;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.BaseKeyedPoolableObjectFactory;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.DirContextType;
import org.springframework.ldap.pool.validation.DirContextValidator;
/**
* Factory that creates {@link DirContext} instances for pooling via a
* configured {@link ContextSource}. The {@link DirContext}s are keyed based
* on if they are read only or read/write. The expected key type is the
* {@link DirContextType} enum.
*
* <br>
* <br>
* Configuration: <table border="1">
* <tr>
* <th align="left">Property</th>
* <th align="left">Description</th>
* <th align="left">Required</th>
* <th align="left">Default</th>
* </tr>
* <tr>
* <td valign="top">contextSource</td>
* <td valign="top"> The {@link ContextSource} to get {@link DirContext}s from
* for adding to the pool. </td>
* <td valign="top">Yes</td>
* <td valign="top">null</td>
* </tr>
* <tr>
* <td valign="top">dirContextValidator</td>
* <td valign="top"> The {@link DirContextValidator} to use to validate
* {@link DirContext}s. This is only required if the pool has validation of any
* kind turned on. </td>
* <td valign="top">No</td>
* <td valign="top">null</td>
* </tr>
* </table>
*
* @author Eric Dalquist <a
* href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
class DirContextPoolableObjectFactory extends BaseKeyedPoolableObjectFactory {
protected final Log logger = LogFactory.getLog(this.getClass());
private ContextSource contextSource;
private DirContextValidator dirContextValidator;
/**
* @return the contextSource
*/
public ContextSource getContextSource() {
return this.contextSource;
}
/**
* @param contextSource
* the contextSource to set
*/
public void setContextSource(ContextSource contextSource) {
if (contextSource == null) {
throw new IllegalArgumentException("contextSource may not be null");
}
this.contextSource = contextSource;
}
/**
* @return the dirContextValidator
*/
public DirContextValidator getDirContextValidator() {
return this.dirContextValidator;
}
/**
* @param dirContextValidator
* the dirContextValidator to set
*/
public void setDirContextValidator(DirContextValidator dirContextValidator) {
if (dirContextValidator == null) {
throw new IllegalArgumentException(
"dirContextValidator may not be null");
}
this.dirContextValidator = dirContextValidator;
}
/**
* @see org.apache.commons.pool.BaseKeyedPoolableObjectFactory#makeObject(java.lang.Object)
*/
public Object makeObject(Object key) throws Exception {
Validate.notNull(this.contextSource, "ContextSource may not be null");
Validate.isTrue(key instanceof DirContextType,
"key must be a DirContextType");
final DirContextType contextType = (DirContextType) key;
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating a new " + contextType + " DirContext");
}
if (contextType == DirContextType.READ_WRITE) {
final DirContext readWriteContext = this.contextSource
.getReadWriteContext();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Created new " + DirContextType.READ_WRITE
+ " DirContext='" + readWriteContext + "'");
}
return readWriteContext;
} else if (contextType == DirContextType.READ_ONLY) {
final DirContext readOnlyContext = this.contextSource
.getReadOnlyContext();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Created new " + DirContextType.READ_ONLY
+ " DirContext='" + readOnlyContext + "'");
}
return readOnlyContext;
} else {
throw new IllegalArgumentException("Unrecognized ContextType: "
+ contextType);
}
}
/**
* @see org.apache.commons.pool.BaseKeyedPoolableObjectFactory#validateObject(java.lang.Object,
* java.lang.Object)
*/
public boolean validateObject(Object key, Object obj) {
Validate.notNull(this.dirContextValidator,
"DirContextValidator may not be null");
Validate.isTrue(key instanceof DirContextType,
"key must be a DirContextType");
Validate.isTrue(obj instanceof DirContext,
"The Object to validate must be of type '" + DirContext.class
+ "'");
try {
final DirContextType contextType = (DirContextType) key;
final DirContext dirContext = (DirContext) obj;
return this.dirContextValidator.validateDirContext(contextType,
dirContext);
} catch (Exception e) {
this.logger.warn("Failed to validate '" + obj
+ "' due to an unexpected exception.", e);
return false;
}
}
/**
* @see org.apache.commons.pool.BaseKeyedPoolableObjectFactory#destroyObject(java.lang.Object,
* java.lang.Object)
*/
public void destroyObject(Object key, Object obj) throws Exception {
Validate.isTrue(obj instanceof DirContext,
"The Object to validate must be of type '" + DirContext.class
+ "'");
try {
final DirContext dirContext = (DirContext) obj;
if (this.logger.isDebugEnabled()) {
this.logger.debug("Closing " + key + " DirContext='"
+ dirContext + "'");
}
dirContext.close();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Closed " + key + " DirContext='"
+ dirContext + "'");
}
} catch (Exception e) {
this.logger.warn(
"An exception occured while closing '" + obj + "'", e);
}
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.factory;
import javax.naming.directory.DirContext;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.BaseKeyedPoolableObjectFactory;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.DirContextType;
import org.springframework.ldap.pool.validation.DirContextValidator;
/**
* Factory that creates {@link DirContext} instances for pooling via a
* configured {@link ContextSource}. The {@link DirContext}s are keyed based
* on if they are read only or read/write. The expected key type is the
* {@link DirContextType} enum.
*
* <br>
* <br>
* Configuration: <table border="1">
* <tr>
* <th align="left">Property</th>
* <th align="left">Description</th>
* <th align="left">Required</th>
* <th align="left">Default</th>
* </tr>
* <tr>
* <td valign="top">contextSource</td>
* <td valign="top"> The {@link ContextSource} to get {@link DirContext}s from
* for adding to the pool. </td>
* <td valign="top">Yes</td>
* <td valign="top">null</td>
* </tr>
* <tr>
* <td valign="top">dirContextValidator</td>
* <td valign="top"> The {@link DirContextValidator} to use to validate
* {@link DirContext}s. This is only required if the pool has validation of any
* kind turned on. </td>
* <td valign="top">No</td>
* <td valign="top">null</td>
* </tr>
* </table>
*
* @author Eric Dalquist <a
* href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
class DirContextPoolableObjectFactory extends BaseKeyedPoolableObjectFactory {
protected final Log logger = LogFactory.getLog(this.getClass());
private ContextSource contextSource;
private DirContextValidator dirContextValidator;
/**
* @return the contextSource
*/
public ContextSource getContextSource() {
return this.contextSource;
}
/**
* @param contextSource
* the contextSource to set
*/
public void setContextSource(ContextSource contextSource) {
if (contextSource == null) {
throw new IllegalArgumentException("contextSource may not be null");
}
this.contextSource = contextSource;
}
/**
* @return the dirContextValidator
*/
public DirContextValidator getDirContextValidator() {
return this.dirContextValidator;
}
/**
* @param dirContextValidator
* the dirContextValidator to set
*/
public void setDirContextValidator(DirContextValidator dirContextValidator) {
if (dirContextValidator == null) {
throw new IllegalArgumentException(
"dirContextValidator may not be null");
}
this.dirContextValidator = dirContextValidator;
}
/**
* @see org.apache.commons.pool.BaseKeyedPoolableObjectFactory#makeObject(java.lang.Object)
*/
public Object makeObject(Object key) throws Exception {
Validate.notNull(this.contextSource, "ContextSource may not be null");
Validate.isTrue(key instanceof DirContextType,
"key must be a DirContextType");
final DirContextType contextType = (DirContextType) key;
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating a new " + contextType + " DirContext");
}
if (contextType == DirContextType.READ_WRITE) {
final DirContext readWriteContext = this.contextSource
.getReadWriteContext();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Created new " + DirContextType.READ_WRITE
+ " DirContext='" + readWriteContext + "'");
}
return readWriteContext;
} else if (contextType == DirContextType.READ_ONLY) {
final DirContext readOnlyContext = this.contextSource
.getReadOnlyContext();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Created new " + DirContextType.READ_ONLY
+ " DirContext='" + readOnlyContext + "'");
}
return readOnlyContext;
} else {
throw new IllegalArgumentException("Unrecognized ContextType: "
+ contextType);
}
}
/**
* @see org.apache.commons.pool.BaseKeyedPoolableObjectFactory#validateObject(java.lang.Object,
* java.lang.Object)
*/
public boolean validateObject(Object key, Object obj) {
Validate.notNull(this.dirContextValidator,
"DirContextValidator may not be null");
Validate.isTrue(key instanceof DirContextType,
"key must be a DirContextType");
Validate.isTrue(obj instanceof DirContext,
"The Object to validate must be of type '" + DirContext.class
+ "'");
try {
final DirContextType contextType = (DirContextType) key;
final DirContext dirContext = (DirContext) obj;
return this.dirContextValidator.validateDirContext(contextType,
dirContext);
} catch (Exception e) {
this.logger.warn("Failed to validate '" + obj
+ "' due to an unexpected exception.", e);
return false;
}
}
/**
* @see org.apache.commons.pool.BaseKeyedPoolableObjectFactory#destroyObject(java.lang.Object,
* java.lang.Object)
*/
public void destroyObject(Object key, Object obj) throws Exception {
Validate.isTrue(obj instanceof DirContext,
"The Object to validate must be of type '" + DirContext.class
+ "'");
try {
final DirContext dirContext = (DirContext) obj;
if (this.logger.isDebugEnabled()) {
this.logger.debug("Closing " + key + " DirContext='"
+ dirContext + "'");
}
dirContext.close();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Closed " + key + " DirContext='"
+ dirContext + "'");
}
} catch (Exception e) {
this.logger.warn(
"An exception occured while closing '" + obj + "'", e);
}
}
}

View File

@@ -1,461 +1,463 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.factory;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericKeyedObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.DelegatingDirContext;
import org.springframework.ldap.pool.DelegatingLdapContext;
import org.springframework.ldap.pool.DirContextType;
import org.springframework.ldap.pool.validation.DirContextValidator;
/**
* A {@link ContextSource} implementation that wraps an object pool and another {@link ContextSource}.
* {@link DirContext}s are retrieved from the pool which maintains them.
*
*
* <br>
* <br>
* Configuration:
* <table border="1">
* <tr>
* <th align="left">Property</th>
* <th align="left">Description</th>
* <th align="left">Required</th>
* <th align="left">Default</th>
* </tr>
* <tr>
* <td valign="top">contextSource</td>
* <td valign="top">
* The {@link ContextSource} to get {@link DirContext}s from for adding to the pool.
* </td>
* <td valign="top">Yes</td>
* <td valign="top">null</td>
* </tr>
* <tr>
* <td valign="top">dirContextValidator</td>
* <td valign="top">
* The {@link DirContextValidator} to use for validating {@link DirContext}s. Required
* if any of the test/validate options are enabled.
* </td>
* <td valign="top">No</td>
* <td valign="top">null</td>
* </tr>
* <tr>
* <td valign="top">minIdle</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMinIdle(int)}</td>
* <td valign="top">No</td>
* <td valign="top">0</td>
* </tr>
* <tr>
* <td valign="top">maxIdle</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMaxIdle(int)}</td>
* <td valign="top">No</td>
* <td valign="top">8</td>
* </tr>
* <tr>
* <td valign="top">maxActive</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMaxActive(int)}</td>
* <td valign="top">No</td>
* <td valign="top">8</td>
* </tr>
* <tr>
* <td valign="top">maxTotal</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMaxTotal(int)}</td>
* <td valign="top">No</td>
* <td valign="top">-1</td>
* </tr>
* <tr>
* <td valign="top">maxWait</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMaxWait(long)}</td>
* <td valign="top">No</td>
* <td valign="top">-1L</td>
* </tr>
* <tr>
* <td valign="top">whenExhaustedAction</td>
* <td valign="top">{@link GenericKeyedObjectPool#setWhenExhaustedAction(byte)}</td>
* <td valign="top">No</td>
* <td valign="top">{@link GenericObjectPool#WHEN_EXHAUSTED_BLOCK}</td>
* </tr>
* <tr>
* <td valign="top">testOnBorrow</td>
* <td valign="top">{@link GenericKeyedObjectPool#setTestOnBorrow(boolean)}</td>
* <td valign="top">No</td>
* <td valign="top">false</td>
* </tr>
* <tr>
* <td valign="top">testOnReturn</td>
* <td valign="top">{@link GenericKeyedObjectPool#setTestOnReturn(boolean)}</td>
* <td valign="top">No</td>
* <td valign="top">false</td>
* </tr>
* <tr>
* <td valign="top">testWhileIdle</td>
* <td valign="top">{@link GenericKeyedObjectPool#setTestWhileIdle(boolean)}</td>
* <td valign="top">No</td>
* <td valign="top">false</td>
* </tr>
* <tr>
* <td valign="top">timeBetweenEvictionRunsMillis</td>
* <td valign="top">{@link GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis(long)}</td>
* <td valign="top">No</td>
* <td valign="top">-1L</td>
* </tr>
* <tr>
* <td valign="top">minEvictableIdleTimeMillis</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMinEvictableIdleTimeMillis(long)}</td>
* <td valign="top">No</td>
* <td valign="top">1000L * 60L * 30L</td>
* </tr>
* <tr>
* <td valign="top">numTestsPerEvictionRun</td>
* <td valign="top">{@link GenericKeyedObjectPool#setNumTestsPerEvictionRun(int)}</td>
* <td valign="top">No</td>
* <td valign="top">3</td>
* </tr>
* </table>
*
*
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class PoolingContextSource implements ContextSource {
protected final Log logger = LogFactory.getLog(this.getClass());
private final GenericKeyedObjectPool keyedObjectPool;
private final DirContextPoolableObjectFactory dirContextPoolableObjectFactory;
public static final class WhenExhaustedAction {
static {
values = new HashMap();
}
/**
* A "when exhausted action" type indicating that when the pool is
* exhausted (i.e., the maximum number of active objects has
* been reached), the {@link #borrowObject}
* method should fail, throwing a {@link NoSuchElementException}.
*/
public static final WhenExhaustedAction FAIL = new WhenExhaustedAction("FAIL", GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL);
/**
* A "when exhausted action" type indicating that when the pool
* is exhausted (i.e., the maximum number
* of active objects has been reached), the {@link #borrowObject}
* method should block until a new object is available, or the
* {@link #getMaxWait maximum wait time} has been reached.
*/
public static final WhenExhaustedAction BLOCK = new WhenExhaustedAction("BLOCK", GenericKeyedObjectPool.WHEN_EXHAUSTED_BLOCK);
/**
* A "when exhausted action" type indicating that when the pool is
* exhausted (i.e., the maximum number
* of active objects has been reached), the {@link #borrowObject}
* method should simply create a new object anyway.
*/
public static final WhenExhaustedAction GROW = new WhenExhaustedAction("GROW", GenericKeyedObjectPool.WHEN_EXHAUSTED_GROW);
private static Map values;
private final byte commonsPoolId;
private final String name;
private WhenExhaustedAction(String name, byte id) {
this.name = name;
this.commonsPoolId = id;
values.put(new Byte(id), this);
}
/*
* @see java.lang.Object#toString()
*/
public String toString() {
return name;
}
/**
* The appropriate {@link GenericKeyedObjectPool} constant for the {@link GenericKeyedObjectPool#setWhenExhaustedAction(byte)}
*/
public byte getCommonsPoolId() {
return this.commonsPoolId;
}
public static WhenExhaustedAction getActionForId(byte id) {
return (WhenExhaustedAction) values.get(new Byte(id));
}
}
public PoolingContextSource() {
this.dirContextPoolableObjectFactory = new DirContextPoolableObjectFactory();
this.keyedObjectPool = new GenericKeyedObjectPool();
this.keyedObjectPool.setFactory(this.dirContextPoolableObjectFactory);
}
//***** Pool Property Configuration *****//
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMaxActive()
*/
public int getMaxActive() {
return this.keyedObjectPool.getMaxActive();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMaxIdle()
*/
public int getMaxIdle() {
return this.keyedObjectPool.getMaxIdle();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMaxTotal()
*/
public int getMaxTotal() {
return this.keyedObjectPool.getMaxTotal();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMaxWait()
*/
public long getMaxWait() {
return this.keyedObjectPool.getMaxWait();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
*/
public long getMinEvictableIdleTimeMillis() {
return this.keyedObjectPool.getMinEvictableIdleTimeMillis();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMinIdle()
*/
public int getMinIdle() {
return this.keyedObjectPool.getMinIdle();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getNumActive()
*/
public int getNumActive() {
return this.keyedObjectPool.getNumActive();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getNumIdle()
*/
public int getNumIdle() {
return this.keyedObjectPool.getNumIdle();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getNumTestsPerEvictionRun()
*/
public int getNumTestsPerEvictionRun() {
return this.keyedObjectPool.getNumTestsPerEvictionRun();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getTestOnBorrow()
*/
public boolean getTestOnBorrow() {
return this.keyedObjectPool.getTestOnBorrow();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getTestOnReturn()
*/
public boolean getTestOnReturn() {
return this.keyedObjectPool.getTestOnReturn();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getTestWhileIdle()
*/
public boolean getTestWhileIdle() {
return this.keyedObjectPool.getTestWhileIdle();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
*/
public long getTimeBetweenEvictionRunsMillis() {
return this.keyedObjectPool.getTimeBetweenEvictionRunsMillis();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getWhenExhaustedAction()
*/
public WhenExhaustedAction getWhenExhaustedAction() {
final byte whenExhaustedAction = this.keyedObjectPool.getWhenExhaustedAction();
return WhenExhaustedAction.getActionForId(whenExhaustedAction);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxActive(int)
*/
public void setMaxActive(int maxActive) {
this.keyedObjectPool.setMaxActive(maxActive);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxIdle(int)
*/
public void setMaxIdle(int maxIdle) {
this.keyedObjectPool.setMaxIdle(maxIdle);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxTotal(int)
*/
public void setMaxTotal(int maxTotal) {
this.keyedObjectPool.setMaxTotal(maxTotal);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxWait(long)
*/
public void setMaxWait(long maxWait) {
this.keyedObjectPool.setMaxWait(maxWait);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMinEvictableIdleTimeMillis(long)
*/
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.keyedObjectPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMinIdle(int)
*/
public void setMinIdle(int poolSize) {
this.keyedObjectPool.setMinIdle(poolSize);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setNumTestsPerEvictionRun(int)
*/
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
this.keyedObjectPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setTestOnBorrow(boolean)
*/
public void setTestOnBorrow(boolean testOnBorrow) {
this.keyedObjectPool.setTestOnBorrow(testOnBorrow);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setTestOnReturn(boolean)
*/
public void setTestOnReturn(boolean testOnReturn) {
this.keyedObjectPool.setTestOnReturn(testOnReturn);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setTestWhileIdle(boolean)
*/
public void setTestWhileIdle(boolean testWhileIdle) {
this.keyedObjectPool.setTestWhileIdle(testWhileIdle);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis(long)
*/
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.keyedObjectPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setWhenExhaustedAction(byte)
*/
public void setWhenExhaustedAction(WhenExhaustedAction whenExhaustedAction) {
if (whenExhaustedAction == null) {
throw new IllegalArgumentException("whenExhaustedAction may not be null");
}
this.keyedObjectPool.setWhenExhaustedAction(whenExhaustedAction.getCommonsPoolId());
}
//***** Object Factory Property Configuration *****//
/**
* @return the contextSource
*/
public ContextSource getContextSource() {
return this.dirContextPoolableObjectFactory.getContextSource();
}
/**
* @return the dirContextValidator
*/
public DirContextValidator getDirContextValidator() {
return this.dirContextPoolableObjectFactory.getDirContextValidator();
}
/**
* @param contextSource the contextSource to set
* @Required
*/
public void setContextSource(ContextSource contextSource) {
this.dirContextPoolableObjectFactory.setContextSource(contextSource);
}
/**
* @param dirContextValidator the dirContextValidator to set
* @Required
*/
public void setDirContextValidator(DirContextValidator dirContextValidator) {
this.dirContextPoolableObjectFactory.setDirContextValidator(dirContextValidator);
}
//***** Maintenance Methods *****//
public void close() {
try {
this.keyedObjectPool.close();
}
catch (Exception e) {
this.logger.warn("An exception occured while closing the underlying pool.", e);
}
}
//***** ContextSource interface methods *****//
/**
* @see org.springframework.ldap.ContextSource#getReadOnlyContext()
*/
public DirContext getReadOnlyContext() throws NamingException {
return this.getContext(DirContextType.READ_ONLY);
}
/**
* @see org.springframework.ldap.ContextSource#getReadWriteContext()
*/
public DirContext getReadWriteContext() throws NamingException {
return this.getContext(DirContextType.READ_WRITE);
}
protected DirContext getContext(DirContextType dirContextType) throws NamingException {
final DirContext dirContext;
try {
dirContext = (DirContext)this.keyedObjectPool.borrowObject(dirContextType);
}
catch (Exception e) {
throw new DataAccessResourceFailureException("Failed to borrow DirContext from pool.", e);
}
if (dirContext instanceof LdapContext) {
return new DelegatingLdapContext(this.keyedObjectPool, (LdapContext)dirContext, dirContextType);
}
else {
return new DelegatingDirContext(this.keyedObjectPool, dirContext, dirContextType);
}
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.factory;
import java.util.HashMap;
import java.util.Map;
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.pool.impl.GenericKeyedObjectPool;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.DelegatingDirContext;
import org.springframework.ldap.pool.DelegatingLdapContext;
import org.springframework.ldap.pool.DirContextType;
import org.springframework.ldap.pool.validation.DirContextValidator;
/**
* A {@link ContextSource} implementation that wraps an object pool and another {@link ContextSource}.
* {@link DirContext}s are retrieved from the pool which maintains them.
*
*
* <br>
* <br>
* Configuration:
* <table border="1">
* <tr>
* <th align="left">Property</th>
* <th align="left">Description</th>
* <th align="left">Required</th>
* <th align="left">Default</th>
* </tr>
* <tr>
* <td valign="top">contextSource</td>
* <td valign="top">
* The {@link ContextSource} to get {@link DirContext}s from for adding to the pool.
* </td>
* <td valign="top">Yes</td>
* <td valign="top">null</td>
* </tr>
* <tr>
* <td valign="top">dirContextValidator</td>
* <td valign="top">
* The {@link DirContextValidator} to use for validating {@link DirContext}s. Required
* if any of the test/validate options are enabled.
* </td>
* <td valign="top">No</td>
* <td valign="top">null</td>
* </tr>
* <tr>
* <td valign="top">minIdle</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMinIdle(int)}</td>
* <td valign="top">No</td>
* <td valign="top">0</td>
* </tr>
* <tr>
* <td valign="top">maxIdle</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMaxIdle(int)}</td>
* <td valign="top">No</td>
* <td valign="top">8</td>
* </tr>
* <tr>
* <td valign="top">maxActive</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMaxActive(int)}</td>
* <td valign="top">No</td>
* <td valign="top">8</td>
* </tr>
* <tr>
* <td valign="top">maxTotal</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMaxTotal(int)}</td>
* <td valign="top">No</td>
* <td valign="top">-1</td>
* </tr>
* <tr>
* <td valign="top">maxWait</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMaxWait(long)}</td>
* <td valign="top">No</td>
* <td valign="top">-1L</td>
* </tr>
* <tr>
* <td valign="top">whenExhaustedAction</td>
* <td valign="top">{@link GenericKeyedObjectPool#setWhenExhaustedAction(byte)}</td>
* <td valign="top">No</td>
* <td valign="top">{@link GenericObjectPool#WHEN_EXHAUSTED_BLOCK}</td>
* </tr>
* <tr>
* <td valign="top">testOnBorrow</td>
* <td valign="top">{@link GenericKeyedObjectPool#setTestOnBorrow(boolean)}</td>
* <td valign="top">No</td>
* <td valign="top">false</td>
* </tr>
* <tr>
* <td valign="top">testOnReturn</td>
* <td valign="top">{@link GenericKeyedObjectPool#setTestOnReturn(boolean)}</td>
* <td valign="top">No</td>
* <td valign="top">false</td>
* </tr>
* <tr>
* <td valign="top">testWhileIdle</td>
* <td valign="top">{@link GenericKeyedObjectPool#setTestWhileIdle(boolean)}</td>
* <td valign="top">No</td>
* <td valign="top">false</td>
* </tr>
* <tr>
* <td valign="top">timeBetweenEvictionRunsMillis</td>
* <td valign="top">{@link GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis(long)}</td>
* <td valign="top">No</td>
* <td valign="top">-1L</td>
* </tr>
* <tr>
* <td valign="top">minEvictableIdleTimeMillis</td>
* <td valign="top">{@link GenericKeyedObjectPool#setMinEvictableIdleTimeMillis(long)}</td>
* <td valign="top">No</td>
* <td valign="top">1000L * 60L * 30L</td>
* </tr>
* <tr>
* <td valign="top">numTestsPerEvictionRun</td>
* <td valign="top">{@link GenericKeyedObjectPool#setNumTestsPerEvictionRun(int)}</td>
* <td valign="top">No</td>
* <td valign="top">3</td>
* </tr>
* </table>
*
*
* @author Eric Dalquist
*/
public class PoolingContextSource implements ContextSource, DisposableBean {
protected final Log logger = LogFactory.getLog(this.getClass());
private final GenericKeyedObjectPool keyedObjectPool;
private final DirContextPoolableObjectFactory dirContextPoolableObjectFactory;
public static final class WhenExhaustedAction {
static {
values = new HashMap();
}
/**
* A "when exhausted action" type indicating that when the pool is
* exhausted (i.e., the maximum number of active objects has
* been reached), the {@link #borrowObject}
* method should fail, throwing a {@link NoSuchElementException}.
*/
public static final WhenExhaustedAction FAIL = new WhenExhaustedAction("FAIL", GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL);
/**
* A "when exhausted action" type indicating that when the pool
* is exhausted (i.e., the maximum number
* of active objects has been reached), the {@link #borrowObject}
* method should block until a new object is available, or the
* {@link #getMaxWait maximum wait time} has been reached.
*/
public static final WhenExhaustedAction BLOCK = new WhenExhaustedAction("BLOCK", GenericKeyedObjectPool.WHEN_EXHAUSTED_BLOCK);
/**
* A "when exhausted action" type indicating that when the pool is
* exhausted (i.e., the maximum number
* of active objects has been reached), the {@link #borrowObject}
* method should simply create a new object anyway.
*/
public static final WhenExhaustedAction GROW = new WhenExhaustedAction("GROW", GenericKeyedObjectPool.WHEN_EXHAUSTED_GROW);
private static Map values;
private final byte commonsPoolId;
private final String name;
private WhenExhaustedAction(String name, byte id) {
this.name = name;
this.commonsPoolId = id;
values.put(new Byte(id), this);
}
/*
* @see java.lang.Object#toString()
*/
public String toString() {
return name;
}
/**
* The appropriate {@link GenericKeyedObjectPool} constant for the {@link GenericKeyedObjectPool#setWhenExhaustedAction(byte)}
*/
public byte getCommonsPoolId() {
return this.commonsPoolId;
}
public static WhenExhaustedAction getActionForId(byte id) {
return (WhenExhaustedAction) values.get(new Byte(id));
}
}
public PoolingContextSource() {
this.dirContextPoolableObjectFactory = new DirContextPoolableObjectFactory();
this.keyedObjectPool = new GenericKeyedObjectPool();
this.keyedObjectPool.setFactory(this.dirContextPoolableObjectFactory);
}
//***** Pool Property Configuration *****//
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMaxActive()
*/
public int getMaxActive() {
return this.keyedObjectPool.getMaxActive();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMaxIdle()
*/
public int getMaxIdle() {
return this.keyedObjectPool.getMaxIdle();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMaxTotal()
*/
public int getMaxTotal() {
return this.keyedObjectPool.getMaxTotal();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMaxWait()
*/
public long getMaxWait() {
return this.keyedObjectPool.getMaxWait();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
*/
public long getMinEvictableIdleTimeMillis() {
return this.keyedObjectPool.getMinEvictableIdleTimeMillis();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getMinIdle()
*/
public int getMinIdle() {
return this.keyedObjectPool.getMinIdle();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getNumActive()
*/
public int getNumActive() {
return this.keyedObjectPool.getNumActive();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getNumIdle()
*/
public int getNumIdle() {
return this.keyedObjectPool.getNumIdle();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getNumTestsPerEvictionRun()
*/
public int getNumTestsPerEvictionRun() {
return this.keyedObjectPool.getNumTestsPerEvictionRun();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getTestOnBorrow()
*/
public boolean getTestOnBorrow() {
return this.keyedObjectPool.getTestOnBorrow();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getTestOnReturn()
*/
public boolean getTestOnReturn() {
return this.keyedObjectPool.getTestOnReturn();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getTestWhileIdle()
*/
public boolean getTestWhileIdle() {
return this.keyedObjectPool.getTestWhileIdle();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
*/
public long getTimeBetweenEvictionRunsMillis() {
return this.keyedObjectPool.getTimeBetweenEvictionRunsMillis();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getWhenExhaustedAction()
*/
public WhenExhaustedAction getWhenExhaustedAction() {
final byte whenExhaustedAction = this.keyedObjectPool.getWhenExhaustedAction();
return WhenExhaustedAction.getActionForId(whenExhaustedAction);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxActive(int)
*/
public void setMaxActive(int maxActive) {
this.keyedObjectPool.setMaxActive(maxActive);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxIdle(int)
*/
public void setMaxIdle(int maxIdle) {
this.keyedObjectPool.setMaxIdle(maxIdle);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxTotal(int)
*/
public void setMaxTotal(int maxTotal) {
this.keyedObjectPool.setMaxTotal(maxTotal);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxWait(long)
*/
public void setMaxWait(long maxWait) {
this.keyedObjectPool.setMaxWait(maxWait);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMinEvictableIdleTimeMillis(long)
*/
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.keyedObjectPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMinIdle(int)
*/
public void setMinIdle(int poolSize) {
this.keyedObjectPool.setMinIdle(poolSize);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setNumTestsPerEvictionRun(int)
*/
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
this.keyedObjectPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setTestOnBorrow(boolean)
*/
public void setTestOnBorrow(boolean testOnBorrow) {
this.keyedObjectPool.setTestOnBorrow(testOnBorrow);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setTestOnReturn(boolean)
*/
public void setTestOnReturn(boolean testOnReturn) {
this.keyedObjectPool.setTestOnReturn(testOnReturn);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setTestWhileIdle(boolean)
*/
public void setTestWhileIdle(boolean testWhileIdle) {
this.keyedObjectPool.setTestWhileIdle(testWhileIdle);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis(long)
*/
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.keyedObjectPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setWhenExhaustedAction(byte)
*/
public void setWhenExhaustedAction(WhenExhaustedAction whenExhaustedAction) {
if (whenExhaustedAction == null) {
throw new IllegalArgumentException("whenExhaustedAction may not be null");
}
this.keyedObjectPool.setWhenExhaustedAction(whenExhaustedAction.getCommonsPoolId());
}
//***** Object Factory Property Configuration *****//
/**
* @return the contextSource
*/
public ContextSource getContextSource() {
return this.dirContextPoolableObjectFactory.getContextSource();
}
/**
* @return the dirContextValidator
*/
public DirContextValidator getDirContextValidator() {
return this.dirContextPoolableObjectFactory.getDirContextValidator();
}
/**
* @param contextSource the contextSource to set
* @Required
*/
public void setContextSource(ContextSource contextSource) {
this.dirContextPoolableObjectFactory.setContextSource(contextSource);
}
/**
* @param dirContextValidator the dirContextValidator to set
* @Required
*/
public void setDirContextValidator(DirContextValidator dirContextValidator) {
this.dirContextPoolableObjectFactory.setDirContextValidator(dirContextValidator);
}
//***** DisposableBean interface methods *****//
/* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
try {
this.keyedObjectPool.close();
}
catch (Exception e) {
this.logger.warn("An exception occured while closing the underlying pool.", e);
}
}
//***** ContextSource interface methods *****//
/**
* @see org.springframework.ldap.ContextSource#getReadOnlyContext()
*/
public DirContext getReadOnlyContext() throws NamingException {
return this.getContext(DirContextType.READ_ONLY);
}
/**
* @see org.springframework.ldap.ContextSource#getReadWriteContext()
*/
public DirContext getReadWriteContext() throws NamingException {
return this.getContext(DirContextType.READ_WRITE);
}
protected DirContext getContext(DirContextType dirContextType) throws NamingException {
final DirContext dirContext;
try {
dirContext = (DirContext)this.keyedObjectPool.borrowObject(dirContextType);
}
catch (Exception e) {
throw new DataAccessResourceFailureException("Failed to borrow DirContext from pool.", e);
}
if (dirContext instanceof LdapContext) {
return new DelegatingLdapContext(this.keyedObjectPool, (LdapContext)dirContext, dirContextType);
}
else {
return new DelegatingDirContext(this.keyedObjectPool, dirContext, dirContextType);
}
}
}

View File

@@ -1,166 +1,166 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.validation;
import javax.naming.NamingEnumeration;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.pool.DirContextType;
/**
* Default {@link DirContext} validator that executes {@link DirContext#search(String, String, SearchControls)}. The
* name, filter and {@link SearchControls} are all configurable. There is no special handling for read only versus
* read write {@link DirContext}s.
*
* <br>
* <br>
* Configuration:
* <table border="1">
* <tr>
* <th align="left">Property</th>
* <th align="left">Description</th>
* <th align="left">Required</th>
* <th align="left">Default</th>
* </tr>
* <tr>
* <td valign="top">base</td>
* <td valign="top">
* The name parameter to the search method.
* </td>
* <td valign="top">No</td>
* <td valign="top">""</td>
* </tr>
* <tr>
* <td valign="top">filter</td>
* <td valign="top">
* The filter parameter to the search method.
* </td>
* <td valign="top">No</td>
* <td valign="top">"objectclass=*"</td>
* </tr>
* <tr>
* <td valign="top">searchControls</td>
* <td valign="top">
* The {@link SearchControls} parameter to the search method.
* </td>
* <td valign="top">No</td>
* <td valign="top">
* {@link SearchControls#setCountLimit(long)} = 1<br/>
* {@link SearchControls#setReturningAttributes(String[])} = new String[] { "objectclass" }<br/>
* {@link SearchControls#setTimeLimit(int)} = 500
* </td>
* </tr>
* </table>
*
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DefaultDirContextValidator implements DirContextValidator {
protected final Log logger = LogFactory.getLog(this.getClass());
private String base;
private String filter;
private SearchControls searchControls;
public DefaultDirContextValidator() {
this.searchControls = new SearchControls();
this.searchControls.setCountLimit(1);
this.searchControls.setReturningAttributes(new String[] { "objectclass" });
this.searchControls.setTimeLimit(500);
this.base = "";
this.filter = "objectclass=*";
}
/**
* @return the baseName
*/
public String getBase() {
return this.base;
}
/**
* @param base the baseName to set
*/
public void setBase(String base) {
this.base = base;
}
/**
* @return the filter
*/
public String getFilter() {
return this.filter;
}
/**
* @param filter the filter to set
*/
public void setFilter(String filter) {
if (filter == null) {
throw new IllegalArgumentException("filter may not be null");
}
this.filter = filter;
}
/**
* @return the searchControls
*/
public SearchControls getSearchControls() {
return this.searchControls;
}
/**
* @param searchControls the searchControls to set
*/
public void setSearchControls(SearchControls searchControls) {
if (searchControls == null) {
throw new IllegalArgumentException("searchControls may not be null");
}
this.searchControls = searchControls;
}
/**
* @see edu.wisc.commons.lcp.validation.DirContextValidator#validateDirContext(edu.wisc.commons.lcp.pool.DirContextType, javax.naming.directory.DirContext)
*/
public boolean validateDirContext(DirContextType contextType, DirContext dirContext) {
Validate.notNull(contextType, "contextType may not be null");
Validate.notNull(dirContext, "dirContext may not be null");
try {
final NamingEnumeration searchResults = dirContext.search(this.base, this.filter, this.searchControls);
if (searchResults.hasMore()) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("DirContext '" + dirContext + "' passed validation.");
}
return true;
}
}
catch (Exception e) {
this.logger.warn("DirContext '" + dirContext + "' failed validation with an exception.", e);
}
if (this.logger.isInfoEnabled()) {
this.logger.info("DirContext '" + dirContext + "' failed validation.");
}
return false;
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.validation;
import javax.naming.NamingEnumeration;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.pool.DirContextType;
/**
* Default {@link DirContext} validator that executes {@link DirContext#search(String, String, SearchControls)}. The
* name, filter and {@link SearchControls} are all configurable. There is no special handling for read only versus
* read write {@link DirContext}s.
*
* <br>
* <br>
* Configuration:
* <table border="1">
* <tr>
* <th align="left">Property</th>
* <th align="left">Description</th>
* <th align="left">Required</th>
* <th align="left">Default</th>
* </tr>
* <tr>
* <td valign="top">base</td>
* <td valign="top">
* The name parameter to the search method.
* </td>
* <td valign="top">No</td>
* <td valign="top">""</td>
* </tr>
* <tr>
* <td valign="top">filter</td>
* <td valign="top">
* The filter parameter to the search method.
* </td>
* <td valign="top">No</td>
* <td valign="top">"objectclass=*"</td>
* </tr>
* <tr>
* <td valign="top">searchControls</td>
* <td valign="top">
* The {@link SearchControls} parameter to the search method.
* </td>
* <td valign="top">No</td>
* <td valign="top">
* {@link SearchControls#setCountLimit(long)} = 1<br/>
* {@link SearchControls#setReturningAttributes(String[])} = new String[] { "objectclass" }<br/>
* {@link SearchControls#setTimeLimit(int)} = 500
* </td>
* </tr>
* </table>
*
* @author Eric Dalquist
*/
public class DefaultDirContextValidator implements DirContextValidator {
protected final Log logger = LogFactory.getLog(this.getClass());
private String base;
private String filter;
private SearchControls searchControls;
public DefaultDirContextValidator() {
this.searchControls = new SearchControls();
this.searchControls.setCountLimit(1);
this.searchControls.setReturningAttributes(new String[] { "objectclass" });
this.searchControls.setTimeLimit(500);
this.base = "";
this.filter = "objectclass=*";
}
/**
* @return the baseName
*/
public String getBase() {
return this.base;
}
/**
* @param base the baseName to set
*/
public void setBase(String base) {
this.base = base;
}
/**
* @return the filter
*/
public String getFilter() {
return this.filter;
}
/**
* @param filter the filter to set
*/
public void setFilter(String filter) {
if (filter == null) {
throw new IllegalArgumentException("filter may not be null");
}
this.filter = filter;
}
/**
* @return the searchControls
*/
public SearchControls getSearchControls() {
return this.searchControls;
}
/**
* @param searchControls the searchControls to set
*/
public void setSearchControls(SearchControls searchControls) {
if (searchControls == null) {
throw new IllegalArgumentException("searchControls may not be null");
}
this.searchControls = searchControls;
}
/**
* @see edu.wisc.commons.lcp.validation.DirContextValidator#validateDirContext(edu.wisc.commons.lcp.pool.DirContextType, javax.naming.directory.DirContext)
*/
public boolean validateDirContext(DirContextType contextType, DirContext dirContext) {
Validate.notNull(contextType, "contextType may not be null");
Validate.notNull(dirContext, "dirContext may not be null");
try {
final NamingEnumeration searchResults = dirContext.search(this.base, this.filter, this.searchControls);
if (searchResults.hasMore()) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("DirContext '" + dirContext + "' passed validation.");
}
return true;
}
}
catch (Exception e) {
this.logger.warn("DirContext '" + dirContext + "' failed validation with an exception.", e);
}
if (this.logger.isInfoEnabled()) {
this.logger.info("DirContext '" + dirContext + "' failed validation.");
}
return false;
}
}

View File

@@ -1,39 +1,38 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.validation;
import javax.naming.directory.DirContext;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.DirContextType;
/**
* A validator for {@link DirContext}s.
*
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public interface DirContextValidator {
/**
* Validates the {@link DirContext}. A valid {@link DirContext} should be able
* to answer queries and if applicable write to the directory.
*
* @param contextType The type of the {@link DirContext}, refers to if {@link ContextSource#getReadOnlyContext()} or {@link ContextSource#getReadWriteContext()} was called to create the {@link DirContext}
* @param dirContext The {@link DirContext} to validate.
* @return <code>true</code> if the {@link DirContext} operated correctly during validation.
*/
public boolean validateDirContext(DirContextType contextType, DirContext dirContext);
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.validation;
import javax.naming.directory.DirContext;
import org.springframework.ldap.pool.DirContextType;
/**
* A validator for {@link DirContext}s.
*
* @author Eric Dalquist
*/
public interface DirContextValidator {
/**
* Validates the {@link DirContext}. A valid {@link DirContext} should be able
* to answer queries and if applicable write to the directory.
*
* @param contextType The type of the {@link DirContext}, refers to if {@link ContextSource#getReadOnlyContext()} or {@link ContextSource#getReadWriteContext()} was called to create the {@link DirContext}
* @param dirContext The {@link DirContext} to validate.
* @return <code>true</code> if the {@link DirContext} operated correctly during validation.
*/
public boolean validateDirContext(DirContextType contextType, DirContext dirContext);
}

View File

@@ -1,440 +1,446 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import org.apache.commons.pool.KeyedObjectPool;
import org.easymock.MockControl;
/**
* @author Eric Dalquist <a
* href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DelegatingContextTest extends AbstractPoolTestCase {
public void testConstructorAssertions() {
replay();
try {
new DelegatingContext(null, contextMock, DirContextType.READ_ONLY);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new DelegatingContext(keyedObjectPoolMock, null,
DirContextType.READ_ONLY);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new DelegatingContext(keyedObjectPoolMock, contextMock, null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testHelperMethods() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
// Wrap the Context once
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
final Context delegateContext = delegatingContext.getDelegateContext();
assertEquals(contextMock, delegateContext);
final Context innerDelegateContext = delegatingContext
.getInnermostDelegateContext();
assertEquals(contextMock, innerDelegateContext);
delegatingContext.assertOpen();
// Wrap the wrapper
MockControl secondKeyedObjectPoolControl = MockControl
.createControl(KeyedObjectPool.class);
KeyedObjectPool secondKeyedObjectPoolMock = (KeyedObjectPool) secondKeyedObjectPoolControl
.getMock();
secondKeyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
delegatingContext);
secondKeyedObjectPoolControl.setVoidCallable(1);
secondKeyedObjectPoolControl.replay();
final DelegatingContext delegatingContext2 = new DelegatingContext(
secondKeyedObjectPoolMock, delegatingContext,
DirContextType.READ_ONLY);
final Context delegateContext2 = delegatingContext2
.getDelegateContext();
assertEquals(delegatingContext, delegateContext2);
final Context innerDelegateContext2 = delegatingContext2
.getInnermostDelegateContext();
assertEquals(contextMock, innerDelegateContext2);
delegatingContext2.assertOpen();
// Close the outer wrapper
delegatingContext2.close();
final Context delegateContext2closed = delegatingContext2
.getDelegateContext();
assertNull(delegateContext2closed);
final Context innerDelegateContext2closed = delegatingContext2
.getInnermostDelegateContext();
assertNull(innerDelegateContext2closed);
try {
delegatingContext2.assertOpen();
fail("delegatingContext2.assertOpen() should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
// Close the outer wrapper
delegatingContext.close();
final Context delegateContextclosed = delegatingContext
.getDelegateContext();
assertNull(delegateContextclosed);
final Context innerDelegateContextclosed = delegatingContext
.getInnermostDelegateContext();
assertNull(innerDelegateContextclosed);
try {
delegatingContext.assertOpen();
fail("delegatingContext.assertOpen() should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
verify();
secondKeyedObjectPoolControl.verify();
}
public void testObjectMethods() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
// Wrap the Context once
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
assertEquals("EasyMock for interface javax.naming.Context",
delegatingContext.toString());
delegatingContext.hashCode(); // Run it to make sure it doesn't fail
assertTrue(delegatingContext.equals(delegatingContext));
assertFalse(delegatingContext.equals(new Object()));
final DelegatingContext delegatingContext2 = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
assertTrue(delegatingContext.equals(delegatingContext2));
assertTrue(delegatingContext2.equals(delegatingContext));
assertTrue(delegatingContext.equals(contextMock));
// Close the contextMock and try again
delegatingContext.close();
assertEquals("Context is closed", delegatingContext.toString());
assertEquals(0, delegatingContext.hashCode()); // Run it to make sure
// it doesn't fail
assertTrue(delegatingContext.equals(delegatingContext));
assertFalse(delegatingContext.equals(new Object()));
assertFalse(delegatingContext.equals(delegatingContext2));
assertFalse(delegatingContext2.equals(delegatingContext));
assertFalse(delegatingContext.equals(contextMock));
verify();
}
public void testUnsupportedMethods() throws Exception {
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
try {
delegatingContext.addToEnvironment(null, null);
fail("DelegatingContext.addToEnvironment Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.bind((Name) null, null);
fail("DelegatingContext.addToEnvironment Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.bind((String) null, null);
fail("DelegatingContext.bind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.createSubcontext((Name) null);
fail("DelegatingContext.createSubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.createSubcontext((String) null);
fail("DelegatingContext.createSubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.destroySubcontext((Name) null);
fail("DelegatingContext.destroySubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.destroySubcontext((String) null);
fail("DelegatingContext.destroySubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.rebind((Name) null, null);
fail("DelegatingContext.rebind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.rebind((String) null, null);
fail("DelegatingContext.rebind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.removeFromEnvironment(null);
fail("DelegatingContext.removeFromEnvironment Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.unbind((Name) null);
fail("DelegatingContext.unbind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.unbind((String) null);
fail("DelegatingContext.unbind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
verify();
}
public void testAllMethodsOpened() throws Exception {
contextControl = MockControl.createNiceControl(Context.class);
contextMock = (Context) contextControl.getMock();
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
delegatingContext.composeName((Name) null, (Name) null);
delegatingContext.composeName((String) null, (String) null);
delegatingContext.getEnvironment();
delegatingContext.getNameInNamespace();
delegatingContext.getNameParser((Name) null);
delegatingContext.getNameParser((String) null);
delegatingContext.list((Name) null);
delegatingContext.list((String) null);
delegatingContext.listBindings((Name) null);
delegatingContext.listBindings((String) null);
delegatingContext.lookup((Name) null);
delegatingContext.lookup((String) null);
delegatingContext.lookupLink((Name) null);
delegatingContext.lookupLink((String) null);
delegatingContext.rename((Name) null, (Name) null);
delegatingContext.rename((String) null, (String) null);
verify();
}
public void testAllMethodsClosed() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
delegatingContext.close();
try {
delegatingContext.composeName((Name) null, (Name) null);
fail("DelegatingContext.composeName should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.composeName((String) null, (String) null);
fail("DelegatingContext.composeName should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.getEnvironment();
fail("DelegatingContext.getEnvironment should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.getNameInNamespace();
fail("DelegatingContext.getNameInNamespace should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.getNameParser((Name) null);
fail("DelegatingContext.getNameParser should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.getNameParser((String) null);
fail("DelegatingContext.getNameParser should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.list((Name) null);
fail("DelegatingContext.list should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.list((String) null);
fail("DelegatingContext.list should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.listBindings((Name) null);
fail("DelegatingContext.listBindings should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.listBindings((String) null);
fail("DelegatingContext.listBindings should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.lookup((Name) null);
fail("DelegatingContext.lookup should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.lookup((String) null);
fail("DelegatingContext.lookup should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.lookupLink((Name) null);
fail("DelegatingContext.lookupLink should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.lookupLink((String) null);
fail("DelegatingContext.lookupLink should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.rename((Name) null, (Name) null);
fail("DelegatingContext.rename should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.rename((String) null, (String) null);
fail("DelegatingContext.rename should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
verify();
}
public void testDoubleClose() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
delegatingContext.close();
// noop close
delegatingContext.close();
verify();
}
public void testPoolExceptionOnClose() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setThrowable(new Exception(
"Fake Pool returnObject Exception"));
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
try {
delegatingContext.close();
fail("DelegatingContext.close should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
verify();
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import org.apache.commons.pool.KeyedObjectPool;
import org.easymock.MockControl;
/**
* @author Eric Dalquist <a
* href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DelegatingContextTest extends AbstractPoolTestCase {
public void testConstructorAssertions() {
replay();
try {
new DelegatingContext(null, contextMock, DirContextType.READ_ONLY);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new DelegatingContext(keyedObjectPoolMock, null,
DirContextType.READ_ONLY);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new DelegatingContext(keyedObjectPoolMock, contextMock, null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testHelperMethods() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
// Wrap the Context once
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
final Context delegateContext = delegatingContext.getDelegateContext();
assertEquals(contextMock, delegateContext);
final Context innerDelegateContext = delegatingContext
.getInnermostDelegateContext();
assertEquals(contextMock, innerDelegateContext);
delegatingContext.assertOpen();
// Wrap the wrapper
MockControl secondKeyedObjectPoolControl = MockControl
.createControl(KeyedObjectPool.class);
KeyedObjectPool secondKeyedObjectPoolMock = (KeyedObjectPool) secondKeyedObjectPoolControl
.getMock();
secondKeyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
delegatingContext);
secondKeyedObjectPoolControl.setVoidCallable(1);
secondKeyedObjectPoolControl.replay();
final DelegatingContext delegatingContext2 = new DelegatingContext(
secondKeyedObjectPoolMock, delegatingContext,
DirContextType.READ_ONLY);
final Context delegateContext2 = delegatingContext2
.getDelegateContext();
assertEquals(delegatingContext, delegateContext2);
final Context innerDelegateContext2 = delegatingContext2
.getInnermostDelegateContext();
assertEquals(contextMock, innerDelegateContext2);
delegatingContext2.assertOpen();
// Close the outer wrapper
delegatingContext2.close();
final Context delegateContext2closed = delegatingContext2
.getDelegateContext();
assertNull(delegateContext2closed);
final Context innerDelegateContext2closed = delegatingContext2
.getInnermostDelegateContext();
assertNull(innerDelegateContext2closed);
try {
delegatingContext2.assertOpen();
fail("delegatingContext2.assertOpen() should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
// Close the outer wrapper
delegatingContext.close();
final Context delegateContextclosed = delegatingContext
.getDelegateContext();
assertNull(delegateContextclosed);
final Context innerDelegateContextclosed = delegatingContext
.getInnermostDelegateContext();
assertNull(innerDelegateContextclosed);
try {
delegatingContext.assertOpen();
fail("delegatingContext.assertOpen() should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
verify();
secondKeyedObjectPoolControl.verify();
}
public void testObjectMethods() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
// Wrap the Context once
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
assertEquals("EasyMock for interface javax.naming.Context",
delegatingContext.toString());
delegatingContext.hashCode(); // Run it to make sure it doesn't fail
assertTrue(delegatingContext.equals(delegatingContext));
assertFalse(delegatingContext.equals(new Object()));
final DelegatingContext delegatingContext2 = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
assertTrue(delegatingContext.equals(delegatingContext2));
assertTrue(delegatingContext2.equals(delegatingContext));
assertTrue(delegatingContext.equals(contextMock));
// Close the contextMock and try again
delegatingContext.close();
assertEquals("Context is closed", delegatingContext.toString());
assertEquals(0, delegatingContext.hashCode()); // Run it to make sure
// it doesn't fail
assertTrue(delegatingContext.equals(delegatingContext));
assertFalse(delegatingContext.equals(new Object()));
assertFalse(delegatingContext.equals(delegatingContext2));
assertFalse(delegatingContext2.equals(delegatingContext));
assertFalse(delegatingContext.equals(contextMock));
verify();
}
public void testUnsupportedMethods() throws Exception {
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
try {
delegatingContext.addToEnvironment(null, null);
fail("DelegatingContext.addToEnvironment Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.createSubcontext((Name) null);
fail("DelegatingContext.createSubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.createSubcontext((String) null);
fail("DelegatingContext.createSubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.destroySubcontext((Name) null);
fail("DelegatingContext.destroySubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.destroySubcontext((String) null);
fail("DelegatingContext.destroySubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingContext.removeFromEnvironment(null);
fail("DelegatingContext.removeFromEnvironment Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
verify();
}
public void testAllMethodsOpened() throws Exception {
contextControl = MockControl.createNiceControl(Context.class);
contextMock = (Context) contextControl.getMock();
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
delegatingContext.bind((Name) null, null);
delegatingContext.bind((String) null, null);
delegatingContext.composeName((Name) null, (Name) null);
delegatingContext.composeName((String) null, (String) null);
delegatingContext.getEnvironment();
delegatingContext.getNameInNamespace();
delegatingContext.getNameParser((Name) null);
delegatingContext.getNameParser((String) null);
delegatingContext.list((Name) null);
delegatingContext.list((String) null);
delegatingContext.listBindings((Name) null);
delegatingContext.listBindings((String) null);
delegatingContext.lookup((Name) null);
delegatingContext.lookup((String) null);
delegatingContext.lookupLink((Name) null);
delegatingContext.lookupLink((String) null);
delegatingContext.rebind((Name) null, null);
delegatingContext.rebind((String) null, null);
delegatingContext.rename((Name) null, (Name) null);
delegatingContext.rename((String) null, (String) null);
delegatingContext.unbind((Name) null);
delegatingContext.unbind((String) null);
verify();
}
public void testAllMethodsClosed() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
delegatingContext.close();
try {
delegatingContext.bind((Name) null, null);
fail("DelegatingContext.bind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.bind((String) null, null);
fail("DelegatingContext.bind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.composeName((Name) null, (Name) null);
fail("DelegatingContext.composeName should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.composeName((String) null, (String) null);
fail("DelegatingContext.composeName should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.getEnvironment();
fail("DelegatingContext.getEnvironment should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.getNameInNamespace();
fail("DelegatingContext.getNameInNamespace should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.getNameParser((Name) null);
fail("DelegatingContext.getNameParser should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.getNameParser((String) null);
fail("DelegatingContext.getNameParser should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.list((Name) null);
fail("DelegatingContext.list should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.list((String) null);
fail("DelegatingContext.list should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.listBindings((Name) null);
fail("DelegatingContext.listBindings should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.listBindings((String) null);
fail("DelegatingContext.listBindings should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.lookup((Name) null);
fail("DelegatingContext.lookup should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.lookup((String) null);
fail("DelegatingContext.lookup should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.lookupLink((Name) null);
fail("DelegatingContext.lookupLink should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.lookupLink((String) null);
fail("DelegatingContext.lookupLink should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.rebind((Name) null, null);
fail("DelegatingContext.rebind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.rebind((String) null, null);
fail("DelegatingContext.rebind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.rename((Name) null, (Name) null);
fail("DelegatingContext.rename should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.rename((String) null, (String) null);
fail("DelegatingContext.rename should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.unbind((Name) null);
fail("DelegatingContext.unbind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingContext.unbind((String) null);
fail("DelegatingContext.unbind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
verify();
}
public void testDoubleClose() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
delegatingContext.close();
// noop close
delegatingContext.close();
verify();
}
public void testPoolExceptionOnClose() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY, contextMock);
keyedObjectPoolControl.setThrowable(new Exception(
"Fake Pool returnObject Exception"));
replay();
final DelegatingContext delegatingContext = new DelegatingContext(
keyedObjectPoolMock, contextMock, DirContextType.READ_ONLY);
try {
delegatingContext.close();
fail("DelegatingContext.close should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
verify();
}
}

View File

@@ -1,415 +1,419 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import org.apache.commons.pool.KeyedObjectPool;
import org.easymock.MockControl;
/**
* @author Eric Dalquist <a
* href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DelegatingDirContextTest extends AbstractPoolTestCase {
public void testConstructorAssertions() {
replay();
try {
new DelegatingDirContext(keyedObjectPoolMock, null,
DirContextType.READ_ONLY);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new DelegatingDirContext(keyedObjectPoolMock, dirContextMock, null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testHelperMethods() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
dirContextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
// Wrap the DirContext once
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
final Context delegateContext = delegatingDirContext
.getDelegateContext();
assertEquals(dirContextMock, delegateContext);
final DirContext delegateDirContext = delegatingDirContext
.getDelegateDirContext();
assertEquals(dirContextMock, delegateDirContext);
final DirContext innerDelegateDirContext = delegatingDirContext
.getInnermostDelegateDirContext();
assertEquals(dirContextMock, innerDelegateDirContext);
delegatingDirContext.assertOpen();
// Wrap the wrapper
MockControl secondKeyedObjectPoolControl = MockControl
.createControl(KeyedObjectPool.class);
KeyedObjectPool secondKeyedObjectPoolMock = (KeyedObjectPool) secondKeyedObjectPoolControl
.getMock();
secondKeyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
delegatingDirContext);
secondKeyedObjectPoolControl.setVoidCallable(1);
secondKeyedObjectPoolControl.replay();
final DelegatingDirContext delegatingDirContext2 = new DelegatingDirContext(
secondKeyedObjectPoolMock, delegatingDirContext,
DirContextType.READ_ONLY);
final DirContext delegateDirContext2 = delegatingDirContext2
.getDelegateDirContext();
assertEquals(delegatingDirContext, delegateDirContext2);
final DirContext innerDelegateDirContext2 = delegatingDirContext2
.getInnermostDelegateDirContext();
assertEquals(dirContextMock, innerDelegateDirContext2);
delegatingDirContext2.assertOpen();
// Close the outer wrapper
delegatingDirContext2.close();
final DirContext delegateContext2closed = delegatingDirContext2
.getDelegateDirContext();
assertNull(delegateContext2closed);
final DirContext innerDelegateContext2closed = delegatingDirContext2
.getInnermostDelegateDirContext();
assertNull(innerDelegateContext2closed);
try {
delegatingDirContext2.assertOpen();
fail("delegatingDirContext2.assertOpen() should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
// Close the outer wrapper
delegatingDirContext.close();
final DirContext delegateDirContextClosed = delegatingDirContext
.getDelegateDirContext();
assertNull(delegateDirContextClosed);
final DirContext innerDelegateDirContextClosed = delegatingDirContext
.getInnermostDelegateDirContext();
assertNull(innerDelegateDirContextClosed);
try {
delegatingDirContext.assertOpen();
fail("delegatingDirContext.assertOpen() should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
secondKeyedObjectPoolControl.verify();
verify();
}
public void testObjectMethods() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
dirContextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
// Wrap the DirContext once
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
assertEquals(
"EasyMock for interface javax.naming.directory.DirContext",
delegatingDirContext.toString());
delegatingDirContext.hashCode(); // Run it to make sure it doesn't
// fail
assertTrue(delegatingDirContext.equals(delegatingDirContext));
assertFalse(delegatingDirContext.equals(new Object()));
final DelegatingDirContext delegatingDirContext2 = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
assertTrue(delegatingDirContext.equals(delegatingDirContext2));
assertTrue(delegatingDirContext2.equals(delegatingDirContext));
assertTrue(delegatingDirContext.equals(dirContextMock));
// Close the context and try again
delegatingDirContext.close();
assertEquals("DirContext is closed", delegatingDirContext.toString());
assertEquals(0, delegatingDirContext.hashCode()); // Run it to make
// sure it doesn't
// fail
assertTrue(delegatingDirContext.equals(delegatingDirContext));
assertFalse(delegatingDirContext.equals(new Object()));
assertFalse(delegatingDirContext.equals(delegatingDirContext2));
assertFalse(delegatingDirContext2.equals(delegatingDirContext));
assertFalse(delegatingDirContext.equals(dirContextMock));
verify();
}
// nice
public void testUnsupportedMethods() throws Exception {
replay();
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
try {
delegatingDirContext.bind((Name) null, null, null);
fail("DelegatingDirContext.bind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.bind((String) null, null, null);
fail("DelegatingDirContext.bind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.createSubcontext((Name) null, null);
fail("DelegatingDirContext.createSubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.createSubcontext((String) null, null);
fail("DelegatingDirContext.createSubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.getSchema((Name) null);
fail("DelegatingDirContext.getSchema Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.getSchema((String) null);
fail("DelegatingDirContext.getSchema Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.getSchemaClassDefinition((Name) null);
fail("DelegatingDirContext.getSchemaClassDefinition Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.getSchemaClassDefinition((String) null);
fail("DelegatingDirContext.getSchemaClassDefinition Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.rebind((Name) null, null, null);
fail("DelegatingDirContext.rebind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.rebind((String) null, null, null);
fail("DelegatingDirContext.rebind Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
verify();
}
public void testAllMethodsOpened() throws Exception {
// override with a nice control
dirContextControl = MockControl.createNiceControl(DirContext.class);
dirContextMock = (DirContext) dirContextControl.getMock();
replay();
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
delegatingDirContext.getAttributes((Name) null, null);
delegatingDirContext.getAttributes((Name) null);
delegatingDirContext.getAttributes((String) null, null);
delegatingDirContext.getAttributes((String) null);
delegatingDirContext.modifyAttributes((Name) null, 0, null);
delegatingDirContext.modifyAttributes((Name) null, null);
delegatingDirContext.modifyAttributes((String) null, 0, null);
delegatingDirContext.modifyAttributes((String) null, null);
delegatingDirContext.search((Name) null, (Attributes) null, null);
delegatingDirContext.search((Name) null, null);
delegatingDirContext.search((Name) null, null, null, null);
delegatingDirContext.search((Name) null, (String) null, null);
delegatingDirContext.search((String) null, (Attributes) null, null);
delegatingDirContext.search((String) null, null);
delegatingDirContext.search((String) null, null, null, null);
delegatingDirContext.search((String) null, (String) null, null);
verify();
}
public void testAllMethodsClosed() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
dirContextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
delegatingDirContext.close();
try {
delegatingDirContext.getAttributes((Name) null, null);
fail("DelegatingDirContext.getAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.getAttributes((Name) null);
fail("DelegatingDirContext.getAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.getAttributes((String) null, null);
fail("DelegatingDirContext.getAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.getAttributes((String) null);
fail("DelegatingDirContext.getAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.modifyAttributes((Name) null, 0, null);
fail("DelegatingDirContext.modifyAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.modifyAttributes((Name) null, null);
fail("DelegatingDirContext.modifyAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.modifyAttributes((String) null, 0, null);
fail("DelegatingDirContext.modifyAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.modifyAttributes((String) null, null);
fail("DelegatingDirContext.modifyAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((Name) null, (Attributes) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((Name) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((Name) null, null, null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((Name) null, (String) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((String) null, (Attributes) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((String) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((String) null, null, null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((String) null, (String) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
verify();
}
public void testDoubleClose() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
dirContextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
delegatingDirContext.close();
// noop close
delegatingDirContext.close();
verify();
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import org.apache.commons.pool.KeyedObjectPool;
import org.easymock.MockControl;
/**
* @author Eric Dalquist <a
* href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DelegatingDirContextTest extends AbstractPoolTestCase {
public void testConstructorAssertions() {
replay();
try {
new DelegatingDirContext(keyedObjectPoolMock, null,
DirContextType.READ_ONLY);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
new DelegatingDirContext(keyedObjectPoolMock, dirContextMock, null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testHelperMethods() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
dirContextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
// Wrap the DirContext once
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
final Context delegateContext = delegatingDirContext
.getDelegateContext();
assertEquals(dirContextMock, delegateContext);
final DirContext delegateDirContext = delegatingDirContext
.getDelegateDirContext();
assertEquals(dirContextMock, delegateDirContext);
final DirContext innerDelegateDirContext = delegatingDirContext
.getInnermostDelegateDirContext();
assertEquals(dirContextMock, innerDelegateDirContext);
delegatingDirContext.assertOpen();
// Wrap the wrapper
MockControl secondKeyedObjectPoolControl = MockControl
.createControl(KeyedObjectPool.class);
KeyedObjectPool secondKeyedObjectPoolMock = (KeyedObjectPool) secondKeyedObjectPoolControl
.getMock();
secondKeyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
delegatingDirContext);
secondKeyedObjectPoolControl.setVoidCallable(1);
secondKeyedObjectPoolControl.replay();
final DelegatingDirContext delegatingDirContext2 = new DelegatingDirContext(
secondKeyedObjectPoolMock, delegatingDirContext,
DirContextType.READ_ONLY);
final DirContext delegateDirContext2 = delegatingDirContext2
.getDelegateDirContext();
assertEquals(delegatingDirContext, delegateDirContext2);
final DirContext innerDelegateDirContext2 = delegatingDirContext2
.getInnermostDelegateDirContext();
assertEquals(dirContextMock, innerDelegateDirContext2);
delegatingDirContext2.assertOpen();
// Close the outer wrapper
delegatingDirContext2.close();
final DirContext delegateContext2closed = delegatingDirContext2
.getDelegateDirContext();
assertNull(delegateContext2closed);
final DirContext innerDelegateContext2closed = delegatingDirContext2
.getInnermostDelegateDirContext();
assertNull(innerDelegateContext2closed);
try {
delegatingDirContext2.assertOpen();
fail("delegatingDirContext2.assertOpen() should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
// Close the outer wrapper
delegatingDirContext.close();
final DirContext delegateDirContextClosed = delegatingDirContext
.getDelegateDirContext();
assertNull(delegateDirContextClosed);
final DirContext innerDelegateDirContextClosed = delegatingDirContext
.getInnermostDelegateDirContext();
assertNull(innerDelegateDirContextClosed);
try {
delegatingDirContext.assertOpen();
fail("delegatingDirContext.assertOpen() should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
secondKeyedObjectPoolControl.verify();
verify();
}
public void testObjectMethods() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
dirContextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
// Wrap the DirContext once
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
assertEquals(
"EasyMock for interface javax.naming.directory.DirContext",
delegatingDirContext.toString());
delegatingDirContext.hashCode(); // Run it to make sure it doesn't
// fail
assertTrue(delegatingDirContext.equals(delegatingDirContext));
assertFalse(delegatingDirContext.equals(new Object()));
final DelegatingDirContext delegatingDirContext2 = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
assertTrue(delegatingDirContext.equals(delegatingDirContext2));
assertTrue(delegatingDirContext2.equals(delegatingDirContext));
assertTrue(delegatingDirContext.equals(dirContextMock));
// Close the context and try again
delegatingDirContext.close();
assertEquals("DirContext is closed", delegatingDirContext.toString());
assertEquals(0, delegatingDirContext.hashCode()); // Run it to make
// sure it doesn't
// fail
assertTrue(delegatingDirContext.equals(delegatingDirContext));
assertFalse(delegatingDirContext.equals(new Object()));
assertFalse(delegatingDirContext.equals(delegatingDirContext2));
assertFalse(delegatingDirContext2.equals(delegatingDirContext));
assertFalse(delegatingDirContext.equals(dirContextMock));
verify();
}
// nice
public void testUnsupportedMethods() throws Exception {
replay();
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
try {
delegatingDirContext.createSubcontext((Name) null, null);
fail("DelegatingDirContext.createSubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.createSubcontext((String) null, null);
fail("DelegatingDirContext.createSubcontext Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.getSchema((Name) null);
fail("DelegatingDirContext.getSchema Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.getSchema((String) null);
fail("DelegatingDirContext.getSchema Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.getSchemaClassDefinition((Name) null);
fail("DelegatingDirContext.getSchemaClassDefinition Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
try {
delegatingDirContext.getSchemaClassDefinition((String) null);
fail("DelegatingDirContext.getSchemaClassDefinition Should have thrown an UnsupportedOperationException");
} catch (UnsupportedOperationException uoe) {
// Expected
}
verify();
}
public void testAllMethodsOpened() throws Exception {
// override with a nice control
dirContextControl = MockControl.createNiceControl(DirContext.class);
dirContextMock = (DirContext) dirContextControl.getMock();
replay();
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
delegatingDirContext.bind((Name) null, null, null);
delegatingDirContext.bind((String) null, null, null);
delegatingDirContext.getAttributes((Name) null, null);
delegatingDirContext.getAttributes((Name) null);
delegatingDirContext.getAttributes((String) null, null);
delegatingDirContext.getAttributes((String) null);
delegatingDirContext.modifyAttributes((Name) null, 0, null);
delegatingDirContext.modifyAttributes((Name) null, null);
delegatingDirContext.modifyAttributes((String) null, 0, null);
delegatingDirContext.modifyAttributes((String) null, null);
delegatingDirContext.rebind((Name) null, null, null);
delegatingDirContext.rebind((String) null, null, null);
delegatingDirContext.search((Name) null, (Attributes) null, null);
delegatingDirContext.search((Name) null, null);
delegatingDirContext.search((Name) null, null, null, null);
delegatingDirContext.search((Name) null, (String) null, null);
delegatingDirContext.search((String) null, (Attributes) null, null);
delegatingDirContext.search((String) null, null);
delegatingDirContext.search((String) null, null, null, null);
delegatingDirContext.search((String) null, (String) null, null);
verify();
}
public void testAllMethodsClosed() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
dirContextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
delegatingDirContext.close();
try {
delegatingDirContext.bind((Name) null, null, null);
fail("DelegatingDirContext.bind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.bind((String) null, null, null);
fail("DelegatingDirContext.bind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.getAttributes((Name) null, null);
fail("DelegatingDirContext.getAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.getAttributes((Name) null);
fail("DelegatingDirContext.getAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.getAttributes((String) null, null);
fail("DelegatingDirContext.getAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.getAttributes((String) null);
fail("DelegatingDirContext.getAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.modifyAttributes((Name) null, 0, null);
fail("DelegatingDirContext.modifyAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.modifyAttributes((Name) null, null);
fail("DelegatingDirContext.modifyAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.modifyAttributes((String) null, 0, null);
fail("DelegatingDirContext.modifyAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.modifyAttributes((String) null, null);
fail("DelegatingDirContext.modifyAttributes should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.rebind((Name) null, null, null);
fail("DelegatingDirContext.rebind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.rebind((String) null, null, null);
fail("DelegatingDirContext.rebind should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((Name) null, (Attributes) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((Name) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((Name) null, null, null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((Name) null, (String) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((String) null, (Attributes) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((String) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((String) null, null, null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
try {
delegatingDirContext.search((String) null, (String) null, null);
fail("DelegatingDirContext.search should have thrown a NamingException");
} catch (NamingException ne) {
// Expected
}
verify();
}
public void testDoubleClose() throws Exception {
keyedObjectPoolMock.returnObject(DirContextType.READ_ONLY,
dirContextMock);
keyedObjectPoolControl.setVoidCallable(1);
replay();
final DelegatingDirContext delegatingDirContext = new DelegatingDirContext(
keyedObjectPoolMock, dirContextMock, DirContextType.READ_ONLY);
delegatingDirContext.close();
// noop close
delegatingDirContext.close();
verify();
}
}

View File

@@ -1,243 +1,243 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.factory;
import javax.naming.directory.DirContext;
import org.easymock.MockControl;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.AbstractPoolTestCase;
import org.springframework.ldap.pool.DirContextType;
import org.springframework.ldap.pool.validation.DirContextValidator;
/**
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class DirContextPoolableObjectFactoryTest extends AbstractPoolTestCase {
public void testProperties() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
replay();
try {
objectFactory.setContextSource(null);
fail("DirContextPoolableObjectFactory.setContextSource should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
objectFactory.setContextSource(contextSourceMock);
final ContextSource contextSource2 = objectFactory.getContextSource();
assertEquals(contextSourceMock, contextSource2);
try {
objectFactory.setDirContextValidator(null);
fail("DirContextPoolableObjectFactory.setDirContextValidator should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
objectFactory.setDirContextValidator(dirContextValidatorMock);
final DirContextValidator dirContextValidator2 = objectFactory.getDirContextValidator();
assertEquals(dirContextValidatorMock, dirContextValidator2);
verify();
}
public void testMakeObjectAssertions() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
replay();
try {
objectFactory.makeObject(DirContextType.READ_ONLY);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
objectFactory.setContextSource(contextSourceMock);
try {
objectFactory.makeObject(null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testMakeObjectReadOnly() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
MockControl readOnlyContextControl = MockControl.createControl(DirContext.class);
DirContext readOnlyContextMock = (DirContext) readOnlyContextControl.getMock();
readOnlyContextControl.replay();
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), readOnlyContextMock, 1);
objectFactory.setContextSource(contextSourceMock);
replay();
final Object createdDirContext = objectFactory.makeObject(DirContextType.READ_ONLY);
readOnlyContextControl.verify();
verify();
assertEquals(readOnlyContextMock, createdDirContext);
}
public void testMakeObjectReadWrite() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
MockControl readWriteContextControl = MockControl.createControl(DirContext.class);
DirContext readWriteContextMock = (DirContext) readWriteContextControl.getMock();
readWriteContextControl.replay();
contextSourceControl.expectAndReturn(contextSourceMock.getReadWriteContext(), readWriteContextMock, 1);
objectFactory.setContextSource(contextSourceMock);
replay();
final Object createdDirContext = objectFactory.makeObject(DirContextType.READ_WRITE);
readWriteContextControl.verify();
verify();
assertEquals(readWriteContextMock, createdDirContext);
}
public void testValidateObjectAssertions() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
replay();
try {
objectFactory.validateObject(DirContextType.READ_ONLY, dirContextMock);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
objectFactory.setDirContextValidator(dirContextValidatorMock);
try {
objectFactory.validateObject(null, dirContextMock);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
objectFactory.validateObject(new Object(), dirContextMock);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
objectFactory.validateObject(DirContextType.READ_ONLY, null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
objectFactory.validateObject(DirContextType.READ_ONLY, new Object());
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testValidateObject() throws Exception {
dirContextValidatorControl.expectAndReturn(dirContextValidatorMock
.validateDirContext(DirContextType.READ_ONLY, dirContextMock),
true);
replay();
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
objectFactory.setDirContextValidator(dirContextValidatorMock);
final boolean valid = objectFactory.validateObject(DirContextType.READ_ONLY, dirContextMock);
assertTrue(valid);
//Check exception in validator
MockControl secondDirContextValidatorControl = MockControl.createControl(DirContextValidator.class);
DirContextValidator secondDirContextValidatorMock = (DirContextValidator) secondDirContextValidatorControl.getMock();
secondDirContextValidatorControl.expectAndThrow(secondDirContextValidatorMock.validateDirContext(DirContextType.READ_ONLY, dirContextMock), new RuntimeException("Failed to validate"));
secondDirContextValidatorControl.replay();
objectFactory.setDirContextValidator(secondDirContextValidatorMock);
final boolean valid2 = objectFactory.validateObject(DirContextType.READ_ONLY, dirContextMock);
assertFalse(valid2);
secondDirContextValidatorControl.verify();
verify();
}
public void testDestroyObjectAssertions() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
replay();
try {
objectFactory.destroyObject(DirContextType.READ_ONLY, null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
objectFactory.validateObject(DirContextType.READ_ONLY, new Object());
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testDestroyObject() throws Exception {
dirContextMock.close();
dirContextControl.setVoidCallable(1);
replay();
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
objectFactory.destroyObject(DirContextType.READ_ONLY, dirContextMock);
MockControl throwingDirContextControl = MockControl.createControl(DirContext.class);
DirContext throwingDirContextMock = (DirContext) throwingDirContextControl.getMock();
throwingDirContextMock.close();
throwingDirContextControl.setThrowable(new RuntimeException("Failed to close"));
throwingDirContextControl.replay();
objectFactory.destroyObject(DirContextType.READ_ONLY, throwingDirContextMock);
throwingDirContextControl.verify();
verify();
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.factory;
import javax.naming.directory.DirContext;
import org.easymock.MockControl;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.AbstractPoolTestCase;
import org.springframework.ldap.pool.DirContextType;
import org.springframework.ldap.pool.validation.DirContextValidator;
/**
* @author Eric Dalquist
*/
public class DirContextPoolableObjectFactoryTest extends AbstractPoolTestCase {
public void testProperties() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
replay();
try {
objectFactory.setContextSource(null);
fail("DirContextPoolableObjectFactory.setContextSource should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
objectFactory.setContextSource(contextSourceMock);
final ContextSource contextSource2 = objectFactory.getContextSource();
assertEquals(contextSourceMock, contextSource2);
try {
objectFactory.setDirContextValidator(null);
fail("DirContextPoolableObjectFactory.setDirContextValidator should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
objectFactory.setDirContextValidator(dirContextValidatorMock);
final DirContextValidator dirContextValidator2 = objectFactory.getDirContextValidator();
assertEquals(dirContextValidatorMock, dirContextValidator2);
verify();
}
public void testMakeObjectAssertions() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
replay();
try {
objectFactory.makeObject(DirContextType.READ_ONLY);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
objectFactory.setContextSource(contextSourceMock);
try {
objectFactory.makeObject(null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testMakeObjectReadOnly() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
MockControl readOnlyContextControl = MockControl.createControl(DirContext.class);
DirContext readOnlyContextMock = (DirContext) readOnlyContextControl.getMock();
readOnlyContextControl.replay();
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), readOnlyContextMock, 1);
objectFactory.setContextSource(contextSourceMock);
replay();
final Object createdDirContext = objectFactory.makeObject(DirContextType.READ_ONLY);
readOnlyContextControl.verify();
verify();
assertEquals(readOnlyContextMock, createdDirContext);
}
public void testMakeObjectReadWrite() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
MockControl readWriteContextControl = MockControl.createControl(DirContext.class);
DirContext readWriteContextMock = (DirContext) readWriteContextControl.getMock();
readWriteContextControl.replay();
contextSourceControl.expectAndReturn(contextSourceMock.getReadWriteContext(), readWriteContextMock, 1);
objectFactory.setContextSource(contextSourceMock);
replay();
final Object createdDirContext = objectFactory.makeObject(DirContextType.READ_WRITE);
readWriteContextControl.verify();
verify();
assertEquals(readWriteContextMock, createdDirContext);
}
public void testValidateObjectAssertions() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
replay();
try {
objectFactory.validateObject(DirContextType.READ_ONLY, dirContextMock);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
objectFactory.setDirContextValidator(dirContextValidatorMock);
try {
objectFactory.validateObject(null, dirContextMock);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
objectFactory.validateObject(new Object(), dirContextMock);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
objectFactory.validateObject(DirContextType.READ_ONLY, null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
objectFactory.validateObject(DirContextType.READ_ONLY, new Object());
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testValidateObject() throws Exception {
dirContextValidatorControl.expectAndReturn(dirContextValidatorMock
.validateDirContext(DirContextType.READ_ONLY, dirContextMock),
true);
replay();
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
objectFactory.setDirContextValidator(dirContextValidatorMock);
final boolean valid = objectFactory.validateObject(DirContextType.READ_ONLY, dirContextMock);
assertTrue(valid);
//Check exception in validator
MockControl secondDirContextValidatorControl = MockControl.createControl(DirContextValidator.class);
DirContextValidator secondDirContextValidatorMock = (DirContextValidator) secondDirContextValidatorControl.getMock();
secondDirContextValidatorControl.expectAndThrow(secondDirContextValidatorMock.validateDirContext(DirContextType.READ_ONLY, dirContextMock), new RuntimeException("Failed to validate"));
secondDirContextValidatorControl.replay();
objectFactory.setDirContextValidator(secondDirContextValidatorMock);
final boolean valid2 = objectFactory.validateObject(DirContextType.READ_ONLY, dirContextMock);
assertFalse(valid2);
secondDirContextValidatorControl.verify();
verify();
}
public void testDestroyObjectAssertions() throws Exception {
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
replay();
try {
objectFactory.destroyObject(DirContextType.READ_ONLY, null);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
objectFactory.validateObject(DirContextType.READ_ONLY, new Object());
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
verify();
}
public void testDestroyObject() throws Exception {
dirContextMock.close();
dirContextControl.setVoidCallable(1);
replay();
final DirContextPoolableObjectFactory objectFactory = new DirContextPoolableObjectFactory();
objectFactory.destroyObject(DirContextType.READ_ONLY, dirContextMock);
MockControl throwingDirContextControl = MockControl.createControl(DirContext.class);
DirContext throwingDirContextMock = (DirContext) throwingDirContextControl.getMock();
throwingDirContextMock.close();
throwingDirContextControl.setThrowable(new RuntimeException("Failed to close"));
throwingDirContextControl.replay();
objectFactory.destroyObject(DirContextType.READ_ONLY, throwingDirContextMock);
throwingDirContextControl.verify();
verify();
}
}

View File

@@ -1,282 +1,282 @@
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.factory;
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapContext;
import org.easymock.MockControl;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.AbstractPoolTestCase;
import org.springframework.ldap.pool.factory.PoolingContextSource.WhenExhaustedAction;
import org.springframework.ldap.pool.validation.DirContextValidator;
/**
* @author Eric Dalquist <a href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu</a>
*/
public class PoolingContextSourceTest extends AbstractPoolTestCase {
public void testProperties() throws Exception {
final PoolingContextSource poolingContextSource = new PoolingContextSource();
replay();
try {
poolingContextSource.setContextSource(null);
fail("PoolingContextSource.setBaseName should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
poolingContextSource.setContextSource(contextSourceMock);
final ContextSource contextSource2 = poolingContextSource.getContextSource();
assertEquals(contextSourceMock, contextSource2);
try {
poolingContextSource.setDirContextValidator(null);
fail("PoolingContextSource.setDirContextValidator should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
poolingContextSource.setDirContextValidator(dirContextValidatorMock);
final DirContextValidator dirContextValidator2 = poolingContextSource.getDirContextValidator();
assertEquals(dirContextValidatorMock, dirContextValidator2);
poolingContextSource.setMaxActive(1000);
final int maxActive = poolingContextSource.getMaxActive();
assertEquals(1000, maxActive);
poolingContextSource.setMaxIdle(500);
final int maxIdle = poolingContextSource.getMaxIdle();
assertEquals(500, maxIdle);
poolingContextSource.setMaxTotal(5000);
final int maxTotal = poolingContextSource.getMaxTotal();
assertEquals(5000, maxTotal);
poolingContextSource.setMaxWait(2000L);
final long maxWait = poolingContextSource.getMaxWait();
assertEquals(2000L, maxWait);
poolingContextSource.setMinEvictableIdleTimeMillis(60000L);
final long minEvictableIdleTimeMillis = poolingContextSource.getMinEvictableIdleTimeMillis();
assertEquals(60000L, minEvictableIdleTimeMillis);
poolingContextSource.setMinIdle(100);
final int minIdle = poolingContextSource.getMinIdle();
assertEquals(100, minIdle);
poolingContextSource.setNumTestsPerEvictionRun(5);
final int numTestsPerEvictionRun = poolingContextSource.getNumTestsPerEvictionRun();
assertEquals(5, numTestsPerEvictionRun);
poolingContextSource.setTestOnBorrow(true);
final boolean testOnBorrow = poolingContextSource.getTestOnBorrow();
assertEquals(true, testOnBorrow);
poolingContextSource.setTestOnReturn(true);
final boolean testOnReturn = poolingContextSource.getTestOnReturn();
assertEquals(true, testOnReturn);
poolingContextSource.setTestWhileIdle(true);
final boolean testWhileIdle = poolingContextSource.getTestWhileIdle();
assertEquals(true, testWhileIdle);
poolingContextSource.setTimeBetweenEvictionRunsMillis(120000L);
final long timeBetweenEvictionRunsMillis = poolingContextSource.getTimeBetweenEvictionRunsMillis();
assertEquals(120000L, timeBetweenEvictionRunsMillis);
try {
poolingContextSource.setWhenExhaustedAction(null);
fail("PoolingContextSource.setWhenExhaustedAction should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
poolingContextSource.setWhenExhaustedAction(PoolingContextSource.WhenExhaustedAction.BLOCK);
final WhenExhaustedAction whenExhaustedAction = poolingContextSource.getWhenExhaustedAction();
assertEquals(PoolingContextSource.WhenExhaustedAction.BLOCK, whenExhaustedAction);
assertNull(PoolingContextSource.WhenExhaustedAction.getActionForId(Byte.MAX_VALUE));
final int numActive = poolingContextSource.getNumActive();
assertEquals(0, numActive);
final int numIdle = poolingContextSource.getNumIdle();
assertEquals(0, numIdle);
}
public void testGetReadOnlyContextPool() throws Exception {
MockControl secondDirContextControl = MockControl.createControl(DirContext.class);
DirContext secondDirContextMock = (DirContext) secondDirContextControl.getMock();
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), dirContextMock);
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), secondDirContextMock);
replay();
final PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setContextSource(contextSourceMock);
//Get a context
final DirContext readOnlyContext1 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext1, dirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close the context
readOnlyContext1.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Get the context again
final DirContext readOnlyContext2 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext2, dirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Get a new context
final DirContext readOnlyContext3 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext3, secondDirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(2, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close context
readOnlyContext2.close();
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Close context
readOnlyContext3.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(2, poolingContextSource.getNumIdle());
}
public void testGetReadWriteContextPool() throws Exception {
MockControl secondDirContextControl = MockControl.createControl(DirContext.class);
DirContext secondDirContextMock = (DirContext) secondDirContextControl.getMock();
contextSourceControl.expectAndReturn(contextSourceMock.getReadWriteContext(), dirContextMock);
contextSourceControl.expectAndReturn(contextSourceMock.getReadWriteContext(), secondDirContextMock);
replay();
final PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setContextSource(contextSourceMock);
//Get a context
final DirContext readOnlyContext1 = poolingContextSource.getReadWriteContext();
assertEquals(readOnlyContext1, dirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close the context
readOnlyContext1.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Get the context again
final DirContext readOnlyContext2 = poolingContextSource.getReadWriteContext();
assertEquals(readOnlyContext2, dirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Get a new context
final DirContext readOnlyContext3 = poolingContextSource.getReadWriteContext();
assertEquals(readOnlyContext3, secondDirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(2, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close context
readOnlyContext2.close();
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Close context
readOnlyContext3.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(2, poolingContextSource.getNumIdle());
}
public void testGetContextException() throws Exception {
contextSourceControl.expectAndThrow(contextSourceMock.getReadWriteContext(), new RuntimeException("Problem getting context"));
replay();
final PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setContextSource(contextSourceMock);
try {
poolingContextSource.getReadWriteContext();
fail("PoolingContextSource.getReadWriteContext should have thrown DataAccessResourceFailureException");
}
catch (DataAccessResourceFailureException darfe) {
// Expected
}
}
public void testGetReadOnlyLdapContext() throws Exception {
MockControl secondLdapContextControl = MockControl.createControl(LdapContext.class);
LdapContext secondLdapContextMock = (LdapContext) secondLdapContextControl.getMock();
secondLdapContextControl.replay();
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), ldapContextMock);
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), secondLdapContextMock);
replay();
final PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setContextSource(contextSourceMock);
//Get a context
final DirContext readOnlyContext1 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext1, ldapContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close the context
readOnlyContext1.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Get the context again
final DirContext readOnlyContext2 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext2, ldapContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Get a new context
final DirContext readOnlyContext3 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext3, secondLdapContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(2, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close context
readOnlyContext2.close();
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Close context
readOnlyContext3.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(2, poolingContextSource.getNumIdle());
secondLdapContextControl.verify();
}
}
/*
* Copyright 2005-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.pool.factory;
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapContext;
import org.easymock.MockControl;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.AbstractPoolTestCase;
import org.springframework.ldap.pool.factory.PoolingContextSource.WhenExhaustedAction;
import org.springframework.ldap.pool.validation.DirContextValidator;
/**
* @author Eric Dalquist
*/
public class PoolingContextSourceTest extends AbstractPoolTestCase {
public void testProperties() throws Exception {
final PoolingContextSource poolingContextSource = new PoolingContextSource();
replay();
try {
poolingContextSource.setContextSource(null);
fail("PoolingContextSource.setBaseName should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
poolingContextSource.setContextSource(contextSourceMock);
final ContextSource contextSource2 = poolingContextSource.getContextSource();
assertEquals(contextSourceMock, contextSource2);
try {
poolingContextSource.setDirContextValidator(null);
fail("PoolingContextSource.setDirContextValidator should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
poolingContextSource.setDirContextValidator(dirContextValidatorMock);
final DirContextValidator dirContextValidator2 = poolingContextSource.getDirContextValidator();
assertEquals(dirContextValidatorMock, dirContextValidator2);
poolingContextSource.setMaxActive(1000);
final int maxActive = poolingContextSource.getMaxActive();
assertEquals(1000, maxActive);
poolingContextSource.setMaxIdle(500);
final int maxIdle = poolingContextSource.getMaxIdle();
assertEquals(500, maxIdle);
poolingContextSource.setMaxTotal(5000);
final int maxTotal = poolingContextSource.getMaxTotal();
assertEquals(5000, maxTotal);
poolingContextSource.setMaxWait(2000L);
final long maxWait = poolingContextSource.getMaxWait();
assertEquals(2000L, maxWait);
poolingContextSource.setMinEvictableIdleTimeMillis(60000L);
final long minEvictableIdleTimeMillis = poolingContextSource.getMinEvictableIdleTimeMillis();
assertEquals(60000L, minEvictableIdleTimeMillis);
poolingContextSource.setMinIdle(100);
final int minIdle = poolingContextSource.getMinIdle();
assertEquals(100, minIdle);
poolingContextSource.setNumTestsPerEvictionRun(5);
final int numTestsPerEvictionRun = poolingContextSource.getNumTestsPerEvictionRun();
assertEquals(5, numTestsPerEvictionRun);
poolingContextSource.setTestOnBorrow(true);
final boolean testOnBorrow = poolingContextSource.getTestOnBorrow();
assertEquals(true, testOnBorrow);
poolingContextSource.setTestOnReturn(true);
final boolean testOnReturn = poolingContextSource.getTestOnReturn();
assertEquals(true, testOnReturn);
poolingContextSource.setTestWhileIdle(true);
final boolean testWhileIdle = poolingContextSource.getTestWhileIdle();
assertEquals(true, testWhileIdle);
poolingContextSource.setTimeBetweenEvictionRunsMillis(120000L);
final long timeBetweenEvictionRunsMillis = poolingContextSource.getTimeBetweenEvictionRunsMillis();
assertEquals(120000L, timeBetweenEvictionRunsMillis);
try {
poolingContextSource.setWhenExhaustedAction(null);
fail("PoolingContextSource.setWhenExhaustedAction should have thrown an IllegalArgumentException");
}
catch (IllegalArgumentException iae) {
// Expected
}
poolingContextSource.setWhenExhaustedAction(PoolingContextSource.WhenExhaustedAction.BLOCK);
final WhenExhaustedAction whenExhaustedAction = poolingContextSource.getWhenExhaustedAction();
assertEquals(PoolingContextSource.WhenExhaustedAction.BLOCK, whenExhaustedAction);
assertNull(PoolingContextSource.WhenExhaustedAction.getActionForId(Byte.MAX_VALUE));
final int numActive = poolingContextSource.getNumActive();
assertEquals(0, numActive);
final int numIdle = poolingContextSource.getNumIdle();
assertEquals(0, numIdle);
}
public void testGetReadOnlyContextPool() throws Exception {
MockControl secondDirContextControl = MockControl.createControl(DirContext.class);
DirContext secondDirContextMock = (DirContext) secondDirContextControl.getMock();
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), dirContextMock);
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), secondDirContextMock);
replay();
final PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setContextSource(contextSourceMock);
//Get a context
final DirContext readOnlyContext1 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext1, dirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close the context
readOnlyContext1.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Get the context again
final DirContext readOnlyContext2 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext2, dirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Get a new context
final DirContext readOnlyContext3 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext3, secondDirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(2, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close context
readOnlyContext2.close();
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Close context
readOnlyContext3.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(2, poolingContextSource.getNumIdle());
}
public void testGetReadWriteContextPool() throws Exception {
MockControl secondDirContextControl = MockControl.createControl(DirContext.class);
DirContext secondDirContextMock = (DirContext) secondDirContextControl.getMock();
contextSourceControl.expectAndReturn(contextSourceMock.getReadWriteContext(), dirContextMock);
contextSourceControl.expectAndReturn(contextSourceMock.getReadWriteContext(), secondDirContextMock);
replay();
final PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setContextSource(contextSourceMock);
//Get a context
final DirContext readOnlyContext1 = poolingContextSource.getReadWriteContext();
assertEquals(readOnlyContext1, dirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close the context
readOnlyContext1.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Get the context again
final DirContext readOnlyContext2 = poolingContextSource.getReadWriteContext();
assertEquals(readOnlyContext2, dirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Get a new context
final DirContext readOnlyContext3 = poolingContextSource.getReadWriteContext();
assertEquals(readOnlyContext3, secondDirContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(2, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close context
readOnlyContext2.close();
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Close context
readOnlyContext3.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(2, poolingContextSource.getNumIdle());
}
public void testGetContextException() throws Exception {
contextSourceControl.expectAndThrow(contextSourceMock.getReadWriteContext(), new RuntimeException("Problem getting context"));
replay();
final PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setContextSource(contextSourceMock);
try {
poolingContextSource.getReadWriteContext();
fail("PoolingContextSource.getReadWriteContext should have thrown DataAccessResourceFailureException");
}
catch (DataAccessResourceFailureException darfe) {
// Expected
}
}
public void testGetReadOnlyLdapContext() throws Exception {
MockControl secondLdapContextControl = MockControl.createControl(LdapContext.class);
LdapContext secondLdapContextMock = (LdapContext) secondLdapContextControl.getMock();
secondLdapContextControl.replay();
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), ldapContextMock);
contextSourceControl.expectAndReturn(contextSourceMock.getReadOnlyContext(), secondLdapContextMock);
replay();
final PoolingContextSource poolingContextSource = new PoolingContextSource();
poolingContextSource.setContextSource(contextSourceMock);
//Get a context
final DirContext readOnlyContext1 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext1, ldapContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close the context
readOnlyContext1.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Get the context again
final DirContext readOnlyContext2 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext2, ldapContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Get a new context
final DirContext readOnlyContext3 = poolingContextSource.getReadOnlyContext();
assertEquals(readOnlyContext3, secondLdapContextMock); //Order reversed because the 'wrapper' has the needed equals logic
assertEquals(2, poolingContextSource.getNumActive());
assertEquals(0, poolingContextSource.getNumIdle());
//Close context
readOnlyContext2.close();
assertEquals(1, poolingContextSource.getNumActive());
assertEquals(1, poolingContextSource.getNumIdle());
//Close context
readOnlyContext3.close();
assertEquals(0, poolingContextSource.getNumActive());
assertEquals(2, poolingContextSource.getNumIdle());
secondLdapContextControl.verify();
}
}