diff --git a/sandbox/.classpath b/sandbox/.classpath
index e1da7745..447de866 100644
--- a/sandbox/.classpath
+++ b/sandbox/.classpath
@@ -43,6 +43,10 @@
+
+
+
+
diff --git a/sandbox/.springBeans b/sandbox/.springBeans
index f9aa76ca..64348ed0 100644
--- a/sandbox/.springBeans
+++ b/sandbox/.springBeans
@@ -1,7 +1,11 @@
+
+ xml
+
src/iutest/conf/ldapTemplateBaseSuffixTestContext.xml
+ src/itest/java/conf/ldapTemplateTransactionTestContext.xml
src/iutest/conf/ldapTemplateTestContext.xml
@@ -21,5 +25,13 @@
src/iutest/conf/ldapTemplateTestContext.xml
+
+ iutesttransactions
+ false
+ false
+
+ src/itest/java/conf/ldapTemplateTransactionTestContext.xml
+
+
diff --git a/sandbox/ivy.xml b/sandbox/ivy.xml
index ebb1c36d..84500f8e 100644
--- a/sandbox/ivy.xml
+++ b/sandbox/ivy.xml
@@ -43,6 +43,8 @@
conf="buildtime->default" />
+
@@ -57,6 +59,8 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PROPAGATION_REQUIRED
+
+
+
+
diff --git a/sandbox/src/itest/java/log4j.properties b/sandbox/src/itest/java/log4j.properties
index f57302e8..5269b4f5 100644
--- a/sandbox/src/itest/java/log4j.properties
+++ b/sandbox/src/itest/java/log4j.properties
@@ -5,5 +5,4 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
#Enable debug logging
-log4j.category.net.sf.ldaptemplate=INFO
-log4j.category.net.sf.ldaptemplate.LdapTemplate=DEBUG
+log4j.category.org.springframework.ldap=DEBUG
diff --git a/sandbox/src/itest/java/org/springframework/ldap/ConfigEnvHelper.java b/sandbox/src/itest/java/org/springframework/ldap/ConfigEnvHelper.java
new file mode 100644
index 00000000..20710fae
--- /dev/null
+++ b/sandbox/src/itest/java/org/springframework/ldap/ConfigEnvHelper.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2002-2005 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ldap;
+
+import java.io.File;
+import java.util.Hashtable;
+
+import javax.naming.Context;
+
+import org.apache.directory.server.configuration.MutableServerStartupConfiguration;
+import org.apache.directory.server.jndi.ServerContextFactory;
+import org.springframework.beans.factory.InitializingBean;
+
+/**
+ * Helper class to simplify Spring configuration of ApacheDS.
+ *
+ * @author Mattias Arthursson
+ */
+public class ConfigEnvHelper implements InitializingBean {
+ private final MutableServerStartupConfiguration configuration;
+
+ private final Hashtable initialEnv;
+
+ private final File workingDir = new File(System
+ .getProperty("java.io.tmpdir")
+ + File.separator + "ldaptemplate_apacheds");
+
+ public ConfigEnvHelper(Hashtable initialEnv,
+ MutableServerStartupConfiguration configuration) {
+
+ this.initialEnv = initialEnv;
+ this.configuration = configuration;
+ }
+
+ public Hashtable getEnv() {
+ return initialEnv;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ initialEnv.put(Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName());
+ configuration.setWorkingDirectory(workingDir);
+ initialEnv.putAll(configuration.toJndiEnvironment());
+ }
+}
diff --git a/sandbox/src/itest/java/org/springframework/ldap/LdapServerManager.java b/sandbox/src/itest/java/org/springframework/ldap/LdapServerManager.java
new file mode 100644
index 00000000..9b36a6a8
--- /dev/null
+++ b/sandbox/src/itest/java/org/springframework/ldap/LdapServerManager.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2002-2005 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ldap;
+
+import java.util.Properties;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.ContextNotEmptyException;
+import javax.naming.InitialContext;
+import javax.naming.Name;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.directory.server.core.configuration.ShutdownConfiguration;
+import org.apache.directory.server.jndi.ServerContextFactory;
+import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.ldap.support.DefaultDirObjectFactory;
+import org.springframework.ldap.support.DistinguishedName;
+
+/**
+ * Utility class to initialize the apache directory server for use in the
+ * integration tests.
+ *
+ * @author Mattias Arthursson
+ *
+ */
+public class LdapServerManager implements DisposableBean {
+ private static Log log = LogFactory.getLog(LdapServerManager.class);
+
+ private ContextSource contextSource;
+
+ public void setContextSource(ContextSource contextSource) {
+ this.contextSource = contextSource;
+ }
+
+ public void destroy() throws Exception {
+ Properties env = new Properties();
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+ ServerContextFactory.class.getName());
+ env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
+ env.setProperty(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
+ env.setProperty(Context.SECURITY_CREDENTIALS, "secret");
+
+ ShutdownConfiguration configuration = new ShutdownConfiguration();
+ env.putAll(configuration.toJndiEnvironment());
+
+ new InitialContext(env);
+ }
+
+ public void cleanAndSetup(String ldifFile) throws Exception {
+ DirContext ctx = contextSource.getReadWriteContext();
+
+ // First of all, make sure the database is empty.
+ Name startingPoint = null;
+
+ // Different test cases have different base paths. This means that the
+ // starting point will be different.
+ if (ctx.getEnvironment().get(
+ DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY) != null) {
+ startingPoint = DistinguishedName.EMPTY_PATH;
+ } else {
+ startingPoint = new DistinguishedName("dc=jayway,dc=se");
+ }
+
+ try {
+ log.info("Cleaning all present data.");
+ clearSubContexts(ctx, startingPoint);
+ // Load the ldif to the recently started server
+ log.info("Loading setup data");
+ LdifFileLoader loader = new LdifFileLoader(ctx, ldifFile);
+ loader.execute();
+ } finally {
+ ctx.close();
+ }
+ }
+
+ private void clearSubContexts(DirContext ctx, Name name)
+ throws NamingException {
+
+ NamingEnumeration enumeration = null;
+ try {
+ enumeration = ctx.listBindings(name);
+ while (enumeration.hasMore()) {
+ Binding element = (Binding) enumeration.next();
+ DistinguishedName childName = new DistinguishedName(element
+ .getName());
+ childName.prepend((DistinguishedName) name);
+
+ try {
+ ctx.destroySubcontext(childName);
+ } catch (ContextNotEmptyException e) {
+ clearSubContexts(ctx, childName);
+ ctx.destroySubcontext(childName);
+ }
+ }
+ } catch (NamingException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ enumeration.close();
+ } catch (Exception e) {
+ // Never mind this
+ }
+ }
+ }
+}
diff --git a/sandbox/src/itest/java/org/springframework/ldap/support/transaction/ContextSourceTransactionManagerIntegrationTest.java b/sandbox/src/itest/java/org/springframework/ldap/support/transaction/ContextSourceTransactionManagerIntegrationTest.java
new file mode 100644
index 00000000..81308de7
--- /dev/null
+++ b/sandbox/src/itest/java/org/springframework/ldap/support/transaction/ContextSourceTransactionManagerIntegrationTest.java
@@ -0,0 +1,119 @@
+package org.springframework.ldap.support.transaction;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.ldap.AttributesMapper;
+import org.springframework.ldap.EntryNotFoundException;
+import org.springframework.ldap.LdapServerManager;
+import org.springframework.ldap.LdapTemplate;
+import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
+
+public class ContextSourceTransactionManagerIntegrationTest extends
+ AbstractDependencyInjectionSpringContextTests {
+
+ private static Log log = LogFactory
+ .getLog(ContextSourceTransactionManagerIntegrationTest.class);
+
+ public ContextSourceTransactionManagerIntegrationTest() {
+ setAutowireMode(AbstractDependencyInjectionSpringContextTests.AUTOWIRE_BY_NAME);
+ }
+
+ private DummyDaoImpl dummyDao;
+
+ private LdapTemplate ldapTemplate;
+
+ private LdapServerManager ldapServerManager;
+
+ public void setLdapServerManager(LdapServerManager ldapServerManager) {
+ this.ldapServerManager = ldapServerManager;
+ }
+
+ public void setLdapTemplate(LdapTemplate ldapTemplate) {
+ this.ldapTemplate = ldapTemplate;
+ }
+
+ public void setDummyDao(DummyDaoImpl dummyDaoImpl) {
+ this.dummyDao = dummyDaoImpl;
+ }
+
+ protected String[] getConfigLocations() {
+ return new String[] { "conf/ldapTemplateTransactionTestContext.xml" };
+ }
+
+ protected void onSetUp() throws Exception {
+ ldapServerManager.cleanAndSetup("setup_data.ldif");
+ }
+
+ public void testCreateWithException() {
+ try {
+ dummyDao.createWithException("Sweden", "company1",
+ "some testperson", "testperson", "some description");
+ fail("RuntimeException expected");
+ } catch (RuntimeException expected) {
+ assertTrue(true);
+ }
+
+ log.debug("Verifying result");
+
+ try {
+ ldapTemplate.lookup("cn=some testperson, ou=company1, c=Sweden");
+ fail("EntryNotFoundException expected");
+ } catch (EntryNotFoundException expected) {
+ assertTrue(true);
+ }
+ }
+
+ public void testCreateWithNoException() {
+ dummyDao.create("Sweden", "company1", "some testperson", "testperson",
+ "some description");
+
+ log.debug("Verifying result");
+ ldapTemplate.lookup("cn=some testperson, ou=company1, c=Sweden");
+ }
+
+ public void testUpdateWithException() {
+ String dn = "cn=Some Person,ou=company1,c=Sweden";
+ try {
+ dummyDao.updateWithException(dn, "Updated Person",
+ "Updated description");
+ fail("RuntimeException expected");
+ } catch (RuntimeException expected) {
+ assertTrue(true);
+ }
+
+ log.debug("Verifying result");
+
+ Object result = ldapTemplate.lookup(dn, new AttributesMapper() {
+ public Object mapFromAttributes(Attributes attributes)
+ throws NamingException {
+ assertEquals("Person", attributes.get("sn").get());
+ assertEquals("Sweden, Company1, Some Person", attributes.get(
+ "description").get());
+ return new Object();
+ }
+ });
+
+ assertNotNull(result);
+ }
+
+ public void testUpdate() {
+ String dn = "cn=Some Person,ou=company1,c=Sweden";
+ dummyDao.update(dn, "Updated Person", "Updated description");
+
+ log.debug("Verifying result");
+ Object result = ldapTemplate.lookup(dn, new AttributesMapper() {
+ public Object mapFromAttributes(Attributes attributes)
+ throws NamingException {
+ assertEquals("Updated Person", attributes.get("sn").get());
+ assertEquals("Updated description", attributes.get(
+ "description").get());
+ return new Object();
+ }
+ });
+
+ assertNotNull(result);
+ }
+}
diff --git a/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyDao.java b/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyDao.java
new file mode 100644
index 00000000..d2226234
--- /dev/null
+++ b/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyDao.java
@@ -0,0 +1,4 @@
+package org.springframework.ldap.support.transaction;
+
+public interface DummyDao {
+}
diff --git a/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyDaoImpl.java b/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyDaoImpl.java
new file mode 100644
index 00000000..c74230b2
--- /dev/null
+++ b/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyDaoImpl.java
@@ -0,0 +1,49 @@
+package org.springframework.ldap.support.transaction;
+
+import org.springframework.ldap.LdapTemplate;
+import org.springframework.ldap.support.DirContextAdapter;
+import org.springframework.ldap.support.DistinguishedName;
+
+public class DummyDaoImpl {
+ private LdapTemplate ldapTemplate;
+
+ public void setLdapTemplate(LdapTemplate ldapTemplate) {
+ this.ldapTemplate = ldapTemplate;
+ }
+
+ public void createWithException(String country, String company,
+ String fullname, String lastname, String description) {
+ create(country, company, fullname, lastname, description);
+ throw new RuntimeException("This method failed");
+ }
+
+ public void create(String country, String company, String fullname,
+ String lastname, String description) {
+ DistinguishedName dn = new DistinguishedName();
+ dn.add("c", country);
+ dn.add("ou", company);
+ dn.add("cn", fullname);
+
+ DirContextAdapter ctx = new DirContextAdapter();
+ ctx.setAttributeValues("objectclass", new String[] { "top", "person" });
+ ctx.setAttributeValue("cn", fullname);
+ ctx.setAttributeValue("sn", lastname);
+ ctx.setAttributeValue("description", description);
+ ldapTemplate.bind(dn, ctx, null);
+ }
+
+ public void update(String dn, String lastname, String description) {
+ DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn);
+ ctx.setAttributeValue("sn", lastname);
+ ctx.setAttributeValue("description", description);
+ ctx.update();
+
+ ldapTemplate.rebind(dn, ctx, null);
+ }
+
+ public void updateWithException(String dn, String lastname,
+ String description) {
+ update(dn, lastname, description);
+ throw new RuntimeException("This method failed.");
+ }
+}
diff --git a/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyServiceImpl.java b/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyServiceImpl.java
new file mode 100644
index 00000000..86f4e638
--- /dev/null
+++ b/sandbox/src/itest/java/org/springframework/ldap/support/transaction/DummyServiceImpl.java
@@ -0,0 +1,9 @@
+package org.springframework.ldap.support.transaction;
+
+public class DummyServiceImpl {
+ private DummyDaoImpl dummyDaoImpl;
+
+ public void setDummyDaoImpl(DummyDaoImpl dummyDaoImpl) {
+ this.dummyDaoImpl = dummyDaoImpl;
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/ContextSourceTransactionManager.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/ContextSourceTransactionManager.java
index 7c6a9af7..d1596fb9 100644
--- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/ContextSourceTransactionManager.java
+++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/ContextSourceTransactionManager.java
@@ -3,6 +3,8 @@ package org.springframework.ldap.support.transaction;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.ContextSource;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
@@ -20,6 +22,9 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
public class ContextSourceTransactionManager extends
AbstractPlatformTransactionManager {
+ private static Log log = LogFactory
+ .getLog(ContextSourceTransactionManager.class);
+
private ContextSource contextSource;
/**
@@ -98,11 +103,14 @@ public class ContextSourceTransactionManager extends
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doCleanupAfterCompletion(java.lang.Object)
*/
protected void doCleanupAfterCompletion(Object transaction) {
- ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) transaction;
+ log.debug("Cleaning stored ContextHolder");
TransactionSynchronizationManager.unbindResource(contextSource);
+
+ ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) transaction;
DirContext ctx = txObject.getContextHolder().getCtx();
try {
+ log.debug("Closing target context");
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
@@ -110,5 +118,4 @@ public class ContextSourceTransactionManager extends
txObject.getContextHolder().clear();
}
-
}
diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/DirContextProxy.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/DirContextProxy.java
index 15c632a8..836cd35c 100644
--- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/DirContextProxy.java
+++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/DirContextProxy.java
@@ -2,6 +2,6 @@ package org.springframework.ldap.support.transaction;
import javax.naming.directory.DirContext;
-public interface DirContextProxy {
+public interface DirContextProxy extends DirContext {
DirContext getTargetContext();
}
diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/LdapCompensatingTransactionDataManager.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/LdapCompensatingTransactionDataManager.java
index d7319e53..9edfaefa 100644
--- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/LdapCompensatingTransactionDataManager.java
+++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/LdapCompensatingTransactionDataManager.java
@@ -1,5 +1,9 @@
package org.springframework.ldap.support.transaction;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.util.Stack;
import javax.naming.directory.DirContext;
@@ -42,6 +46,7 @@ public class LdapCompensatingTransactionDataManager implements
* @see org.springframework.ldap.support.CompensatingTransactionDataManager#rollback()
*/
public void rollback() {
+ log.debug("Performing rollback");
while (!rollbackOperations.isEmpty()) {
CompensatingTransactionRollbackOperation rollbackOperation = (CompensatingTransactionRollbackOperation) rollbackOperations
.pop();
@@ -83,23 +88,6 @@ public class LdapCompensatingTransactionDataManager implements
return new NullRecordingOperation();
}
- static class SingleContextSource implements ContextSource {
- private DirContext ctx;
-
- public SingleContextSource(DirContext ctx) {
- this.ctx = ctx;
- }
-
- public DirContext getReadOnlyContext() throws DataAccessException {
- return ctx;
- }
-
- public DirContext getReadWriteContext() throws DataAccessException {
- return ctx;
- }
-
- }
-
/**
* Set the LdapOperations to use. For testing purposes only.
*
@@ -110,4 +98,61 @@ public class LdapCompensatingTransactionDataManager implements
this.ldapOperations = ldapOperations;
}
+ static class SingleContextSource implements ContextSource {
+ private DirContext ctx;
+
+ public SingleContextSource(DirContext ctx) {
+ this.ctx = ctx;
+ }
+
+ public DirContext getReadOnlyContext() throws DataAccessException {
+ return getNonClosingDirContextProxy(ctx);
+ }
+
+ public DirContext getReadWriteContext() throws DataAccessException {
+ return getNonClosingDirContextProxy(ctx);
+ }
+
+ private DirContext getNonClosingDirContextProxy(DirContext context) {
+ return (DirContext) Proxy.newProxyInstance(DirContextProxy.class
+ .getClassLoader(), new Class[] { DirContextProxy.class },
+ new NonClosingDirContextInvocationHandler(context));
+
+ }
+ }
+
+ public static class NonClosingDirContextInvocationHandler implements
+ InvocationHandler {
+
+ private DirContext target;
+
+ public NonClosingDirContextInvocationHandler(DirContext target) {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+
+ String methodName = method.getName();
+ if (methodName.equals("getTargetContext")) {
+ return target;
+ } else if (methodName.equals("equals")) {
+ // Only consider equal when proxies are identical.
+ return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
+ } else if (methodName.equals("hashCode")) {
+ // Use hashCode of Connection proxy.
+ return new Integer(proxy.hashCode());
+ } else if (methodName.equals("close")) {
+ // Never close the target context, as this class will only be
+ // used for operations concerning the compensating transactions.
+ return null;
+ }
+
+ try {
+ return method.invoke(target, args);
+ } catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+ }
}
diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/LdapUtils.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/LdapUtils.java
index d4a569ef..3ca86a37 100644
--- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/LdapUtils.java
+++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/LdapUtils.java
@@ -5,6 +5,8 @@ import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.ContextSource;
import org.springframework.ldap.support.DistinguishedName;
import org.springframework.transaction.support.TransactionSynchronizationManager;
@@ -16,6 +18,8 @@ import org.springframework.util.Assert;
* @author Mattias Arthursson
*/
public class LdapUtils {
+ private static Log log = LogFactory.getLog(LdapUtils.class);
+
public static final String REBIND_METHOD_NAME = "rebind";
public static final String BIND_METHOD_NAME = "bind";
@@ -63,9 +67,12 @@ public class LdapUtils {
.getResource(contextSource);
if (transactionContextHolder == null
|| transactionContextHolder.getCtx() != context) {
+ log.debug("Closing context");
// This is not the transactional context or the transaction is
// no longer active - we should close it.
context.close();
+ } else {
+ log.debug("Leaving transactional context open");
}
}
diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/TransactionAwareContextSourceProxy.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/TransactionAwareContextSourceProxy.java
index 2a645e94..1659d77c 100644
--- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/TransactionAwareContextSourceProxy.java
+++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/TransactionAwareContextSourceProxy.java
@@ -17,21 +17,7 @@ public class TransactionAwareContextSourceProxy implements ContextSource {
}
public DirContext getReadOnlyContext() throws DataAccessException {
- DirContextHolder contextHolder = (DirContextHolder) TransactionSynchronizationManager
- .getResource(target);
- DirContext ctx = null;
-
- if (contextHolder != null) {
- ctx = contextHolder.getCtx();
- }
-
- if (ctx == null) {
- ctx = target.getReadOnlyContext();
- if (contextHolder != null) {
- contextHolder.setCtx(ctx);
- }
- }
- return getTransactionAwareDirContextProxy(ctx, target);
+ return getReadWriteContext();
}
private DirContext getTransactionAwareDirContextProxy(DirContext context,
@@ -45,6 +31,20 @@ public class TransactionAwareContextSourceProxy implements ContextSource {
}
public DirContext getReadWriteContext() throws DataAccessException {
- throw new UnsupportedOperationException("Not implemented yet");
+ DirContextHolder contextHolder = (DirContextHolder) TransactionSynchronizationManager
+ .getResource(target);
+ DirContext ctx = null;
+
+ if (contextHolder != null) {
+ ctx = contextHolder.getCtx();
+ }
+
+ if (ctx == null) {
+ ctx = target.getReadWriteContext();
+ if (contextHolder != null) {
+ contextHolder.setCtx(ctx);
+ }
+ }
+ return getTransactionAwareDirContextProxy(ctx, target);
}
}
diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/TransactionAwareDirContextInvocationHandler.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/TransactionAwareDirContextInvocationHandler.java
index c913fd97..35df5c99 100644
--- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/TransactionAwareDirContextInvocationHandler.java
+++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/TransactionAwareDirContextInvocationHandler.java
@@ -1,6 +1,3 @@
-/**
- *
- */
package org.springframework.ldap.support.transaction;
import java.lang.reflect.InvocationHandler;
@@ -45,7 +42,8 @@ public class TransactionAwareDirContextInvocationHandler implements
return null;
} else if (LdapUtils.isSupportedWriteTransactionOperation(methodName)) {
// Store transaction data and allow operation to proceed.
- LdapUtils.storeCompensatingTransactionData(contextSource, methodName, args);
+ LdapUtils.storeCompensatingTransactionData(contextSource,
+ methodName, args);
}
try {
@@ -54,5 +52,4 @@ public class TransactionAwareDirContextInvocationHandler implements
throw e.getTargetException();
}
}
-
}
\ No newline at end of file
diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/UnbindRollbackOperationTest.java b/sandbox/src/test/java/org/springframework/ldap/support/transaction/UnbindRollbackOperationTest.java
similarity index 100%
rename from sandbox/src/main/java/org/springframework/ldap/support/transaction/UnbindRollbackOperationTest.java
rename to sandbox/src/test/java/org/springframework/ldap/support/transaction/UnbindRollbackOperationTest.java