Index: service/src/test/java/org/appfuse/service/impl/UserSecurityAdviceTest.java =================================================================== --- service/src/test/java/org/appfuse/service/impl/UserSecurityAdviceTest.java (revision 3174) +++ service/src/test/java/org/appfuse/service/impl/UserSecurityAdviceTest.java (working copy) @@ -1,4 +1,4 @@ -package org.appfuse.service; +package org.appfuse.service.impl; import org.springframework.security.AccessDeniedException; import org.springframework.security.Authentication; @@ -7,6 +7,9 @@ import org.springframework.security.context.SecurityContextImpl; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.appfuse.Constants; +import org.appfuse.service.impl.UserManagerImpl; +import org.appfuse.service.UserManager; +import org.appfuse.service.UserSecurityAdvice; import org.appfuse.dao.UserDao; import org.appfuse.model.Role; import org.appfuse.model.User; @@ -20,6 +23,7 @@ import org.junit.Before; import org.junit.After; import org.junit.Test; +import org.junit.Assert; import static org.junit.Assert.*; @RunWith(JMock.class) @@ -65,7 +69,7 @@ fail("AccessDeniedException not thrown"); } catch (AccessDeniedException expected) { assertNotNull(expected); - assertEquals(expected.getMessage(), UserSecurityAdvice.ACCESS_DENIED); + Assert.assertEquals(expected.getMessage(), UserSecurityAdvice.ACCESS_DENIED); } } Property changes on: service/src/test/java/org/appfuse/service/impl/UserSecurityAdviceTest.java ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native Index: service/src/test/java/org/appfuse/service/impl/UniversalManagerTest.java =================================================================== --- service/src/test/java/org/appfuse/service/impl/UniversalManagerTest.java (revision 3174) +++ service/src/test/java/org/appfuse/service/impl/UniversalManagerTest.java (working copy) @@ -1,93 +0,0 @@ -package org.appfuse.service.impl; - -import org.appfuse.dao.UniversalDao; -import org.appfuse.model.User; -import org.jmock.Expectations; -import org.springframework.orm.ObjectRetrievalFailureException; -import org.springframework.test.AssertThrows; -import org.junit.Before; -import org.junit.After; -import org.junit.Test; -import static org.junit.Assert.*; - -/** - * This class tests the generic UniversalManager and UniversalManagerImpl implementation. - */ -public class UniversalManagerTest extends BaseManagerMockTestCase { - protected UniversalManagerImpl manager = new UniversalManagerImpl(); - protected UniversalDao dao; - - @Before - public void setUp() throws Exception { - dao = context.mock(UniversalDao.class); - manager.setDao(dao); - } - - @After - public void tearDown() throws Exception { - manager = null; - dao = null; - } - - /** - * Simple test to verify BaseDao works. - */ - @Test - public void testCreate() { - final User user = createUser(); - context.checking(new Expectations() {{ - one(dao).save(with(same(user))); - will(returnValue(user)); - }}); - - manager.save(user); - } - - @Test - public void testRetrieve() { - final User user = createUser(); - context.checking(new Expectations() {{ - one(dao).get(User.class, "foo"); - will(returnValue(user)); - }}); - - User user2 = (User) manager.get(User.class, user.getUsername()); - assertTrue(user2.getUsername().equals("foo")); - } - - @Test - public void testUpdate() { - context.checking(new Expectations() {{ - one(dao).save(createUser()); - }}); - - User user = createUser(); - user.getAddress().setCountry("USA"); - manager.save(user); - } - - @Test - public void testDelete() { - final Exception ex = new ObjectRetrievalFailureException(User.class, "foo"); - - context.checking(new Expectations() {{ - one(dao).remove(User.class, "foo"); - one(dao).get(User.class, "foo"); - will(throwException(ex)); - }}); - - manager.remove(User.class, "foo"); - new AssertThrows(ObjectRetrievalFailureException.class) { - public void test() { - manager.get(User.class, "foo"); - } - }.runTest(); - } - - private User createUser() { - User user = new User(); - // set required fields - user.setUsername("foo"); - return user; - } -} Index: service/src/test/java/org/appfuse/service/impl/LookupManagerImplTest.java =================================================================== --- service/src/test/java/org/appfuse/service/impl/LookupManagerImplTest.java (revision 3174) +++ service/src/test/java/org/appfuse/service/impl/LookupManagerImplTest.java (working copy) @@ -15,12 +15,12 @@ public class LookupManagerImplTest extends BaseManagerMockTestCase { private LookupManagerImpl mgr = new LookupManagerImpl(); - private LookupDao lookupDao = null; + private LookupDao lookupDao; @Before public void setUp() throws Exception { lookupDao = context.mock(LookupDao.class); - mgr.setLookupDao(lookupDao); + mgr.dao = lookupDao; } @Test Index: service/src/test/java/org/appfuse/service/impl/UserManagerImplTest.java =================================================================== --- service/src/test/java/org/appfuse/service/impl/UserManagerImplTest.java (revision 3174) +++ service/src/test/java/org/appfuse/service/impl/UserManagerImplTest.java (working copy) @@ -13,13 +13,14 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.test.annotation.ExpectedException; public class UserManagerImplTest extends BaseManagerMockTestCase { //~ Instance fields ======================================================== private UserManagerImpl userManager = new UserManagerImpl(); private RoleManagerImpl roleManager = new RoleManagerImpl(); - private UserDao userDao = null; - private RoleDao roleDao = null; + private UserDao userDao; + private RoleDao roleDao; //~ Methods ================================================================ @Before @@ -27,7 +28,7 @@ userDao = context.mock(UserDao.class); userManager.setUserDao(userDao); roleDao = context.mock(RoleDao.class); - roleManager.setRoleDao(roleDao); + roleManager.roleDao = roleDao; } @Test @@ -48,7 +49,7 @@ } @Test - public void testSaveUser() throws Exception { + public void testSaveUser() throws Exception { final User testData = new User("1"); testData.getRoles().add(new Role("user")); Index: service/src/test/java/org/appfuse/service/UserSecurityAdviceTest.java =================================================================== --- service/src/test/java/org/appfuse/service/UserSecurityAdviceTest.java (revision 3174) +++ service/src/test/java/org/appfuse/service/UserSecurityAdviceTest.java (working copy) @@ -1,197 +0,0 @@ -package org.appfuse.service; - -import org.springframework.security.AccessDeniedException; -import org.springframework.security.Authentication; -import org.springframework.security.context.SecurityContext; -import org.springframework.security.context.SecurityContextHolder; -import org.springframework.security.context.SecurityContextImpl; -import org.springframework.security.providers.UsernamePasswordAuthenticationToken; -import org.appfuse.Constants; -import org.appfuse.dao.UserDao; -import org.appfuse.model.Role; -import org.appfuse.model.User; -import org.jmock.integration.junit4.JMock; -import org.jmock.integration.junit4.JUnit4Mockery; -import org.jmock.Mockery; -import org.jmock.Expectations; -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.junit.runner.RunWith; -import org.junit.Before; -import org.junit.After; -import org.junit.Test; -import static org.junit.Assert.*; - -@RunWith(JMock.class) -public class UserSecurityAdviceTest { - Mockery context = new JUnit4Mockery(); - UserDao userDao = null; - ApplicationContext ctx = null; - SecurityContext initialSecurityContext = null; - - @Before - public void setUp() throws Exception { - // store initial security context for later restoration - initialSecurityContext = SecurityContextHolder.getContext(); - - SecurityContext context = new SecurityContextImpl(); - User user = new User("user"); - user.setId(1L); - user.setPassword("password"); - user.addRole(new Role(Constants.USER_ROLE)); - - UsernamePasswordAuthenticationToken token = - new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), user.getAuthorities()); - token.setDetails(user); - context.setAuthentication(token); - SecurityContextHolder.setContext(context); - } - - @After - public void tearDown() { - SecurityContextHolder.setContext(initialSecurityContext); - } - - @Test - public void testAddUserWithoutAdminRole() throws Exception { - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - assertTrue(auth.isAuthenticated()); - UserManager userManager = makeInterceptedTarget(); - User user = new User("admin"); - user.setId(2L); - - try { - userManager.saveUser(user); - fail("AccessDeniedException not thrown"); - } catch (AccessDeniedException expected) { - assertNotNull(expected); - assertEquals(expected.getMessage(), UserSecurityAdvice.ACCESS_DENIED); - } - } - - @Test - public void testAddUserAsAdmin() throws Exception { - SecurityContext securityContext = new SecurityContextImpl(); - User user = new User("admin"); - user.setId(2L); - user.setPassword("password"); - user.addRole(new Role(Constants.ADMIN_ROLE)); - UsernamePasswordAuthenticationToken token = - new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), user.getAuthorities()); - token.setDetails(user); - securityContext.setAuthentication(token); - SecurityContextHolder.setContext(securityContext); - - UserManager userManager = makeInterceptedTarget(); - final User adminUser = new User("admin"); - adminUser.setId(2L); - - context.checking(new Expectations() {{ - one(userDao).saveUser(with(same(adminUser))); - }}); - - userManager.saveUser(adminUser); - } - - @Test - public void testUpdateUserProfile() throws Exception { - UserManager userManager = makeInterceptedTarget(); - final User user = new User("user"); - user.setId(1L); - user.getRoles().add(new Role(Constants.USER_ROLE)); - - context.checking(new Expectations() {{ - one(userDao).saveUser(with(same(user))); - }}); - - userManager.saveUser(user); - } - - // Test fix to http://issues.appfuse.org/browse/APF-96 - @Test - public void testChangeToAdminRoleFromUserRole() throws Exception { - UserManager userManager = makeInterceptedTarget(); - User user = new User("user"); - user.setId(1L); - user.getRoles().add(new Role(Constants.ADMIN_ROLE)); - - try { - userManager.saveUser(user); - fail("AccessDeniedException not thrown"); - } catch (AccessDeniedException expected) { - assertNotNull(expected); - assertEquals(expected.getMessage(), UserSecurityAdvice.ACCESS_DENIED); - } - } - - // Test fix to http://issues.appfuse.org/browse/APF-96 - @Test - public void testAddAdminRoleWhenAlreadyHasUserRole() throws Exception { - UserManager userManager = makeInterceptedTarget(); - User user = new User("user"); - user.setId(1L); - user.getRoles().add(new Role(Constants.ADMIN_ROLE)); - user.getRoles().add(new Role(Constants.USER_ROLE)); - - try { - userManager.saveUser(user); - fail("AccessDeniedException not thrown"); - } catch (AccessDeniedException expected) { - assertNotNull(expected); - assertEquals(expected.getMessage(), UserSecurityAdvice.ACCESS_DENIED); - } - } - - // Test fix to http://issues.appfuse.org/browse/APF-96 - @Test - public void testAddUserRoleWhenHasAdminRole() throws Exception { - SecurityContext securityContext = new SecurityContextImpl(); - User user1 = new User("user"); - user1.setId(1L); - user1.setPassword("password"); - user1.addRole(new Role(Constants.ADMIN_ROLE)); - UsernamePasswordAuthenticationToken token = - new UsernamePasswordAuthenticationToken(user1.getUsername(), user1.getPassword(), user1.getAuthorities()); - token.setDetails(user1); - securityContext.setAuthentication(token); - SecurityContextHolder.setContext(securityContext); - - UserManager userManager = makeInterceptedTarget(); - final User user = new User("user"); - user.setId(1L); - user.getRoles().add(new Role(Constants.ADMIN_ROLE)); - user.getRoles().add(new Role(Constants.USER_ROLE)); - - context.checking(new Expectations() {{ - one(userDao).saveUser(with(same(user))); - }}); - - userManager.saveUser(user); - } - - // Test fix to http://issues.appfuse.org/browse/APF-96 - @Test - public void testUpdateUserWithUserRole() throws Exception { - UserManager userManager = makeInterceptedTarget(); - final User user = new User("user"); - user.setId(1L); - user.getRoles().add(new Role(Constants.USER_ROLE)); - - context.checking(new Expectations() {{ - one(userDao).saveUser(with(same(user))); - }}); - - userManager.saveUser(user); - } - - private UserManager makeInterceptedTarget() { - ctx = new ClassPathXmlApplicationContext("/applicationContext-test.xml"); - - UserManager userManager = (UserManager) ctx.getBean("target"); - - // Mock the userDao - userDao = context.mock(UserDao.class); - userManager.setUserDao(userDao); - return userManager; - } -} Index: service/src/test/java/org/appfuse/service/MailEngineTest.java =================================================================== --- service/src/test/java/org/appfuse/service/MailEngineTest.java (revision 3174) +++ service/src/test/java/org/appfuse/service/MailEngineTest.java (working copy) @@ -1,5 +1,10 @@ package org.appfuse.service; +import org.junit.After; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSenderImpl; @@ -16,29 +21,24 @@ * @author Bryan Noll */ public class MailEngineTest extends BaseManagerTestCase { + @Autowired MailEngine mailEngine; + @Autowired SimpleMailMessage mailMessage; JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); - public void setMailEngine(MailEngine mailEngine) { - this.mailEngine = mailEngine; - } - - public void setMailMessage(SimpleMailMessage mailMessage) { - this.mailMessage = mailMessage; - } - - @Override - protected void onSetUp() { + @Before + public void setUp() { mailSender.setHost("localhost"); mailEngine.setMailSender(mailSender); } - @Override - protected void onTearDown() { + @After + public void tearDown() { mailEngine.setMailSender(null); } - + + @Test public void testSend() throws Exception { // mock smtp server Wiser wiser = new Wiser(); @@ -62,7 +62,8 @@ assertEquals(emailSubject, wm.getMimeMessage().getSubject()); assertEquals(emailBody, wm.getMimeMessage().getContent()); } - + + @Test public void testSendMessageWithAttachment() throws Exception { final String ATTACHMENT_NAME = "boring-attachment.txt"; Index: service/src/test/java/org/appfuse/service/UserManagerTest.java =================================================================== --- service/src/test/java/org/appfuse/service/UserManagerTest.java (revision 3174) +++ service/src/test/java/org/appfuse/service/UserManagerTest.java (working copy) @@ -4,23 +4,19 @@ import org.apache.commons.logging.LogFactory; import org.appfuse.Constants; import org.appfuse.model.User; +import static org.junit.Assert.*; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; public class UserManagerTest extends BaseManagerTestCase { - //~ Instance fields ======================================================== - - private UserManager mgr = null; - private RoleManager roleManager = null; private Log log = LogFactory.getLog(UserManagerTest.class); + @Autowired + private UserManager mgr; + @Autowired + private RoleManager roleManager; private User user; - - public void setUserManager(UserManager userManager) { - this.mgr = userManager; - } - - public void setRoleManager(RoleManager roleManager) { - this.roleManager = roleManager; - } + @Test public void testGetUser() throws Exception { user = mgr.getUserByUsername("user"); assertNotNull(user); @@ -29,6 +25,7 @@ assertEquals(1, user.getRoles().size()); } + @Test public void testSaveUser() throws Exception { user = mgr.getUserByUsername("user"); user.setPhoneNumber("303-555-1212"); @@ -40,6 +37,7 @@ assertEquals(1, user.getRoles().size()); } + @Test public void testAddAndRemoveUser() throws Exception { user = new User(); Index: service/src/test/java/org/appfuse/service/UserExistsExceptionTest.java =================================================================== --- service/src/test/java/org/appfuse/service/UserExistsExceptionTest.java (revision 3174) +++ service/src/test/java/org/appfuse/service/UserExistsExceptionTest.java (working copy) @@ -1,24 +1,29 @@ package org.appfuse.service; import org.appfuse.model.User; +import static org.junit.Assert.*; +import org.junit.Test; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; +import org.springframework.test.annotation.ExpectedException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; -public class UserExistsExceptionTest extends BaseManagerTestCase { - private UserManager manager = null; +@ContextConfiguration( + locations={"/applicationContext-service.xml", + "/applicationContext-resources.xml", + "classpath:/applicationContext-dao.xml"}) +public class UserExistsExceptionTest extends AbstractTransactionalJUnit4SpringContextTests { + @Autowired + private UserManager manager; + private Log log = LogFactory.getLog(UserExistsExceptionTest.class); - public void setUserManager(UserManager userManager) { - this.manager = userManager; - } - - protected String[] getConfigLocations() { - setAutowireMode(AUTOWIRE_BY_NAME); - return new String[] {"/applicationContext-service.xml", - "/applicationContext-resources.xml", - "classpath:/applicationContext-dao.xml"}; - } - + @Test + @ExpectedException(UserExistsException.class) public void testAddExistingUser() throws Exception { - logger.debug("entered 'testAddExistingUser' method"); + log.debug("entered 'testAddExistingUser' method"); assertNotNull(manager); User user = manager.getUser("-1"); @@ -30,12 +35,7 @@ user2.setVersion(null); user2.setRoles(null); - // try saving as new user, this should fail b/c of unique keys - try { - manager.saveUser(user2); - fail("Duplicate user didn't throw UserExistsException"); - } catch (UserExistsException uee) { - assertNotNull(uee); - } + // try saving as new user, this should fail UserExistsException b/c of unique keys + manager.saveUser(user2); } } Index: service/src/test/resources/applicationContext-resources.xml =================================================================== --- service/src/test/resources/applicationContext-resources.xml (revision 3174) +++ service/src/test/resources/applicationContext-resources.xml (working copy) @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> Index: service/src/main/java/org/appfuse/service/BaseManagerTestCase.java =================================================================== --- service/src/main/java/org/appfuse/service/BaseManagerTestCase.java (revision 3174) +++ service/src/main/java/org/appfuse/service/BaseManagerTestCase.java (working copy) @@ -5,26 +5,23 @@ import org.apache.commons.logging.LogFactory; import org.appfuse.util.ConvertUtil; import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests; +import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; +import org.springframework.test.context.ContextConfiguration; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; - -public abstract class BaseManagerTestCase extends AbstractTransactionalDataSourceSpringContextTests { +@ContextConfiguration( + locations={"classpath:/applicationContext-resources.xml", + "classpath:/applicationContext-dao.xml", + "classpath:/applicationContext-service.xml", + "classpath*:/**/applicationContext.xml"}) +public abstract class BaseManagerTestCase extends AbstractTransactionalJUnit4SpringContextTests { //~ Static fields/initializers ============================================= - protected final Log log = LogFactory.getLog(getClass()); protected static ResourceBundle rb = null; - protected String[] getConfigLocations() { - setAutowireMode(AUTOWIRE_BY_NAME); - return new String[] {"/applicationContext-resources.xml", "classpath:/applicationContext-dao.xml", - "/applicationContext-service.xml", "classpath*:/**/applicationContext.xml"}; - // classpath*:/**/applicationContext.xml has to be used since this file does not - // exist in AppFuse, but may exist in projects that depend on it - } - //~ Constructors =========================================================== public BaseManagerTestCase() { Index: service/src/main/java/org/appfuse/service/impl/UniversalManagerImpl.java =================================================================== --- service/src/main/java/org/appfuse/service/impl/UniversalManagerImpl.java (revision 3174) +++ service/src/main/java/org/appfuse/service/impl/UniversalManagerImpl.java (working copy) @@ -1,59 +0,0 @@ -package org.appfuse.service.impl; - -import java.io.Serializable; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.appfuse.dao.UniversalDao; -import org.appfuse.service.UniversalManager; - -/** - * Base class for Business Services - use this class for utility methods and - * generic CRUD methods. - * - * @author Matt Raible - */ -public class UniversalManagerImpl implements UniversalManager { - /** - * Log instance for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging - */ - protected final Log log = LogFactory.getLog(getClass()); - - /** - * UniversalDao instance, ready to charge forward and persist to the database - */ - protected UniversalDao dao; - - public void setDao(UniversalDao dao) { - this.dao = dao; - } - - /** - * {@inheritDoc} - */ - public Object get(Class clazz, Serializable id) { - return dao.get(clazz, id); - } - - /** - * {@inheritDoc} - */ - public List getAll(Class clazz) { - return dao.getAll(clazz); - } - - /** - * {@inheritDoc} - */ - public void remove(Class clazz, Serializable id) { - dao.remove(clazz, id); - } - - /** - * {@inheritDoc} - */ - public Object save(Object o) { - return dao.save(o); - } -} Index: service/src/main/java/org/appfuse/service/impl/LookupManagerImpl.java =================================================================== --- service/src/main/java/org/appfuse/service/impl/LookupManagerImpl.java (revision 3174) +++ service/src/main/java/org/appfuse/service/impl/LookupManagerImpl.java (working copy) @@ -4,6 +4,8 @@ import org.appfuse.model.LabelValue; import org.appfuse.model.Role; import org.appfuse.service.LookupManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @@ -14,19 +16,12 @@ * * @author Matt Raible */ -public class LookupManagerImpl extends UniversalManagerImpl implements LookupManager { - private LookupDao dao; +@Service("lookupManager") +public class LookupManagerImpl implements LookupManager { + @Autowired + LookupDao dao; /** - * Method that allows setting the DAO to talk to the data store with. - * @param dao the dao implementation - */ - public void setLookupDao(LookupDao dao) { - super.dao = dao; - this.dao = dao; - } - - /** * {@inheritDoc} */ public List getAllRoles() { Index: service/src/main/java/org/appfuse/service/impl/GenericManagerImpl.java =================================================================== --- service/src/main/java/org/appfuse/service/impl/GenericManagerImpl.java (revision 3174) +++ service/src/main/java/org/appfuse/service/impl/GenericManagerImpl.java (working copy) @@ -49,50 +49,48 @@ protected final Log log = LogFactory.getLog(getClass()); /** - * GenericDao instance, set by constructor of this class + * GenericDao instance, set by constructor of child classes */ - protected GenericDao genericDao; + protected GenericDao dao; - /** - * Public constructor for creating a new GenericManagerImpl. - * @param genericDao the GenericDao to use for persistence - */ - public GenericManagerImpl(final GenericDao genericDao) { - this.genericDao = genericDao; + public GenericManagerImpl() {} + + public GenericManagerImpl(GenericDao genericDao) { + this.dao = genericDao; } /** * {@inheritDoc} */ public List getAll() { - return genericDao.getAll(); + return dao.getAll(); } /** * {@inheritDoc} */ public T get(PK id) { - return genericDao.get(id); + return dao.get(id); } /** * {@inheritDoc} */ public boolean exists(PK id) { - return genericDao.exists(id); + return dao.exists(id); } /** * {@inheritDoc} */ public T save(T object) { - return genericDao.save(object); + return dao.save(object); } /** * {@inheritDoc} */ public void remove(PK id) { - genericDao.remove(id); + dao.remove(id); } } Index: service/src/main/java/org/appfuse/service/impl/UserManagerImpl.java =================================================================== --- service/src/main/java/org/appfuse/service/impl/UserManagerImpl.java (revision 3174) +++ service/src/main/java/org/appfuse/service/impl/UserManagerImpl.java (working copy) @@ -1,14 +1,17 @@ package org.appfuse.service.impl; -import org.springframework.security.providers.encoding.PasswordEncoder; -import org.springframework.security.userdetails.UsernameNotFoundException; import org.appfuse.dao.UserDao; import org.appfuse.model.User; import org.appfuse.service.UserExistsException; import org.appfuse.service.UserManager; import org.appfuse.service.UserService; -import org.springframework.beans.factory.annotation.Required; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.security.providers.encoding.PasswordEncoder; +import org.springframework.security.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.orm.jpa.JpaSystemException; import javax.jws.WebService; import javax.persistence.PersistenceException; @@ -20,44 +23,37 @@ * * @author Matt Raible */ +@Service("userManager") @WebService(serviceName = "UserService", endpointInterface = "org.appfuse.service.UserService") -public class UserManagerImpl extends UniversalManagerImpl implements UserManager, UserService { - private UserDao dao; +public class UserManagerImpl extends GenericManagerImpl implements UserManager, UserService { private PasswordEncoder passwordEncoder; + private UserDao userDao; - /** - * Set the Dao for communication with the data layer. - * @param dao the UserDao that communicates with the database - */ - @Required - public void setUserDao(UserDao dao) { - this.dao = dao; - } - - /** - * Set the PasswordEncoder used to encrypt passwords. - * @param passwordEncoder the PasswordEncoder implementation - */ - @Required + @Autowired public void setPasswordEncoder(PasswordEncoder passwordEncoder) { this.passwordEncoder = passwordEncoder; } + @Autowired + public void setUserDao(UserDao userDao) { + this.dao = userDao; + this.userDao = userDao; + } + /** * {@inheritDoc} */ public User getUser(String userId) { - return dao.get(new Long(userId)); + return userDao.get(new Long(userId)); } /** * {@inheritDoc} */ public List getUsers(User user) { - return dao.getUsers(); + return userDao.getAllDistinct(); } - - + /** * {@inheritDoc} */ @@ -67,7 +63,7 @@ // if new user, lowercase userId user.setUsername(user.getUsername().toLowerCase()); } - + // Get and prepare password management-related artifacts boolean passwordChanged = false; if (passwordEncoder != null) { @@ -77,7 +73,7 @@ passwordChanged = true; } else { // Existing user, check password in DB - String currentPassword = dao.getUserPassword(user.getUsername()); + String currentPassword = userDao.getUserPassword(user.getUsername()); if (currentPassword == null) { passwordChanged = true; } else { @@ -94,14 +90,14 @@ } else { log.warn("PasswordEncoder not set, skipping password encryption..."); } - + try { - return dao.saveUser(user); + return userDao.saveUser(user); } catch (DataIntegrityViolationException e) { //e.printStackTrace(); log.warn(e.getMessage()); throw new UserExistsException("User '" + user.getUsername() + "' already exists!"); - } catch (PersistenceException e) { // needed for JPA + } catch (JpaSystemException e) { // needed for JPA //e.printStackTrace(); log.warn(e.getMessage()); throw new UserExistsException("User '" + user.getUsername() + "' already exists!"); @@ -113,16 +109,17 @@ */ public void removeUser(String userId) { log.debug("removing user: " + userId); - dao.remove(new Long(userId)); + userDao.remove(new Long(userId)); } /** * {@inheritDoc} + * * @param username the login name of the human * @return User the populated user object * @throws UsernameNotFoundException thrown when username not found */ public User getUserByUsername(String username) throws UsernameNotFoundException { - return (User) dao.loadUserByUsername(username); + return (User) userDao.loadUserByUsername(username); } } Index: service/src/main/java/org/appfuse/service/impl/RoleManagerImpl.java =================================================================== --- service/src/main/java/org/appfuse/service/impl/RoleManagerImpl.java (revision 3174) +++ service/src/main/java/org/appfuse/service/impl/RoleManagerImpl.java (working copy) @@ -3,33 +3,34 @@ import java.util.List; import org.appfuse.dao.RoleDao; +import org.appfuse.dao.UserDao; import org.appfuse.model.Role; import org.appfuse.service.RoleManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * Implementation of RoleManager interface. - * + * * @author Dan Kibler */ -public class RoleManagerImpl extends UniversalManagerImpl implements RoleManager { - private RoleDao dao; +@Service("roleManager") +public class RoleManagerImpl extends GenericManagerImpl implements RoleManager { + @Autowired + RoleDao roleDao; - public void setRoleDao(RoleDao dao) { - this.dao = dao; - } - /** * {@inheritDoc} */ public List getRoles(Role role) { - return dao.getAll(); + return roleDao.getAll(); } /** * {@inheritDoc} */ public Role getRole(String rolename) { - return dao.getRoleByName(rolename); + return roleDao.getRoleByName(rolename); } /** @@ -43,6 +44,6 @@ * {@inheritDoc} */ public void removeRole(String rolename) { - dao.removeRole(rolename); + roleDao.removeRole(rolename); } } \ No newline at end of file Index: service/src/main/java/org/appfuse/service/UniversalManager.java =================================================================== --- service/src/main/java/org/appfuse/service/UniversalManager.java (revision 3174) +++ service/src/main/java/org/appfuse/service/UniversalManager.java (working copy) @@ -1,57 +0,0 @@ -package org.appfuse.service; - -import java.io.Serializable; -import java.util.List; - -/** - * Business Facade interface. - * - * @author Matt Raible - * - * Modifications and comments by Bryan Noll - * This thing used to be named simply 'GenericManager' in versions of AppFuse prior to 2.0. - * It was renamed in an attempt to distinguish and describe it as something - * different than GenericManager. GenericManager is intended for subclassing, and was - * named Generic because 1) it has very general functionality and 2) is - * 'generic' in the Java 5 sense of the word... aka... it uses Generics. - * - * Implementations of this class are not intended for subclassing. You most - * likely would want to subclass GenericManager. The only real difference is that - * instances of java.lang.Class are passed into the methods in this class, and - * they are part of the constructor in the GenericManager, hence you'll have to do - * some casting if you use this one. - * - * @see com.einvite.service.GenericManager - */ -public interface UniversalManager { - /** - * Generic method used to get a all objects of a particular type. - * @param clazz the type of objects - * @return List of populated objects - */ - List getAll(Class clazz); - - /** - * Generic method to get an object based on class and identifier. - * - * @param clazz model class to lookup - * @param id the identifier (primary key) of the class - * @return a populated object - * @see org.springframework.orm.ObjectRetrievalFailureException - */ - Object get(Class clazz, Serializable id); - - /** - * Generic method to save an object. - * @param o the object to save - * @return a populated object - */ - Object save(Object o); - - /** - * Generic method to delete an object based on class and id - * @param clazz model class to lookup - * @param id the identifier of the class - */ - void remove(Class clazz, Serializable id); -} Index: service/src/main/java/org/appfuse/service/LookupManager.java =================================================================== --- service/src/main/java/org/appfuse/service/LookupManager.java (revision 3174) +++ service/src/main/java/org/appfuse/service/LookupManager.java (working copy) @@ -10,7 +10,7 @@ * * @author Matt Raible */ -public interface LookupManager extends UniversalManager { +public interface LookupManager { /** * Retrieves all possible roles from persistence layer * @return List of LabelValue objects Index: service/src/main/java/org/appfuse/service/UserManager.java =================================================================== --- service/src/main/java/org/appfuse/service/UserManager.java (revision 3174) +++ service/src/main/java/org/appfuse/service/UserManager.java (working copy) @@ -14,8 +14,7 @@ * @author Matt Raible * Modified by Dan Kibler */ -public interface UserManager extends UniversalManager { - +public interface UserManager extends GenericManager { /** * Convenience method for testing - allows you to mock the DAO and set it on an interface. * @param userDao the UserDao implementation to use Index: service/src/main/java/org/appfuse/service/RoleManager.java =================================================================== --- service/src/main/java/org/appfuse/service/RoleManager.java (revision 3174) +++ service/src/main/java/org/appfuse/service/RoleManager.java (working copy) @@ -10,7 +10,7 @@ * * @author Dan Kibler */ -public interface RoleManager extends UniversalManager { +public interface RoleManager extends GenericManager { /** * {@inheritDoc} */ Index: service/src/main/resources/applicationContext-service.xml =================================================================== --- service/src/main/resources/applicationContext-service.xml (revision 3174) +++ service/src/main/resources/applicationContext-service.xml (working copy) @@ -1,9 +1,12 @@ @@ -21,9 +24,12 @@ - - + + + + + @@ -85,26 +91,4 @@ - - - - - - - - - - - - - - - - - - - - - - Index: data/hibernate/src/test/java/org/appfuse/dao/hibernate/HibernateConfigurationTest.java =================================================================== --- data/hibernate/src/test/java/org/appfuse/dao/hibernate/HibernateConfigurationTest.java (revision 3174) +++ data/hibernate/src/test/java/org/appfuse/dao/hibernate/HibernateConfigurationTest.java (working copy) @@ -5,16 +5,16 @@ import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.persister.entity.EntityPersister; +import org.springframework.beans.factory.annotation.Autowired; +import org.junit.Test; import java.util.Map; public class HibernateConfigurationTest extends BaseDaoTestCase { - private SessionFactory sessionFactory; + @Autowired + SessionFactory sessionFactory; - public void setSessionFactory(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - + @Test public void testColumnMapping() throws Exception { Session session = sessionFactory.openSession(); try { Index: data/hibernate/src/test/java/org/appfuse/dao/UserDaoTest.java =================================================================== --- data/hibernate/src/test/java/org/appfuse/dao/UserDaoTest.java (revision 3174) +++ data/hibernate/src/test/java/org/appfuse/dao/UserDaoTest.java (working copy) @@ -4,31 +4,28 @@ import org.appfuse.model.Address; import org.appfuse.model.Role; import org.appfuse.model.User; +import static org.junit.Assert.*; +import org.junit.Test; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; -import junit.framework.Assert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.NotTransactional; +import org.springframework.test.annotation.ExpectedException; public class UserDaoTest extends BaseDaoTestCase { - private UserDao dao = null; - private RoleDao rdao = null; - - public void setUserDao(UserDao dao) { - this.dao = dao; - } - - public void setRoleDao(RoleDao rdao) { - this.rdao = rdao; - } + @Autowired + private UserDao dao; + @Autowired + private RoleDao rdao; + @Test + @ExpectedException(DataAccessException.class) public void testGetUserInvalid() throws Exception { - try { - dao.get(1000L); - fail("'badusername' found in database, failing test..."); - } catch (DataAccessException d) { - assertTrue(d != null); - } + // should throw DataAccessException + dao.get(1000L); } + @Test public void testGetUser() throws Exception { User user = dao.get(-1L); @@ -37,6 +34,7 @@ assertTrue(user.isEnabled()); } + @Test public void testGetUserPassword() throws Exception { User user = dao.get(-1L); String password = dao.getUserPassword(user.getUsername()); @@ -44,6 +42,9 @@ log.debug("password: " + password); } + @Test + @NotTransactional + @ExpectedException(DataIntegrityViolationException.class) public void testUpdateUser() throws Exception { User user = dao.get(-1L); @@ -56,29 +57,22 @@ user = dao.get(-1L); assertEquals(address, user.getAddress()); assertEquals("new address", user.getAddress().getAddress()); - + // verify that violation occurs when adding new user with same username user.setId(null); - endTransaction(); - - try { - dao.saveUser(user); - flush(); - fail("saveUser didn't throw DataIntegrityViolationException"); - } catch (DataIntegrityViolationException e) { - assertNotNull(e); - log.debug("expected exception: " + e.getMessage()); - } + // should throw DataIntegrityViolationException + dao.saveUser(user); } + @Test public void testAddUserRole() throws Exception { User user = dao.get(-1L); assertEquals(1, user.getRoles().size()); Role role = rdao.getRoleByName(Constants.ADMIN_ROLE); user.addRole(role); - user = dao.saveUser(user); + dao.saveUser(user); flush(); user = dao.get(-1L); @@ -100,6 +94,8 @@ assertEquals(1, user.getRoles().size()); } + @Test + @ExpectedException(DataAccessException.class) public void testAddAndRemoveUser() throws Exception { User user = new User("testuser"); user.setPassword("testpass"); @@ -113,7 +109,7 @@ user.setAddress(address); user.setEmail("testuser@appfuse.org"); user.setWebsite("http://raibledesigns.com"); - + Role role = rdao.getRoleByName(Constants.USER_ROLE); assertNotNull(role.getId()); user.addRole(role); @@ -127,20 +123,18 @@ dao.remove(user.getId()); flush(); - - try { - dao.get(user.getId()); - fail("getUser didn't throw DataAccessException"); - } catch (DataAccessException d) { - assertNotNull(d); - } + + // should throw DataAccessException + dao.get(user.getId()); } - + + @Test public void testUserExists() throws Exception { boolean b = dao.exists(-1L); assertTrue(b); } - + + @Test public void testUserNotExists() throws Exception { boolean b = dao.exists(111L); assertFalse(b); Index: data/hibernate/src/test/java/org/appfuse/dao/RoleDaoTest.java =================================================================== --- data/hibernate/src/test/java/org/appfuse/dao/RoleDaoTest.java (revision 3174) +++ data/hibernate/src/test/java/org/appfuse/dao/RoleDaoTest.java (working copy) @@ -6,23 +6,27 @@ import org.appfuse.Constants; import org.appfuse.model.Role; +import static org.junit.Assert.*; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + public class RoleDaoTest extends BaseDaoTestCase { + @Autowired private RoleDao dao; - public void setRoleDao(RoleDao dao) { - this.dao = dao; - } - + @Test public void testGetRoleInvalid() throws Exception { Role role = dao.getRoleByName("badrolename"); assertNull(role); } + @Test public void testGetRole() throws Exception { Role role = dao.getRoleByName(Constants.USER_ROLE); assertNotNull(role); } + @Test public void testUpdateRole() throws Exception { Role role = dao.getRoleByName("ROLE_USER"); role.setDescription("test descr"); @@ -33,6 +37,7 @@ assertEquals("test descr", role.getDescription()); } + @Test public void testAddAndRemoveRole() throws Exception { Role role = new Role("testrole"); role.setDescription("new role descr"); @@ -48,12 +53,9 @@ role = dao.getRoleByName("testrole"); assertNull(role); } - - /** - * Tests the generic findByNamedQuery method - * @throws Exception - */ - public void testFindByNamedQuery() throws Exception { + + @Test + public void testFindByNamedQuery() { HashMap queryParams = new HashMap(); queryParams.put("name", Constants.USER_ROLE); List roles = dao.findByNamedQuery("findRoleByName", queryParams); Index: data/hibernate/src/test/java/org/appfuse/dao/UniversalDaoTest.java =================================================================== --- data/hibernate/src/test/java/org/appfuse/dao/UniversalDaoTest.java (revision 3174) +++ data/hibernate/src/test/java/org/appfuse/dao/UniversalDaoTest.java (working copy) @@ -1,70 +0,0 @@ -package org.appfuse.dao; - -import org.appfuse.model.User; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.orm.ObjectRetrievalFailureException; - -/** - * This class tests the generic GenericDao and BaseDao implementation. - */ -public class UniversalDaoTest extends BaseDaoTestCase { - protected UniversalDao universalDao; - - /** - * This method is used instead of setUniversalDao b/c setUniversalDao uses - * autowire byType setPopulateProtectedVariables(true) can also - * be used, but it's a little bit slower. - */ - public void onSetUpBeforeTransaction() throws Exception { - universalDao = (UniversalDao) applicationContext.getBean("universalDao"); - } - - public void onTearDownAfterTransaction() throws Exception { - universalDao = null; - } - - /** - * Simple test to verify CRUD works. - */ - public void testCRUD() { - User user = new User(); - // set required fields - user.setUsername("foo"); - user.setPassword("bar"); - user.setFirstName("first"); - user.setLastName("last"); - user.getAddress().setCity("Denver"); - user.getAddress().setPostalCode("80465"); - user.setEmail("foo@bar.com"); - - // create - user = (User)universalDao.save(user); - flush(); - assertNotNull(user.getId()); - - // retrieve - user = (User) universalDao.get(User.class, user.getId()); - assertNotNull(user); - assertEquals("last", user.getLastName()); - - // update - user.getAddress().setCountry("USA"); - universalDao.save(user); - flush(); - - user = (User) universalDao.get(User.class, user.getId()); - assertEquals( "USA", user.getAddress().getCountry()); - - // delete - universalDao.remove(User.class, user.getId()); - flush(); - try { - universalDao.get(User.class, user.getId()); - fail("User 'foo' found in database"); - } catch (ObjectRetrievalFailureException e) { - assertNotNull(e.getMessage()); - } catch (InvalidDataAccessApiUsageException e) { // Spring 2.0 throws this one - assertNotNull(e.getMessage()); - } - } -} Index: data/hibernate/src/test/java/org/appfuse/dao/LookupDaoTest.java =================================================================== --- data/hibernate/src/test/java/org/appfuse/dao/LookupDaoTest.java (revision 3174) +++ data/hibernate/src/test/java/org/appfuse/dao/LookupDaoTest.java (working copy) @@ -1,5 +1,9 @@ package org.appfuse.dao; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + import java.util.List; /** @@ -7,14 +11,12 @@ * @author mraible */ public class LookupDaoTest extends BaseDaoTestCase { - private LookupDao dao; - - public void setLookupDao(LookupDao dao) { - this.dao = dao; - } + @Autowired + LookupDao lookupDao; + @Test public void testGetRoles() { - List roles = dao.getRoles(); + List roles = lookupDao.getRoles(); log.debug(roles); assertTrue(roles.size() > 0); } Index: data/hibernate/src/main/java/org/appfuse/dao/GenericDao.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/GenericDao.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/GenericDao.java (working copy) @@ -25,6 +25,14 @@ List getAll(); /** + * Gets all records without duplicates. + *

Note that if you use this method, it is imperative that your model + * classes correctly implement the hashcode/equals methods

+ * @return List of populated objects + */ + List getAllDistinct(); + + /** * Generic method to get an object based on class and identifier. An * ObjectRetrievalFailureException Runtime Exception is thrown if * nothing is found. @@ -54,15 +62,6 @@ * @param id the identifier (primary key) of the object to remove */ void remove(PK id); - - /** - * Gets all records without duplicates. - *

Note that if you use this method, it is imperative that your model - * classes correctly implement the hashcode/equals methods

- * @return List of populated objects - */ - List getAllDistinct(); - /** * Find a list of records by using a named query Index: data/hibernate/src/main/java/org/appfuse/dao/hibernate/LookupDaoHibernate.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/hibernate/LookupDaoHibernate.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/hibernate/LookupDaoHibernate.java (working copy) @@ -3,15 +3,30 @@ import java.util.List; import org.appfuse.dao.LookupDao; +import org.appfuse.dao.GenericDao; import org.appfuse.model.Role; +import org.springframework.stereotype.Repository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.orm.hibernate3.HibernateTemplate; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.logging.Log; +import org.hibernate.SessionFactory; /** * Hibernate implementation of LookupDao. * * @author Matt Raible */ -public class LookupDaoHibernate extends UniversalDaoHibernate implements LookupDao { +@Repository +public class LookupDaoHibernate implements LookupDao { + private Log log = LogFactory.getLog(LookupDaoHibernate.class); + private HibernateTemplate hibernateTemplate; + @Autowired + public LookupDaoHibernate(SessionFactory sessionFactory) { + this.hibernateTemplate = new HibernateTemplate(sessionFactory); + } + /** * {@inheritDoc} */ @@ -19,6 +34,6 @@ public List getRoles() { log.debug("Retrieving all role names..."); - return getHibernateTemplate().find("from Role order by name"); + return hibernateTemplate.find("from Role order by name"); } } Index: data/hibernate/src/main/java/org/appfuse/dao/hibernate/GenericDaoHibernate.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/hibernate/GenericDaoHibernate.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/hibernate/GenericDaoHibernate.java (working copy) @@ -4,12 +4,14 @@ import org.apache.commons.logging.LogFactory; import org.appfuse.dao.GenericDao; import org.springframework.orm.ObjectRetrievalFailureException; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; +import org.springframework.orm.hibernate3.HibernateTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; +import org.hibernate.SessionFactory; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -31,29 +33,46 @@ * @param a type variable * @param the primary key for that type */ -public class GenericDaoHibernate extends HibernateDaoSupport implements GenericDao { +public class GenericDaoHibernate implements GenericDao { /** * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging */ protected final Log log = LogFactory.getLog(getClass()); private Class persistentClass; + private HibernateTemplate hibernateTemplate; + private SessionFactory sessionFactory; /** * Constructor that takes in a class to see which type of entity to persist * @param persistentClass the class type you'd like to persist */ + @Autowired public GenericDaoHibernate(final Class persistentClass) { this.persistentClass = persistentClass; } + public HibernateTemplate getHibernateTemplate() { + return this.hibernateTemplate; + } + + public SessionFactory getSessionFactory() { + return this.sessionFactory; + } + + @Autowired + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + this.hibernateTemplate = new HibernateTemplate(sessionFactory); + } + /** * {@inheritDoc} */ @SuppressWarnings("unchecked") public List getAll() { - return super.getHibernateTemplate().loadAll(this.persistentClass); + return hibernateTemplate.loadAll(this.persistentClass); } - + /** * {@inheritDoc} */ @@ -62,13 +81,13 @@ Collection result = new LinkedHashSet(getAll()); return new ArrayList(result); } - + /** * {@inheritDoc} */ @SuppressWarnings("unchecked") public T get(PK id) { - T entity = (T) super.getHibernateTemplate().get(this.persistentClass, id); + T entity = (T) hibernateTemplate.get(this.persistentClass, id); if (entity == null) { log.warn("Uh oh, '" + this.persistentClass + "' object with id '" + id + "' not found..."); @@ -83,7 +102,7 @@ */ @SuppressWarnings("unchecked") public boolean exists(PK id) { - T entity = (T) super.getHibernateTemplate().get(this.persistentClass, id); + T entity = (T) hibernateTemplate.get(this.persistentClass, id); return entity != null; } @@ -92,35 +111,33 @@ */ @SuppressWarnings("unchecked") public T save(T object) { - return (T) super.getHibernateTemplate().merge(object); + return (T) hibernateTemplate.merge(object); } /** * {@inheritDoc} */ public void remove(PK id) { - super.getHibernateTemplate().delete(this.get(id)); + hibernateTemplate.delete(this.get(id)); } - - /** + + /** * {@inheritDoc} */ @SuppressWarnings("unchecked") public List findByNamedQuery( - String queryName, + String queryName, Map queryParams) { - String []params = new String[queryParams.size()]; - Object []values = new Object[queryParams.size()]; + String[] params = new String[queryParams.size()]; + Object[] values = new Object[queryParams.size()]; int index = 0; - Iterator i = queryParams.keySet().iterator(); - while (i.hasNext()) { - String key = i.next(); - params[index] = key; - values[index++] = queryParams.get(key); + for (String s : queryParams.keySet()) { + params[index] = s; + values[index++] = queryParams.get(s); } - return getHibernateTemplate().findByNamedQueryAndNamedParam( - queryName, - params, + return hibernateTemplate.findByNamedQueryAndNamedParam( + queryName, + params, values); } } Index: data/hibernate/src/main/java/org/appfuse/dao/hibernate/UserDaoHibernate.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/hibernate/UserDaoHibernate.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/hibernate/UserDaoHibernate.java (working copy) @@ -9,6 +9,9 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.orm.hibernate3.SessionFactoryUtils; +import org.springframework.stereotype.Repository; +import org.springframework.beans.factory.annotation.Autowired; +import org.hibernate.SessionFactory; import javax.persistence.Table; import java.util.List; @@ -23,6 +26,7 @@ * Modified by Bryan Noll to work with * the new BaseDaoHibernate implementation that uses generics. */ +@Repository("userDao") public class UserDaoHibernate extends GenericDaoHibernate implements UserDao, UserDetailsService { /** @@ -44,7 +48,8 @@ * {@inheritDoc} */ public User saveUser(User user) { - log.debug("user's id: " + user.getId()); + if (log.isDebugEnabled()) + log.debug("user's id: " + user.getId()); getHibernateTemplate().saveOrUpdate(user); // necessary to throw a DataIntegrityViolation and catch it in UserManager getHibernateTemplate().flush(); Index: data/hibernate/src/main/java/org/appfuse/dao/hibernate/RoleDaoHibernate.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/hibernate/RoleDaoHibernate.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/hibernate/RoleDaoHibernate.java (working copy) @@ -4,6 +4,9 @@ import org.appfuse.dao.RoleDao; import org.appfuse.model.Role; +import org.springframework.stereotype.Repository; +import org.springframework.beans.factory.annotation.Autowired; +import org.hibernate.SessionFactory; /** @@ -12,6 +15,7 @@ * * @author Bryan Noll */ +@Repository public class RoleDaoHibernate extends GenericDaoHibernate implements RoleDao { /** Index: data/hibernate/src/main/java/org/appfuse/dao/hibernate/UniversalDaoHibernate.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/hibernate/UniversalDaoHibernate.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/hibernate/UniversalDaoHibernate.java (working copy) @@ -1,58 +0,0 @@ -package org.appfuse.dao.hibernate; - -import java.io.Serializable; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.appfuse.dao.UniversalDao; -import org.springframework.orm.ObjectRetrievalFailureException; -import org.springframework.orm.hibernate3.support.HibernateDaoSupport; - -/** - * This class serves as the a class that can CRUD any object witout any - * Spring configuration. The only downside is it does require casting - * from Object to the object class. - * - * @author Bryan Noll - */ -public class UniversalDaoHibernate extends HibernateDaoSupport implements UniversalDao { - /** - * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging - */ - protected final Log log = LogFactory.getLog(getClass()); - - /** - * {@inheritDoc} - */ - public Object save(Object o) { - return getHibernateTemplate().merge(o); - } - - /** - * {@inheritDoc} - */ - public Object get(Class clazz, Serializable id) { - Object o = getHibernateTemplate().get(clazz, id); - - if (o == null) { - throw new ObjectRetrievalFailureException(clazz, id); - } - - return o; - } - - /** - * {@inheritDoc} - */ - public List getAll(Class clazz) { - return getHibernateTemplate().loadAll(clazz); - } - - /** - * {@inheritDoc} - */ - public void remove(Class clazz, Serializable id) { - getHibernateTemplate().delete(get(clazz, id)); - } -} Index: data/hibernate/src/main/java/org/appfuse/dao/BaseDaoTestCase.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/BaseDaoTestCase.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/BaseDaoTestCase.java (working copy) @@ -5,19 +5,26 @@ import org.apache.commons.logging.LogFactory; import org.hibernate.SessionFactory; import org.springframework.orm.hibernate3.HibernateTemplate; -import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests; +import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.ResourceBundle; +import java.util.*; /** * Base class for running DAO tests. * @author mraible */ -public abstract class BaseDaoTestCase extends AbstractTransactionalDataSourceSpringContextTests { +@ContextConfiguration( + locations={"classpath:/applicationContext-resources.xml", + "classpath:/applicationContext-dao.xml", + "classpath*:/applicationContext.xml", + "classpath:**/applicationContext*.xml"}) +public abstract class BaseDaoTestCase extends AbstractTransactionalJUnit4SpringContextTests { + @Autowired + private SessionFactory sessionFactory; + /** * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging */ @@ -28,20 +35,6 @@ protected ResourceBundle rb; /** - * Sets AutowireMode to AUTOWIRE_BY_NAME and configures all context files needed to tests DAOs. - * @return String array of Spring context files. - */ - protected String[] getConfigLocations() { - setAutowireMode(AUTOWIRE_BY_NAME); - return new String[] { - "classpath:/applicationContext-resources.xml", - "classpath:/applicationContext-dao.xml", - "classpath*:/applicationContext.xml", // for modular projects - "classpath:**/applicationContext*.xml" // for web projects - }; - } - - /** * Default constructor - populates "rb" variable if properties file exists for the class in * src/test/resources. */ @@ -81,10 +74,10 @@ /** * Create a HibernateTemplate from the SessionFactory and call flush() and clear() on it. * Designed to be used after "save" methods in tests: http://issues.appfuse.org/browse/APF-178. + * @throws org.springframework.beans.BeansException when can't find 'sessionFactory' bean */ - protected void flush() { - HibernateTemplate hibernateTemplate = - new HibernateTemplate((SessionFactory) applicationContext.getBean("sessionFactory")); + protected void flush() throws BeansException { + HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory); hibernateTemplate.flush(); hibernateTemplate.clear(); } Index: data/hibernate/src/main/java/org/appfuse/dao/UniversalDao.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/UniversalDao.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/UniversalDao.java (working copy) @@ -1,62 +0,0 @@ -package org.appfuse.dao; - -import java.io.Serializable; -import java.util.List; - - -/** - * Data Access Object (DAO) interface. - * - * @author Matt Raible - * - * Modifications and comments by Bryan Noll - * This thing used to be named simply 'GenericDao' in versions of appfuse prior to 2.0. - * It was renamed in an attempt to distinguish and describe it as something - * different than GenericDao. GenericDao is intended for subclassing, and was - * named Generic because 1) it has very general functionality and 2) is - * 'generic' in the Java 5 sense of the word... aka... it uses Generics. - * - * Implementations of this class are not intended for subclassing. You most - * likely would want to subclass GenericDao. The only real difference is that - * instances of java.lang.Class are passed into the methods in this class, and - * they are part of the constructor in the GenericDao, hence you'll have to do - * some casting if you use this one. - * - * @see org.appfuse.dao.GenericDao - */ -public interface UniversalDao { - - /** - * Generic method used to get all objects of a particular type. This - * is the same as lookup up all rows in a table. - * @param clazz the type of objects (a.k.a. while table) to get data from - * @return List of populated objects - */ - List getAll(Class clazz); - - /** - * Generic method to get an object based on class and identifier. An - * ObjectRetrievalFailureException Runtime Exception is thrown if - * nothing is found. - * - * @param clazz model class to lookup - * @param id the identifier (primary key) of the class - * @return a populated object - * @see org.springframework.orm.ObjectRetrievalFailureException - */ - Object get(Class clazz, Serializable id); - - /** - * Generic method to save an object - handles both update and insert. - * @param o the object to save - * @return a populated object - */ - Object save(Object o); - - /** - * Generic method to delete an object based on class and id - * @param clazz model class to lookup - * @param id the identifier (primary key) of the class - */ - void remove(Class clazz, Serializable id); -} \ No newline at end of file Index: data/hibernate/src/main/java/org/appfuse/dao/LookupDao.java =================================================================== --- data/hibernate/src/main/java/org/appfuse/dao/LookupDao.java (revision 3174) +++ data/hibernate/src/main/java/org/appfuse/dao/LookupDao.java (working copy) @@ -10,7 +10,7 @@ * * @author Matt Raible */ -public interface LookupDao extends UniversalDao { +public interface LookupDao { //~ Methods ================================================================ /** Index: data/hibernate/src/main/resources/applicationContext-dao.xml =================================================================== --- data/hibernate/src/main/resources/applicationContext-dao.xml (revision 3174) +++ data/hibernate/src/main/resources/applicationContext-dao.xml (working copy) @@ -1,8 +1,12 @@ + + @@ -23,42 +27,11 @@ - - - - - - - - - - - - - - - - - - + + - + + Index: data/common/src/main/java/org/appfuse/model/Address.java =================================================================== --- data/common/src/main/java/org/appfuse/model/Address.java (revision 3174) +++ data/common/src/main/java/org/appfuse/model/Address.java (working copy) @@ -28,7 +28,7 @@ return address; } - @Column(nullable=false,length=50) + @Column(length=50) public String getCity() { return city; } @@ -43,7 +43,7 @@ return country; } - @Column(name="postal_code",nullable=false,length=15) + @Column(name="postal_code",length=15) public String getPostalCode() { return postalCode; } Index: data/jpa/src/test/java/org/appfuse/dao/UserDaoTest.java =================================================================== --- data/jpa/src/test/java/org/appfuse/dao/UserDaoTest.java (revision 3174) +++ data/jpa/src/test/java/org/appfuse/dao/UserDaoTest.java (working copy) @@ -1,34 +1,32 @@ package org.appfuse.dao; -import javax.persistence.EntityNotFoundException; -import javax.persistence.PersistenceException; - import org.appfuse.Constants; import org.appfuse.model.Address; import org.appfuse.model.Role; import org.appfuse.model.User; +import static org.junit.Assert.*; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.orm.ObjectRetrievalFailureException; +import org.springframework.test.annotation.ExpectedException; +import org.springframework.test.annotation.NotTransactional; +import org.springframework.dao.DataIntegrityViolationException; +import javax.persistence.PersistenceException; + public class UserDaoTest extends BaseDaoTestCase { - private UserDao dao = null; - private RoleDao rdao = null; - - public void setUserDao(UserDao dao) { - this.dao = dao; - } - - public void setRoleDao(RoleDao rdao) { - this.rdao = rdao; - } + @Autowired + private UserDao dao; + @Autowired + private RoleDao rdao; + @Test + @ExpectedException(ObjectRetrievalFailureException.class) public void testGetUserInvalid() throws Exception { - try { - dao.get(1000L); - fail("'badusername' found in database, failing test..."); - } catch (EntityNotFoundException e) { - assertTrue(e != null); - } + dao.get(1000L); } + @Test public void testGetUser() throws Exception { User user = dao.get(-1L); @@ -37,6 +35,7 @@ assertTrue(user.isEnabled()); } + @Test public void testGetUserPassword() throws Exception { User user = dao.get(-1L); String password = dao.getUserPassword(user.getUsername()); @@ -44,7 +43,8 @@ log.debug("password: " + password); } - + @Test + //@ExpectedException(DataIntegrityViolationException.class) public void testUpdateUser() throws Exception { User user = dao.get(-1L); @@ -53,24 +53,18 @@ dao.save(user); + user = dao.get(-1L); assertEquals(user.getAddress(), address); assertEquals("new address", user.getAddress().getAddress()); - super.endTransaction(); - //verify that violation occurs when adding new user with same username user.setId(null); - super.startNewTransaction(); - try { - dao.save(user); - fail("saveUser didn't throw PersistenceException"); - } catch (PersistenceException e) { - assertNotNull(e); - log.debug("expected exception: " + e.getMessage()); - } + // should throw DataIntegrityViolationException + dao.save(user); } + @Test public void testAddUserRole() throws Exception { User user = dao.get(-1L); assertEquals(1, user.getRoles().size()); @@ -93,6 +87,8 @@ assertEquals(1, user.getRoles().size()); } + @Test + @ExpectedException(ObjectRetrievalFailureException.class) public void testAddAndRemoveUser() throws Exception { User user = new User("testuser"); user.setPassword("testpass"); @@ -118,21 +114,17 @@ dao.remove(user.getId()); - try { - dao.get(user.getId()); - fail("getUser didn't throw DataAccessException"); - } catch (EntityNotFoundException e) { - assertNotNull(e); - } + // should throw EntityNotFoundException + dao.get(user.getId()); } public void testUserExists() throws Exception { boolean b = dao.exists(-1L); - super.assertTrue(b); + assertTrue(b); } public void testUserNotExists() throws Exception { boolean b = dao.exists(111L); - super.assertFalse(b); + assertFalse(b); } } Index: data/jpa/src/test/java/org/appfuse/dao/RoleDaoTest.java =================================================================== --- data/jpa/src/test/java/org/appfuse/dao/RoleDaoTest.java (revision 3174) +++ data/jpa/src/test/java/org/appfuse/dao/RoleDaoTest.java (working copy) @@ -3,23 +3,28 @@ import org.appfuse.Constants; import org.appfuse.model.Role; +import static org.junit.Assert.*; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.NotTransactional; + public class RoleDaoTest extends BaseDaoTestCase { + @Autowired private RoleDao dao; - public void setRoleDao(RoleDao dao) { - this.dao = dao; - } - + @Test public void testGetRoleInvalid() throws Exception { Role role = dao.getRoleByName("badrolename"); assertNull(role); } + @Test public void testGetRole() throws Exception { Role role = dao.getRoleByName(Constants.USER_ROLE); assertNotNull(role); } + @Test public void testUpdateRole() throws Exception { Role role = dao.getRoleByName("ROLE_USER"); log.debug(role); @@ -29,22 +34,23 @@ assertEquals(role.getDescription(), "test descr"); } + @Test public void testAddAndRemoveRole() throws Exception { Role role = new Role("testrole"); role.setDescription("new role descr"); dao.save(role); - setComplete(); // change behavior from rollback to commit - endTransaction(); + //setComplete(); // change behavior from rollback to commit + //endTransaction(); - startNewTransaction(); + //startNewTransaction(); role = dao.getRoleByName("testrole"); assertNotNull(role.getDescription()); dao.removeRole("testrole"); - setComplete(); - super.endTransaction(); // deletes role from database + //setComplete(); + //super.endTransaction(); // deletes role from database - super.startNewTransaction(); + //super.startNewTransaction(); role = dao.getRoleByName("testrole"); assertNull(role); } Index: data/jpa/src/test/java/org/appfuse/dao/UniversalDaoTest.java =================================================================== --- data/jpa/src/test/java/org/appfuse/dao/UniversalDaoTest.java (revision 3174) +++ data/jpa/src/test/java/org/appfuse/dao/UniversalDaoTest.java (working copy) @@ -1,76 +0,0 @@ -package org.appfuse.dao; - -import javax.persistence.EntityNotFoundException; - -import org.appfuse.model.User; - -import java.util.List; - -/** - * This class tests the generic GenericDao and BaseDao implementation. - */ -public class UniversalDaoTest extends BaseDaoTestCase { - protected UniversalDao universalDao; - - /** - * This method is used instead of setUniversalDao b/c setUniversalDao uses - * autowire byType setPopulateProtectedVariables(true) can also - * be used, but it's a little bit slower. - */ - public void onSetUpBeforeTransaction() throws Exception { - universalDao = (UniversalDao) applicationContext.getBean("universalDao"); - } - - public void onTearDownAfterTransaction() throws Exception { - universalDao = null; - } - - @SuppressWarnings("unchecked") - public void testGetAll() { - List users = universalDao.getAll(User.class); - assertEquals(users.size(), 2); - } - - /** - * Simple test to verify CRUD works. - */ - public void testCRUD() { - User user = new User(); - // set required fields - user.setUsername("foo"); - user.setPassword("bar"); - user.setFirstName("first"); - user.setLastName("last"); - user.getAddress().setCity("Denver"); - user.getAddress().setPostalCode("80465"); - user.setEmail("foo@bar.com"); - - // create - user = (User)universalDao.save(user); - assertNotNull(user.getId()); - - // retrieve - user = (User) universalDao.get(User.class, user.getId()); - assertNotNull(user); - assertEquals(user.getLastName(), "last"); - - // update - user.getAddress().setCountry("USA"); - universalDao.save(user); - assertEquals(user.getAddress().getCountry(), "USA"); - - // delete - universalDao.remove(User.class, user.getId()); - try { - universalDao.get(User.class, user.getId()); - fail("User 'foo' found in database"); - } catch (EntityNotFoundException e) { - super.assertNotNull(e); - } -// catch (ObjectRetrievalFailureException e) { -// assertNotNull(e.getMessage()); -// } catch (InvalidDataAccessApiUsageException e) { // Spring 2.0 throws this one -// assertNotNull(e.getMessage()); -// } - } -} Index: data/jpa/src/test/java/org/appfuse/dao/LookupDaoTest.java =================================================================== --- data/jpa/src/test/java/org/appfuse/dao/LookupDaoTest.java (revision 3174) +++ data/jpa/src/test/java/org/appfuse/dao/LookupDaoTest.java (working copy) @@ -1,5 +1,9 @@ package org.appfuse.dao; +import org.springframework.beans.factory.annotation.Autowired; +import org.junit.Test; +import static org.junit.Assert.*; + import java.util.List; /** @@ -7,12 +11,10 @@ * @author mraible */ public class LookupDaoTest extends BaseDaoTestCase { + @Autowired private LookupDao dao; - - public void setLookupDao(LookupDao dao) { - this.dao = dao; - } + @Test public void testGetRoles() { List roles = dao.getRoles(); log.debug(roles); Index: data/jpa/src/main/java/org/appfuse/dao/GenericDao.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/GenericDao.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/GenericDao.java (working copy) @@ -24,6 +24,14 @@ List getAll(); /** + * Gets all records without duplicates. + *

Note that if you use this method, it is imperative that your model + * classes correctly implement the hashcode/equals methods

+ * @return List of populated objects + */ + List getAllDistinct(); + + /** * Generic method to get an object based on class and identifier. An * ObjectRetrievalFailureException Runtime Exception is thrown if * nothing is found. Index: data/jpa/src/main/java/org/appfuse/dao/BaseDaoTestCase.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/BaseDaoTestCase.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/BaseDaoTestCase.java (working copy) @@ -4,6 +4,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.test.jpa.AbstractJpaTests; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import java.util.Enumeration; import java.util.HashMap; @@ -15,7 +17,12 @@ * Base class for running DAO tests. * @author mraible */ -public abstract class BaseDaoTestCase extends AbstractJpaTests { +@ContextConfiguration( + locations={"classpath:/applicationContext-resources.xml", + "classpath:/applicationContext-dao.xml", + "classpath*:/applicationContext.xml", + "classpath:**/applicationContext*.xml"}) +public abstract class BaseDaoTestCase extends AbstractTransactionalJUnit4SpringContextTests { /** * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging */ @@ -26,20 +33,6 @@ protected ResourceBundle rb; /** - * Sets AutowireMode to AUTOWIRE_BY_NAME and configures all context files needed to tests DAOs. - * @return String array of Spring context files. - */ - protected String[] getConfigLocations() { - setAutowireMode(AUTOWIRE_BY_NAME); - return new String[] { - "classpath:/applicationContext-resources.xml", - "classpath:/applicationContext-dao.xml", - "classpath*:/applicationContext.xml", // for modular projects - "classpath:**/applicationContext*.xml" // for web projects - }; - } - - /** * Default constructor - populates "rb" variable if properties file exists for the class in * src/test/resources. */ Index: data/jpa/src/main/java/org/appfuse/dao/jpa/RoleDaoJpa.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/jpa/RoleDaoJpa.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/jpa/RoleDaoJpa.java (working copy) @@ -6,6 +6,7 @@ import org.appfuse.dao.RoleDao; import org.appfuse.model.Role; +import org.springframework.stereotype.Repository; /** @@ -14,6 +15,7 @@ * * @author Bryan Noll */ +@Repository public class RoleDaoJpa extends GenericDaoJpa implements RoleDao { /** @@ -27,7 +29,7 @@ * {@inheritDoc} */ public Role getRoleByName(String rolename) { - Query q = super.entityManager.createQuery("select r from Role r where r.name = ?"); + Query q = getEntityManager().createQuery("select r from Role r where r.name = ?"); q.setParameter(1, rolename); List roles = q.getResultList(); @@ -43,6 +45,6 @@ */ public void removeRole(String rolename) { Object role = getRoleByName(rolename); - super.entityManager.remove(role); + getEntityManager().remove(role); } } Index: data/jpa/src/main/java/org/appfuse/dao/jpa/UniversalDaoJpa.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/jpa/UniversalDaoJpa.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/jpa/UniversalDaoJpa.java (working copy) @@ -1,71 +0,0 @@ -package org.appfuse.dao.jpa; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.appfuse.dao.UniversalDao; - -import javax.persistence.EntityManager; -import javax.persistence.EntityNotFoundException; -import javax.persistence.PersistenceContext; -import java.io.Serializable; -import java.util.List; - -/** - * This class serves as the a class that can CRUD any object witout any - * Spring configuration. The only downside is it does require casting - * from Object to the object class. - * - * @author Bryan Noll - */ -public class UniversalDaoJpa implements UniversalDao { - /** - * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging - */ - protected final Log log = LogFactory.getLog(getClass()); - /** - * Entity manager, injected by Spring using @PersistenceContext annotation on setEntityManager() - */ - protected EntityManager entityManager; - - @PersistenceContext(unitName="ApplicationEntityManager") - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } - - /** - * {@inheritDoc} - */ - public Object save(Object o) { - return this.entityManager.merge(o); - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public Object get(Class clazz, Serializable id) { - Object o = this.entityManager.find(clazz, id); - - if (o == null) { - String msg = "Uh oh, '" + clazz + "' object with id '" + id + "' not found..."; - log.warn(msg); - throw new EntityNotFoundException(msg); - } - - return o; - } - - /** - * {@inheritDoc} - */ - public List getAll(Class clazz) { - return this.entityManager.createQuery("select obj from " + clazz.getSimpleName() + " obj").getResultList(); - } - - /** - * {@inheritDoc} - */ - public void remove(Class clazz, Serializable id) { - this.entityManager.remove(this.get(clazz, id)); - } -} Index: data/jpa/src/main/java/org/appfuse/dao/jpa/LookupDaoJpa.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/jpa/LookupDaoJpa.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/jpa/LookupDaoJpa.java (working copy) @@ -4,13 +4,23 @@ import org.appfuse.dao.LookupDao; import org.appfuse.model.Role; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.stereotype.Repository; +import javax.persistence.PersistenceContext; +import javax.persistence.EntityManager; + /** * JPA implementation of LookupDao. * * @author Bryan Noll */ -public class LookupDaoJpa extends UniversalDaoJpa implements LookupDao { +@Repository +public class LookupDaoJpa implements LookupDao { + private Log log = LogFactory.getLog(LookupDaoJpa.class); + @PersistenceContext + EntityManager entityManager; /** * {@inheritDoc} @@ -19,7 +29,7 @@ public List getRoles() { log.debug("Retrieving all role names..."); - return super.entityManager.createQuery( + return entityManager.createQuery( "select r from Role r order by name").getResultList(); } } Index: data/jpa/src/main/java/org/appfuse/dao/jpa/GenericDaoJpa.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/jpa/GenericDaoJpa.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/jpa/GenericDaoJpa.java (working copy) @@ -9,6 +9,9 @@ import javax.persistence.PersistenceContext; import java.io.Serializable; import java.util.List; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.ArrayList; /** * This class serves as the Base class for all other DAOs - namely to hold @@ -32,10 +35,14 @@ * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging */ protected final Log log = LogFactory.getLog(getClass()); + + public static final String PERSISTENCE_UNIT_NAME = "ApplicationEntityManager"; + /** * Entity manager, injected by Spring using @PersistenceContext annotation on setEntityManager() */ - protected EntityManager entityManager; + @PersistenceContext(unitName=PERSISTENCE_UNIT_NAME) + private EntityManager entityManager; private Class persistentClass; /** @@ -46,11 +53,10 @@ this.persistentClass = persistentClass; } - @PersistenceContext(unitName="ApplicationEntityManager") - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; + public EntityManager getEntityManager() { + return this.entityManager; } - + /** * {@inheritDoc} */ @@ -64,6 +70,15 @@ /** * {@inheritDoc} */ + @SuppressWarnings("unchecked") + public List getAllDistinct() { + Collection result = new LinkedHashSet(getAll()); + return new ArrayList(result); + } + + /** + * {@inheritDoc} + */ public T get(PK id) { T entity = this.entityManager.find(this.persistentClass, id); Index: data/jpa/src/main/java/org/appfuse/dao/jpa/UserDaoJpa.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/jpa/UserDaoJpa.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/jpa/UserDaoJpa.java (working copy) @@ -9,6 +9,7 @@ import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.transaction.annotation.Transactional; import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.stereotype.Repository; import javax.persistence.Query; import javax.persistence.Table; @@ -25,16 +26,16 @@ * Modified by Bryan Noll to work with * the new BaseDaoHibernate implementation that uses generics. */ +@Repository("userDao") public class UserDaoJpa extends GenericDaoJpa implements UserDao, UserDetailsService { + @Autowired private DataSource dataSource; /** * Constructor that sets the entity to User.class. - * @param dataSource the dataSource to use for looking up user's password with a jdbcTemplate */ - public UserDaoJpa(DataSource dataSource) { + public UserDaoJpa() { super(User.class); - this.dataSource = dataSource; } /** @@ -42,7 +43,7 @@ */ @SuppressWarnings("unchecked") public List getUsers() { - Query q = this.entityManager.createQuery("select u from User u order by upper(u.username)"); + Query q = getEntityManager().createQuery("select u from User u order by upper(u.username)"); return q.getResultList(); } @@ -52,7 +53,7 @@ @SuppressWarnings("unchecked") @Transactional public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - Query q = this.entityManager.createQuery("select u from User u where username=?"); + Query q = getEntityManager().createQuery("select u from User u where username=?"); q.setParameter(1, username); List users = q.getResultList(); if (users == null || users.isEmpty()) { @@ -69,7 +70,7 @@ */ public User saveUser(User user) { User u = super.save(user); - entityManager.flush(); + getEntityManager().flush(); return u; } Index: data/jpa/src/main/java/org/appfuse/dao/UniversalDao.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/UniversalDao.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/UniversalDao.java (working copy) @@ -1,62 +0,0 @@ -package org.appfuse.dao; - -import java.io.Serializable; -import java.util.List; - - -/** - * Data Access Object (DAO) interface. - * - * @author Matt Raible - * - * Modifications and comments by Bryan Noll - * This thing used to be named simply 'GenericDao' in versions of appfuse prior to 2.0. - * It was renamed in an attempt to distinguish and describe it as something - * different than GenericDao. GenericDao is intended for subclassing, and was - * named Generic because 1) it has very general functionality and 2) is - * 'generic' in the Java 5 sense of the word... aka... it uses Generics. - * - * Implementations of this class are not intended for subclassing. You most - * likely would want to subclass GenericDao. The only real difference is that - * instances of java.lang.Class are passed into the methods in this class, and - * they are part of the constructor in the GenericDao, hence you'll have to do - * some casting if you use this one. - * - * @see org.appfuse.dao.GenericDao - */ -public interface UniversalDao { - - /** - * Generic method used to get all objects of a particular type. This - * is the same as lookup up all rows in a table. - * @param clazz the type of objects (a.k.a. while table) to get data from - * @return List of populated objects - */ - List getAll(Class clazz); - - /** - * Generic method to get an object based on class and identifier. An - * ObjectRetrievalFailureException Runtime Exception is thrown if - * nothing is found. - * - * @param clazz model class to lookup - * @param id the identifier (primary key) of the class - * @return a populated object - * @see org.springframework.orm.ObjectRetrievalFailureException - */ - Object get(Class clazz, Serializable id); - - /** - * Generic method to save an object - handles both update and insert. - * @param o the object to save - * @return a populated object - */ - Object save(Object o); - - /** - * Generic method to delete an object based on class and id - * @param clazz model class to lookup - * @param id the identifier (primary key) of the class - */ - void remove(Class clazz, Serializable id); -} \ No newline at end of file Index: data/jpa/src/main/java/org/appfuse/dao/LookupDao.java =================================================================== --- data/jpa/src/main/java/org/appfuse/dao/LookupDao.java (revision 3174) +++ data/jpa/src/main/java/org/appfuse/dao/LookupDao.java (working copy) @@ -10,7 +10,7 @@ * * @author Matt Raible */ -public interface LookupDao extends UniversalDao { +public interface LookupDao { //~ Methods ================================================================ /** Index: data/jpa/src/main/resources/applicationContext-dao.xml =================================================================== --- data/jpa/src/main/resources/applicationContext-dao.xml (revision 3174) +++ data/jpa/src/main/resources/applicationContext-dao.xml (working copy) @@ -1,8 +1,12 @@ + + @@ -35,34 +39,9 @@ - - + + - - - - - - - - - - - - - - + + Index: data/pom.xml =================================================================== --- data/pom.xml (revision 3174) +++ data/pom.xml (working copy) @@ -53,6 +53,11 @@ org.springframework + spring-aop + ${spring.version} + + + org.springframework spring-jdbc ${spring.version} Index: data/ibatis/src/test/java/org/appfuse/dao/UserDaoTest.java =================================================================== --- data/ibatis/src/test/java/org/appfuse/dao/UserDaoTest.java (revision 3174) +++ data/ibatis/src/test/java/org/appfuse/dao/UserDaoTest.java (working copy) @@ -6,28 +6,24 @@ import org.appfuse.model.User; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.ExpectedException; +import static org.junit.Assert.*; +import org.junit.Test; public class UserDaoTest extends BaseDaoTestCase { - private UserDao dao = null; - private RoleDao rdao = null; - - public void setUserDao(UserDao dao) { - this.dao = dao; - } - - public void setRoleDao(RoleDao rdao) { - this.rdao = rdao; - } + @Autowired + private UserDao dao; + @Autowired + private RoleDao rdao; + @Test + @ExpectedException(DataAccessException.class) public void testGetUserInvalid() throws Exception { - try { - dao.get(1000L); - fail("'badusername' found in database, failing test..."); - } catch (DataAccessException d) { - assertTrue(d != null); - } + dao.get(1000L); } + @Test public void testGetUser() throws Exception { User user = dao.get(-1L); @@ -36,12 +32,15 @@ assertTrue(user.isEnabled()); } + @Test public void testGetUserPassword() throws Exception { User user = dao.get(-1L); String password = dao.getUserPassword(user.getUsername()); assertNotNull(password); } + @Test + @ExpectedException(DataIntegrityViolationException.class) public void testUpdateUser() throws Exception { User user = dao.get(-1L); @@ -56,17 +55,12 @@ // verify that violation occurs when adding new user with same username user.setId(null); - endTransaction(); + //endTransaction(); - try { - user = dao.saveUser(user); - fail("saveUser didn't throw DataIntegrityViolationException"); - } catch (DataIntegrityViolationException e) { - assertNotNull(e); - log.debug("expected exception: " + e.getMessage()); - } + dao.saveUser(user); } + @Test public void testAddUserRole() throws Exception { User user = dao.get(-1L); assertEquals(1, user.getRoles().size()); @@ -89,6 +83,8 @@ assertEquals(1, user.getRoles().size()); } + @Test + @ExpectedException(DataAccessException.class) public void testAddAndRemoveUser() throws Exception { User user = new User("testuser"); user.setPassword("testpass"); @@ -114,21 +110,17 @@ dao.remove(user.getId()); - try { - dao.get(user.getId()); - fail("getUser didn't throw DataAccessException"); - } catch (DataAccessException d) { - assertNotNull(d); - } + // should throw DataAccessException + dao.get(user.getId()); } public void testUserExists() throws Exception { boolean b = dao.exists(-1L); - super.assertTrue(b); + assertTrue(b); } public void testUserNotExists() throws Exception { boolean b = dao.exists(111L); - super.assertFalse(b); + assertFalse(b); } } Index: data/ibatis/src/test/java/org/appfuse/dao/RoleDaoTest.java =================================================================== --- data/ibatis/src/test/java/org/appfuse/dao/RoleDaoTest.java (revision 3174) +++ data/ibatis/src/test/java/org/appfuse/dao/RoleDaoTest.java (working copy) @@ -2,49 +2,53 @@ import org.appfuse.Constants; import org.appfuse.model.Role; +import static org.junit.Assert.*; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; public class RoleDaoTest extends BaseDaoTestCase { + @Autowired private RoleDao dao; - public void setRoleDao(RoleDao dao) { - this.dao = dao; - } - + @Test public void testGetRoleInvalid() throws Exception { Role role = dao.getRoleByName("badrolename"); assertNull(role); } + @Test public void testGetRole() throws Exception { Role role = dao.getRoleByName(Constants.USER_ROLE); assertNotNull(role); } + @Test public void testUpdateRole() throws Exception { Role role = dao.getRoleByName("ROLE_USER"); log.debug(role); role.setDescription("test descr"); - role = dao.save(role); + dao.save(role); role = dao.getRoleByName("ROLE_USER"); assertEquals(role.getDescription(), "test descr"); } + @Test public void testAddAndRemoveRole() throws Exception { Role role = new Role("testrole"); role.setDescription("new role descr"); dao.save(role); - setComplete(); // change behavior from rollback to commit - endTransaction(); + //setComplete(); // change behavior from rollback to commit + //endTransaction(); - startNewTransaction(); + //startNewTransaction(); role = dao.getRoleByName("testrole"); assertNotNull(role.getDescription()); dao.removeRole("testrole"); - setComplete(); - endTransaction(); // deletes role from database + //setComplete(); + //endTransaction(); // deletes role from database role = dao.getRoleByName("testrole"); assertNull(role); Index: data/ibatis/src/test/java/org/appfuse/dao/LookupDaoTest.java =================================================================== --- data/ibatis/src/test/java/org/appfuse/dao/LookupDaoTest.java (revision 3174) +++ data/ibatis/src/test/java/org/appfuse/dao/LookupDaoTest.java (working copy) @@ -1,5 +1,9 @@ package org.appfuse.dao; +import static org.junit.Assert.*; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + import java.util.List; /** @@ -7,12 +11,10 @@ * @author mraible */ public class LookupDaoTest extends BaseDaoTestCase { + @Autowired private LookupDao dao; - - public void setLookupDao(LookupDao dao) { - this.dao = dao; - } + @Test public void testGetRoles() { List roles = dao.getRoles(); log.debug(roles); Index: data/ibatis/src/main/java/org/appfuse/dao/GenericDao.java =================================================================== --- data/ibatis/src/main/java/org/appfuse/dao/GenericDao.java (revision 3174) +++ data/ibatis/src/main/java/org/appfuse/dao/GenericDao.java (working copy) @@ -2,6 +2,9 @@ import java.io.Serializable; import java.util.List; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.ArrayList; /** @@ -24,6 +27,14 @@ List getAll(); /** + * Gets all records without duplicates. + *

Note that if you use this method, it is imperative that your model + * classes correctly implement the hashcode/equals methods

+ * @return List of populated objects + */ + List getAllDistinct(); + + /** * Generic method to get an object based on class and identifier. An * ObjectRetrievalFailureException Runtime Exception is thrown if * nothing is found. Index: data/ibatis/src/main/java/org/appfuse/dao/BaseDaoTestCase.java =================================================================== --- data/ibatis/src/main/java/org/appfuse/dao/BaseDaoTestCase.java (revision 3174) +++ data/ibatis/src/main/java/org/appfuse/dao/BaseDaoTestCase.java (working copy) @@ -3,7 +3,8 @@ import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests; +import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; +import org.springframework.test.context.ContextConfiguration; import java.util.Enumeration; import java.util.HashMap; @@ -15,7 +16,12 @@ * Base class for running DAO tests. * @author mraible */ -public abstract class BaseDaoTestCase extends AbstractTransactionalDataSourceSpringContextTests { +@ContextConfiguration( + locations={"classpath:/applicationContext-resources.xml", + "classpath:/applicationContext-dao.xml", + "classpath*:/applicationContext.xml", + "classpath:**/applicationContext*.xml"}) +public abstract class BaseDaoTestCase extends AbstractTransactionalJUnit4SpringContextTests { /** * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging */ @@ -24,22 +30,8 @@ * ResourceBundle loaded from src/test/resources/${package.name}/ClassName.properties (if exists) */ protected ResourceBundle rb; - + /** - * Sets AutowireMode to AUTOWIRE_BY_NAME and configures all context files needed to tests DAOs. - * @return String array of Spring context files. - */ - protected String[] getConfigLocations() { - setAutowireMode(AUTOWIRE_BY_NAME); - return new String[] { - "classpath:/applicationContext-resources.xml", - "classpath:/applicationContext-dao.xml", - "classpath*:/applicationContext.xml", // for modular projects - "classpath:**/applicationContext*.xml" // for web projects - }; - } - - /** * Default constructor - populates "rb" variable if properties file exists for the class in * src/test/resources. */ Index: data/ibatis/src/main/java/org/appfuse/dao/ibatis/RoleDaoiBatis.java =================================================================== --- data/ibatis/src/main/java/org/appfuse/dao/ibatis/RoleDaoiBatis.java (revision 3174) +++ data/ibatis/src/main/java/org/appfuse/dao/ibatis/RoleDaoiBatis.java (working copy) @@ -2,6 +2,7 @@ import org.appfuse.dao.RoleDao; import org.appfuse.model.Role; +import org.springframework.stereotype.Repository; import java.util.List; @@ -11,6 +12,7 @@ * * @author Matt Raible */ +@Repository public class RoleDaoiBatis extends GenericDaoiBatis implements RoleDao { /** @@ -23,7 +25,8 @@ /** * {@inheritDoc} */ - @Override @SuppressWarnings("unchecked") + @Override + @SuppressWarnings("unchecked") public List getAll() { return getSqlMapClientTemplate().queryForList("getRoles", null); } Index: data/ibatis/src/main/java/org/appfuse/dao/ibatis/UniversalDaoiBatis.java =================================================================== --- data/ibatis/src/main/java/org/appfuse/dao/ibatis/UniversalDaoiBatis.java (revision 3174) +++ data/ibatis/src/main/java/org/appfuse/dao/ibatis/UniversalDaoiBatis.java (working copy) @@ -1,89 +0,0 @@ -package org.appfuse.dao.ibatis; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.appfuse.dao.UniversalDao; -import org.springframework.orm.ObjectRetrievalFailureException; -import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport; -import org.springframework.util.ClassUtils; - -import java.io.Serializable; -import java.util.List; - -/** - * This class serves as the a class that can CRUD any object witout any - * Spring configuration. The only downside is it does require casting - * from Object to the object class. - * - * @author Bobby Diaz, Bryan Noll - */ -public class UniversalDaoiBatis extends SqlMapClientDaoSupport implements UniversalDao { - /** - * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging - */ - protected final Log log = LogFactory.getLog(getClass()); - - /** - * {@inheritDoc} - */ - public List getAll(Class clazz) { - return getSqlMapClientTemplate().queryForList( - iBatisDaoUtils.getSelectQuery(ClassUtils.getShortName(clazz)), null); - } - - /** - * {@inheritDoc} - */ - public Object get(Class clazz, Serializable primaryKey) { - Object object = getSqlMapClientTemplate().queryForObject( - iBatisDaoUtils.getFindQuery(ClassUtils.getShortName(clazz)), primaryKey); - if (object == null) { - throw new ObjectRetrievalFailureException(ClassUtils.getShortName(clazz), primaryKey); - } - return object; - } - - /** - * {@inheritDoc} - */ - public Object save(final Object object) { - String className = ClassUtils.getShortName(object.getClass()); - Object primaryKey = iBatisDaoUtils.getPrimaryKeyValue(object); - String keyId = null; - - // check for null id - if (primaryKey != null) { - keyId = primaryKey.toString(); - } - - // check for new record - if (StringUtils.isBlank(keyId)) { - iBatisDaoUtils.prepareObjectForSaveOrUpdate(object); - primaryKey = getSqlMapClientTemplate().insert(iBatisDaoUtils.getInsertQuery(className), object); - - // check for null id - if (primaryKey != null) { - keyId = primaryKey.toString(); - } - iBatisDaoUtils.setPrimaryKey(object, Long.class, new Long(keyId)); - } else { - iBatisDaoUtils.prepareObjectForSaveOrUpdate(object); - getSqlMapClientTemplate().update(iBatisDaoUtils.getUpdateQuery(className), object); - } - - // check for null id - if (iBatisDaoUtils.getPrimaryKeyValue(object) == null) { - throw new ObjectRetrievalFailureException(className, object); - } else { - return object; - } - } - - /** - * {@inheritDoc} - */ - public void remove(Class clazz, Serializable primaryKey) { - getSqlMapClientTemplate().update(iBatisDaoUtils.getDeleteQuery(ClassUtils.getShortName(clazz)), primaryKey); - } -} Index: data/ibatis/src/main/java/org/appfuse/dao/ibatis/LookupDaoiBatis.java =================================================================== --- data/ibatis/src/main/java/org/appfuse/dao/ibatis/LookupDaoiBatis.java (revision 3174) +++ data/ibatis/src/main/java/org/appfuse/dao/ibatis/LookupDaoiBatis.java (working copy) @@ -4,14 +4,28 @@ import org.appfuse.dao.LookupDao; import org.appfuse.model.Role; +import org.springframework.stereotype.Repository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.orm.ibatis.SqlMapClientTemplate; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import com.ibatis.sqlmap.client.SqlMapClient; /** * iBatis implementation of LookupDao. * * @author Matt Raible */ -public class LookupDaoiBatis extends UniversalDaoiBatis implements LookupDao { +@Repository +public class LookupDaoiBatis implements LookupDao { + private Log log = LogFactory.getLog(LookupDaoiBatis.class); + private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate(); + @Autowired + public final void setSqlMapClient(SqlMapClient sqlMapClient) { + this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient); + } + /** * {@inheritDoc} */ @@ -19,6 +33,6 @@ public List getRoles() { log.debug("Retrieving all role names..."); - return getSqlMapClientTemplate().queryForList("getRoles", null); + return sqlMapClientTemplate.queryForList("getRoles", null); } } Index: data/ibatis/src/main/java/org/appfuse/dao/ibatis/GenericDaoiBatis.java =================================================================== --- data/ibatis/src/main/java/org/appfuse/dao/ibatis/GenericDaoiBatis.java (revision 3174) +++ data/ibatis/src/main/java/org/appfuse/dao/ibatis/GenericDaoiBatis.java (working copy) @@ -6,16 +6,26 @@ import org.appfuse.dao.GenericDao; import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport; +import org.springframework.orm.ibatis.SqlMapClientTemplate; import org.springframework.util.ClassUtils; +import org.springframework.util.Assert; +import org.springframework.stereotype.Repository; +import org.springframework.beans.factory.annotation.Autowired; +import javax.sql.DataSource; import java.io.Serializable; import java.util.List; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.ArrayList; +import com.ibatis.sqlmap.client.SqlMapClient; + /** * This class serves as the Base class for all other DAOs - namely to hold * common CRUD methods that they might all use. You should only need to extend * this class when your require custom CRUD logic. - * + *

*

To register this class in your Spring context file, use the following XML. *

  *      <bean id="fooDao" class="org.appfuse.dao.ibatis.GenericDaoiBatis">
@@ -28,15 +38,17 @@
  * @param  a type variable
  * @param  the primary key for that type
  */
-public class GenericDaoiBatis extends SqlMapClientDaoSupport implements GenericDao {
+public class GenericDaoiBatis implements GenericDao {
     /**
      * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging
      */
     protected final Log log = LogFactory.getLog(getClass());
     private Class persistentClass;
+    private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate();
 
     /**
      * Constructor that takes in a class to see which type of entity to persist
+     *
      * @param persistentClass the class type you'd like to persist
      */
     public GenericDaoiBatis(final Class persistentClass) {
@@ -44,6 +56,27 @@
     }
 
     /**
+     * Set the iBATIS Database Layer SqlMapClient to work with.
+     * Either this or a "sqlMapClientTemplate" is required.
+     *
+     * @param sqlMapClient the configured SqlMapClient
+     */
+    @Autowired
+    public final void setSqlMapClient(SqlMapClient sqlMapClient) {
+        this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);
+    }
+
+    /**
+     * Return the SqlMapClientTemplate for this DAO,
+     * pre-initialized with the SqlMapClient or set explicitly.
+     *
+     * @return an initialized SqlMapClientTemplate
+     */
+    public final SqlMapClientTemplate getSqlMapClientTemplate() {
+        return this.sqlMapClientTemplate;
+    }
+
+    /**
      * {@inheritDoc}
      */
     @SuppressWarnings("unchecked")
@@ -56,6 +89,15 @@
      * {@inheritDoc}
      */
     @SuppressWarnings("unchecked")
+    public List getAllDistinct() {
+        Collection result = new LinkedHashSet(getAll());
+        return new ArrayList(result);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings("unchecked")
     public T get(PK id) {
         T object = (T) getSqlMapClientTemplate().queryForObject(
                 iBatisDaoUtils.getFindQuery(ClassUtils.getShortName(this.persistentClass)), id);
Index: data/ibatis/src/main/java/org/appfuse/dao/ibatis/UserDaoiBatis.java
===================================================================
--- data/ibatis/src/main/java/org/appfuse/dao/ibatis/UserDaoiBatis.java	(revision 3174)
+++ data/ibatis/src/main/java/org/appfuse/dao/ibatis/UserDaoiBatis.java	(working copy)
@@ -8,6 +8,7 @@
 import org.appfuse.model.User;
 import org.springframework.orm.ObjectRetrievalFailureException;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.stereotype.Repository;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -20,13 +21,14 @@
  *
  * @author Matt Raible
  */
+@Repository("userDao")
 public class UserDaoiBatis extends GenericDaoiBatisimplements UserDao, UserDetailsService {
 
     /**
      * Constructor that sets the entity to User.class.
      */
     public UserDaoiBatis() {
-        super(org.appfuse.model.User.class);
+        super(User.class);
     }
 
     /**
@@ -41,7 +43,7 @@
         User user = (User) getSqlMapClientTemplate().queryForObject("getUser", userId);
 
         if (user == null) {
-            logger.warn("uh oh, user not found...");
+            log.warn("uh oh, user not found...");
             throw new ObjectRetrievalFailureException(User.class, userId);
         } else {
             List roles = getSqlMapClientTemplate().queryForList("getUserRoles", user);
@@ -129,7 +131,7 @@
          User user = (User) getSqlMapClientTemplate().queryForObject("getUserByUsername", username);
 
          if (user == null) {
-             logger.warn("uh oh, user not found...");
+             log.warn("uh oh, user not found...");
              throw new UsernameNotFoundException("user '" + username + "' not found...");
          } else {
              List roles = getSqlMapClientTemplate().queryForList("getUserRoles", user);
Index: data/ibatis/src/main/java/org/appfuse/dao/LookupDao.java
===================================================================
--- data/ibatis/src/main/java/org/appfuse/dao/LookupDao.java	(revision 3174)
+++ data/ibatis/src/main/java/org/appfuse/dao/LookupDao.java	(working copy)
@@ -10,7 +10,7 @@
  *
  * @author Matt Raible
  */
-public interface LookupDao extends UniversalDao {
+public interface LookupDao {
     //~ Methods ================================================================
 
     /**
Index: data/ibatis/src/main/resources/applicationContext-dao.xml
===================================================================
--- data/ibatis/src/main/resources/applicationContext-dao.xml	(revision 3174)
+++ data/ibatis/src/main/resources/applicationContext-dao.xml	(working copy)
@@ -1,56 +1,24 @@
 
 
     
-    
-    
-        
-    
-
     
     
-        
-            classpath:/sql-map-config.xml
-        
+        
         
     
 
-    
-    
+    
+    
         
-        
-     
-    
-     
-        
-        
-     
-    
-     
-        
-        
-     
-
-    
-        
-        
     
-    
-    
+    
 
-    
-        
-        
-        
-    
-    -->
-
-    
+    
+    
 
Index: pom.xml
===================================================================
--- pom.xml	(revision 3174)
+++ pom.xml	(working copy)
@@ -278,7 +278,7 @@
             
                 
                     org.springframework
-                    spring-core
+                    spring-aop
                 
                 
                     org.springframework
@@ -502,7 +502,7 @@
         1.0.4
         2.2.1
         2.5.5
-        2.0.1
+        2.0.4
         0.8
         2.0.11.1
         2.4.3
Index: web/pom.xml
===================================================================
--- web/pom.xml	(revision 3174)
+++ web/pom.xml	(working copy)
@@ -68,11 +68,11 @@
             commons-dbcp
             ${commons.dbcp.version}
             
-	            
-		            xerces
-		            xercesImpl
-		        
                 
+                    xerces
+                    xercesImpl
+                
+                
                     commons-collections
                     commons-collections