Introduced ContextSourceTransactionManagerDelegate and ContextSourceAndDataSourceTransactionManager.

This commit is contained in:
Mattias Arthursson
2007-02-12 17:28:24 +00:00
parent 1c59ec4d80
commit 3fffbf1408
6 changed files with 335 additions and 255 deletions

View File

@@ -49,5 +49,7 @@
<classpathentry kind="lib" path="lib/test/backport-util-concurrent.jar"/>
<classpathentry kind="lib" path="lib/global/spring-ldap.jar" sourcepath="lib/source/spring-ldap-src.zip"/>
<classpathentry kind="lib" path="lib/test/shared-asn1-codec.jar"/>
<classpathentry kind="lib" path="lib/test/hsqldb.jar"/>
<classpathentry kind="lib" path="lib/test/dbunit.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -1,105 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<ivy-module version="1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.jayasoft.org/misc/ivy/samples/ivy.xsd">
<info organisation="org.springframework" module="spring-ldap-sandbox" />
<info organisation="org.springframework"
module="spring-ldap-sandbox" />
<configurations>
<conf name="default" extends="global" />
<conf name="global" visibility="private" />
<conf name="buildtime" visibility="private" />
<conf name="test" visibility="private" />
<conf name="source" visibility="public" />
</configurations>
<configurations>
<conf name="default" extends="global" />
<conf name="global" visibility="private" />
<conf name="buildtime" visibility="private" />
<conf name="test" visibility="private" />
<conf name="source" visibility="public" />
</configurations>
<publications>
<artifact name="spring-ldap-sandbox" type="jar" conf="default" />
<artifact name="spring-ldap-sandbox-src" type="zip" conf="source" />
<artifact name="spring-ldap-sandbox-src" type="zip"
conf="source" />
</publications>
<dependencies defaultconf="global->default">
<!-- global (core) dependencies -->
<dependency org="commons-logging" name="commons-logging" rev="1.0.4" />
<dependency org="commons-lang" name="commons-lang" rev="2.1" />
<dependency org="commons-collections" name="commons-collections" rev="3.1" />
<dependency org="org.springframework" name="spring-ldap" rev="latest.integration"
conf="global->default;source->source"/>
<dependency org="org.springframework" name="spring-beans" rev="2.0.2"/>
<dependency org="org.springframework" name="spring-core" rev="2.0.2"/>
<dependency org="org.springframework" name="spring-context" rev="2.0.2"/>
<dependency org="org.springframework" name="spring-dao" rev="2.0.2"/>
<dependency org="org.springframework" name="spring-src" rev="2.0.2" conf="source->source">
<artifact name="spring-src" type="zip"/>
</dependency>
<dependency org="com.sun" name="ldapbp" rev="1.0" />
<!-- build time only dependencies -->
<dependency org="org.acegisecurity" name="acegi-security" rev="1.0.1"
conf="buildtime->default" />
<!-- kind of nasty, acegi needs some 1.2.7 stuff, so we override with newer! -->
<dependency org="org.springframework" name="spring-jdbc" rev="2.0.2"
conf="buildtime->default" />
<dependency org="org.springframework" name="spring-remoting" rev="2.0.2"
conf="buildtime->default" />
<dependency org="org.springframework" name="spring-support" rev="2.0.2"
conf="buildtime->default" />
<dependency org="org.springframework" name="spring-jpa" rev="2.0.2"
conf="buildtime->default" />
<dependencies defaultconf="global->default">
<!-- global (core) dependencies -->
<dependency org="commons-logging" name="commons-logging"
rev="1.0.4" />
<dependency org="commons-lang" name="commons-lang" rev="2.1" />
<dependency org="commons-collections" name="commons-collections"
rev="3.1" />
<dependency org="org.springframework" name="spring-ldap"
rev="latest.integration" conf="global->default;source->source" />
<dependency org="org.springframework" name="spring-beans"
rev="2.0.2" />
<dependency org="org.springframework" name="spring-core"
rev="2.0.2" />
<dependency org="org.springframework" name="spring-context"
rev="2.0.2" />
<dependency org="org.springframework" name="spring-dao"
rev="2.0.2" />
<dependency org="org.springframework" name="spring-src"
rev="2.0.2" conf="source->source">
<artifact name="spring-src" type="zip" />
</dependency>
<dependency org="com.sun" name="ldapbp" rev="1.0" />
<!-- test time only dependencies -->
<dependency org="com.cenqua.clover" name="clover" rev="1.3.12" conf="test->default" />
<dependency org="org.springframework" name="spring-mock" rev="2.0.2"
conf="test->default"/>
<dependency org="gsbase" name="gsbase" rev="2.0.1" conf="test->default"/>
<dependency org="junit" name="junit" rev="3.8.1" conf="test->default"/>
<dependency org="junit-addons" name="junit-addons" rev="1.4" conf="test->default"/>
<dependency org="easymock" name="easymock" rev="1.2_Java1.3" conf="test->default"/>
<dependency org="ehcache" name="ehcache" rev="1.1" conf="test->default" />
<dependency org="net.sf.ehcache" name="ehcache-constructs" rev="0.6" conf="test->default" />
<dependency org="jexcelapi" name="jxl" rev="2.5.9" conf="test->default" />
<dependency org="org.ddsteps" name="DDSteps" rev="1.1" conf="test->default" />
<dependency org="cglib" name="cglib-nodep" rev="2.1_3" conf="test->default"/>
<dependency org="org.springframework" name="spring-aop" rev="2.0.2" conf="test->default"/>
<dependency org="aopalliance" name="aopalliance" rev="1.0" conf="test->default" />
<!-- Test dependencies for Apache Directory Server -->
<dependency org="org.apache.directory.server" name="apacheds-core" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.directory.server" name="apacheds-core-shared" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.directory.server" name="apacheds-server-jndi" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.directory.server" name="apacheds-server-main" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.directory.server" name="apacheds-protocol-shared" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.directory.server" name="apacheds-protocol-changepw" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.directory.server" name="apacheds-protocol-kerberos" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.directory.server" name="apacheds-kerberos-shared" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.directory.server" name="apacheds-protocol-ldap" rev="1.0.0"
conf="test->default"/>
<!-- build time only dependencies -->
<dependency org="org.acegisecurity" name="acegi-security"
rev="1.0.1" conf="buildtime->default" />
<!-- kind of nasty, acegi needs some 1.2.7 stuff, so we override with newer! -->
<dependency org="org.springframework" name="spring-jdbc"
rev="2.0.2" conf="buildtime->default" />
<dependency org="org.springframework" name="spring-remoting"
rev="2.0.2" conf="buildtime->default" />
<dependency org="org.springframework" name="spring-support"
rev="2.0.2" conf="buildtime->default" />
<dependency org="org.springframework" name="spring-jpa"
rev="2.0.2" conf="buildtime->default" />
<dependency org="org.apache.directory.shared" name="shared-asn1" rev="0.9.5.3"
conf="test->default"/>
<dependency org="org.apache.directory.shared" name="shared-asn1-codec" rev="0.9.5.3"
conf="test->default"/>
<dependency org="org.apache.directory.shared" name="shared-ldap" rev="0.9.5.3"
conf="test->default"/>
<!-- test time only dependencies -->
<dependency org="com.cenqua.clover" name="clover" rev="1.3.12"
conf="test->default" />
<dependency org="org.springframework" name="spring-mock"
rev="2.0.2" conf="test->default" />
<dependency org="gsbase" name="gsbase" rev="2.0.1"
conf="test->default" />
<dependency org="junit" name="junit" rev="3.8.1"
conf="test->default" />
<dependency org="junit-addons" name="junit-addons" rev="1.4"
conf="test->default" />
<dependency org="easymock" name="easymock" rev="1.2_Java1.3"
conf="test->default" />
<dependency org="ehcache" name="ehcache" rev="1.1"
conf="test->default" />
<dependency org="net.sf.ehcache" name="ehcache-constructs"
rev="0.6" conf="test->default" />
<dependency org="jexcelapi" name="jxl" rev="2.5.9"
conf="test->default" />
<dependency org="org.ddsteps" name="DDSteps" rev="1.1"
conf="test->default" />
<dependency org="cglib" name="cglib-nodep" rev="2.1_3"
conf="test->default" />
<dependency org="org.springframework" name="spring-aop"
rev="2.0.2" conf="test->default" />
<dependency org="aopalliance" name="aopalliance" rev="1.0"
conf="test->default" />
<dependency org="hsqldb" name="hsqldb" rev="1.8.0.7"
conf="test->default" />
<dependency org="org.dbunit" name="dbunit" rev="2.2"
conf="test->default" />
<dependency org="log4j" name="log4j" rev="1.2.9" conf="test->default" />
<dependency org="antlr" name="antlr" rev="2.7.2" conf="test->default" />
<dependency org="jdbm" name="jdbm" rev="1.0" conf="test->default" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.0"
conf="test->default" />
<dependency org="org.apache.mina" name="mina-core" rev="1.0.0"
conf="test->default"/>
<dependency org="org.apache.mina" name="mina-filter-ssl" rev="1.0.0"
conf="test->default"/>
<!-- End test dependencies for Apache Directory Server -->
<!-- Test dependencies for Apache Directory Server -->
<dependency org="org.apache.directory.server"
name="apacheds-core" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-core-shared" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-server-jndi" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-server-main" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-protocol-shared" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-protocol-changepw" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-protocol-kerberos" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-kerberos-shared" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.server"
name="apacheds-protocol-ldap" rev="1.0.0" conf="test->default" />
<dependency org="org.apache.directory.shared" name="shared-asn1"
rev="0.9.5.3" conf="test->default" />
<dependency org="org.apache.directory.shared"
name="shared-asn1-codec" rev="0.9.5.3" conf="test->default" />
<dependency org="org.apache.directory.shared" name="shared-ldap"
rev="0.9.5.3" conf="test->default" />
<dependency org="log4j" name="log4j" rev="1.2.9"
conf="test->default" />
<dependency org="antlr" name="antlr" rev="2.7.2"
conf="test->default" />
<dependency org="jdbm" name="jdbm" rev="1.0"
conf="test->default" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.0"
conf="test->default" />
<dependency org="org.apache.mina" name="mina-core" rev="1.0.0"
conf="test->default" />
<dependency org="org.apache.mina" name="mina-filter-ssl"
rev="1.0.0" conf="test->default" />
<!-- End test dependencies for Apache Directory Server -->
</dependencies>
</dependencies>
</ivy-module>

