ModifyAttributesOperationRecorder implements
        CompensatingTransactionOperationRecorder { public CompensatingTransactionOperationExecutor recordOperation( Object[] args) { Assert.notNull(args); Name dn = LdapTransactionUtils.getFirstArgumentAsName(args); if (args.length != 2 || !(args[1] instanceof ModificationItem[])) { throw new IllegalArgumentException( "Unexpected arguments to ModifyAttributes operation"); } ModificationItem[] incomingModifications = (ModificationItem[]) args[1]; Set<String> set = new HashSet<String>(); for (ModificationItem incomingModification : incomingModifications) { set.add(incomingModification.getAttribute().getID()); } String[] attributeNameArray = set.toArray(new String[set.size()]); IncrementalAttributesMapper<?> attributesMapper = getAttributesMapper(attributeNameArray); while (attributesMapper.hasMore()) { ldapOperations.lookup(dn, attributesMapper.getAttributesForLookup(), attributesMapper); } Attributes currentAttributes = attributesMapper.getCollectedAttributes(); ModificationItem[] rollbackItems = new ModificationItem[incomingModifications.length]; for (int i = 0; i < incomingModifications.length; i++) { rollbackItems[i] = getCompensatingModificationItem( currentAttributes, incomingModifications[i]); } return new ModifyAttributesOperationExecutor(ldapOperations, dn, incomingModifications, rollbackItems); } ModifyAttributesOperationRecorder(LdapOperations ldapOperations); CompensatingTransactionOperationExecutor recordOperation(
            Object[] args);  }
@Test public void testRecordOperation() { final ModificationItem incomingItem = new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute("attribute1")); ModificationItem[] incomingMods = new ModificationItem[]{incomingItem}; final ModificationItem compensatingItem = new ModificationItem( DirContext.ADD_ATTRIBUTE, new BasicAttribute("attribute2")); final Attributes expectedAttributes = new BasicAttributes(); tested = new ModifyAttributesOperationRecorder(ldapOperationsMock) { IncrementalAttributesMapper getAttributesMapper(String[] attributeNames) { return attributesMapperMock; } protected ModificationItem getCompensatingModificationItem( Attributes originalAttributes, ModificationItem modificationItem) { assertThat(originalAttributes).isSameAs(expectedAttributes); assertThat(modificationItem).isSameAs(incomingItem); return compensatingItem; } }; LdapName expectedName = LdapUtils.newLdapName("cn=john doe"); when(attributesMapperMock.hasMore()).thenReturn(true, false); when(attributesMapperMock.getAttributesForLookup()) .thenReturn(new String[]{"attribute1"}); when(ldapOperationsMock.lookup(expectedName, new String[]{"attribute1"}, attributesMapperMock)) .thenReturn(expectedAttributes); when(attributesMapperMock.getCollectedAttributes()) .thenReturn(expectedAttributes); CompensatingTransactionOperationExecutor operation = tested .recordOperation(new Object[]{expectedName, incomingMods}); assertThat(operation instanceof ModifyAttributesOperationExecutor).isTrue(); ModifyAttributesOperationExecutor rollbackOperation = (ModifyAttributesOperationExecutor) operation; assertThat(rollbackOperation.getDn()).isSameAs(expectedName); assertThat(rollbackOperation.getLdapOperations()).isSameAs(ldapOperationsMock); ModificationItem[] actualModifications = rollbackOperation.getActualModifications(); assertThat(actualModifications.length).isEqualTo(incomingMods.length); assertThat(actualModifications[0]).isEqualTo(incomingMods[0]); assertThat(rollbackOperation.getCompensatingModifications().length).isEqualTo(1); assertThat(rollbackOperation.getCompensatingModifications()[0]).isSameAs(compensatingItem); }