diff --git a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessor.java b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessor.java
index 09f34fbd..1398391f 100644
--- a/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessor.java
+++ b/core/src/main/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessor.java
@@ -27,6 +27,7 @@ import org.springframework.ldap.support.LdapUtils;
import org.springframework.util.StringUtils;
import javax.naming.ldap.LdapName;
+import java.util.Collection;
/**
* This BeanPostProcessor checks each bean if it implements
@@ -89,17 +90,40 @@ public class BaseLdapPathBeanPostProcessor implements BeanPostProcessor, Applica
BaseLdapPathSource getBaseLdapPathSourceFromApplicationContext() {
if (StringUtils.hasLength(baseLdapPathSourceName)) {
- return (BaseLdapPathSource) applicationContext.getBean(baseLdapPathSourceName);
+ return applicationContext.getBean(baseLdapPathSourceName, BaseLdapPathSource.class);
}
- String[] definedContextSources = applicationContext.getBeanNamesForType(BaseLdapPathSource.class);
- if (definedContextSources.length < 1) {
- throw new NoSuchBeanDefinitionException("No BaseLdapPathSource implementation definition found");
- }
- else if (definedContextSources.length > 1) {
- throw new NoSuchBeanDefinitionException(
- "More than BaseLdapPathSource implementation definition found in current ApplicationContext");
- }
- return (BaseLdapPathSource) applicationContext.getBean(definedContextSources[0]);
+
+ Collection beans = applicationContext.getBeansOfType(BaseLdapPathSource.class).values();
+ if (beans.isEmpty()) {
+ throw new NoSuchBeanDefinitionException("No BaseLdapPathSource implementation definition found");
+ } else if (beans.size() == 1) {
+ return beans.iterator().next();
+ } else {
+ BaseLdapPathSource found = null;
+
+ // Try to find the correct one
+ for (BaseLdapPathSource bean : beans) {
+ if(bean instanceof AbstractContextSource) {
+ if(found != null) {
+ // More than one found - nothing much to do.
+ throw new NoSuchBeanDefinitionException(
+ "More than BaseLdapPathSource implementation definition found in current ApplicationContext; " +
+ "unable to determine the one to use. Please specify 'baseLdapPathSourceName'");
+ }
+
+ found = bean;
+ }
+ }
+
+ if(found == null) {
+ throw new NoSuchBeanDefinitionException(
+ "More than BaseLdapPathSource implementation definition found in current ApplicationContext; " +
+ "unable to determine the one to use (one of them should be an AbstractContextSource instance). " +
+ "Please specify 'baseLdapPathSourceName'");
+ }
+
+ return found;
+ }
}
/*
diff --git a/core/src/main/java/org/springframework/ldap/core/support/DelegatingBaseLdapPathContextSourceSupport.java b/core/src/main/java/org/springframework/ldap/core/support/DelegatingBaseLdapPathContextSourceSupport.java
new file mode 100644
index 00000000..fb54be76
--- /dev/null
+++ b/core/src/main/java/org/springframework/ldap/core/support/DelegatingBaseLdapPathContextSourceSupport.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2005-2013 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.core.support;
+
+import org.springframework.ldap.core.ContextSource;
+import org.springframework.ldap.core.DistinguishedName;
+
+import javax.naming.ldap.LdapName;
+
+/**
+ * Support class to provide {@link BaseLdapPathSource} functionality to ContextSource instances
+ * that act as proxies.
+ *
+ * @author Mattias Hellborg Arthursson
+ * @since 2.0
+ */
+public abstract class DelegatingBaseLdapPathContextSourceSupport implements BaseLdapPathSource {
+
+ /**
+ * Get the target ContextSource.
+ * @return the target ContextSource.
+ */
+ protected abstract ContextSource getTarget();
+
+ private BaseLdapPathSource getTargetAsBaseLdapPathSource() {
+ try {
+ return (BaseLdapPathSource) getTarget();
+ } catch (ClassCastException e) {
+ throw new UnsupportedOperationException("This operation is not supported on a target ContextSource that does not " +
+ " implement BaseLdapPathContextSource", e);
+ }
+ }
+
+ @Override
+ public final LdapName getBaseLdapName() {
+ return getTargetAsBaseLdapPathSource().getBaseLdapName();
+ }
+
+ @Override
+ public final DistinguishedName getBaseLdapPath() {
+ return getTargetAsBaseLdapPathSource().getBaseLdapPath();
+ }
+
+ @Override
+ public final String getBaseLdapPathAsString() {
+ return getTargetAsBaseLdapPathSource().getBaseLdapPathAsString();
+ }
+}
diff --git a/core/src/main/java/org/springframework/ldap/pool/factory/PoolingContextSource.java b/core/src/main/java/org/springframework/ldap/pool/factory/PoolingContextSource.java
index 25b1a9df..3e9773ee 100644
--- a/core/src/main/java/org/springframework/ldap/pool/factory/PoolingContextSource.java
+++ b/core/src/main/java/org/springframework/ldap/pool/factory/PoolingContextSource.java
@@ -23,6 +23,7 @@ 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.core.support.DelegatingBaseLdapPathContextSourceSupport;
import org.springframework.ldap.pool.DelegatingDirContext;
import org.springframework.ldap.pool.DelegatingLdapContext;
import org.springframework.ldap.pool.DirContextType;
@@ -141,7 +142,9 @@ import java.util.Collection;
*
* @author Eric Dalquist
*/
-public class PoolingContextSource implements ContextSource, DisposableBean {
+public class PoolingContextSource
+ extends DelegatingBaseLdapPathContextSourceSupport
+ implements ContextSource, DisposableBean {
/**
* The logger for this class and sub-classes
*/
@@ -410,7 +413,12 @@ public class PoolingContextSource implements ContextSource, DisposableBean {
}
}
- // ***** ContextSource interface methods *****//
+ @Override
+ protected ContextSource getTarget() {
+ return getContextSource();
+ }
+
+ // ***** ContextSource interface methods *****//
/*
* @see ContextSource#getReadOnlyContext()
diff --git a/core/src/main/java/org/springframework/ldap/transaction/compensating/manager/TransactionAwareContextSourceProxy.java b/core/src/main/java/org/springframework/ldap/transaction/compensating/manager/TransactionAwareContextSourceProxy.java
index 98979825..c3e17b13 100644
--- a/core/src/main/java/org/springframework/ldap/transaction/compensating/manager/TransactionAwareContextSourceProxy.java
+++ b/core/src/main/java/org/springframework/ldap/transaction/compensating/manager/TransactionAwareContextSourceProxy.java
@@ -15,16 +15,17 @@
*/
package org.springframework.ldap.transaction.compensating.manager;
-import java.lang.reflect.Proxy;
-
-import javax.naming.directory.DirContext;
-
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.DirContextProxy;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.springframework.ldap.core.support.DelegatingBaseLdapPathContextSourceSupport;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.transaction.support.TransactionSynchronizationManager;
+import javax.naming.directory.DirContext;
+import java.lang.reflect.Proxy;
+
/**
* A proxy for ContextSource to make sure that the returned DirContext objects
* are aware of the surrounding transactions. This makes sure that the
@@ -36,7 +37,10 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
* @author Mattias Hellborg Arthursson
* @since 1.2
*/
-public class TransactionAwareContextSourceProxy implements ContextSource {
+public class TransactionAwareContextSourceProxy
+ extends DelegatingBaseLdapPathContextSourceSupport
+ implements ContextSource {
+
private ContextSource target;
/**
@@ -49,11 +53,7 @@ public class TransactionAwareContextSourceProxy implements ContextSource {
this.target = target;
}
- /**
- * Get the target ContextSource.
- *
- * @return the target ContextSource.
- */
+ @Override
public ContextSource getTarget() {
return target;
}
@@ -102,4 +102,13 @@ public class TransactionAwareContextSourceProxy implements ContextSource {
public DirContext getContext(String principal, String credentials) throws NamingException {
throw new UnsupportedOperationException("Not supported on a transacted ContextSource");
}
+
+ private BaseLdapPathContextSource convertToBaseLdapPathContextSource(ContextSource contextSource) {
+ if (contextSource instanceof BaseLdapPathContextSource) {
+ return (BaseLdapPathContextSource) contextSource;
+ }
+
+ throw new UnsupportedOperationException("This operation is not supported on a target ContextSource that does not " +
+ " implement BaseLdapPathContextSource");
+ }
}
diff --git a/core/src/test/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessorTest.java b/core/src/test/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessorTest.java
index b9f6868b..536a663d 100644
--- a/core/src/test/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessorTest.java
+++ b/core/src/test/java/org/springframework/ldap/core/support/BaseLdapPathBeanPostProcessorTest.java
@@ -22,6 +22,8 @@ import org.springframework.context.ApplicationContext;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.support.LdapUtils;
+import java.util.HashMap;
+
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -118,8 +120,12 @@ public class BaseLdapPathBeanPostProcessorTest {
public void testGetAbstractContextSourceFromApplicationContext() throws Exception {
when(applicationContextMock.getBeanNamesForType(BaseLdapPathSource.class))
.thenReturn(new String[]{"contextSource"});
- LdapContextSource expectedContextSource = new LdapContextSource();
- when(applicationContextMock.getBean("contextSource")).thenReturn(expectedContextSource);
+ final LdapContextSource expectedContextSource = new LdapContextSource();
+
+ HashMap expectedBeans = new HashMap() {{
+ put("dummy", expectedContextSource);
+ }};
+ when(applicationContextMock.getBeansOfType(BaseLdapPathSource.class)).thenReturn(expectedBeans);
BaseLdapPathSource result = tested.getBaseLdapPathSourceFromApplicationContext();
diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/itest/core/support/BaseLdapPathBeanPostprocessorITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/itest/core/support/BaseLdapPathBeanPostprocessorITest.java
index ffdc9b12..491b95e0 100644
--- a/test/integration-tests/src/test/java/org/springframework/ldap/itest/core/support/BaseLdapPathBeanPostprocessorITest.java
+++ b/test/integration-tests/src/test/java/org/springframework/ldap/itest/core/support/BaseLdapPathBeanPostprocessorITest.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.ldap.itest.core.support;
import org.junit.Test;
@@ -20,8 +21,6 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.ldap.itest.core.support.DummyBaseLdapNameAware;
-import org.springframework.ldap.itest.core.support.DummyBaseLdapPathAware;
import org.springframework.ldap.support.LdapUtils;
import static junit.framework.Assert.assertEquals;
@@ -30,7 +29,7 @@ import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
/**
- * Integration tests for {@link BaseLdapPathBeanPostProcessor}.
+ * Integration tests for {@link org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor}.
*
* @author Mattias Hellborg Arthursson
*/
diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/itest/core/support/BaseLdapPathBeanPostprocessorNamespaceConfigITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/itest/core/support/BaseLdapPathBeanPostprocessorNamespaceConfigITest.java
new file mode 100644
index 00000000..ecf5bafc
--- /dev/null
+++ b/test/integration-tests/src/test/java/org/springframework/ldap/itest/core/support/BaseLdapPathBeanPostprocessorNamespaceConfigITest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2005-2013 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.itest.core.support;
+
+import org.junit.Test;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.support.LdapUtils;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+/**
+ * Integration tests for {@link org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor}.
+ *
+ * @author Mattias Hellborg Arthursson
+ */
+public class BaseLdapPathBeanPostprocessorNamespaceConfigITest {
+
+ @Test
+ public void testPostProcessBeforeInitializationWithNamespaceConfig() throws Exception {
+ ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
+ "/conf/baseLdapPathPostProcessorNamespaceTestContext.xml");
+ DummyBaseLdapPathAware tested = ctx.getBean(DummyBaseLdapPathAware.class);
+
+ DistinguishedName base = tested.getBase();
+ assertNotNull(base);
+ assertEquals(new DistinguishedName("dc=jayway,dc=se"), base);
+
+ DummyBaseLdapNameAware otherTested = ctx.getBean(DummyBaseLdapNameAware.class);
+ assertEquals(LdapUtils.newLdapName("dc=jayway,dc=se"), otherTested.getBaseLdapPath());
+ }
+
+ @Test
+ public void testPostProcessBeforeInitializationWithNamespaceConfigAndPooling() throws Exception {
+ ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
+ "/conf/baseLdapPathPostProcessorPoolingNamespaceTestContext.xml");
+ DummyBaseLdapPathAware tested = ctx.getBean(DummyBaseLdapPathAware.class);
+
+ DistinguishedName base = tested.getBase();
+ assertNotNull(base);
+ assertEquals(new DistinguishedName("dc=jayway,dc=se"), base);
+
+ DummyBaseLdapNameAware otherTested = ctx.getBean(DummyBaseLdapNameAware.class);
+ assertEquals(LdapUtils.newLdapName("dc=jayway,dc=se"), otherTested.getBaseLdapPath());
+ }
+
+
+}
diff --git a/test/integration-tests/src/test/resources/conf/baseLdapPathPostProcessorNamespaceTestContext.xml b/test/integration-tests/src/test/resources/conf/baseLdapPathPostProcessorNamespaceTestContext.xml
new file mode 100644
index 00000000..5ee7c048
--- /dev/null
+++ b/test/integration-tests/src/test/resources/conf/baseLdapPathPostProcessorNamespaceTestContext.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/integration-tests/src/test/resources/conf/baseLdapPathPostProcessorPoolingNamespaceTestContext.xml b/test/integration-tests/src/test/resources/conf/baseLdapPathPostProcessorPoolingNamespaceTestContext.xml
new file mode 100644
index 00000000..02885bfa
--- /dev/null
+++ b/test/integration-tests/src/test/resources/conf/baseLdapPathPostProcessorPoolingNamespaceTestContext.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+