View File

@@ -1,23 +1,35 @@
package org.springframework.ldap.transaction.core;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.ldap.LdapServerManager;
import org.springframework.ldap.NameNotFoundException;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
import org.springframework.transaction.support.TransactionSynchronizationManager;
public class ContextSourceTransactionManagerIntegrationTest extends
/**
* Integration tests for {@link ContextSourceAndDataSourceTransactionManager}.
*
* @author Mattias Arthursson
*/
public class ContextSourceAndDataSourceTransactionManagerIntegrationTest extends
AbstractDependencyInjectionSpringContextTests {
private static Log log = LogFactory
.getLog(ContextSourceTransactionManagerIntegrationTest.class);
.getLog(ContextSourceAndDataSourceTransactionManagerIntegrationTest.class);
public ContextSourceTransactionManagerIntegrationTest() {
public ContextSourceAndDataSourceTransactionManagerIntegrationTest() {
setAutowireMode(AbstractDependencyInjectionSpringContextTests.AUTOWIRE_BY_NAME);
}
@@ -25,6 +37,8 @@ public class ContextSourceTransactionManagerIntegrationTest extends
private LdapTemplate ldapTemplate;
private JdbcTemplate jdbcTemplate;
private LdapServerManager ldapServerManager;
public void setLdapServerManager(LdapServerManager ldapServerManager) {
@@ -44,7 +58,19 @@ public class ContextSourceTransactionManagerIntegrationTest extends
}
protected void onSetUp() throws Exception {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.clearSynchronization();
}
ldapServerManager.cleanAndSetup("setup_data.ldif");
jdbcTemplate
.execute("create table PERSON(fullname VARCHAR, lastname VARCHAR, description VARCHAR)");
jdbcTemplate.update("insert into PERSON values(?, ?, ?)", new Object[] {
"Some Person", "Person", "Sweden, Company1, Some Person" });
}
protected void onTearDown() throws Exception {
jdbcTemplate.execute("drop table PERSON");
}
public void testCreateWithException() {
@@ -58,12 +84,27 @@ public class ContextSourceTransactionManagerIntegrationTest extends
log.debug("Verifying result");
// Verify that no entry was created
try {
ldapTemplate.lookup("cn=some testperson, ou=company1, c=Sweden");
fail("NameNotFoundException expected");
} catch (NameNotFoundException expected) {
assertTrue(true);
}
try {
jdbcTemplate.queryForObject(
"select * from PERSON where fullname='some testperson'",
new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
return null;
}
});
fail("EmptyResultDataAccessException expected");
} catch (EmptyResultDataAccessException expected) {
assertTrue(true);
}
}
public void testCreate() {
@@ -71,13 +112,24 @@ public class ContextSourceTransactionManagerIntegrationTest extends
"some description");
log.debug("Verifying result");
ldapTemplate.lookup("cn=some testperson, ou=company1, c=Sweden");
Object ldapResult = ldapTemplate
.lookup("cn=some testperson, ou=company1, c=Sweden");
Object dbResult = jdbcTemplate.queryForObject(
"select * from PERSON where fullname='some testperson'",
new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
return new Object();
}
});
assertNotNull(ldapResult);
assertNotNull(dbResult);
}
public void testUpdateWithException() {
String dn = "cn=Some Person,ou=company1,c=Sweden";
try {
dummyDao.updateWithException(dn, "Updated Person",
dummyDao.updateWithException(dn, "Some Person", "Updated Person",
"Updated description");
fail("DummyException expected");
} catch (DummyException expected) {
@@ -86,7 +138,7 @@ public class ContextSourceTransactionManagerIntegrationTest extends
log.debug("Verifying result");
Object result = ldapTemplate.lookup(dn, new AttributesMapper() {
Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() {
public Object mapFromAttributes(Attributes attributes)
throws NamingException {
assertEquals("Person", attributes.get("sn").get());
@@ -96,15 +148,29 @@ public class ContextSourceTransactionManagerIntegrationTest extends
}
});
assertNotNull(result);
Object jdbcResult = jdbcTemplate.queryForObject(
"select * from PERSON where fullname=?",
new Object[] { "Some Person" }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
assertEquals("Person", rs.getString("lastname"));
assertEquals("Sweden, Company1, Some Person", rs
.getString("description"));
return new Object();
}
});
assertNotNull(ldapResult);
assertNotNull(jdbcResult);
}
public void testUpdate() {
String dn = "cn=Some Person,ou=company1,c=Sweden";
dummyDao.update(dn, "Updated Person", "Updated description");
dummyDao.update(dn, "Some Person", "Updated Person",
"Updated description");
log.debug("Verifying result");
Object result = ldapTemplate.lookup(dn, new AttributesMapper() {
Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() {
public Object mapFromAttributes(Attributes attributes)
throws NamingException {
assertEquals("Updated Person", attributes.get("sn").get());
@@ -114,7 +180,20 @@ public class ContextSourceTransactionManagerIntegrationTest extends
}
});
assertNotNull(result);
Object jdbcResult = jdbcTemplate.queryForObject(
"select * from PERSON where fullname=?",
new Object[] { "Some Person" }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
assertEquals("Updated Person", rs.getString("lastname"));
assertEquals("Updated description", rs
.getString("description"));
return new Object();
}
});
assertNotNull(ldapResult);
assertNotNull(jdbcResult);
}
public void testUpdateAndRenameWithException() {
@@ -217,31 +296,39 @@ public class ContextSourceTransactionManagerIntegrationTest extends
String dn = "cn=Some Person,ou=company1,c=Sweden";
try {
// Perform test
dummyDao.unbindWithException(dn);
dummyDao.unbindWithException(dn, "Some Person");
fail("DummyException expected");
} catch (DummyException expected) {
assertTrue(true);
}
// Verify result - check that the operation was properly rolled back
Object result = ldapTemplate.lookup(dn, new AttributesMapper() {
Object ldapResult = ldapTemplate.lookup(dn, new AttributesMapper() {
public Object mapFromAttributes(Attributes attributes)
throws NamingException {
assertEquals("Some Person", attributes.get("cn").get());
assertEquals("Person", attributes.get("sn").get());
assertEquals("Sweden, Company1, Some Person", attributes.get(
"description").get());
// Just verify that the entry still exists.
return new Object();
}
});
assertNotNull(result);
Object jdbcResult = jdbcTemplate.queryForObject(
"select * from PERSON where fullname=?",
new Object[] { "Some Person" }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
// Just verify that the entry still exists.
return new Object();
}
});
assertNotNull(ldapResult);
assertNotNull(jdbcResult);
}
public void testUnbind() {
String dn = "cn=Some Person,ou=company1,c=Sweden";
// Perform test
dummyDao.unbind(dn);
dummyDao.unbind(dn, "Some Person");
try {
// Verify result - check that the operation was not rolled back
@@ -251,5 +338,22 @@ public class ContextSourceTransactionManagerIntegrationTest extends
assertTrue(true);
}
try {
jdbcTemplate.queryForObject(
"select * from PERSON where fullname=?",
new Object[] { "Some Person" }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
return null;
}
});
fail("EmptyResultDataAccessException expected");
} catch (EmptyResultDataAccessException expected) {
assertTrue(true);
}
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}

