diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/AbstractCompensatingTransactionDataManager.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/AbstractCompensatingTransactionDataManager.java new file mode 100644 index 00000000..1a24d8e4 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/AbstractCompensatingTransactionDataManager.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2007 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.support.transaction; + +import java.util.Stack; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Abstract superclass for {@link CompensatingTransactionDataManager} + * implementations. Keeps track of the basic plumbing and defines the + * {@link #getRecordingOperation(String)} method for subclasses to implement. + * + * @author Mattias Arthursson + */ +public abstract class AbstractCompensatingTransactionDataManager implements + CompensatingTransactionDataManager { + + private static Log log = LogFactory + .getLog(AbstractCompensatingTransactionDataManager.class); + + private Stack rollbackOperations = new Stack(); + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionDataManager#operationPerformed(java.lang.String, + * java.lang.Object[]) + */ + public void operationPerformed(String operation, Object[] params) { + CompensatingTransactionRecordingOperation recordingOperation = getRecordingOperation(operation); + rollbackOperations.push(recordingOperation.performOperation(params)); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionDataManager#rollback() + */ + public void rollback() { + log.debug("Performing rollback"); + while (!rollbackOperations.isEmpty()) { + CompensatingTransactionRollbackOperation rollbackOperation = (CompensatingTransactionRollbackOperation) rollbackOperations + .pop(); + rollbackOperation.rollback(); + } + } + + /** + * Get a {@link CompensatingTransactionRecordingOperation} to record the + * operation corresponding to the supplied operation. + * + * @param operation + * the operation (method) to be invoked. + * @return a CompensatingTransactionRecordingOperation for handling the + * supplied operation. + */ + protected abstract CompensatingTransactionRecordingOperation getRecordingOperation( + String operation); + + /** + * Get the rollback operations. Package protected for testing purposes. + * + * @return the rollback operations. + */ + protected Stack getRollbackOperations() { + return rollbackOperations; + } + + /** + * Set the rollback operations. Package protected - for testing purposes + * only. + * + * @param rollbackOperations + * the rollback operations. + */ + void setRollbackOperations(Stack rollbackOperations) { + this.rollbackOperations = rollbackOperations; + } + +} 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 d2783a36..0b223e0c 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 @@ -1,18 +1,53 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.Name; import org.springframework.ldap.LdapOperations; +/** + * A {@link CompensatingTransactionRecordingOperation} to manage LDAP bind + * operations. The corresponding + * {@link CompensatingTransactionRollbackOperation} is + * {@link UnbindRollbackOperation}. + * + * @author Mattias Arthursson + */ public class BindRecordingOperation implements CompensatingTransactionRecordingOperation { private LdapOperations ldapOperations; + /** + * Constructor. + * + * @param ldapOperations + * {@link LdapOperations} to use for supplying to the + * corresponding rollback operation. + */ public BindRecordingOperation(LdapOperations ldapOperations) { this.ldapOperations = ldapOperations; } + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + */ public CompensatingTransactionRollbackOperation performOperation( Object[] args) { Name dn = LdapUtils.getFirstArgumentAsName(args); diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/BindRollbackOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/BindRollbackOperation.java index 500187f9..66db9f0a 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/BindRollbackOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/BindRollbackOperation.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.Name; @@ -7,6 +22,13 @@ import org.apache.commons.logging.LogFactory; import org.springframework.ldap.LdapOperations; import org.springframework.ldap.support.DirContextOperations; +/** + * A {@link CompensatingTransactionRollbackOperation} to rollback an unbind + * operation. This implementation performs a bind operation using the + * {@link DirContextOperations} instance supplied on construction. + * + * @author Mattias Arthursson + */ public class BindRollbackOperation implements CompensatingTransactionRollbackOperation { @@ -16,12 +38,28 @@ public class BindRollbackOperation implements private DirContextOperations dirContextOperations; + /** + * Constructor. + * + * @param ldapOperations + * The {@link LdapOperations} to use for performing the rollback + * operation. + * @param dirContextOperations + * a {@link DirContextOperations} instance to be used for + * obtaining the DN of the affected entry and to be used when + * performing the rollback, binding it to the DN. + */ public BindRollbackOperation(LdapOperations ldapOperations, DirContextOperations dirContextOperations) { this.ldapOperations = ldapOperations; this.dirContextOperations = dirContextOperations; } + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRollbackOperation#rollback() + */ public void rollback() { Name dn = dirContextOperations.getDn(); try { 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 d84232d1..5c272493 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 @@ -1,6 +1,44 @@ +/* + * Copyright 2002-2007 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.support.transaction; +/** + * A CompensatingTransactionDataManager implementation records operations that + * are performed in a transaction and keeps track of compensating actions + * necessary for rolling back each individual operation. + * + * @author Mattias Arthursson + * + */ 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. + * + * @param operation + * the method to be invoked. + * @param params + * arguments supplied to the operation. + */ public void operationPerformed(String operation, Object[] params); + + /** + * Rollback all recorded operations, by performing each of the recorded + * rollback operations. + */ public void rollback(); } diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionRecordingOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionRecordingOperation.java index 4b230152..ac53f35d 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionRecordingOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionRecordingOperation.java @@ -1,5 +1,24 @@ package org.springframework.ldap.support.transaction; +/** + * An implementation of this interface is responsible for recording data and + * supplying a {@link CompensatingTransactionRollbackOperation} to be invoked + * should the operation need to be rolled back. Recording of an operation should + * not fail (throwing an Exception), but rather log the result. + * + * @author Mattias Arthursson + */ public interface CompensatingTransactionRecordingOperation { - public CompensatingTransactionRollbackOperation performOperation(Object[] args); + /** + * Record information about the operation performed and return a + * corresponding {@link CompensatingTransactionRollbackOperation} to be used + * if the operation would need to be rolled back. + * + * @param args + * The arguments that have been sent to the operation. + * @return A {@link CompensatingTransactionRollbackOperation} to be used if + * the recorded operation should need to be rolled back. + */ + public CompensatingTransactionRollbackOperation performOperation( + Object[] args); } diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionRollbackOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionRollbackOperation.java index b30f7200..1c28e8da 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionRollbackOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/CompensatingTransactionRollbackOperation.java @@ -1,5 +1,35 @@ +/* + * Copyright 2002-2007 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.support.transaction; +/** + * Responsible for rolling back a single operation, restoring the state of the + * target as it was before the operation was performed. Instances of this + * interface are constructed by + * {@link CompensatingTransactionRecordingOperation} objects, supplying them + * with the information necessary for rollback. + * + * @author Mattias Arthursson + */ public interface CompensatingTransactionRollbackOperation { + /** + * Rollback the operation, restoring state of the target as it was before + * the operation was performed using the information supplied on creation of + * this instance (supplied by a + * {@link CompensatingTransactionRecordingOperation}). + */ public void rollback(); } 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 d1596fb9..663967a8 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 @@ -1,3 +1,18 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.NamingException; @@ -14,14 +29,33 @@ import org.springframework.transaction.support.TransactionSynchronizationManager /** * TransactionManager for managing LDAP transactions. Since transactions are not - * supported in the LDAP protocol, this class and its collaborators aims to - * provide compensating transactions instead. TODO: improve javadoc. + * supported in the LDAP protocol this class and its collaborators aims to + * provide compensating transactions instead. + *

+ * A transaction is tied to a {@link ContextSource}, to be supplied to the + * {@link #setContextSource(ContextSource)} method. While the actual + * ContextSource used by the target LdapTemplate instance needs to be of the + * type {@link TransactionAwareContextSourceProxy}, the ContextSource supplied + * to this class should be the actual target ContextSource. + *

+ *

+ * This class creates a {@link ContextSourceTransactionObject} as the + * implementation specific Transaction object. The actual transaction data is + * managed by a {@link DirContextHolder} and its collaborating + * {@link LdapCompensatingTransactionDataManager}. Using a + * {@link TransactionAwareContextSourceProxy} all modify operations (bind, + * rebind, modifyAttributes, unbind) will result in corresponding rollback + * operations to be recorded and these operations will be invoked should the + * transaction be rolled back. + *

* * @author Mattias Arthursson */ public class ContextSourceTransactionManager extends AbstractPlatformTransactionManager { + private static final long serialVersionUID = -4308820955185446535L; + private static Log log = LogFactory .getLog(ContextSourceTransactionManager.class); diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/ContextSourceTransactionObject.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/ContextSourceTransactionObject.java index 7376cf5c..d6e83f06 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/ContextSourceTransactionObject.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/ContextSourceTransactionObject.java @@ -1,21 +1,53 @@ -package org.springframework.ldap.support.transaction; +/* + * Copyright 2002-2007 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.support.transaction; /** - * Transaction object for ContextSourceTransactionManager. + * Transaction object for ContextSourceTransactionManager. Keeps a reference to + * the {@link DirContextHolder} associated with the current transaction. * * @author Mattias Arthursson */ public class ContextSourceTransactionObject { private DirContextHolder contextHolder; + /** + * Constructor. + * + * @param contextHolder + * the DirContextHolder associated with the current transaction. + */ public ContextSourceTransactionObject(DirContextHolder contextHolder) { this.contextHolder = contextHolder; } + /** + * Get the DirContextHolder. + * + * @return the DirContextHolder. + */ public DirContextHolder getContextHolder() { return contextHolder; } + /** + * Set the DirContextHolder associated with the current transaction.s + * + * @param contextHolder + * the DirContextHolder associated with the current transaction. + */ public void setContextHolder(DirContextHolder contextHolder) { this.contextHolder = contextHolder; } 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 70f2f00a..42b58e03 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 @@ -1,26 +1,68 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.directory.DirContext; import org.springframework.transaction.support.ResourceHolderSupport; +/** + * Keeps track of the transaction DirContext. The same DirContext instance will + * be reused throughout a transaction. Also keeps a + * {@link CompensatingTransactionDataManager}, responsible for keeping track of + * all changes and storing compensating rollback operations, should the + * transaction need to be rolled back. + * + * @author Mattias Arthursson + * + */ public class DirContextHolder extends ResourceHolderSupport { private DirContext ctx; private CompensatingTransactionDataManager transactionDataManager; - public void setCtx(DirContext ctx) { - this.ctx = ctx; - this.transactionDataManager = new LdapCompensatingTransactionDataManager( - ctx); - } - + /** + * Constructor. + * + * @param ctx + * The DirContext associated with the current transaction. + */ public DirContextHolder(DirContext ctx) { this.ctx = ctx; this.transactionDataManager = new LdapCompensatingTransactionDataManager( ctx); } + /** + * Set the DirContext associated with the current transaction. + * + * @param ctx + * the DirContext associated with the current transaction. + */ + public void setCtx(DirContext ctx) { + this.ctx = ctx; + this.transactionDataManager = new LdapCompensatingTransactionDataManager( + ctx); + } + + /** + * Get the DirContext associated with the current transaction. + * + * @return + */ public DirContext getCtx() { return ctx; } 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 836cd35c..9ab2b7ad 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 @@ -1,7 +1,33 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.directory.DirContext; +/** + * Helper interface to be able to get hold of the target DirContext from proxies + * created by {@link TransactionAwareContextSourceProxy}. + * + * @author Mattias Arthursson + */ public interface DirContextProxy extends DirContext { + /** + * Get the target DirContext of the proxy. + * + * @return the target 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 f8df1e1e..c8692676 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,10 +1,24 @@ +/* + * Copyright 2002-2007 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.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; @@ -16,15 +30,33 @@ import org.springframework.ldap.ContextSource; import org.springframework.ldap.LdapOperations; import org.springframework.ldap.LdapTemplate; -public class LdapCompensatingTransactionDataManager implements - CompensatingTransactionDataManager { +/** + * A {@link CompensatingTransactionDataManager} for LDAP operations. Called by + * {@link TransactionAwareDirContextInvocationHandler} to record LDAP operations + * and keep track of rollback operations. Manages bind, + * rebind, unbind, rename and + * modifyAttributes operations. All created + * {@link CompensatingTransactionRecordingOperation} objects (and consequently, + * all {@link CompensatingTransactionRollbackOperation} objects created by + * these) will use the transactional DirContext instance to perform all their + * necessary operations, via an internal {@link LdapTemplate} instance referring + * a special ContextSource implementation.. + * + * @author Mattias Arthursson + */ +public class LdapCompensatingTransactionDataManager extends + AbstractCompensatingTransactionDataManager { private static Log log = LogFactory .getLog(LdapCompensatingTransactionDataManager.class); - private Stack rollbackOperations = new Stack(); - private LdapOperations ldapOperations; + /** + * Constructor. + * + * @param ctx + * The transactional DirContext. + */ public LdapCompensatingTransactionDataManager(DirContext ctx) { this.ldapOperations = new LdapTemplate(new SingleContextSource(ctx)); } @@ -32,48 +64,8 @@ public class LdapCompensatingTransactionDataManager implements /* * (non-Javadoc) * - * @see org.springframework.ldap.support.CompensatingTransactionDataManager#operationPerformed(java.lang.String, - * java.lang.Object[]) + * @see org.springframework.ldap.support.transaction.AbstractCompensatingTransactionDataManager#getRecordingOperation(java.lang.String) */ - public void operationPerformed(String operation, Object[] params) { - CompensatingTransactionRecordingOperation recordingOperation = getRecordingOperation(operation); - rollbackOperations.push(recordingOperation.performOperation(params)); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.support.CompensatingTransactionDataManager#rollback() - */ - public void rollback() { - log.debug("Performing rollback"); - while (!rollbackOperations.isEmpty()) { - CompensatingTransactionRollbackOperation rollbackOperation = (CompensatingTransactionRollbackOperation) rollbackOperations - .pop(); - rollbackOperation.rollback(); - } - } - - /** - * Get the rollback operations. Package protected for testing purposes. - * - * @return the rollback operations. - */ - Stack getRollbackOperations() { - return rollbackOperations; - } - - /** - * Set the rollback operations. Package protected - for testing purposes - * only. - * - * @param rollbackOperations - * the rollback operations. - */ - void setRollbackOperations(Stack rollbackOperations) { - this.rollbackOperations = rollbackOperations; - } - protected CompensatingTransactionRecordingOperation getRecordingOperation( String operation) { if (StringUtils.equals(operation, LdapUtils.BIND_METHOD_NAME)) { @@ -108,17 +100,40 @@ public class LdapCompensatingTransactionDataManager implements this.ldapOperations = ldapOperations; } + /** + * A {@link ContextSource} implementation using returning + * {@link NonClosingDirContextInvocationHandler} proxies on the same + * DirContext instance for each call. + * + * @author Mattias Arthursson + */ static class SingleContextSource implements ContextSource { private DirContext ctx; + /** + * Constructor. + * + * @param ctx + * the target DirContext. + */ public SingleContextSource(DirContext ctx) { this.ctx = ctx; } + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.ContextSource#getReadOnlyContext() + */ public DirContext getReadOnlyContext() throws DataAccessException { return getNonClosingDirContextProxy(ctx); } + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.ContextSource#getReadWriteContext() + */ public DirContext getReadWriteContext() throws DataAccessException { return getNonClosingDirContextProxy(ctx); } @@ -131,6 +146,13 @@ public class LdapCompensatingTransactionDataManager implements } } + /** + * A proxy for DirContext forwarding all operation to the target DirContext, + * but making sure that no close operations will be + * performed. + * + * @author Mattias Arthursson + */ public static class NonClosingDirContextInvocationHandler implements InvocationHandler { @@ -140,6 +162,12 @@ public class LdapCompensatingTransactionDataManager implements this.target = target; } + /* + * (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 { 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 06ac4fa3..e6bfb263 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 @@ -1,3 +1,18 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.Name; 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 0fb6f938..e5c3adda 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 @@ -1,3 +1,18 @@ +/* + * Copyright 2002-2007 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.support.transaction; import java.util.HashSet; @@ -15,6 +30,13 @@ import org.springframework.ldap.AttributesMapper; import org.springframework.ldap.LdapOperations; import org.springframework.util.Assert; +/** + * A {@link CompensatingTransactionRecordingOperation} keeping track of + * modifyAttributes operations, creating corresponding + * {@link ModifyAttributesRollbackOperation} instances for rollback. + * + * @author Mattias Arthursson + */ public class ModifyAttributesRecordingOperation implements CompensatingTransactionRecordingOperation { @@ -24,6 +46,11 @@ public class ModifyAttributesRecordingOperation implements this.ldapOperations = ldapOperations; } + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + */ public CompensatingTransactionRollbackOperation performOperation( Object[] args) { Assert.notNull(args); @@ -58,6 +85,13 @@ public class ModifyAttributesRecordingOperation implements rollbackItems); } + /** + * Get an {@link AttributesMapper} that just returns the supplied + * Attributes. + * + * @return the {@link AttributesMapper} to use for getting the current + * Attributes of the target DN. + */ AttributesMapper getAttributesMapper() { return new AttributesMapper() { public Object mapFromAttributes(Attributes attributes) @@ -67,6 +101,17 @@ public class ModifyAttributesRecordingOperation implements }; } + /** + * Get a ModificationItem to use for rollback of the supplied modification. + * + * @param originalAttributes + * All Attributes of the target DN that are affected of any of + * the ModificationItems. + * @param modificationItem + * the ModificationItem to create a rollback item for. + * @return A ModificationItem to use for rollback of the supplied + * ModificationItem. + */ protected ModificationItem getCompensatingModificationItem( Attributes originalAttributes, ModificationItem modificationItem) { Attribute modificationAttribute = modificationItem.getAttribute(); diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/ModifyAttributesRollbackOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/ModifyAttributesRollbackOperation.java index 0367419d..a975638c 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/ModifyAttributesRollbackOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/ModifyAttributesRollbackOperation.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.Name; @@ -7,6 +22,14 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.ldap.LdapOperations; +/** + * A {@link CompensatingTransactionRollbackOperation} to rollback a + * modifyAttributes operation. Performs a + * modifyAttributes operation using the DN of the target entry + * and ModificationItems undoing the modifications of the recorded operation. + * + * @author Mattias Arthursson + */ public class ModifyAttributesRollbackOperation implements CompensatingTransactionRollbackOperation { @@ -19,6 +42,17 @@ public class ModifyAttributesRollbackOperation implements private ModificationItem[] modificationItems; + /** + * Constructor. + * + * @param ldapOperations + * The {@link LdapOperations} to use to perform the rollback + * operation. + * @param dn + * the DN of the target entry. + * @param modificationItems + * the ModificationItems to undo the recorded operation. + */ public ModifyAttributesRollbackOperation(LdapOperations ldapOperations, Name dn, ModificationItem[] modificationItems) { this.ldapOperations = ldapOperations; @@ -26,6 +60,11 @@ public class ModifyAttributesRollbackOperation implements this.modificationItems = modificationItems; } + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRollbackOperation#rollback() + */ public void rollback() { try { ldapOperations.modifyAttributes(dn, modificationItems); 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 01c52ad4..3680d42f 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 @@ -1,8 +1,38 @@ +/* + * Copyright 2002-2007 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.support.transaction; +/** + * A {@link CompensatingTransactionRecordingOperation} performing nothing, + * returning a {@link NullRollbackOperation} regardless of the input. Instances + * of this class will be created if the + * {@link CompensatingTransactionDataManager} cannot determine any appropriate + * {@link CompensatingTransactionRecordingOperation} for the current operation. + * + * @author Mattias Arthursson + * + */ public class NullRecordingOperation implements CompensatingTransactionRecordingOperation { + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + */ public CompensatingTransactionRollbackOperation performOperation( Object[] args) { return new NullRollbackOperation(); diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/NullRollbackOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/NullRollbackOperation.java index f31bd862..5ca503a2 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/NullRollbackOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/NullRollbackOperation.java @@ -1,13 +1,38 @@ +/* + * Copyright 2002-2007 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.support.transaction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +/** + * A {@link CompensatingTransactionRollbackOperation} that performs nothing. + * + * @author Mattias Arthursson + */ public class NullRollbackOperation implements CompensatingTransactionRollbackOperation { private static Log log = LogFactory.getLog(NullRollbackOperation.class); + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRollbackOperation#rollback() + */ public void rollback() { log.info("Rolling back null operation"); } 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 f0b08a94..d8cc02a4 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 @@ -1,3 +1,18 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.Name; @@ -7,6 +22,13 @@ import org.apache.commons.logging.LogFactory; import org.springframework.ldap.LdapOperations; import org.springframework.ldap.support.DirContextAdapter; +/** + * A {@link CompensatingTransactionRecordingOperation} keeping track of a rebind + * operation. Creates {@link RebindRollbackOperation} objects in + * {@link #performOperation(Object[])}. + * + * @author Mattias Arthursson + */ public class RebindRecordingOperation implements CompensatingTransactionRecordingOperation { @@ -14,10 +36,22 @@ public class RebindRecordingOperation implements private LdapOperations ldapOperations; + /** + * Constructor. + * + * @param ldapOperations + * {@link LdapOperations} to use for getting the rollback + * information and supply to the {@link RebindRollbackOperation}. + */ public RebindRecordingOperation(LdapOperations ldapOperations) { this.ldapOperations = ldapOperations; } + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[]) + */ public CompensatingTransactionRollbackOperation performOperation( Object[] args) { Name dn = LdapUtils.getFirstArgumentAsName(args); diff --git a/sandbox/src/main/java/org/springframework/ldap/support/transaction/RebindRollbackOperation.java b/sandbox/src/main/java/org/springframework/ldap/support/transaction/RebindRollbackOperation.java index 987946fd..4e298ace 100644 --- a/sandbox/src/main/java/org/springframework/ldap/support/transaction/RebindRollbackOperation.java +++ b/sandbox/src/main/java/org/springframework/ldap/support/transaction/RebindRollbackOperation.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-2007 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.support.transaction; import javax.naming.Name; @@ -7,6 +22,13 @@ import org.apache.commons.logging.LogFactory; import org.springframework.ldap.LdapOperations; import org.springframework.ldap.support.DirContextOperations; +/** + * A {@link CompensatingTransactionRollbackOperation} to rollback a rebind + * operation, performing a rebind operation using the supplied + * {@link DirContextOperations} object. + * + * @author Mattias Arthursson + */ public class RebindRollbackOperation implements CompensatingTransactionRollbackOperation { @@ -16,6 +38,15 @@ public class RebindRollbackOperation implements private DirContextOperations dirContextOperations; + /** + * Constructor. + * + * @param ldapOperations + * the {@link LdapOperations} to use to perform the rollback. + * @param dirContextOperations + * the {@link DirContextOperations} to use as input to the rebind + * operation performing the rollback. + */ public RebindRollbackOperation(LdapOperations ldapOperations, DirContextOperations dirContextOperations) { this.ldapOperations = ldapOperations; @@ -41,6 +72,11 @@ public class RebindRollbackOperation implements return ldapOperations; } + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.transaction.CompensatingTransactionRollbackOperation#rollback() + */ public void rollback() { Name dn = dirContextOperations.getDn(); try { diff --git a/sandbox/src/test/java/org/springframework/ldap/support/transaction/LdapCompensatingTransactionDataManagerTest.java b/sandbox/src/test/java/org/springframework/ldap/support/transaction/LdapCompensatingTransactionDataManagerTest.java index 2b5aff7a..e4a9e2e0 100644 --- a/sandbox/src/test/java/org/springframework/ldap/support/transaction/LdapCompensatingTransactionDataManagerTest.java +++ b/sandbox/src/test/java/org/springframework/ldap/support/transaction/LdapCompensatingTransactionDataManagerTest.java @@ -65,7 +65,7 @@ public class LdapCompensatingTransactionDataManagerTest extends TestCase { } public void testOperationPerformed() { - LdapCompensatingTransactionDataManager tested = new LdapCompensatingTransactionDataManager( + AbstractCompensatingTransactionDataManager tested = new LdapCompensatingTransactionDataManager( null) { protected CompensatingTransactionRecordingOperation getRecordingOperation( String operation) { @@ -88,7 +88,7 @@ public class LdapCompensatingTransactionDataManagerTest extends TestCase { } public void testRollback() { - LdapCompensatingTransactionDataManager tested = new LdapCompensatingTransactionDataManager( + AbstractCompensatingTransactionDataManager tested = new LdapCompensatingTransactionDataManager( null); tested.getRollbackOperations().push(rollbackOperationMock);