diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/BindRecordingOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/BindRecordingOperation.java index 2e22e888..1a59f745 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/BindRecordingOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/BindRecordingOperation.java @@ -46,9 +46,9 @@ public class BindRecordingOperation implements /* * (non-Javadoc) * - * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[]) */ - public CompensatingTransactionRollbackOperation performOperation( + public CompensatingTransactionRollbackOperation recordOperation( Object[] args) { Name dn = LdapUtils.getFirstArgumentAsName(args); return new UnbindRollbackOperation(ldapOperations, dn); diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionDataManager.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionDataManager.java index 5c272493..4bd8a9e9 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionDataManager.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionDataManager.java @@ -25,16 +25,16 @@ package org.springframework.ldap.support.transaction; */ public interface CompensatingTransactionDataManager { /** - * Indicates that the supplied operation (method name) has been invoked with - * the specified parameters. This method is called just prior the the actual - * invocation of the target method. + * Indicates that the supplied operation (method name) has been performed + * and that the supplied {@link CompensatingTransactionRollbackOperation} + * should be stored for possible rollback. This method is called after the + * the actual invocation of the target method. * * @param operation * the method to be invoked. - * @param params - * arguments supplied to the operation. */ - public void operationPerformed(String operation, Object[] params); + public void operationPerformed( + CompensatingTransactionRollbackOperation operation); /** * Rollback all recorded operations, by performing each of the recorded diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/DirContextHolder.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/DirContextHolder.java index 42b58e03..854cb5cc 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/DirContextHolder.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/DirContextHolder.java @@ -34,6 +34,8 @@ public class DirContextHolder extends ResourceHolderSupport { private CompensatingTransactionDataManager transactionDataManager; + private CompensatingTransactionOperationFactory operationFactory; + /** * Constructor. * @@ -42,7 +44,8 @@ public class DirContextHolder extends ResourceHolderSupport { */ public DirContextHolder(DirContext ctx) { this.ctx = ctx; - this.transactionDataManager = new LdapCompensatingTransactionDataManager( + this.transactionDataManager = new DefaultCompensatingTransactionDataManager(); + this.operationFactory = new LdapCompensatingTransactionOperationFactory( ctx); } @@ -54,7 +57,8 @@ public class DirContextHolder extends ResourceHolderSupport { */ public void setCtx(DirContext ctx) { this.ctx = ctx; - this.transactionDataManager = new LdapCompensatingTransactionDataManager( + this.transactionDataManager = new DefaultCompensatingTransactionDataManager(); + this.operationFactory = new LdapCompensatingTransactionOperationFactory( ctx); } @@ -70,6 +74,7 @@ public class DirContextHolder extends ResourceHolderSupport { public void clear() { super.clear(); transactionDataManager = null; + operationFactory = null; } /** @@ -92,4 +97,8 @@ public class DirContextHolder extends ResourceHolderSupport { CompensatingTransactionDataManager transactionDataManager) { this.transactionDataManager = transactionDataManager; } + + public CompensatingTransactionOperationFactory getOperationFactory() { + return operationFactory; + } } 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 5f466d21..f50663ea 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 @@ -15,6 +15,9 @@ */ package org.springframework.ldap.support.transaction; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + import javax.naming.Name; import javax.naming.NamingException; import javax.naming.directory.DirContext; @@ -131,23 +134,51 @@ public class LdapUtils { /** * Store compensating transaction data for the supplied operation and - * arguments. + * arguments. TODO: Clean up this mess. * * @param contextSource * the ContextSource we are operating on. - * @param methodName + * @param method * name of the method to be invoked. * @param args * arguments with which the operation is invoked. */ - public static void storeCompensatingTransactionData( - ContextSource contextSource, String methodName, Object[] args) { + public static Object operationPerformed(ContextSource contextSource, + Method method, Object[] args) throws Throwable { DirContextHolder transactionContextHolder = (DirContextHolder) TransactionSynchronizationManager .getResource(contextSource); if (transactionContextHolder != null) { CompensatingTransactionDataManager transactionDataManager = transactionContextHolder .getTransactionDataManager(); - transactionDataManager.operationPerformed(methodName, args); + CompensatingTransactionOperationFactory operationFactory = transactionContextHolder + .getOperationFactory(); + + // Record the operation + CompensatingTransactionRecordingOperation operation = operationFactory + .createRecordingOperation(method.getName()); + CompensatingTransactionRollbackOperation rollbackOperation = operation + .recordOperation(args); + + Object result = null; + // Perform the target operation + try { + result = method.invoke(transactionContextHolder.getCtx(), args); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + transactionDataManager.operationPerformed(rollbackOperation); + + return result; + } else { + Object result = null; + // Perform the target operation + try { + result = method.invoke(transactionContextHolder.getCtx(), args); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + + return result; } } } diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/ModifyAttributesRecordingOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/ModifyAttributesRecordingOperation.java index 98a420e5..f489bea9 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/ModifyAttributesRecordingOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/ModifyAttributesRecordingOperation.java @@ -49,9 +49,9 @@ public class ModifyAttributesRecordingOperation implements /* * (non-Javadoc) * - * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[]) */ - public CompensatingTransactionRollbackOperation performOperation( + public CompensatingTransactionRollbackOperation recordOperation( Object[] args) { Assert.notNull(args); Name dn = LdapUtils.getFirstArgumentAsName(args); diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/NullRecordingOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/NullRecordingOperation.java index 3680d42f..f32d52ab 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/NullRecordingOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/NullRecordingOperation.java @@ -31,9 +31,9 @@ public class NullRecordingOperation implements /* * (non-Javadoc) * - * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[]) */ - public CompensatingTransactionRollbackOperation performOperation( + public CompensatingTransactionRollbackOperation recordOperation( Object[] args) { return new NullRollbackOperation(); } diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/RebindRecordingOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/RebindRecordingOperation.java index 9183e0af..1e806861 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/RebindRecordingOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/RebindRecordingOperation.java @@ -25,7 +25,7 @@ import org.springframework.ldap.support.DirContextAdapter; /** * A {@link CompensatingTransactionRecordingOperation} keeping track of a rebind * operation. Creates {@link RebindRollbackOperation} objects in - * {@link #performOperation(Object[])}. + * {@link #recordOperation(Object[])}. * * @author Mattias Arthursson */ @@ -50,9 +50,9 @@ public class RebindRecordingOperation implements /* * (non-Javadoc) * - * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[]) */ - public CompensatingTransactionRollbackOperation performOperation( + public CompensatingTransactionRollbackOperation recordOperation( Object[] args) { Name dn = LdapUtils.getFirstArgumentAsName(args); diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/RenameRecordingOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/RenameRecordingOperation.java index b8a87463..6454cae8 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/RenameRecordingOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/RenameRecordingOperation.java @@ -51,9 +51,9 @@ public class RenameRecordingOperation implements /* * (non-Javadoc) * - * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[]) */ - public CompensatingTransactionRollbackOperation performOperation( + public CompensatingTransactionRollbackOperation recordOperation( Object[] args) { log.debug("Storing rollback information for rename operation"); Assert.notEmpty(args); 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 49540612..c7d459f5 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 @@ -52,6 +52,12 @@ public class TransactionAwareDirContextInvocationHandler implements this.contextSource = contextSource; } + /* + * (non-Javadoc) + * + * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, + * java.lang.reflect.Method, java.lang.Object[]) + */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { @@ -69,14 +75,13 @@ public class TransactionAwareDirContextInvocationHandler implements return null; } else if (LdapUtils.isSupportedWriteTransactionOperation(methodName)) { // Store transaction data and allow operation to proceed. - LdapUtils.storeCompensatingTransactionData(contextSource, - methodName, args); - } - - try { - return method.invoke(target, args); - } catch (InvocationTargetException e) { - throw e.getTargetException(); + return LdapUtils.operationPerformed(contextSource, method, args); + } else { + try { + return method.invoke(target, args); + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } } } } \ No newline at end of file diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/UnbindRecordingOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/UnbindRecordingOperation.java index e9dfea11..82242a05 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/UnbindRecordingOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/UnbindRecordingOperation.java @@ -47,9 +47,9 @@ public class UnbindRecordingOperation implements /* * (non-Javadoc) * - * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[]) */ - public CompensatingTransactionRollbackOperation performOperation( + public CompensatingTransactionRollbackOperation recordOperation( Object[] args) { Name dn = LdapUtils.getFirstArgumentAsName(args); DirContextAdapter ctx = (DirContextAdapter) ldapOperations.lookup(dn);