View File

@@ -7,9 +7,10 @@ public interface DummyDao {
void create(String country, String company, String fullname,
String lastname, String description);
void update(String dn, String lastname, String description);
void update(String dn, String fullname, String lastname, String description);
void updateWithException(String dn, String lastname, String description);
void updateWithException(String dn, String fullname, String lastname,
String description);
void updateAndRename(String dn, String newDn, String description);
@@ -21,8 +22,8 @@ public interface DummyDao {
void modifyAttributesWithException(String dn, String lastName,
String description);
void unbind(String dn);
void unbind(String dn, String fullname);
void unbindWithException(String dn);
void unbindWithException(String dn, String fullname);
}

View File

@@ -5,7 +5,7 @@ import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapTemplate;
public class DummyDaoImpl implements DummyDao{
public class LdapAndJdbcDummyDaoImpl implements DummyDao {
private LdapTemplate ldapTemplate;
private JdbcTemplate jdbcTemplate;
@@ -21,13 +21,10 @@ public class DummyDaoImpl implements DummyDao{
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#createWithException(java.lang.String,
* @see org.springframework.ldap.transaction.core.DummyDao#createWithException(java.lang.String,
* java.lang.String, java.lang.String, java.lang.String,
* java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#createWithException(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public void createWithException(String country, String company,
String fullname, String lastname, String description) {
create(country, company, fullname, lastname, description);
@@ -37,13 +34,10 @@ public class DummyDaoImpl implements DummyDao{
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#create(java.lang.String,
* @see org.springframework.ldap.transaction.core.DummyDao#create(java.lang.String,
* java.lang.String, java.lang.String, java.lang.String,
* java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#create(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public void create(String country, String company, String fullname,
String lastname, String description) {
DistinguishedName dn = new DistinguishedName();
@@ -57,70 +51,63 @@ public class DummyDaoImpl implements DummyDao{
ctx.setAttributeValue("sn", lastname);
ctx.setAttributeValue("description", description);
ldapTemplate.bind(dn, ctx, null);
// jdbcTemplate.execute("insert into test values(1, 'kalle', 'pettersson', 123)");
jdbcTemplate.update("insert into PERSON values(?, ?, ?)", new Object[] {
fullname, lastname, description });
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#update(java.lang.String,
* @see org.springframework.ldap.transaction.core.DummyDao#update(java.lang.String,
* java.lang.String, java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#update(java.lang.String, java.lang.String, java.lang.String)
*/
public void update(String dn, String lastname, String description) {
public void update(String dn, String fullname, 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);
jdbcTemplate
.update(
"update PERSON set lastname=?, description = ? where fullname = ?",
new Object[] { lastname, description, fullname });
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#updateWithException(java.lang.String,
* @see org.springframework.ldap.transaction.core.DummyDao#updateWithException(java.lang.String,
* java.lang.String, java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#updateWithException(java.lang.String, java.lang.String, java.lang.String)
*/
public void updateWithException(String dn, String lastname,
String description) {
update(dn, lastname, description);
public void updateWithException(String dn, String fullname,
String lastname, String description) {
update(dn, fullname, lastname, description);
throw new DummyException("This method failed.");
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#updateAndRename(java.lang.String,
* @see org.springframework.ldap.transaction.core.DummyDao#updateAndRename(java.lang.String,
* java.lang.String, java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#updateAndRename(java.lang.String, java.lang.String, java.lang.String)
*/
public void updateAndRename(String dn, String newDn, String description) {
DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn);
ctx.setAttributeValue("description", description);
ctx.update();
ldapTemplate.rebind(dn, ctx, null);
ldapTemplate.rename(dn, newDn);
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#updateAndRenameWithException(java.lang.String,
* @see org.springframework.ldap.transaction.core.DummyDao#updateAndRenameWithException(java.lang.String,
* java.lang.String, java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#updateAndRenameWithException(java.lang.String, java.lang.String, java.lang.String)
*/
public void updateAndRenameWithException(String dn, String newDn,
String description) {
updateAndRename(dn, newDn, description);
@@ -130,12 +117,9 @@ public class DummyDaoImpl implements DummyDao{
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#modifyAttributes(java.lang.String,
* @see org.springframework.ldap.transaction.core.DummyDao#modifyAttributes(java.lang.String,
* java.lang.String, java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#modifyAttributes(java.lang.String, java.lang.String, java.lang.String)
*/
public void modifyAttributes(String dn, String lastName, String description) {
DirContextAdapter ctx = (DirContextAdapter) ldapTemplate.lookup(dn);
ctx.setAttributeValue("sn", lastName);
@@ -147,12 +131,9 @@ public class DummyDaoImpl implements DummyDao{
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#modifyAttributesWithException(java.lang.String,
* @see org.springframework.ldap.transaction.core.DummyDao#modifyAttributesWithException(java.lang.String,
* java.lang.String, java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#modifyAttributesWithException(java.lang.String, java.lang.String, java.lang.String)
*/
public void modifyAttributesWithException(String dn, String lastName,
String description) {
modifyAttributes(dn, lastName, description);
@@ -162,25 +143,21 @@ public class DummyDaoImpl implements DummyDao{
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#unbind(java.lang.String)
* @see org.springframework.ldap.transaction.core.DummyDao#unbind(java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#unbind(java.lang.String)
*/
public void unbind(String dn) {
public void unbind(String dn, String fullname) {
ldapTemplate.unbind(dn);
jdbcTemplate.update("delete from PERSON where fullname=?",
new Object[] { fullname });
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.DummyDao#unbindWithException(java.lang.String)
* @see org.springframework.ldap.transaction.core.DummyDao#unbindWithException(java.lang.String)
*/
/* (non-Javadoc)
* @see org.springframework.ldap.support.transaction.TempDummyDao#unbindWithException(java.lang.String)
*/
public void unbindWithException(String dn) {
unbind(dn);
public void unbindWithException(String dn, String fullname) {
unbind(dn, fullname);
throw new DummyException("This operation failed.");
}
}

View File

@@ -15,19 +15,14 @@
*/
package org.springframework.ldap.transaction.core;
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.core.ContextSource;
import org.springframework.ldap.transaction.CompensatingTransactionOperationExecutor;
import org.springframework.ldap.transaction.CompensatingTransactionOperationRecorder;
import org.springframework.ldap.transaction.DefaultCompensatingTransactionOperationManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* TransactionManager for managing LDAP transactions. Since transactions are not
@@ -92,56 +87,27 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
* {@link DefaultTempEntryRenamingStrategy}), specified in
* {@link #setRenamingStrategy(TempEntryRenamingStrategy)}.
* </p>
* <p>
* The actual work of this Transaction Manager is delegated to a
* {@link ContextSourceTransactionManagerDelegate}. This is because the exact
* same logic needs to be used if we want to wrap a JDBC and LDAP transaction in
* the same logical transaction.
* </p>
*
* @author Mattias Arthursson
*
* @see ContextSourceAndDataSourceTransactionManager
* @see ContextSourceTransactionManagerDelegate
* @see DefaultCompensatingTransactionOperationManager
* @see TempEntryRenamingStrategy
* @see TransactionAwareContextSourceProxy
*/
public class ContextSourceTransactionManager extends
AbstractPlatformTransactionManager {
private static final long serialVersionUID = -4308820955185446535L;
private static final long serialVersionUID = 7138208218687237856L;
private static Log log = LogFactory
.getLog(ContextSourceTransactionManager.class);
private ContextSource contextSource;
private TempEntryRenamingStrategy renamingStrategy = new DefaultTempEntryRenamingStrategy();
/**
* Set the ContextSource to work on. Even though the actual ContextSource
* sent to the LdapTemplate instance should be a
* {@link TransactionAwareContextSourceProxy}, the one sent to this method
* should be the target of that proxy. If it is not, the target will be
* extracted and used instead.
*
* @param contextSource
* the ContextSource to work on.
*/
public void setContextSource(ContextSource contextSource) {
if (contextSource instanceof TransactionAwareContextSourceProxy) {
TransactionAwareContextSourceProxy proxy = (TransactionAwareContextSourceProxy) contextSource;
this.contextSource = proxy.getTarget();
} else {
this.contextSource = contextSource;
}
}
public ContextSource getContextSource() {
return contextSource;
}
/*
* (non-Javadoc)
*
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doGetTransaction()
*/
protected Object doGetTransaction() throws TransactionException {
DirContextHolder contextHolder = (DirContextHolder) TransactionSynchronizationManager
.getResource(this.contextSource);
ContextSourceTransactionObject txObject = new ContextSourceTransactionObject(
contextHolder);
return txObject;
}
private ContextSourceTransactionManagerDelegate delegate = new ContextSourceTransactionManagerDelegate();
/*
* (non-Javadoc)
@@ -151,17 +117,16 @@ public class ContextSourceTransactionManager extends
*/
protected void doBegin(Object transaction, TransactionDefinition definition)
throws TransactionException {
ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) transaction;
delegate.doBegin(transaction, definition);
}
if (txObject.getContextHolder() == null) {
DirContext newCtx = getContextSource().getReadOnlyContext();
DirContextHolder contextHolder = new DirContextHolder(newCtx,
renamingStrategy);
txObject.setContextHolder(contextHolder);
TransactionSynchronizationManager.bindResource(getContextSource(),
contextHolder);
}
/*
* (non-Javadoc)
*
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doCleanupAfterCompletion(java.lang.Object)
*/
protected void doCleanupAfterCompletion(Object transaction) {
delegate.doCleanupAfterCompletion(transaction);
}
/*
@@ -171,10 +136,16 @@ public class ContextSourceTransactionManager extends
*/
protected void doCommit(DefaultTransactionStatus status)
throws TransactionException {
ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) status
.getTransaction();
txObject.getContextHolder().getTransactionDataManager().commit();
delegate.doCommit(status);
}
/*
* (non-Javadoc)
*
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doGetTransaction()
*/
protected Object doGetTransaction() throws TransactionException {
return delegate.doGetTransaction();
}
/*
@@ -184,42 +155,38 @@ public class ContextSourceTransactionManager extends
*/
protected void doRollback(DefaultTransactionStatus status)
throws TransactionException {
ContextSourceTransactionObject txObject = (ContextSourceTransactionObject) status
.getTransaction();
txObject.getContextHolder().getTransactionDataManager().rollback();
}
/*
* (non-Javadoc)
*
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#doCleanupAfterCompletion(java.lang.Object)
*/
protected void doCleanupAfterCompletion(Object 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();
}
txObject.getContextHolder().clear();
delegate.doRollback(status);
}
/**
* Set the {@link TempEntryRenamingStrategy} to be used when renaming
* temporary entries in unbind and rebind operations. Default value is a
* {@link DefaultTempEntryRenamingStrategy}.
* Get the ContextSource.
*
* @return the contextSource.
* @see ContextSourceTransactionManagerDelegate#getContextSource()
*/
public ContextSource getContextSource() {
return delegate.getContextSource();
}
/**
* Set the ContextSource.
*
* @param contextSource
* the ContextSource.
* @see ContextSourceTransactionManagerDelegate#setContextSource(ContextSource)
*/
public void setContextSource(ContextSource contextSource) {
delegate.setContextSource(contextSource);
}
/**
* Set the {@link TempEntryRenamingStrategy}.
*
* @param renamingStrategy
* the {@link TempEntryRenamingStrategy} to use.
* the Renaming Strategy.
* @see ContextSourceTransactionManagerDelegate#setRenamingStrategy(TempEntryRenamingStrategy)
*/
public void setRenamingStrategy(TempEntryRenamingStrategy renamingStrategy) {
this.renamingStrategy = renamingStrategy;
delegate.setRenamingStrategy(renamingStrategy);
}
}