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