@@ -264,7 +264,7 @@
The
- FAIL
+ FAIL (0)
option will throw a
NoSuchElementException
@@ -273,32 +273,32 @@
-
-
- The
- GROW
- option will create and return a
- new object (essentially making
- maxActive
- meaningless).
-
-
+
+
+ The
+ BLOCK (1)
+ option will wait until a new
+ object is available. If
+ maxWait
+ is positive a
+
+ NoSuchElementException
+
+ is thrown if no new object is
+ available after the
+ maxWait
+ time expires.
+
+
The
- BLOCK
- option will wait until a new
- object is available. If
- maxWait
- is positive a
-
- NoSuchElementException
-
- is thrown if no new object is
- available after the
- maxWait
- time expires.
+ GROW (2)
+ option will create and return a
+ new object (essentially making
+ maxActive
+ meaningless).
diff --git a/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingContext.java b/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingContext.java
index 729baece..1d51315e 100644
--- a/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingContext.java
+++ b/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingContext.java
@@ -26,8 +26,13 @@ import javax.naming.NamingException;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
+import org.springframework.ldap.pool.factory.PoolingContextSource;
/**
+ * Used by {@link PoolingContextSource} to wrap a {@link Context}, delegating most methods
+ * to the underlying context, retains a reference to the pool the context was checked out
+ * from and returns itself to the pool when {@link #close()} is called.
+ *
* @author Eric Dalquist
*/
public class DelegatingContext implements Context {
@@ -36,6 +41,14 @@ public class DelegatingContext implements Context {
private final DirContextType dirContextType;
+ /**
+ * Create a new delegating context for the specified pool, context and context type.
+ *
+ * @param keyedObjectPool The pool the delegate context was checked out from.
+ * @param delegateContext The context to delegate operations to.
+ * @param dirContextType The type of context, used as a key for the pool.
+ * @throws IllegalArgumentException if any of the arguments are null
+ */
public DelegatingContext(KeyedObjectPool keyedObjectPool, Context delegateContext, DirContextType dirContextType) {
Validate.notNull(keyedObjectPool, "keyedObjectPool may not be null");
Validate.notNull(delegateContext, "delegateContext may not be null");
@@ -49,21 +62,31 @@ public class DelegatingContext implements Context {
//***** Helper Methods *****//
+ /**
+ * @return The direct delegate for this context proxy
+ */
public Context getDelegateContext() {
return this.delegateContext;
}
+ /**
+ * Recursivley inspect delegates until a non-delegating context is found.
+ *
+ * @return The innermost (real) Context that is being delegated to.
+ */
public Context getInnermostDelegateContext() {
final Context delegateContext = this.getDelegateContext();
if (delegateContext instanceof DelegatingContext) {
return ((DelegatingContext)delegateContext).getInnermostDelegateContext();
}
- else {
- return delegateContext;
- }
+
+ return delegateContext;
}
+ /**
+ * @throws NamingException If the delegate is null, {@link #close()} has been called.
+ */
protected void assertOpen() throws NamingException {
if (this.delegateContext == null) {
throw new NamingException("Context is closed.");
diff --git a/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingDirContext.java b/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingDirContext.java
index 334672d1..defa0d00 100644
--- a/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingDirContext.java
+++ b/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingDirContext.java
@@ -28,14 +28,27 @@ import javax.naming.directory.SearchControls;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
import org.springframework.ldap.core.DirContextProxy;
+import org.springframework.ldap.pool.factory.PoolingContextSource;
/**
+ * Used by {@link PoolingContextSource} to wrap a {@link DirContext}, delegating most methods
+ * to the underlying context. This class extends {@link DelegatingContext} which handles returning
+ * the context to the pool on a call to {@link #close()}
+ *
* @author Eric Dalquist
*/
public class DelegatingDirContext extends DelegatingContext implements DirContext, DirContextProxy {
private DirContext delegateDirContext;
+ /**
+ * Create a new delegating dir context for the specified pool, context and context type.
+ *
+ * @param keyedObjectPool The pool the delegate context was checked out from.
+ * @param delegateDirContext The dir context to delegate operations to.
+ * @param dirContextType The type of context, used as a key for the pool.
+ * @throws IllegalArgumentException if any of the arguments are null
+ */
public DelegatingDirContext(KeyedObjectPool keyedObjectPool, DirContext delegateDirContext, DirContextType dirContextType) {
super(keyedObjectPool, delegateDirContext, dirContextType);
Validate.notNull(delegateDirContext, "delegateDirContext may not be null");
@@ -46,6 +59,9 @@ public class DelegatingDirContext extends DelegatingContext implements DirContex
//***** Helper Methods *****//
+ /**
+ * @return The direct delegate for this dir context proxy
+ */
public DirContext getDelegateDirContext() {
return this.delegateDirContext;
}
@@ -54,15 +70,19 @@ public class DelegatingDirContext extends DelegatingContext implements DirContex
return this.getDelegateDirContext();
}
+ /**
+ * Recursivley inspect delegates until a non-delegating dir context is found.
+ *
+ * @return The innermost (real) DirContext that is being delegated to.
+ */
public DirContext getInnermostDelegateDirContext() {
final DirContext delegateDirContext = this.getDelegateDirContext();
if (delegateDirContext instanceof DelegatingDirContext) {
return ((DelegatingDirContext)delegateDirContext).getInnermostDelegateDirContext();
}
- else {
- return delegateDirContext;
- }
+
+ return delegateDirContext;
}
protected void assertOpen() throws NamingException {
@@ -119,7 +139,7 @@ public class DelegatingDirContext extends DelegatingContext implements DirContex
* @see org.springframework.ldap.core.DirContextProxy#getTargetContext()
*/
public DirContext getTargetContext() {
- return this.delegateDirContext;
+ return this.getInnermostDelegateDirContext();
}
@@ -328,7 +348,7 @@ public class DelegatingDirContext extends DelegatingContext implements DirContex
}
/**
- * @see edu.wisc.commons.lcp.pool.DelegatingContext#close()
+ * @see DelegatingContext#close()
*/
public void close() throws NamingException {
if (this.delegateDirContext == null) {
diff --git a/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingLdapContext.java b/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingLdapContext.java
index 99fd6717..1c64a16a 100644
--- a/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingLdapContext.java
+++ b/spring-ldap/src/main/java/org/springframework/ldap/pool/DelegatingLdapContext.java
@@ -25,13 +25,26 @@ import javax.naming.ldap.LdapContext;
import org.apache.commons.lang.Validate;
import org.apache.commons.pool.KeyedObjectPool;
+import org.springframework.ldap.pool.factory.PoolingContextSource;
/**
+ * Used by {@link PoolingContextSource} to wrap a {@link LdapContext}, delegating most methods
+ * to the underlying context. This class extends {@link DelegatingDirContext} which handles returning
+ * the context to the pool on a call to {@link #close()}
+ *
* @author Eric Dalquist
*/
public class DelegatingLdapContext extends DelegatingDirContext implements LdapContext {
private LdapContext delegateLdapContext;
+ /**
+ * Create a new delegating ldap context for the specified pool, context and context type.
+ *
+ * @param keyedObjectPool The pool the delegate context was checked out from.
+ * @param delegateLdapContext The ldap context to delegate operations to.
+ * @param dirContextType The type of context, used as a key for the pool.
+ * @throws IllegalArgumentException if any of the arguments are null
+ */
public DelegatingLdapContext(KeyedObjectPool keyedObjectPool, LdapContext delegateLdapContext, DirContextType dirContextType) {
super(keyedObjectPool, delegateLdapContext, dirContextType);
Validate.notNull(delegateLdapContext, "delegateLdapContext may not be null");
@@ -42,6 +55,9 @@ public class DelegatingLdapContext extends DelegatingDirContext implements LdapC
//***** Helper Methods *****//
+ /**
+ * @return The direct delegate for this ldap context proxy
+ */
public LdapContext getDelegateLdapContext() {
return this.delegateLdapContext;
}
@@ -51,15 +67,19 @@ public class DelegatingLdapContext extends DelegatingDirContext implements LdapC
return this.getDelegateLdapContext();
}
+ /**
+ * Recursivley inspect delegates until a non-delegating ldap context is found.
+ *
+ * @return The innermost (real) DirContext that is being delegated to.
+ */
public LdapContext getInnermostDelegateLdapContext() {
final LdapContext delegateLdapContext = this.getDelegateLdapContext();
if (delegateLdapContext instanceof DelegatingLdapContext) {
return ((DelegatingLdapContext)delegateLdapContext).getInnermostDelegateLdapContext();
}
- else {
- return delegateLdapContext;
- }
+
+ return delegateLdapContext;
}
protected void assertOpen() throws NamingException {
@@ -166,7 +186,7 @@ public class DelegatingLdapContext extends DelegatingDirContext implements LdapC
}
/**
- * @see edu.wisc.commons.lcp.pool.DelegatingContext#close()
+ * @see DelegatingDirContext#close()
*/
public void close() throws NamingException {
if (this.delegateLdapContext == null) {
diff --git a/spring-ldap/src/main/java/org/springframework/ldap/pool/DirContextType.java b/spring-ldap/src/main/java/org/springframework/ldap/pool/DirContextType.java
index 18e96c96..93b5ae50 100644
--- a/spring-ldap/src/main/java/org/springframework/ldap/pool/DirContextType.java
+++ b/spring-ldap/src/main/java/org/springframework/ldap/pool/DirContextType.java
@@ -16,6 +16,10 @@
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
diff --git a/spring-ldap/src/main/java/org/springframework/ldap/pool/factory/DirContextPoolableObjectFactory.java b/spring-ldap/src/main/java/org/springframework/ldap/pool/factory/DirContextPoolableObjectFactory.java
index 2ffe4e0f..b71e82c9 100644
--- a/spring-ldap/src/main/java/org/springframework/ldap/pool/factory/DirContextPoolableObjectFactory.java
+++ b/spring-ldap/src/main/java/org/springframework/ldap/pool/factory/DirContextPoolableObjectFactory.java
@@ -62,6 +62,9 @@ import org.springframework.ldap.pool.validation.DirContextValidator;
* href="mailto:eric.dalquist@doit.wisc.edu">eric.dalquist@doit.wisc.edu
*/
class DirContextPoolableObjectFactory extends BaseKeyedPoolableObjectFactory {
+ /**
+ * Logger for this class and subclasses
+ */
protected final Log logger = LogFactory.getLog(this.getClass());
private ContextSource contextSource;
diff --git a/spring-ldap/src/main/java/org/springframework/ldap/pool/factory/PoolingContextSource.java b/spring-ldap/src/main/java/org/springframework/ldap/pool/factory/PoolingContextSource.java
index 6e8009b7..1e5b1f87 100644
--- a/spring-ldap/src/main/java/org/springframework/ldap/pool/factory/PoolingContextSource.java
+++ b/spring-ldap/src/main/java/org/springframework/ldap/pool/factory/PoolingContextSource.java
@@ -16,9 +16,6 @@
package org.springframework.ldap.pool.factory;
-import java.util.HashMap;
-import java.util.Map;
-
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapContext;
@@ -100,7 +97,7 @@ import org.springframework.ldap.pool.validation.DirContextValidator;
* | whenExhaustedAction |
* {@link GenericKeyedObjectPool#setWhenExhaustedAction(byte)} |
* No |
- * {@link GenericObjectPool#WHEN_EXHAUSTED_BLOCK} |
+ * {@link GenericKeyedObjectPool#WHEN_EXHAUSTED_BLOCK} |
*
*
* | testOnBorrow |
@@ -144,73 +141,18 @@ import org.springframework.ldap.pool.validation.DirContextValidator;
* @author Eric Dalquist
*/
public class PoolingContextSource implements ContextSource, DisposableBean {
+ /**
+ * The logger for this class and sub-classes
+ */
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));
- }
- }
-
+ /**
+ * Creates a new pooling context source, setting up the DirContext object factory
+ * and generic keyed object pool.
+ */
public PoolingContextSource() {
this.dirContextPoolableObjectFactory = new DirContextPoolableObjectFactory();
this.keyedObjectPool = new GenericKeyedObjectPool();
@@ -301,9 +243,8 @@ public class PoolingContextSource implements ContextSource, DisposableBean {
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#getWhenExhaustedAction()
*/
- public WhenExhaustedAction getWhenExhaustedAction() {
- final byte whenExhaustedAction = this.keyedObjectPool.getWhenExhaustedAction();
- return WhenExhaustedAction.getActionForId(whenExhaustedAction);
+ public byte getWhenExhaustedAction() {
+ return this.keyedObjectPool.getWhenExhaustedAction();
}
/**
* @see org.apache.commons.pool.impl.GenericKeyedObjectPool#setMaxActive(int)
@@ -374,12 +315,8 @@ public class PoolingContextSource implements ContextSource, DisposableBean {
/**
* @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());
+ public void setWhenExhaustedAction(byte whenExhaustedAction) {
+ this.keyedObjectPool.setWhenExhaustedAction(whenExhaustedAction);
}
@@ -430,21 +367,28 @@ public class PoolingContextSource implements ContextSource, DisposableBean {
//***** ContextSource interface methods *****//
- /**
- * @see org.springframework.ldap.ContextSource#getReadOnlyContext()
+ /*
+ * @see ContextSource#getReadOnlyContext()
*/
public DirContext getReadOnlyContext() throws NamingException {
return this.getContext(DirContextType.READ_ONLY);
}
- /**
- * @see org.springframework.ldap.ContextSource#getReadWriteContext()
+ /*
+ * @see ContextSource#getReadWriteContext()
*/
public DirContext getReadWriteContext() throws NamingException {
return this.getContext(DirContextType.READ_WRITE);
}
- protected DirContext getContext(DirContextType dirContextType) throws NamingException {
+ /**
+ * Gets a DirContext of the specified type from the keyed object pool.
+ *
+ * @param dirContextType The type of context to return.
+ * @return A wrapped DirContext of the specified type.
+ * @throws DataAccessResourceFailureException If retreiving the object from the pool throws an exception
+ */
+ protected DirContext getContext(DirContextType dirContextType) {
final DirContext dirContext;
try {
dirContext = (DirContext)this.keyedObjectPool.borrowObject(dirContextType);
@@ -456,8 +400,7 @@ public class PoolingContextSource implements ContextSource, DisposableBean {
if (dirContext instanceof LdapContext) {
return new DelegatingLdapContext(this.keyedObjectPool, (LdapContext)dirContext, dirContextType);
}
- else {
- return new DelegatingDirContext(this.keyedObjectPool, dirContext, dirContextType);
- }
+
+ return new DelegatingDirContext(this.keyedObjectPool, dirContext, dirContextType);
}
}
diff --git a/spring-ldap/src/main/java/org/springframework/ldap/pool/validation/DefaultDirContextValidator.java b/spring-ldap/src/main/java/org/springframework/ldap/pool/validation/DefaultDirContextValidator.java
index 92af8ae3..450e88e4 100644
--- a/spring-ldap/src/main/java/org/springframework/ldap/pool/validation/DefaultDirContextValidator.java
+++ b/spring-ldap/src/main/java/org/springframework/ldap/pool/validation/DefaultDirContextValidator.java
@@ -73,12 +73,19 @@ import org.springframework.ldap.pool.DirContextType;
* @author Eric Dalquist
*/
public class DefaultDirContextValidator implements DirContextValidator {
+ /**
+ * Logger for this class and sub-classes
+ */
protected final Log logger = LogFactory.getLog(this.getClass());
private String base;
private String filter;
private SearchControls searchControls;
+ /**
+ * Create the default validator, creates {@link SearchControls} with a countLimit of 1, returningAttributes of
+ * objectclass and timeLimit of 500. The default base is an empty string and the default filter is objectclass=*
+ */
public DefaultDirContextValidator() {
this.searchControls = new SearchControls();
this.searchControls.setCountLimit(1);
@@ -137,7 +144,7 @@ public class DefaultDirContextValidator implements DirContextValidator {
/**
- * @see edu.wisc.commons.lcp.validation.DirContextValidator#validateDirContext(edu.wisc.commons.lcp.pool.DirContextType, javax.naming.directory.DirContext)
+ * @see DirContextValidator#validateDirContext(DirContextType, javax.naming.directory.DirContext)
*/
public boolean validateDirContext(DirContextType contextType, DirContext dirContext) {
Validate.notNull(contextType, "contextType may not be null");
diff --git a/spring-ldap/src/main/java/org/springframework/ldap/pool/validation/DirContextValidator.java b/spring-ldap/src/main/java/org/springframework/ldap/pool/validation/DirContextValidator.java
index 494140a5..5eab0faf 100644
--- a/spring-ldap/src/main/java/org/springframework/ldap/pool/validation/DirContextValidator.java
+++ b/spring-ldap/src/main/java/org/springframework/ldap/pool/validation/DirContextValidator.java
@@ -18,6 +18,7 @@ package org.springframework.ldap.pool.validation;
import javax.naming.directory.DirContext;
+import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.pool.DirContextType;
/**
diff --git a/spring-ldap/src/test/java/org/springframework/ldap/pool/factory/PoolingContextSourceTest.java b/spring-ldap/src/test/java/org/springframework/ldap/pool/factory/PoolingContextSourceTest.java
index 175a1b17..00b8dc2d 100644
--- a/spring-ldap/src/test/java/org/springframework/ldap/pool/factory/PoolingContextSourceTest.java
+++ b/spring-ldap/src/test/java/org/springframework/ldap/pool/factory/PoolingContextSourceTest.java
@@ -18,11 +18,11 @@ package org.springframework.ldap.pool.factory;
import javax.naming.directory.DirContext;
import javax.naming.ldap.LdapContext;
+import org.apache.commons.pool.impl.GenericKeyedObjectPool;
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;
/**
@@ -101,18 +101,9 @@ public class PoolingContextSourceTest extends AbstractPoolTestCase {
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));
+ poolingContextSource.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_BLOCK);
+ final byte whenExhaustedAction = poolingContextSource.getWhenExhaustedAction();
+ assertEquals(GenericKeyedObjectPool.WHEN_EXHAUSTED_BLOCK, whenExhaustedAction);
final int numActive = poolingContextSource.getNumActive();
assertEquals(0, numActive);