├── src ├── main │ ├── webapp │ │ ├── WEB-INF │ │ │ ├── views │ │ │ │ ├── account │ │ │ │ │ ├── head.jsp │ │ │ │ │ ├── account.jsp │ │ │ │ │ ├── views.xml │ │ │ │ │ └── settings │ │ │ │ │ │ └── updateAccountSettings.jsp │ │ │ │ ├── users │ │ │ │ │ ├── disabled │ │ │ │ │ │ ├── head.jsp │ │ │ │ │ │ └── list.jsp │ │ │ │ │ ├── enabled │ │ │ │ │ │ ├── head.jsp │ │ │ │ │ │ └── list.jsp │ │ │ │ │ ├── update │ │ │ │ │ │ ├── head.jsp │ │ │ │ │ │ └── update.jsp │ │ │ │ │ ├── updateUser.jsp │ │ │ │ │ ├── addNewUser.jsp │ │ │ │ │ ├── listDisabledUser.jsp │ │ │ │ │ ├── listEnabledUser.jsp │ │ │ │ │ ├── create │ │ │ │ │ │ ├── head.jsp │ │ │ │ │ │ └── create.jsp │ │ │ │ │ └── views.xml │ │ │ │ ├── commons │ │ │ │ │ ├── resourceNotFound.jsp │ │ │ │ │ └── uncaughtException.jsp │ │ │ │ ├── home.jsp │ │ │ │ ├── head.jsp │ │ │ │ ├── include.jsp │ │ │ │ ├── views.xml │ │ │ │ ├── index.jsp │ │ │ │ ├── login.jsp │ │ │ │ └── header.jsp │ │ │ ├── i18n │ │ │ │ ├── application.properties │ │ │ │ └── messages.properties │ │ │ ├── cron.xml │ │ │ ├── layouts │ │ │ │ ├── layouts.xml │ │ │ │ └── default.jsp │ │ │ ├── appengine-web.xml │ │ │ ├── spring │ │ │ │ └── exampleServlet │ │ │ │ │ ├── controllers.xml │ │ │ │ │ ├── me-servlet.xml │ │ │ │ │ └── mvc-config.xml │ │ │ ├── logging.properties │ │ │ └── web.xml │ │ ├── META-INF │ │ │ └── MANIFEST.MF │ │ └── js │ │ │ └── jquery │ │ │ └── jquery.tablesorter.min.js │ ├── java │ │ └── com │ │ │ └── namespace │ │ │ ├── service │ │ │ ├── CurrentUserManager.java │ │ │ ├── AbstractCurrentUserManager.java │ │ │ ├── dto │ │ │ │ ├── EnabledUserForm.java │ │ │ │ ├── AccountFormAssembler.java │ │ │ │ ├── UserPasswordForm.java │ │ │ │ ├── AccountDetailsForm.java │ │ │ │ ├── AccountControllerForm.java │ │ │ │ ├── UserAdministrationFormAssembler.java │ │ │ │ └── UserAdministrationForm.java │ │ │ ├── AccountManager.java │ │ │ ├── validator │ │ │ │ ├── UserAdministrationDetailsValidator.java │ │ │ │ ├── UserAdministrationPasswordValidator.java │ │ │ │ ├── UserAdministrationValidator.java │ │ │ │ ├── AccountDetailsValidator.java │ │ │ │ └── UserAdministrationCommonsValidations.java │ │ │ ├── UserAdministrationManager.java │ │ │ ├── CustomUserDetailsService.java │ │ │ ├── AccountManagerImpl.java │ │ │ └── UserAdministrationManagerImpl.java │ │ │ ├── repository │ │ │ ├── GenericDAO.java │ │ │ ├── AccountDAO.java │ │ │ ├── UserGaeDAO.java │ │ │ ├── AccountDAOImpl.java │ │ │ └── UserGaeDAOImpl.java │ │ │ ├── util │ │ │ └── Pair.java │ │ │ ├── web │ │ │ ├── CommonsController.java │ │ │ ├── AccountController.java │ │ │ ├── HomeController.java │ │ │ └── UsersController.java │ │ │ └── domain │ │ │ ├── Account.java │ │ │ └── UserGAE.java │ └── resources │ │ ├── log4j.properties │ │ └── META-INF │ │ ├── persistence.xml │ │ └── spring │ │ ├── applicationContext-security.xml │ │ └── applicationContext.xml └── test │ └── java │ └── com │ └── namespace │ ├── repository │ ├── mock │ │ ├── IDaoMocks.java │ │ ├── AccountDAOMock.java │ │ ├── UserGaeDAOMock.java │ │ └── InMemoryObjects.java │ ├── TestBase.java │ ├── AccountDAOTest.java │ └── UserGaeDAOTest.java │ ├── web │ ├── TestAccountController.java │ ├── IntegrationTestAccountController.java │ ├── AccountControllerTest.java │ └── UsersControllerIntegrationTest.java │ ├── util │ ├── SecurityUtil.java │ └── BinderUtil.java │ └── service │ ├── CustomUserDetailsServiceTest.java │ ├── dto │ └── UserAdministrationDTOAssemblerTest.java │ ├── AccountManagerTest.java │ ├── mock │ └── AccountManagerMock.java │ └── UserAdministrationManagerTest.java ├── .gitignore ├── .springBeans ├── README.md └── pom.xml /src/main/webapp/WEB-INF/views/account/head.jsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/disabled/head.jsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/enabled/head.jsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/update/head.jsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Thumbs.db 3 | .settings/ 4 | .project 5 | .classpath -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/commons/resourceNotFound.jsp: -------------------------------------------------------------------------------- 1 | Resource not found. -------------------------------------------------------------------------------- /src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/commons/uncaughtException.jsp: -------------------------------------------------------------------------------- 1 | <%--TODO: fix that page --%> 2 | Sorry! something is broken. -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/home.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> 2 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/updateUser.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/addNewUser.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> 2 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/listDisabledUser.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/listEnabledUser.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/head.jsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/account/account.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> 2 | 3 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/create/head.jsp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/CurrentUserManager.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import com.namespace.domain.UserGAE; 4 | 5 | public interface CurrentUserManager { 6 | 7 | public UserGAE getEnabledUser(); 8 | 9 | } -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/i18n/application.properties: -------------------------------------------------------------------------------- 1 | #Menu 2 | menu_account_settings=Update the current account 3 | menu_users=Users 4 | menu_users_list_enabled_users=Enabled Users 5 | menu_users_list_disabled_users=Disabled Users 6 | menu_users_create=Add a new user 7 | 8 | #Header 9 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/repository/GenericDAO.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository; 2 | 3 | public interface GenericDAO { 4 | 5 | public void create(T item) throws Exception; 6 | 7 | public boolean update(T item) throws Exception; 8 | 9 | public boolean remove(T item) throws Exception; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/repository/AccountDAO.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository; 2 | 3 | import java.util.List; 4 | 5 | import com.namespace.domain.Account; 6 | 7 | public interface AccountDAO extends GenericDAO{ 8 | 9 | public List findAll(); 10 | 11 | public Account findByUsername(String username); 12 | 13 | } -------------------------------------------------------------------------------- /src/test/java/com/namespace/repository/mock/IDaoMocks.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository.mock; 2 | 3 | import com.googlecode.objectify.Objectify; 4 | 5 | public interface IDaoMocks { 6 | 7 | public void datastoreWithNoEntities(Objectify ofy); 8 | 9 | public void datastoreWithOneEntity(Objectify ofy); 10 | 11 | public void datastoreWithManyEntities(Objectify ofy); 12 | 13 | } -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/cron.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/web/TestAccountController.java: -------------------------------------------------------------------------------- 1 | package com.namespace.web; 2 | 3 | import com.namespace.web.AccountController; 4 | 5 | import junit.framework.TestCase; 6 | 7 | public class TestAccountController extends TestCase { 8 | 9 | @SuppressWarnings("unused") 10 | public void testHandleRequestView(){ 11 | AccountController controller = new AccountController(); 12 | 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/repository/mock/AccountDAOMock.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository.mock; 2 | 3 | import com.googlecode.objectify.ObjectifyFactory; 4 | import com.namespace.domain.Account; 5 | import com.namespace.repository.AccountDAOImpl; 6 | 7 | public class AccountDAOMock extends AccountDAOImpl{ 8 | 9 | public AccountDAOMock(ObjectifyFactory objectifyFactory) { 10 | super(objectifyFactory); 11 | objectifyFactory.register(Account.class); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/repository/mock/UserGaeDAOMock.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository.mock; 2 | 3 | import com.googlecode.objectify.ObjectifyFactory; 4 | import com.namespace.domain.UserGAE; 5 | import com.namespace.repository.UserGaeDAOImpl; 6 | 7 | public class UserGaeDAOMock extends UserGaeDAOImpl{ 8 | 9 | public UserGaeDAOMock(ObjectifyFactory objectifyFactory) { 10 | super(objectifyFactory); 11 | objectifyFactory.register(UserGAE.class); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/util/Pair.java: -------------------------------------------------------------------------------- 1 | package com.namespace.util; 2 | 3 | public class Pair { 4 | public final A a; 5 | public final B b; 6 | 7 | public Pair(A a, B b) { 8 | this.a = a; 9 | this.b = b; 10 | } 11 | 12 | public A getA() { 13 | return a; 14 | } 15 | 16 | public B getB() { 17 | return b; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "Pair [a=" + a + ", b=" + b + "]"; 23 | } 24 | 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/account/views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/include.jsp: -------------------------------------------------------------------------------- 1 | <%@ page session="false"%> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 4 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 5 | <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 6 | <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 7 | <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> 8 | -------------------------------------------------------------------------------- /.springBeans: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1 4 | 5 | 6 | 7 | 8 | 9 | 10 | src/main/webapp/WEB-INF/spring/exampleServlet/mvc-config.xml 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/AbstractCurrentUserManager.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import org.springframework.security.core.context.SecurityContextHolder; 4 | 5 | import com.namespace.domain.UserGAE; 6 | 7 | public abstract class AbstractCurrentUserManager implements CurrentUserManager { 8 | 9 | @Override 10 | public UserGAE getEnabledUser() { 11 | UserGAE principal = (UserGAE) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 12 | return principal; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/dto/EnabledUserForm.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.dto; 2 | 3 | import java.util.List; 4 | 5 | public class EnabledUserForm { 6 | 7 | private List deactivate; 8 | 9 | public List getDeactivate() { 10 | return deactivate; 11 | } 12 | 13 | public void setDeactivate(List deactivate) { 14 | this.deactivate = deactivate; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return "EnabledUserForm [deactivate=" + deactivate + "]"; 20 | } 21 | 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/util/SecurityUtil.java: -------------------------------------------------------------------------------- 1 | package com.namespace.util; 2 | 3 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 4 | import org.springframework.security.core.context.SecurityContextHolder; 5 | 6 | import com.namespace.domain.UserGAE; 7 | 8 | public class SecurityUtil{ 9 | 10 | public static void authenticateUser(UserGAE user){ 11 | SecurityContextHolder.getContext().setAuthentication( 12 | new UsernamePasswordAuthenticationToken(user, user.getPassword())); 13 | } 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/layouts/layouts.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/AccountManager.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import com.namespace.domain.Account; 4 | import com.namespace.domain.UserGAE; 5 | 6 | public interface AccountManager extends CurrentUserManager{ 7 | 8 | 9 | public boolean updateAccount(Account account); 10 | public Account getEnabledAccount(); 11 | public Account getAccountByUsername(String username); 12 | public Account getAccountByUser(UserGAE user); 13 | public boolean updateUser(UserGAE user); 14 | public boolean closeEnabledAccount(); 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/repository/UserGaeDAO.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository; 2 | 3 | import java.util.List; 4 | 5 | import com.namespace.domain.Account; 6 | import com.namespace.domain.UserGAE; 7 | 8 | public interface UserGaeDAO extends GenericDAO{ 9 | 10 | public List findAll(); 11 | 12 | public List findAllEnabledUsers(boolean isEnabled); 13 | 14 | public UserGAE findByUsername(String username); 15 | 16 | public UserGAE findByAccount(Account account); 17 | 18 | public void createUserAccount(UserGAE user, Account account); 19 | 20 | } -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/appengine-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | example 4 | 4 5 | true 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/i18n/messages.properties: -------------------------------------------------------------------------------- 1 | #Button labels 2 | button_home=Home 3 | 4 | 5 | #Header labels 6 | header_support=Support 7 | header_account_label=Your Account Settings 8 | header_account_owner=\'s account 9 | 10 | #Security 11 | security_logout=Log Out 12 | security_login_title=Login 13 | 14 | #Account Settings form 15 | firstname_required = The first name is required 16 | 17 | 18 | #Form "Add New User" 19 | username_required=The user name is a required field 20 | email_required=This is a required field 21 | schedulingEmail_required=This is a required field 22 | password_matches=Passwords do not match 23 | password_empty=The password canot be empty 24 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/web/CommonsController.java: -------------------------------------------------------------------------------- 1 | package com.namespace.web; 2 | 3 | import org.springframework.stereotype.Controller; 4 | //import org.springframework.web.bind.annotation.RequestMapping; 5 | //import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | @Controller 8 | public class CommonsController { 9 | 10 | // @RequestMapping(value="/uncaughtException", method=RequestMethod.GET) 11 | public String uncaughtExceptionHandler(){ 12 | return "commons/uncaughtException"; 13 | } 14 | 15 | 16 | // @RequestMapping(value="/resourceNotFound", method=RequestMethod.GET) 17 | public String resourceNotFound(){ 18 | return "commons/resourceNotFound"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/util/BinderUtil.java: -------------------------------------------------------------------------------- 1 | package com.namespace.util; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | 5 | import org.springframework.beans.MutablePropertyValues; 6 | import org.springframework.validation.Validator; 7 | import org.springframework.web.bind.WebDataBinder; 8 | 9 | public class BinderUtil { 10 | 11 | public static WebDataBinder setUpBinder(Object form, Validator validator, HttpServletRequest request) { 12 | WebDataBinder binder = new WebDataBinder(form); 13 | binder.setValidator(validator); 14 | binder.bind(new MutablePropertyValues(request.getParameterMap())); 15 | 16 | binder.getValidator().validate(binder.getTarget(), binder.getBindingResult()); 17 | return binder; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/validator/UserAdministrationDetailsValidator.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.validator; 2 | 3 | import org.springframework.stereotype.Component; 4 | import org.springframework.validation.Errors; 5 | import org.springframework.validation.Validator; 6 | 7 | import com.namespace.service.dto.UserAdministrationForm; 8 | 9 | @Component 10 | public class UserAdministrationDetailsValidator extends UserAdministrationCommonsValidations implements Validator{ 11 | 12 | @Override 13 | public boolean supports(Class clazz) { 14 | return UserAdministrationForm.class.isAssignableFrom(clazz); 15 | } 16 | 17 | @Override 18 | public void validate(Object target, Errors errors) { 19 | commonValidations(errors); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/UserAdministrationManager.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import java.util.List; 4 | 5 | import com.namespace.domain.Account; 6 | import com.namespace.domain.UserGAE; 7 | import com.namespace.util.Pair; 8 | 9 | public interface UserAdministrationManager{ 10 | 11 | public void createNewUserAccount(UserGAE user, Account account); 12 | 13 | public List> getEnabledUsers(); 14 | 15 | public List> getDisabledUsers(); 16 | 17 | public boolean deactivateUserByUsername(String username); 18 | 19 | public boolean deleteUserByUsername(String username); 20 | 21 | public UserGAE getUserByUsername(String username); 22 | 23 | public boolean updateUserDetails(UserGAE user, Account account); 24 | 25 | public boolean updateUser(UserGAE user); 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/validator/UserAdministrationPasswordValidator.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.validator; 2 | 3 | import org.springframework.stereotype.Component; 4 | import org.springframework.validation.Errors; 5 | import org.springframework.validation.Validator; 6 | 7 | import com.namespace.service.dto.UserAdministrationForm; 8 | 9 | @Component 10 | public class UserAdministrationPasswordValidator extends UserAdministrationCommonsValidations implements Validator{ 11 | 12 | @Override 13 | public boolean supports(Class clazz) { 14 | return UserAdministrationForm.class.isAssignableFrom(clazz); 15 | } 16 | 17 | @Override 18 | public void validate(Object target, Errors errors) { 19 | UserAdministrationForm user = (UserAdministrationForm) target; 20 | 21 | passwordValidation(errors, user); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/validator/UserAdministrationValidator.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.validator; 2 | 3 | import org.springframework.stereotype.Component; 4 | import org.springframework.validation.Errors; 5 | import org.springframework.validation.Validator; 6 | 7 | import com.namespace.service.dto.UserAdministrationForm; 8 | 9 | @Component 10 | public class UserAdministrationValidator extends UserAdministrationCommonsValidations implements Validator { 11 | 12 | @Override 13 | public boolean supports(Class clazz) { 14 | return UserAdministrationForm.class.isAssignableFrom(clazz); 15 | } 16 | 17 | @Override 18 | public void validate(Object target, Errors errors) { 19 | commonValidations(errors); 20 | 21 | UserAdministrationForm user = (UserAdministrationForm) target; 22 | 23 | passwordValidation(errors, user); 24 | 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/validator/AccountDetailsValidator.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.validator; 2 | 3 | import org.springframework.stereotype.Component; 4 | import org.springframework.validation.Errors; 5 | import org.springframework.validation.ValidationUtils; 6 | import org.springframework.validation.Validator; 7 | 8 | import com.namespace.service.dto.AccountDetailsForm; 9 | 10 | @Component 11 | public class AccountDetailsValidator implements Validator { 12 | 13 | @Override 14 | public boolean supports(Class clazz) { 15 | return AccountDetailsForm.class.isAssignableFrom(clazz); 16 | } 17 | 18 | @Override 19 | public void validate(Object target, Errors errors) { 20 | ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "firstname_required"); 21 | ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "email_required"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/spring/exampleServlet/controllers.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | #Updated at Fri Jun 03 20:17:06 BOT 2011 2 | #Fri Jun 03 20:17:06 BOT 2011 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.R.File=application.log 5 | log4j.rootLogger=INFO, stdout 6 | log4j.appender.R.MaxFileSize=100KB 7 | log4j.appender.R.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.R.MaxBackupIndex=1 9 | log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n 10 | #log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n 11 | log4j.appender.stdout.layout.ConversionPattern=%-5p %c - %m%n 12 | #log4j.category.DataNucleus=WARN 13 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 14 | log4j.appender.R=org.apache.log4j.RollingFileAppender 15 | 16 | 17 | #The above configurations corresponds to the spring test units 18 | #log4j.rootLogger=WARN,A1 19 | #log4j.appender.A1=org.apache.log4j.ConsoleAppender 20 | #log4j.appender.A1.layout=org.apache.log4j.PatternLayout 21 | #log4j.appender.A1.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c %x - %m%n 22 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/logging.properties: -------------------------------------------------------------------------------- 1 | # A default java.util.logging configuration. 2 | # (All App Engine logging is through java.util.logging by default). 3 | # 4 | # To use this configuration, copy it into your application's WEB-INF 5 | # folder and add the following to your appengine-web.xml: 6 | # 7 | # 8 | # 9 | # 10 | # 11 | 12 | # Set the default logging level for all loggers to WARNING 13 | .level = WARNING 14 | 15 | # Set the default logging level for ORM, specifically, to WARNING 16 | DataNucleus.JDO.level=WARNING 17 | DataNucleus.Persistence.level=WARNING 18 | DataNucleus.Cache.level=WARNING 19 | DataNucleus.MetaData.level=WARNING 20 | DataNucleus.General.level=WARNING 21 | DataNucleus.Utility.level=WARNING 22 | DataNucleus.Transaction.level=WARNING 23 | DataNucleus.Datastore.level=WARNING 24 | DataNucleus.ClassLoading.level=WARNING 25 | DataNucleus.Plugin.level=WARNING 26 | DataNucleus.ValueGeneration.level=WARNING 27 | DataNucleus.Enhancer.level=WARNING 28 | DataNucleus.SchemaTool.level=WARNING 29 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/validator/UserAdministrationCommonsValidations.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.validator; 2 | 3 | import org.springframework.validation.Errors; 4 | import org.springframework.validation.ValidationUtils; 5 | 6 | import com.namespace.service.dto.UserAdministrationForm; 7 | 8 | public class UserAdministrationCommonsValidations { 9 | 10 | public UserAdministrationCommonsValidations() { 11 | super(); 12 | } 13 | 14 | protected void commonValidations(Errors errors) { 15 | ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username", "username_required"); 16 | ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "email_required"); 17 | } 18 | 19 | protected void passwordValidation(Errors errors, UserAdministrationForm user) { 20 | if(! user.getPassword().equals( user.getRetypePassword() ) ){ 21 | errors.rejectValue("password", "password_matches"); 22 | errors.rejectValue("retypePassword", "password_matches"); 23 | } 24 | ValidationUtils.rejectIfEmpty(errors, "password", "password_empty"); 25 | ValidationUtils.rejectIfEmpty(errors, "retypePassword", "password_empty"); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 2 |
3 |
4 |
5 |

Welcome!

6 |

Vestibulum id ligula porta felis euismod semper. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.

7 | 8 | 9 |

10 | Sign in » 11 | Create System Users 12 |

13 | 14 |
15 | 16 |
17 |
18 |
19 |

Vestibulum id ligula porta felis euismod semper.

20 |
21 |
22 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/login.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 2 | 3 |
4 | 5 | 6 | 7 |
8 |

Your login attempt was not successful, try again.

9 | Caused : 10 | ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message} 11 |
12 | 13 |
14 | 15 |
16 | 17 | 26 | 27 |
28 | 29 |
30 |

Vestibulum id ligula porta felis euismod semper.

31 |
32 |
-------------------------------------------------------------------------------- /src/test/java/com/namespace/web/IntegrationTestAccountController.java: -------------------------------------------------------------------------------- 1 | package com.namespace.web; 2 | 3 | import org.junit.Test; 4 | import org.springframework.beans.MutablePropertyValues; 5 | import org.springframework.mock.web.MockHttpServletRequest; 6 | import org.springframework.web.bind.WebDataBinder; 7 | 8 | import com.namespace.service.dto.AccountDetailsForm; 9 | import com.namespace.web.AccountController; 10 | 11 | 12 | import junit.framework.TestCase; 13 | 14 | public class IntegrationTestAccountController extends TestCase { 15 | 16 | @Test 17 | public void testHandlerMethod(){ 18 | 19 | @SuppressWarnings("unused") 20 | AccountController accountController = new AccountController(); 21 | 22 | final MockHttpServletRequest request = new MockHttpServletRequest("post", "/updateAccount"); 23 | 24 | request.setParameter("firstName", "Joe"); 25 | request.setParameter("lastName", "Smith"); 26 | 27 | final AccountDetailsForm accountDetails = new AccountDetailsForm(); 28 | final WebDataBinder binder = new WebDataBinder(accountDetails, "account"); 29 | binder.bind(new MutablePropertyValues(request.getParameterMap())); 30 | 31 | //final String mv = accountController.updateAccount(accountDetails, binder.getBindingResult()); 32 | 33 | //assertEquals("updateAccount", mv); 34 | assertEquals("a", "a"); 35 | 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/dto/AccountFormAssembler.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.dto; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.namespace.domain.Account; 6 | import com.namespace.domain.UserGAE; 7 | 8 | @Component 9 | public class AccountFormAssembler { 10 | 11 | public AccountControllerForm createAccountControllerForm (Account account, UserGAE userGAE){ 12 | return new AccountControllerForm(account, userGAE); 13 | } 14 | 15 | /** 16 | * Account details 17 | */ 18 | public AccountDetailsForm createAccountDetailsForm(Account account){ 19 | AccountDetailsForm form = new AccountDetailsForm(); 20 | form.setFirstName(account.getFirstName()); 21 | form.setLastName(account.getLastName()); 22 | form.setEmail(account.getEmail()); 23 | return form; 24 | } 25 | 26 | public Account copyAccountDetailsFormtoAccount(AccountDetailsForm accountDetailsForm, Account account){ 27 | account.setFirstName(accountDetailsForm.getFirstName()); 28 | account.setLastName(accountDetailsForm.getLastName()); 29 | account.setEmail(accountDetailsForm.getEmail()); 30 | 31 | return account; 32 | } 33 | 34 | public UserPasswordForm createUserPasswordForm(UserGAE user){ 35 | return new UserPasswordForm(); 36 | } 37 | 38 | public UserGAE copyUserPasswordFormToUserGAE(UserPasswordForm userPasswordForm, UserGAE usergae){ 39 | usergae.setPassword(userPasswordForm.getNewPassword()); 40 | return usergae; 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/dto/UserPasswordForm.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.dto; 2 | 3 | public class UserPasswordForm { 4 | 5 | private String oldPassword; 6 | 7 | private String newPassword; 8 | 9 | private String newPasswordConfirmation; 10 | 11 | private boolean accountNonExpired; 12 | 13 | public String getOldPassword() { 14 | return oldPassword; 15 | } 16 | 17 | public void setOldPassword(String oldPassword) { 18 | this.oldPassword = oldPassword; 19 | } 20 | 21 | public String getNewPassword() { 22 | return newPassword; 23 | } 24 | 25 | public void setNewPassword(String newPassword) { 26 | this.newPassword = newPassword; 27 | } 28 | 29 | public String getNewPasswordConfirmation() { 30 | return newPasswordConfirmation; 31 | } 32 | 33 | public void setNewPasswordConfirmation(String newPasswordConfirmation) { 34 | this.newPasswordConfirmation = newPasswordConfirmation; 35 | } 36 | 37 | public boolean isAccountNonExpired() { 38 | return accountNonExpired; 39 | } 40 | 41 | public void setAccountNonExpired(boolean accountNonExpired) { 42 | this.accountNonExpired = accountNonExpired; 43 | } 44 | 45 | public UserPasswordForm() { 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "UserPasswordForm [oldPassword=" + oldPassword 51 | + ", newPassword=" + newPassword + ", newPasswordConfirmation=" 52 | + newPasswordConfirmation + ", accountNonExpired=" 53 | + accountNonExpired + "]"; 54 | } 55 | 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/spring/exampleServlet/me-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | /WEB-INF/layouts/layouts.xml 20 | 21 | /WEB-INF/views/**/views.xml 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/dto/AccountDetailsForm.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.dto; 2 | 3 | /** 4 | * This class transfer the data from the view 5 | * to the form controller 6 | * @author David 7 | */ 8 | public class AccountDetailsForm { 9 | 10 | private String firstName; 11 | 12 | private String lastName; 13 | 14 | private String email; 15 | 16 | private String password; 17 | 18 | public String getFirstName() { 19 | return firstName; 20 | } 21 | 22 | public void setFirstName(String firstName) { 23 | this.firstName = firstName; 24 | } 25 | 26 | public String getLastName() { 27 | return lastName; 28 | } 29 | 30 | public void setLastName(String lastName) { 31 | this.lastName = lastName; 32 | } 33 | 34 | public String getEmail() { 35 | return email; 36 | } 37 | 38 | public void setEmail(String email) { 39 | this.email = email; 40 | } 41 | 42 | public String getPassword() { 43 | return password; 44 | } 45 | 46 | public void setPassword(String password) { 47 | this.password = password; 48 | } 49 | 50 | public AccountDetailsForm(String firstName, String lastName, String email, String password) { 51 | super(); 52 | this.firstName = firstName; 53 | this.lastName = lastName; 54 | this.email = email; 55 | this.password = password; 56 | } 57 | 58 | public AccountDetailsForm() { 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return "AccountDetailsForm [firstName=" + firstName + ", lastName=" 64 | + lastName + ", email=" + email + ", password=" + password 65 | + "]"; 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/account/settings/updateAccountSettings.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/WEB-INF/views/include.jsp" %> 2 | 3 |
4 |
5 |
6 |
7 | 8 |
9 | Update my account 10 |
11 | 12 |
13 | 14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 | 22 |
23 |
24 |
25 | 26 |
27 | 28 | 29 |
30 |
31 |
32 | 33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/spring/applicationContext-security.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/CustomUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.dao.DataAccessException; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.security.core.userdetails.UserDetailsService; 9 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 10 | import org.springframework.stereotype.Service; 11 | 12 | import com.googlecode.objectify.Key; 13 | import com.namespace.domain.Account; 14 | import com.namespace.domain.UserGAE; 15 | import com.namespace.repository.AccountDAO; 16 | import com.namespace.repository.UserGaeDAO; 17 | import com.namespace.web.HomeController; 18 | 19 | @Service(value="customUserDetailsService") 20 | public class CustomUserDetailsService implements UserDetailsService { 21 | 22 | @Autowired private UserGaeDAO userGaeDAO; 23 | 24 | private static final Logger logger = LoggerFactory.getLogger(HomeController.class); 25 | 26 | 27 | public CustomUserDetailsService() { 28 | } 29 | 30 | public CustomUserDetailsService(UserGaeDAO userGaeDAO) { 31 | this.userGaeDAO = userGaeDAO; 32 | } 33 | 34 | @Override 35 | public UserDetails loadUserByUsername(String username) 36 | throws UsernameNotFoundException, DataAccessException { 37 | 38 | UserGAE user = this.userGaeDAO.findByUsername(username); 39 | 40 | logger.info("checking user services.... " + user); 41 | 42 | return user; 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/layouts/default.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> 4 | <%@ include file="/WEB-INF/views/include.jsp" %> 5 | 6 | 7 | 8 | Vestibulum id ligula porta felis euismod semper. 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/service/CustomUserDetailsServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import static org.junit.Assert.assertNull; 4 | 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | 12 | import com.namespace.domain.UserGAE; 13 | import com.namespace.repository.UserGaeDAO; 14 | import com.namespace.repository.TestBase; 15 | import com.namespace.repository.mock.UserGaeDAOMock; 16 | import com.namespace.service.CustomUserDetailsService; 17 | 18 | public class CustomUserDetailsServiceTest extends TestBase{ 19 | 20 | @SuppressWarnings("unused") 21 | private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsServiceTest.class); 22 | 23 | private UserDetailsService manager; 24 | 25 | private UserGaeDAO userGaeDAO; 26 | 27 | @Before 28 | public void setUp(){ 29 | super.setUp(); 30 | this.userGaeDAO = new UserGaeDAOMock(super.objectifyFactory); 31 | 32 | this.manager = new CustomUserDetailsService(userGaeDAO); 33 | } 34 | 35 | @Test 36 | public void loadUserByUsername(){ 37 | //TODO: uncomment 38 | /* 39 | * BoundaryConditions 40 | */ 41 | @SuppressWarnings("unused") 42 | UserDetails defaultUserWhenDatastoreIsEmpty = this.manager.loadUserByUsername(null); 43 | UserGAE userTest = new UserGAE("user", "user", true, true, false); 44 | // assertEquals(userTest, defaultUserWhenDatastoreIsEmpty); 45 | 46 | super.putAndGet(userTest); 47 | assertNull(this.manager.loadUserByUsername(null)); 48 | 49 | /* 50 | * Right results 51 | */ 52 | // assertEquals(userTest, this.manager.loadUserByUsername(userTest.getUsername())); 53 | 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/update/update.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/WEB-INF/views/include.jsp" %> 2 | 3 |
4 |
5 |
6 |
7 | 8 |
9 | Update user 10 |
11 | 12 |
13 | 14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 | 22 |
23 |
24 |
25 | 26 |
27 | 28 | 29 |
30 |
31 |
32 | 33 |
34 | 35 | 36 |
37 |
38 |
39 | 40 |
41 | 42 | 43 |
44 |
45 |
46 | 47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/dto/AccountControllerForm.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.dto; 2 | 3 | import com.namespace.domain.Account; 4 | import com.namespace.domain.UserGAE; 5 | 6 | public class AccountControllerForm { 7 | 8 | private String firstName; 9 | 10 | private String lastName; 11 | 12 | private String email; 13 | 14 | private String oldPassword; 15 | 16 | private String newPassword; 17 | 18 | private String newPasswordConfirmation; 19 | 20 | private boolean accountNonExpired; 21 | 22 | public String getFirstName() { 23 | return firstName; 24 | } 25 | 26 | public void setFirstName(String firstName) { 27 | this.firstName = firstName; 28 | } 29 | 30 | public String getLastName() { 31 | return lastName; 32 | } 33 | 34 | public void setLastName(String lastName) { 35 | this.lastName = lastName; 36 | } 37 | 38 | public String getEmail() { 39 | return email; 40 | } 41 | 42 | public void setEmail(String email) { 43 | this.email = email; 44 | } 45 | 46 | public String getOldPassword() { 47 | return oldPassword; 48 | } 49 | 50 | public void setOldPassword(String oldPassword) { 51 | this.oldPassword = oldPassword; 52 | } 53 | 54 | public String getNewPassword() { 55 | return newPassword; 56 | } 57 | 58 | public void setNewPassword(String newPassword) { 59 | this.newPassword = newPassword; 60 | } 61 | 62 | public String getNewPasswordConfirmation() { 63 | return newPasswordConfirmation; 64 | } 65 | 66 | public void setNewPasswordConfirmation(String newPasswordConfirmation) { 67 | this.newPasswordConfirmation = newPasswordConfirmation; 68 | } 69 | 70 | public boolean isAccountNonExpired() { 71 | return accountNonExpired; 72 | } 73 | 74 | public void setAccountNonExpired(boolean accountNonExpired) { 75 | this.accountNonExpired = accountNonExpired; 76 | } 77 | 78 | public AccountControllerForm() { 79 | // TODO Auto-generated constructor stub 80 | } 81 | 82 | public AccountControllerForm(Account account, UserGAE userGAE) { 83 | this.firstName = account.getFirstName(); 84 | this.lastName = account.getLastName(); 85 | this.email = account.getEmail(); 86 | 87 | /*The view never see the password*/ 88 | //this.password = null; 89 | this.accountNonExpired = userGAE.isAccountNonExpired(); 90 | } 91 | 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/web/AccountControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.namespace.web; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | import static org.junit.Assert.assertEquals; 5 | import static org.junit.Assert.assertNotNull; 6 | import static org.junit.Assert.fail; 7 | 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | import org.springframework.validation.BeanPropertyBindingResult; 11 | import org.springframework.validation.BindingResult; 12 | import org.springframework.web.servlet.ModelAndView; 13 | 14 | import com.namespace.domain.UserGAE; 15 | import com.namespace.service.dto.AccountDetailsForm; 16 | import com.namespace.service.dto.AccountFormAssembler; 17 | import com.namespace.service.mock.AccountManagerMock; 18 | import com.namespace.service.validator.AccountDetailsValidator; 19 | import com.namespace.web.AccountController; 20 | 21 | public class AccountControllerTest { 22 | 23 | private AccountController controller; 24 | private AccountManagerMock accountManager; 25 | 26 | @Before 27 | public void setUp(){ 28 | 29 | UserGAE user = new UserGAE("user", "12345", true); 30 | accountManager = new AccountManagerMock(user); 31 | 32 | AccountFormAssembler accountFormAssembler = new AccountFormAssembler(); 33 | AccountDetailsValidator accountDetailsValidator = new AccountDetailsValidator(); 34 | 35 | controller = new AccountController(accountManager, 36 | accountFormAssembler, 37 | accountDetailsValidator); 38 | } 39 | 40 | @Test 41 | public void accountHome(){ 42 | accountManager.createInMemoryDomainObjects(); 43 | ModelAndView modelAndView = this.controller.accountHome(); 44 | assertEquals("account/account", modelAndView.getViewName()); 45 | assertNotNull(modelAndView.getModel()); 46 | 47 | AccountDetailsForm model = (AccountDetailsForm) modelAndView.getModel().get("account"); 48 | assertNotNull(model); 49 | assertEquals("David", model.getFirstName()); 50 | } 51 | 52 | @Test 53 | public void updateAccount(){ 54 | try { 55 | this.controller.updateAccount(null, null); 56 | fail(); 57 | } catch (NullPointerException e) { 58 | assertTrue(true); 59 | } catch (Exception e){ 60 | fail(); 61 | } 62 | 63 | AccountDetailsForm model = new AccountDetailsForm(); 64 | BindingResult bindingResult = new BeanPropertyBindingResult(model, "account"); 65 | assertEquals("account/account", this.controller.updateAccount(model, bindingResult)); 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/spring/exampleServlet/mvc-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/enabled/list.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/WEB-INF/views/include.jsp" %> 2 | 3 |
4 |
5 |
6 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 |
IdFirst NameLast NameEmail
29 | 30 |
35 |
36 |
37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |
58 |
59 |
60 |
61 | 62 |
63 |
64 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/disabled/list.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/WEB-INF/views/include.jsp" %> 2 | 3 |
4 |
5 |
6 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 |
IdFirst NameLast NameEmail
29 | 30 |
35 |
36 |
37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |
58 |
59 |
60 |
61 | 62 |
63 |
64 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/web/AccountController.java: -------------------------------------------------------------------------------- 1 | package com.namespace.web; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.validation.BindingResult; 8 | import org.springframework.web.bind.annotation.ModelAttribute; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.servlet.ModelAndView; 12 | 13 | import com.namespace.domain.Account; 14 | import com.namespace.service.AccountManager; 15 | import com.namespace.service.dto.AccountDetailsForm; 16 | import com.namespace.service.dto.AccountFormAssembler; 17 | import com.namespace.service.validator.AccountDetailsValidator; 18 | 19 | @Controller 20 | public class AccountController { 21 | 22 | private static final Logger logger = LoggerFactory.getLogger(AccountController.class); 23 | 24 | @Autowired private AccountFormAssembler accountFormAssembler; 25 | @Autowired private AccountManager accountManager; 26 | @Autowired private AccountDetailsValidator accountDetailsValidator; 27 | 28 | public AccountController() { 29 | } 30 | 31 | public AccountController(AccountManager accountManager, 32 | AccountFormAssembler accountFormAssembler, 33 | AccountDetailsValidator accountDetailsValidator) { 34 | this.accountManager = accountManager; 35 | this.accountFormAssembler = accountFormAssembler; 36 | this.accountDetailsValidator = accountDetailsValidator; 37 | } 38 | 39 | @RequestMapping(value="/account", method=RequestMethod.GET) 40 | public ModelAndView accountHome() { 41 | Account enabledAccount = accountManager.getEnabledAccount(); 42 | logger.info("Sending the enabled account for the view: " + enabledAccount); 43 | 44 | AccountDetailsForm model = this.accountFormAssembler.createAccountDetailsForm(enabledAccount); 45 | 46 | return new ModelAndView("account/account", "account", model); 47 | } 48 | 49 | @RequestMapping(value="updateAccount", method=RequestMethod.POST) 50 | public String updateAccount(@ModelAttribute("account") AccountDetailsForm model, 51 | BindingResult result){ 52 | 53 | if(model == null) 54 | throw new NullPointerException("The AccountDetailsFormModel cannot be null at " + AccountController.class.toString() + "updateAccount()"); 55 | 56 | this.accountDetailsValidator.validate(model, result); 57 | 58 | if(result.hasErrors()){ 59 | return "account/account"; 60 | }else{ 61 | Account account = accountFormAssembler.copyAccountDetailsFormtoAccount( 62 | model, this.accountManager.getEnabledAccount()); 63 | this.accountManager.updateAccount(account); 64 | return "redirect:account"; 65 | } 66 | } 67 | 68 | 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/AccountManagerImpl.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import com.namespace.domain.Account; 9 | import com.namespace.domain.UserGAE; 10 | import com.namespace.repository.AccountDAO; 11 | import com.namespace.repository.UserGaeDAO; 12 | 13 | @Service 14 | public class AccountManagerImpl extends AbstractCurrentUserManager implements AccountManager { 15 | 16 | private static final Logger logger = LoggerFactory.getLogger(AccountManagerImpl.class); 17 | 18 | @Autowired private UserGaeDAO userGaeDAO; 19 | @Autowired private AccountDAO accountDAO; 20 | 21 | public AccountManagerImpl(UserGaeDAO userGaeDAO, 22 | AccountDAO accountDAO) { 23 | this.userGaeDAO = userGaeDAO; 24 | this.accountDAO = accountDAO; 25 | } 26 | 27 | public AccountManagerImpl() { 28 | } 29 | 30 | @Override 31 | public boolean updateUser(UserGAE user) { 32 | logger.info("updateUser()"); 33 | try { 34 | logger.info("Trying to update the user using userGaeDAO.update()"); 35 | return this.userGaeDAO.update(user); 36 | } catch (Exception e) { 37 | return false; 38 | } 39 | } 40 | 41 | @Override 42 | public boolean updateAccount(Account account) { 43 | logger.info("updateAccount()"); 44 | 45 | if(account == null) 46 | return false; 47 | 48 | try { 49 | logger.info("Trying to update the account using accountDAO.update() "); 50 | boolean isUpdatedSucessfully = this.accountDAO.update(account); 51 | if(isUpdatedSucessfully){ 52 | logger.info("This account was updated sucessfully" + account.toString()); 53 | }else{ 54 | logger.info("This account was not updated sucessfully" + account.toString()); 55 | } 56 | return isUpdatedSucessfully; 57 | 58 | } catch (Exception e) { 59 | // TODO Auto-generated catch block 60 | e.printStackTrace(); 61 | } 62 | return false; 63 | } 64 | 65 | 66 | @Override 67 | public Account getEnabledAccount() { 68 | UserGAE principal = this.getEnabledUser(); 69 | return this.accountDAO.findByUsername(principal.getUsername()); 70 | } 71 | 72 | @Override 73 | public boolean closeEnabledAccount(){ 74 | UserGAE enabledUser = getEnabledUser(); 75 | enabledUser.setEnabled(false); 76 | enabledUser.setAccountNonExpired(false); 77 | try { 78 | return this.userGaeDAO.update(enabledUser); 79 | } catch (Exception e) { 80 | return false; 81 | } 82 | } 83 | 84 | @Override 85 | public Account getAccountByUsername(String username) { 86 | UserGAE user = this.userGaeDAO.findByUsername(username); 87 | return getAccountByUser(user); 88 | } 89 | 90 | @Override 91 | public Account getAccountByUser(UserGAE user) { 92 | return this.accountDAO.findByUsername(user.getUsername()); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/dto/UserAdministrationFormAssembler.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.dto; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.namespace.domain.Account; 9 | import com.namespace.domain.UserGAE; 10 | 11 | @Component 12 | public class UserAdministrationFormAssembler { 13 | 14 | public UserAdministrationForm createUserAdministrationForm(UserGAE user, Account account){ 15 | UserAdministrationForm form = new UserAdministrationForm(); 16 | if(account != null){ 17 | form.setFirstName(account.getFirstName()); 18 | form.setLastName(account.getLastName()); 19 | form.setEmail(account.getEmail()); 20 | } 21 | 22 | if(user != null){ 23 | form.setAdmin(user.isAdmin()); 24 | form.setUsername(user.getUsername()); 25 | // form.setPassword(null); 26 | form.setEnabled(user.isEnabled()); 27 | form.setBannedUser(user.isBannedUser()); 28 | } 29 | 30 | return form; 31 | } 32 | 33 | public UserAdministrationForm createUserAdministrationForm(){ 34 | return new UserAdministrationForm(); 35 | } 36 | 37 | public Map copyNewUserFromUserAdministrationForm(UserAdministrationForm form){ 38 | HashMap objectsMap = new HashMap(); 39 | 40 | UserGAE user = fillCommonUserInformationFromForm(form, new UserGAE(form.getUsername())); 41 | user.setPassword(form.getPassword()); 42 | user.setEnabled(form.isEnabled()); 43 | user.setBannedUser(form.isBannedUser()); 44 | 45 | Account account = fillCommonAccountInformationFromForm(form, new Account() ); 46 | // account.setUser(new Key(UserGAE.class, user.getUsername())); 47 | 48 | // scheduler.setAccount(new Key(raw)) 49 | 50 | objectsMap.put("user", user); 51 | objectsMap.put("account", account); 52 | 53 | return objectsMap; 54 | } 55 | 56 | public Map updateUserDetailsFromUserAdministrationForm(UserAdministrationForm form, UserGAE userToFill, Account accountToFill){ 57 | HashMap objectsMap = new HashMap(); 58 | 59 | UserGAE user = fillCommonUserInformationFromForm(form, userToFill); 60 | 61 | Account account = fillCommonAccountInformationFromForm(form, accountToFill ); 62 | 63 | objectsMap.put("user", user); 64 | objectsMap.put("account", account); 65 | 66 | return objectsMap; 67 | } 68 | 69 | 70 | 71 | private UserGAE fillCommonUserInformationFromForm(UserAdministrationForm form, UserGAE userToBeFilled){ 72 | userToBeFilled.setAdmin(form.isAdmin()); 73 | return userToBeFilled; 74 | } 75 | 76 | 77 | private Account fillCommonAccountInformationFromForm(UserAdministrationForm form, 78 | Account accountToBeFilled) { 79 | accountToBeFilled.setFirstName(form.getFirstName()); 80 | accountToBeFilled.setLastName(form.getLastName()); 81 | accountToBeFilled.setEmail(form.getEmail()); 82 | return accountToBeFilled; 83 | } 84 | 85 | 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/dto/UserAdministrationForm.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.dto; 2 | 3 | public class UserAdministrationForm { 4 | 5 | private String username; 6 | 7 | private String firstName; 8 | 9 | private String lastName; 10 | 11 | private String email; 12 | 13 | private boolean admin; 14 | 15 | private String password; 16 | 17 | private String retypePassword; 18 | 19 | private boolean enabled; 20 | 21 | private boolean bannedUser; 22 | 23 | public String getUsername() { 24 | return username; 25 | } 26 | 27 | public void setUsername(String username) { 28 | this.username = username; 29 | } 30 | 31 | public String getFirstName() { 32 | return firstName; 33 | } 34 | 35 | public void setFirstName(String firstName) { 36 | this.firstName = firstName; 37 | } 38 | 39 | public String getLastName() { 40 | return lastName; 41 | } 42 | 43 | public void setLastName(String lastName) { 44 | this.lastName = lastName; 45 | } 46 | 47 | public String getEmail() { 48 | return email; 49 | } 50 | 51 | public void setEmail(String email) { 52 | this.email = email; 53 | } 54 | 55 | public boolean isAdmin() { 56 | return admin; 57 | } 58 | 59 | public void setAdmin(boolean admin) { 60 | this.admin = admin; 61 | } 62 | 63 | public String getPassword() { 64 | return password; 65 | } 66 | 67 | public void setPassword(String password) { 68 | this.password = password; 69 | } 70 | 71 | public boolean isEnabled() { 72 | return enabled; 73 | } 74 | 75 | public void setEnabled(boolean enabled) { 76 | this.enabled = enabled; 77 | } 78 | 79 | public boolean isBannedUser() { 80 | return bannedUser; 81 | } 82 | 83 | public void setBannedUser(boolean bannedUser) { 84 | this.bannedUser = bannedUser; 85 | } 86 | 87 | 88 | 89 | public String getRetypePassword() { 90 | return retypePassword; 91 | } 92 | 93 | public void setRetypePassword(String retypePassword) { 94 | this.retypePassword = retypePassword; 95 | } 96 | 97 | public UserAdministrationForm(String username, String firstName, 98 | String lastName, String email, boolean admin, 99 | String password, boolean enabled, boolean bannedUser) { 100 | super(); 101 | this.username = username; 102 | this.firstName = firstName; 103 | this.lastName = lastName; 104 | this.email = email; 105 | this.admin = admin; 106 | this.password = password; 107 | this.enabled = enabled; 108 | this.bannedUser = bannedUser; 109 | } 110 | 111 | public UserAdministrationForm() { 112 | } 113 | 114 | @Override 115 | public String toString() { 116 | return "UserAdministrationForm [username=" + username + ", firstName=" 117 | + firstName + ", lastName=" + lastName + ", email=" + email 118 | + ", admin=" + admin + ", password=" + password 119 | + ", retypePassword=" + retypePassword + ", enabled=" + enabled 120 | + ", bannedUser=" + bannedUser + "]"; 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/users/create/create.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/WEB-INF/views/include.jsp" %> 2 | 3 |
4 |
5 |
6 |
7 | 8 |
9 | Create user 10 |
11 | 12 |
13 | 14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 | 22 |
23 |
24 |
25 | 26 |
27 | 28 | 29 |
30 |
31 |
32 | 33 |
34 | 35 | 36 |
37 |
38 |
39 | 40 |
41 | 42 | 43 |
44 |
45 |
46 | 47 |
48 | <%----%> 49 | 50 | 51 |
52 |
53 |
54 | 55 |
56 | 57 | 58 |
59 |
60 |
61 | 62 |
63 | 64 | 65 |
66 |
67 |
68 | 69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | 77 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/web/HomeController.java: -------------------------------------------------------------------------------- 1 | package com.namespace.web; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.ModelMap; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | 11 | import com.googlecode.objectify.Key; 12 | import com.namespace.domain.Account; 13 | import com.namespace.domain.UserGAE; 14 | import com.namespace.repository.AccountDAO; 15 | import com.namespace.repository.UserGaeDAO; 16 | import com.namespace.service.AbstractCurrentUserManager; 17 | 18 | /** 19 | * Handles requests for the application home page. 20 | */ 21 | @Controller 22 | public class HomeController extends AbstractCurrentUserManager { 23 | 24 | private static final Logger logger = LoggerFactory.getLogger(HomeController.class); 25 | 26 | @Autowired private UserGaeDAO userGaeDAO; 27 | @Autowired private AccountDAO accountDAO; 28 | 29 | public HomeController() { 30 | } 31 | 32 | @RequestMapping(value="/", method=RequestMethod.GET) 33 | public String home() { 34 | logger.info("Welcome home!"); 35 | return "home"; 36 | } 37 | 38 | @RequestMapping(value="/login", method = RequestMethod.GET) 39 | public String login() { 40 | 41 | return "login"; 42 | 43 | } 44 | 45 | @RequestMapping(value="/loginfailed", method = RequestMethod.GET) 46 | public String loginerror(ModelMap model) { 47 | model.addAttribute("error", "true"); 48 | return "login"; 49 | 50 | } 51 | 52 | @RequestMapping(value="/logout", method = RequestMethod.GET) 53 | public String logout() { 54 | 55 | return "home"; 56 | } 57 | 58 | @RequestMapping(value="/createDefaultUsers", method = RequestMethod.GET) 59 | public String createDefaultUsers(ModelMap model) { 60 | try{ 61 | logger.info("Creating default accounts..."); 62 | 63 | UserGAE firstAdminUser = new UserGAE("admin", "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918", true, true, false, true); 64 | UserGAE firstNonAdminUser = new UserGAE("user", "04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb", false, true, false, true); 65 | Key userAdminKey = new Key(UserGAE.class, firstAdminUser.getUsername()); 66 | Key userNonAdminKey = new Key(UserGAE.class, firstNonAdminUser.getUsername()); 67 | Account accountAdmin = new Account(null, "John", "Doe", "example@example.com", userAdminKey); 68 | Account accountNonAdmin = new Account(null, "User1", "User1", "example1@example.com", userNonAdminKey); 69 | 70 | this.userGaeDAO.create(firstAdminUser); 71 | this.userGaeDAO.create(firstNonAdminUser); 72 | this.accountDAO.create(accountAdmin); 73 | this.accountDAO.create(accountNonAdmin); 74 | 75 | model.addAttribute("Error", "true"); 76 | }catch (Exception ex){ 77 | model.addAttribute("Error", "true"); 78 | } 79 | return "home"; 80 | 81 | } 82 | 83 | 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/repository/TestBase.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository; 2 | 3 | import java.util.logging.Logger; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | 8 | import com.google.appengine.api.datastore.Entity; 9 | import com.google.appengine.api.datastore.EntityNotFoundException; 10 | import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig; 11 | import com.google.appengine.tools.development.testing.LocalMemcacheServiceTestConfig; 12 | import com.google.appengine.tools.development.testing.LocalServiceTestHelper; 13 | import com.google.appengine.tools.development.testing.LocalTaskQueueTestConfig; 14 | import com.googlecode.objectify.Key; 15 | import com.googlecode.objectify.Objectify; 16 | import com.googlecode.objectify.ObjectifyFactory; 17 | import com.googlecode.objectify.ObjectifyOpts; 18 | import com.googlecode.objectify.cache.ListenableHook; 19 | 20 | /** 21 | * All tests should extend this class to set up the GAE environment. 22 | * @see Unit Testing in Appengine 23 | */ 24 | public class TestBase 25 | { 26 | @SuppressWarnings("unused") 27 | private static Logger log = Logger.getLogger(TestBase.class.getName()); 28 | 29 | protected ObjectifyFactory objectifyFactory; 30 | 31 | private final LocalServiceTestHelper helper = 32 | new LocalServiceTestHelper( 33 | new LocalDatastoreServiceTestConfig(), 34 | new LocalMemcacheServiceTestConfig(), 35 | new LocalTaskQueueTestConfig() 36 | ); 37 | 38 | @Before 39 | public void setUp() 40 | { 41 | this.helper.setUp(); 42 | 43 | this.objectifyFactory = new ObjectifyFactory() { 44 | @Override 45 | public Objectify begin(ObjectifyOpts opts) 46 | { 47 | // This can be used to enable/disable the memory cache globally. 48 | opts.setGlobalCache(true); 49 | 50 | // This can be used to enable/disable the session caching objectify 51 | // Note that it will break several unit tests that check for transmutation 52 | // when entities are run through the DB (ie, unknown List types become 53 | // ArrayList). These failures are ok. 54 | opts.setSessionCache(false); 55 | 56 | return super.begin(opts); 57 | } 58 | }; 59 | 60 | /* 61 | * Register your classes here or override this method, 62 | * I always override this method and then I call this method using super.setUp() 63 | */ 64 | //this.fact.register(Libro.class); 65 | 66 | } 67 | 68 | @After 69 | public void tearDown() 70 | { 71 | // This normally is done in the AsyncCacheFilter but that doesn't exist for tests 72 | ListenableHook.completeAllPendingFutures(); 73 | this.helper.tearDown(); 74 | } 75 | 76 | /** 77 | * Utility methods that puts and immediately gets an entity 78 | */ 79 | protected T putAndGet(T saveMe) 80 | { 81 | Objectify ofy = this.objectifyFactory.begin(); 82 | 83 | Key key = ofy.put(saveMe); 84 | 85 | try 86 | { 87 | Entity ent = ofy.getDatastore().get(objectifyFactory.getRawKey(key)); 88 | System.out.println(ent); 89 | } 90 | catch (EntityNotFoundException e) { throw new RuntimeException(e); } 91 | 92 | return ofy.find(key); 93 | } 94 | } -------------------------------------------------------------------------------- /src/test/java/com/namespace/repository/mock/InMemoryObjects.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository.mock; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.googlecode.objectify.Key; 7 | import com.googlecode.objectify.Objectify; 8 | import com.namespace.domain.Account; 9 | import com.namespace.domain.UserGAE; 10 | 11 | public class InMemoryObjects implements IDaoMocks { 12 | 13 | /* 14 | * Begin singleton stuffs 15 | */ 16 | 17 | private static InMemoryObjects INSTANCE = null; 18 | 19 | private InMemoryObjects() {} 20 | 21 | private synchronized static void createInstance() { 22 | if (INSTANCE == null) { 23 | INSTANCE = new InMemoryObjects(); 24 | } 25 | } 26 | 27 | public static InMemoryObjects getInstance(){ 28 | if (INSTANCE == null) 29 | createInstance(); 30 | 31 | return INSTANCE; 32 | } 33 | 34 | public Object clone() throws CloneNotSupportedException { 35 | throw new CloneNotSupportedException(); 36 | } 37 | /*End singleton stuffs*/ 38 | 39 | 40 | /* 41 | * InMemoryObjects 42 | */ 43 | private List accounts = new ArrayList(); 44 | private List users = new ArrayList(); 45 | 46 | public List getAccounts() { 47 | return accounts; 48 | } 49 | 50 | public void setAccounts(List accounts) { 51 | if(accounts != null){ 52 | this.accounts = accounts; 53 | }else{ 54 | this.accounts = new ArrayList(); 55 | } 56 | } 57 | 58 | public List getUsers() { 59 | return users; 60 | } 61 | 62 | public void setUsers(List users) { 63 | if(users != null){ 64 | this.users = users; 65 | }else{ 66 | this.users = new ArrayList(); 67 | } 68 | } 69 | 70 | @Override 71 | public void datastoreWithNoEntities(Objectify ofy) { 72 | accounts = new ArrayList(); 73 | users = new ArrayList(); 74 | } 75 | 76 | @Override 77 | public void datastoreWithOneEntity(Objectify ofy) { 78 | users = new ArrayList(); 79 | accounts = new ArrayList(); 80 | 81 | UserGAE user = new UserGAE("user", "12345", true); 82 | Key userKey = new Key(UserGAE.class, "user"); 83 | users.add(user); 84 | ofy.put(user); 85 | 86 | Account account = new Account(new Long(1), "David", "D.", "example@example.com", userKey); 87 | accounts.add(account); 88 | ofy.put(account); 89 | } 90 | 91 | @Override 92 | public void datastoreWithManyEntities(Objectify ofy) { 93 | 94 | users = new ArrayList(); 95 | accounts = new ArrayList(); 96 | 97 | UserGAE user = new UserGAE("user", "12345", true); 98 | Key userKey = new Key(UserGAE.class, "user"); 99 | users.add(user); 100 | ofy.put(user); 101 | 102 | Account account = new Account(new Long(1), "David", "D.", "example@example.com", userKey); 103 | accounts.add(account); 104 | ofy.put(account); 105 | 106 | UserGAE user2 = new UserGAE("user2", "12345", false); 107 | users.add(user2); 108 | ofy.put(user2); 109 | 110 | Account account2 = new Account(new Long(2), "David", "D.", "example@example.com", userKey); 111 | accounts.add(account2); 112 | ofy.put(account2); 113 | 114 | } 115 | 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/domain/Account.java: -------------------------------------------------------------------------------- 1 | package com.namespace.domain; 2 | 3 | import javax.persistence.Id; 4 | 5 | import com.googlecode.objectify.Key; 6 | import com.googlecode.objectify.annotation.Parent; 7 | 8 | public class Account{ 9 | 10 | @Id 11 | private Long id; 12 | 13 | private String firstName; 14 | 15 | private String lastName; 16 | 17 | private String email; 18 | 19 | @Parent 20 | private Key user; 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | 31 | public String getFirstName() { 32 | return firstName; 33 | } 34 | 35 | public void setFirstName(String firstName) { 36 | this.firstName = firstName; 37 | } 38 | 39 | public String getLastName() { 40 | return lastName; 41 | } 42 | 43 | public void setLastName(String lastName) { 44 | this.lastName = lastName; 45 | } 46 | 47 | public String getEmail() { 48 | return email; 49 | } 50 | 51 | public void setEmail(String email) { 52 | this.email = email; 53 | } 54 | 55 | public Key getUser() { 56 | return user; 57 | } 58 | 59 | public void setUser(Key user) { 60 | this.user = user; 61 | } 62 | 63 | public Account(Long id, String firstName, String lastName, 64 | String email, Key user) { 65 | this.id = id; 66 | this.firstName = firstName; 67 | this.lastName = lastName; 68 | this.email = email; 69 | this.user = user; 70 | } 71 | 72 | public Account() { 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "Account [id=" + id + ", firstName=" + firstName + ", lastName=" 78 | + lastName + ", email=" + email + ", user=" + user + "]"; 79 | } 80 | 81 | @Override 82 | public int hashCode() { 83 | final int prime = 31; 84 | int result = 1; 85 | result = prime * result + ((email == null) ? 0 : email.hashCode()); 86 | result = prime * result 87 | + ((firstName == null) ? 0 : firstName.hashCode()); 88 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 89 | result = prime * result 90 | + ((lastName == null) ? 0 : lastName.hashCode()); 91 | result = prime * result + ((user == null) ? 0 : user.hashCode()); 92 | return result; 93 | } 94 | 95 | @Override 96 | public boolean equals(Object obj) { 97 | if (this == obj) 98 | return true; 99 | if (obj == null) 100 | return false; 101 | if (getClass() != obj.getClass()) 102 | return false; 103 | Account other = (Account) obj; 104 | if (email == null) { 105 | if (other.email != null) 106 | return false; 107 | } else if (!email.equals(other.email)) 108 | return false; 109 | if (firstName == null) { 110 | if (other.firstName != null) 111 | return false; 112 | } else if (!firstName.equals(other.firstName)) 113 | return false; 114 | if (id == null) { 115 | if (other.id != null) 116 | return false; 117 | } else if (!id.equals(other.id)) 118 | return false; 119 | if (lastName == null) { 120 | if (other.lastName != null) 121 | return false; 122 | } else if (!lastName.equals(other.lastName)) 123 | return false; 124 | if (user == null) { 125 | if (other.user != null) 126 | return false; 127 | } else if (!user.equals(other.user)) 128 | return false; 129 | return true; 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/service/dto/UserAdministrationDTOAssemblerTest.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.dto; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertFalse; 5 | import static org.junit.Assert.assertNull; 6 | 7 | import java.util.Map; 8 | 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | 12 | import com.namespace.domain.Account; 13 | import com.namespace.domain.UserGAE; 14 | import com.namespace.service.dto.UserAdministrationForm; 15 | import com.namespace.service.dto.UserAdministrationFormAssembler; 16 | 17 | public class UserAdministrationDTOAssemblerTest { 18 | 19 | private UserAdministrationFormAssembler assembler; 20 | 21 | @Before 22 | public void setUp(){ 23 | this.assembler = new UserAdministrationFormAssembler(); 24 | } 25 | 26 | @SuppressWarnings("unused") 27 | @Test 28 | public void createUserAdministrationDTO(){ 29 | UserAdministrationForm formNull = this.assembler.createUserAdministrationForm(null, null); 30 | assertUserNull(formNull); 31 | assertAccountNull(formNull); 32 | 33 | UserGAE user = new UserGAE("user", "12345", true); 34 | Account account = new Account(new Long(1), "David", "D.", "example@example.com", null); 35 | 36 | UserAdministrationForm form1 = this.assembler.createUserAdministrationForm(null, account); 37 | assertUserNull(form1); 38 | assertAccountEquals(form1, account); 39 | 40 | UserAdministrationForm form2 = this.assembler.createUserAdministrationForm(user, null); 41 | assertUserEquals(form2, user); 42 | assertAccountNull(form2); 43 | 44 | UserAdministrationForm form3 = this.assembler.createUserAdministrationForm(user, account); 45 | assertUserEquals(form3, user); 46 | assertAccountEquals(form3, account); 47 | 48 | UserAdministrationForm form = this.assembler.createUserAdministrationForm(user, account); 49 | assertUserEquals(form, user); 50 | assertAccountEquals(form, account); 51 | 52 | Map map = this.assembler.copyNewUserFromUserAdministrationForm(form); 53 | 54 | UserGAE userFromForm = (UserGAE) map.get("user"); 55 | Account accountFromForm = (Account) map.get("account"); 56 | 57 | //TODO: Fix theses tests 58 | // assertEquals(user, userFromForm); 59 | // assertEquals(account, accountFromForm); 60 | // assertEquals(scheduler, schedulerFromForm); 61 | } 62 | 63 | 64 | private void assertUserNull(UserAdministrationForm form){ 65 | assertNull(form.getUsername()); 66 | assertFalse(form.isAdmin()); 67 | assertFalse(form.isBannedUser()); 68 | assertFalse(form.isEnabled()); 69 | assertNull(form.getPassword()); 70 | 71 | } 72 | 73 | private void assertUserEquals(UserAdministrationForm form, UserGAE user){ 74 | assertEquals(user.getUsername() , form.getUsername()); 75 | assertEquals(user.isAdmin() , form.isAdmin()); 76 | assertEquals(user.isBannedUser() , form.isBannedUser()); 77 | assertEquals(user.isEnabled() , form.isEnabled()); 78 | assertNull(form.getPassword()); 79 | } 80 | 81 | private void assertAccountNull(UserAdministrationForm form){ 82 | assertNull(form.getEmail()); 83 | assertNull(form.getFirstName()); 84 | assertNull(form.getLastName()); 85 | } 86 | 87 | 88 | private void assertAccountEquals(UserAdministrationForm form, Account account){ 89 | assertEquals(account.getEmail() , form.getEmail()); 90 | assertEquals(account.getFirstName() , form.getFirstName()); 91 | assertEquals(account.getLastName() , form.getLastName()); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Spring-GAE-boilerplate 5 | 6 | GAE and Spring 3 integration example 7 | 8 | 9 | 10 | defaultHtmlEscape 11 | true 12 | 13 | 14 | 15 | contextConfigLocation 16 | classpath*:META-INF/spring/applicationContext*.xml 17 | 18 | 19 | 20 | CharacterEncodingFilter 21 | org.springframework.web.filter.CharacterEncodingFilter 22 | 23 | encoding 24 | UTF-8 25 | 26 | 27 | forceEncoding 28 | true 29 | 30 | 31 | 32 | 33 | HttpMethodFilter 34 | org.springframework.web.filter.HiddenHttpMethodFilter 35 | 36 | 37 | 38 | springSecurityFilterChain 39 | org.springframework.web.filter.DelegatingFilterProxy 40 | 41 | 42 | CharacterEncodingFilter 43 | /* 44 | 45 | 46 | 47 | HttpMethodFilter 48 | /* 49 | 50 | 51 | 52 | springSecurityFilterChain 53 | /* 54 | 55 | 56 | 57 | 58 | org.springframework.web.context.ContextLoaderListener 59 | 60 | 61 | 62 | 63 | appServlet 64 | org.springframework.web.servlet.DispatcherServlet 65 | 66 | contextConfigLocation 67 | /WEB-INF/spring/exampleServlet/me-servlet.xml 68 | 69 | 1 70 | 71 | 72 | 73 | appServlet 74 | / 75 | 76 | 77 | 78 | 10 79 | 80 | 81 | 82 | java.lang.Exception 83 | /uncaughtException 84 | 85 | 86 | 87 | 404 88 | /resourceNotFound 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/repository/AccountDAOImpl.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Component; 10 | 11 | import com.googlecode.objectify.Key; 12 | import com.googlecode.objectify.Objectify; 13 | import com.googlecode.objectify.ObjectifyFactory; 14 | import com.googlecode.objectify.Query; 15 | import com.namespace.domain.Account; 16 | import com.namespace.domain.UserGAE; 17 | 18 | @Component 19 | public class AccountDAOImpl implements AccountDAO { 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(AccountDAOImpl.class); 22 | 23 | @Autowired private ObjectifyFactory objectifyFactory; 24 | 25 | public AccountDAOImpl() { 26 | } 27 | 28 | public AccountDAOImpl(ObjectifyFactory objectifyFactory) { 29 | if(objectifyFactory != null) 30 | logger.info("objectifyFactory was injected succesfully to accountDao: " + 31 | objectifyFactory.toString()); 32 | 33 | this.objectifyFactory = objectifyFactory; 34 | } 35 | 36 | 37 | @Override 38 | public List findAll() { 39 | Objectify ofy = objectifyFactory.begin(); 40 | 41 | Query q = ofy.query(Account.class); 42 | ArrayList accounts = (ArrayList) q.list(); 43 | 44 | logger.info("retrieving the accounts from the datastore: " + accounts.toString()); 45 | 46 | return accounts; 47 | } 48 | 49 | @Override 50 | public Account findByUsername(String username){ 51 | try { 52 | Objectify ofy = objectifyFactory.begin(); 53 | 54 | Key userGaeKey = new Key(UserGAE.class, username); 55 | 56 | Query q = ofy.query(Account.class).ancestor(userGaeKey); 57 | Account account = q.get(); 58 | 59 | logger.info("retrieving this account from the datastore: " + account.toString()); 60 | 61 | return account; 62 | 63 | } catch (Exception e) { 64 | logger.info("cannot retrieve the " + username + "'s account from the datastore. Should be for two reasons: The account associated with this user doest'n exist, of they are not any accounts in the datastore"); 65 | return null; 66 | } 67 | } 68 | 69 | 70 | @Override 71 | public void create(Account account) { 72 | Objectify ofy = objectifyFactory.begin(); 73 | ofy.put(account); 74 | } 75 | 76 | @Override 77 | public boolean update(Account account) { 78 | logger.info("update()"); 79 | 80 | if(account == null) 81 | return false; 82 | 83 | Objectify ofy = objectifyFactory.begin(); 84 | 85 | logger.info("verify if this account already exist " + 86 | "in the datastore: " + account.toString()); 87 | boolean thisAccountAlreadyExist = ofy.query(Account.class) 88 | .ancestor(account.getUser()) 89 | .get() != null; 90 | 91 | if(thisAccountAlreadyExist){ 92 | logger.info("Confirmed: this account already exist."); 93 | ofy.put(account); 94 | return true; 95 | }else{ 96 | logger.info("This account doesn't exist at the datastore or " + 97 | "something whas wrong (might be the ancestor reference"); 98 | return false; 99 | } 100 | } 101 | 102 | @Override 103 | public boolean remove(Account item) { 104 | Objectify ofy = objectifyFactory.begin(); 105 | ofy.delete(item); 106 | return true; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/service/AccountManagerTest.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | import static org.junit.Assert.assertFalse; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import com.googlecode.objectify.Key; 13 | import com.googlecode.objectify.Objectify; 14 | import com.namespace.domain.Account; 15 | import com.namespace.domain.UserGAE; 16 | import com.namespace.repository.AccountDAO; 17 | import com.namespace.repository.UserGaeDAO; 18 | import com.namespace.repository.TestBase; 19 | import com.namespace.repository.mock.AccountDAOMock; 20 | import com.namespace.repository.mock.UserGaeDAOMock; 21 | import com.namespace.service.AccountManagerImpl; 22 | import com.namespace.service.AccountManager; 23 | 24 | public class AccountManagerTest extends TestBase{ 25 | 26 | @SuppressWarnings("unused") 27 | private static final Logger logger = LoggerFactory.getLogger(AccountManagerTest.class); 28 | 29 | private AccountManager manager; 30 | 31 | private UserGaeDAO userGaeDAO; 32 | private AccountDAO accountDAO; 33 | 34 | @Before 35 | public void setUp(){ 36 | super.setUp(); 37 | 38 | this.userGaeDAO = new UserGaeDAOMock(super.objectifyFactory); 39 | this.accountDAO = new AccountDAOMock(super.objectifyFactory); 40 | 41 | this.manager = new AccountManagerImpl(userGaeDAO, accountDAO); 42 | } 43 | 44 | @Test 45 | public void updateUser_BoundaryConditions(){ 46 | 47 | assertFalse(this.manager.updateUser(null)); 48 | assertFalse(this.manager.updateUser(new UserGAE())); 49 | Objectify ofy = super.objectifyFactory.begin(); 50 | assertEquals(0, ofy.query(UserGAE.class).list().size()); 51 | assertFalse(this.manager.updateUser(new UserGAE("user1", "12345", true))); 52 | } 53 | 54 | @Test 55 | public void updateUser_RightConditions(){ 56 | Objectify ofy = super.objectifyFactory.begin(); 57 | 58 | UserGAE user = new UserGAE("user", "12345", true); 59 | ofy.put(user); 60 | 61 | user.setPassword("AAAAAAAAAA"); 62 | assertTrue(this.manager.updateUser(user)); 63 | assertEquals(user, ofy.query(UserGAE.class).get()); 64 | assertEquals(1, ofy.query(UserGAE.class).filter("username", user.getUsername()).list().size()); 65 | } 66 | 67 | @Test 68 | public void updateAccount(){ 69 | Objectify ofy = super.objectifyFactory.begin(); 70 | 71 | /* 72 | * BoundaryConditions 73 | */ 74 | assertFalse(this.manager.updateAccount(null)); 75 | assertFalse(this.manager.updateAccount(new Account())); 76 | 77 | UserGAE user = new UserGAE("user", "12345", true); 78 | Account account = new Account(null, "David", "D.", "example@example.com", null); 79 | assertFalse(this.manager.updateAccount(account)); 80 | 81 | ofy.put(account); 82 | assertFalse(this.manager.updateAccount(account)); 83 | 84 | /* 85 | * Right results 86 | */ 87 | ofy.put(user); 88 | account.setUser(new Key(UserGAE.class, user.getUsername())); 89 | ofy.put(account); 90 | assertTrue(this.manager.updateAccount(account)); 91 | 92 | Account accountFromDatastore = ofy.query(Account.class).ancestor(user).get(); 93 | assertEquals(account, accountFromDatastore); 94 | 95 | } 96 | 97 | @Test 98 | public void getEnabledAccount(){ 99 | //TODO: implement this test: getEnabledAccount() 100 | } 101 | 102 | @Test 103 | public void getQuotaForEnabledAccount(){ 104 | //TODO: implement this test: getEnabledAccount() 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/service/mock/AccountManagerMock.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service.mock; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | 9 | import com.googlecode.objectify.Key; 10 | import com.namespace.domain.Account; 11 | import com.namespace.domain.UserGAE; 12 | import com.namespace.repository.TestBase; 13 | import com.namespace.service.AccountManager; 14 | import com.namespace.service.CurrentUserManager; 15 | import com.namespace.util.SecurityUtil; 16 | 17 | public class AccountManagerMock extends TestBase implements AccountManager, CurrentUserManager{ 18 | 19 | private List accounts = new ArrayList(); 20 | private List users = new ArrayList(); 21 | 22 | public AccountManagerMock(UserGAE enabledUser) { 23 | SecurityUtil.authenticateUser(enabledUser); 24 | 25 | /* 26 | * Without extending TestBase.java and calling super.seUp() the 27 | * com.googlecode.objectify.Key class doesn't work. 28 | * It's mandatory. 29 | */ 30 | super.setUp(); 31 | // super.objectifyFactory.register(Quota.class); 32 | // super.objectifyFactory.register(Scheduler.class); 33 | // super.objectifyFactory.register(Account.class); 34 | // super.objectifyFactory.register(UserGAE.class); 35 | // super.objectifyFactory.register(Product.class); 36 | // super.objectifyFactory.register(MarketplaceProduct.class); 37 | } 38 | 39 | @Override 40 | public boolean updateAccount(Account account) { 41 | for (Iterator iterator = accounts.iterator(); iterator.hasNext();) { 42 | Account accountInMemory = (Account) iterator.next(); 43 | 44 | if(accountInMemory.getId().equals(account.getId())){ 45 | accounts.add(accounts.indexOf(accountInMemory), account); 46 | return true; 47 | } 48 | } 49 | return false; 50 | } 51 | 52 | @Override 53 | public Account getEnabledAccount() { 54 | return accounts.get(0); 55 | } 56 | 57 | @Override 58 | public boolean updateUser(UserGAE user) { 59 | for (Iterator iterator = users.iterator(); iterator.hasNext();) { 60 | UserGAE userInMemory = (UserGAE) iterator.next(); 61 | 62 | if(userInMemory.getUsername().equals(user.getUsername())){ 63 | users.add(users.indexOf(userInMemory), user); 64 | return true; 65 | } 66 | } 67 | return false; 68 | } 69 | 70 | 71 | @Override 72 | public UserGAE getEnabledUser() { 73 | UserGAE principal = (UserGAE) SecurityContextHolder.getContext() 74 | .getAuthentication() 75 | .getPrincipal(); 76 | return principal; 77 | } 78 | 79 | public void createInMemoryDomainObjects(){ 80 | users = new ArrayList(); 81 | accounts = new ArrayList(); 82 | 83 | UserGAE user = new UserGAE("user", "12345", true); 84 | Key userKey = new Key(UserGAE.class, "user"); 85 | users.add(user); 86 | 87 | Account account = new Account(new Long(1), "David", "D.", "example@example.com", userKey); 88 | accounts.add(account); 89 | 90 | UserGAE user2 = new UserGAE("user2", "12345", false); 91 | Key userKey2 = new Key(UserGAE.class, "user2"); 92 | users.add(user2); 93 | 94 | Account account2 = new Account(new Long(2), "David", "D.", "example@example.com", userKey2); 95 | accounts.add(account2); 96 | 97 | } 98 | 99 | @Override 100 | public boolean closeEnabledAccount() { 101 | // TODO Auto-generated method stub 102 | return false; 103 | } 104 | 105 | @Override 106 | public Account getAccountByUsername(String username) { 107 | // TODO Auto-generated method stub 108 | return null; 109 | } 110 | 111 | @Override 112 | public Account getAccountByUser(UserGAE user) { 113 | // TODO Auto-generated method stub 114 | return null; 115 | } 116 | 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/header.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/WEB-INF/views/include.jsp" %> 2 | <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %> 3 | 4 | 5 | <%-- 6 | ********************************************************** 7 | Top bar 8 | ********************************************************** 9 | --%> 10 | 11 | 12 | 13 | <%-- Menu Users --%> 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 95 | 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Complete Google App Engine + Spring 3 Web App Example 2 | =============================================================================== 3 | 4 | This repository contains best practices for an JEE (Spring based) application architecture. It's a great boilerplate to start JEE web apps and deploy them in GAE. 5 | 6 | ### Introduction 7 | 8 | This sample web app integrate the following technologies, methodologies and tools: 9 | 10 | * Google App Engine (Java) for its back end 11 | * Objectify for persistence layer 12 | * Java Classes organized in the following packages 13 | + Domain 14 | + Repository (with the DAO pattern) 15 | + Service 16 | + DTO (to adapt the domain objects for the Spring MVC models) 17 | + Controller (using Spring MVC) 18 | * RESTful Spring MVC web controllers 19 | * i18n 20 | * JSTL 21 | * Apache Tiles 22 | * JQuery 23 | * Twitter Bootstrap 24 | * Spring Security (with customized user accounts) 25 | * Test Driven development (Test units and integration tests) 26 | * Maven 27 | 28 | You can learn a lot just reading the source code. 29 | 30 | Getting Started 31 | --------------- 32 | 33 | ### Running the app 34 | 35 | To run the app at localhost using maven type the following command in your terminal, at the root folder of the project: 36 | ``` 37 | mvn gae:run 38 | ``` 39 | And launch your web browser to `http://localhost:8000/` and sign in with a default user: 40 | 41 | ``` 42 | User: admin 43 | Password: admin 44 | ``` 45 | 46 | ``` 47 | User: user 48 | Password: user 49 | ``` 50 | 51 | Each user has a different role (for authentication and authorization purposes). 52 | 53 | 54 | ### Deploying the app 55 | 56 | To deploy the app on GAE change fill the following tag src/main/webapp/WEB-INF/appengine-web and change with your application name: 57 | ``` 58 | example 59 | ``` 60 | and type the following maven command in your terminal, at the root folder: 61 | ``` 62 | mvn gae:deploy 63 | ``` 64 | 65 | ### Using Eclipse 66 | 67 | If you use Eclipse, type the following command-line mvn command to create your .classpath file: 68 | ``` 69 | mvn eclipse:eclipse 70 | ``` 71 | 72 | That's all. 73 | 74 | ### Default file system structure 75 | ``` 76 | +---src 77 | +---main 78 | ¦ +---java 79 | ¦ ¦ +---com 80 | ¦ ¦ +---namespace 81 | ¦ ¦ +---domain 82 | ¦ ¦ +---repository 83 | ¦ ¦ +---service 84 | ¦ ¦ ¦ +---dto 85 | ¦ ¦ ¦ +---validator 86 | ¦ ¦ +---util 87 | ¦ ¦ +---web 88 | ¦ +---resources 89 | ¦ ¦ +---META-INF 90 | ¦ ¦ +---spring 91 | ¦ +---webapp 92 | ¦ +---images 93 | ¦ +---js 94 | ¦ +---META-INF 95 | ¦ +---styles 96 | ¦ +---WEB-INF 97 | ¦ +---i18n 98 | ¦ +---layouts 99 | ¦ +---spring 100 | ¦ ¦ +---exampleServlet 101 | ¦ +---views 102 | ¦ +---account 103 | ¦ ¦ +---settings 104 | ¦ +---commons 105 | ¦ +---users 106 | ¦ +---create 107 | ¦ +---disabled 108 | ¦ +---enabled 109 | ¦ +---update 110 | +---test 111 | +---java 112 | ¦ +---com 113 | ¦ +---namespace 114 | ¦ +---domain 115 | ¦ +---repository 116 | ¦ ¦ +---mock 117 | ¦ +---service 118 | ¦ ¦ +---dto 119 | ¦ ¦ +---mock 120 | ¦ ¦ +---validator 121 | ¦ +---util 122 | ¦ +---web 123 | +---resources 124 | ``` 125 | 126 | 127 | ### TODO list 128 | 129 | * Better integration of Apache Tiles with Spring Framework 130 | * Improve the test units, uncomment test cases and fix them 131 | * Fill all the internationalization fields 132 | * Write the pagination for the user lists 133 | * Better error handling for the DAO layer (using GAE specific Exceptions) 134 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/spring/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 17 | 18 | 31 | 32 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | com.namespace.domain.Account 63 | com.namespace.domain.UserGAE 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/service/UserAdministrationManagerImpl.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.security.access.annotation.Secured; 11 | import org.springframework.stereotype.Service; 12 | 13 | import com.googlecode.objectify.Key; 14 | import com.namespace.domain.Account; 15 | import com.namespace.domain.UserGAE; 16 | import com.namespace.repository.AccountDAO; 17 | import com.namespace.repository.UserGaeDAO; 18 | import com.namespace.util.Pair; 19 | 20 | @Service 21 | @Secured({"ROLE_ADMIN"}) 22 | public class UserAdministrationManagerImpl extends AbstractCurrentUserManager implements UserAdministrationManager { 23 | 24 | private static final Logger logger = LoggerFactory.getLogger(UserAdministrationManagerImpl.class); 25 | 26 | @Autowired private UserGaeDAO userGaeDAO; 27 | @Autowired private AccountDAO accountDAO; 28 | 29 | public UserAdministrationManagerImpl(UserGaeDAO userGaeDAO, 30 | AccountDAO accountDAO) { 31 | this.userGaeDAO = userGaeDAO; 32 | this.accountDAO = accountDAO; 33 | } 34 | 35 | public UserAdministrationManagerImpl() { 36 | } 37 | 38 | @Override 39 | public void createNewUserAccount(UserGAE user, Account account){ 40 | logger.info("createNewUserAccount()"); 41 | 42 | try { 43 | logger.info("Trying to create a new user: " + user.toString()); 44 | this.userGaeDAO.create(user); 45 | logger.info("New user created successfully"); 46 | } catch (Exception e) { 47 | // TODO Auto-generated catch block 48 | e.printStackTrace(); 49 | } 50 | 51 | Key userKey = new Key(UserGAE.class, user.getUsername()); 52 | account.setUser(userKey); 53 | try { 54 | logger.info("Trying to create a new account: " + account.toString()); 55 | this.accountDAO.create(account); 56 | logger.info("New account created successfully"); 57 | } catch (Exception e) { 58 | // TODO Auto-generated catch block 59 | e.printStackTrace(); 60 | } 61 | 62 | } 63 | 64 | @Override 65 | public List> getEnabledUsers(){ 66 | List enabledUsers = this.userGaeDAO.findAllEnabledUsers(true); 67 | 68 | 69 | List> enabledAccounts = new ArrayList>(); 70 | for (Iterator iterator = enabledUsers.iterator(); iterator.hasNext();) { 71 | UserGAE enabledUser = (UserGAE) iterator.next(); 72 | enabledAccounts.add(new Pair(this.accountDAO.findByUsername(enabledUser.getUsername()), enabledUser)); 73 | } 74 | 75 | // List enabledAccounts = new ArrayList(); 76 | // for (Iterator iterator = enabledUsers.iterator(); iterator.hasNext();) { 77 | // UserGAE enabledUser = (UserGAE) iterator.next(); 78 | // enabledAccounts.add(this.accountDAO.findByUsername(enabledUser.getUsername())); 79 | // } 80 | return enabledAccounts; 81 | } 82 | 83 | @Override 84 | public List> getDisabledUsers(){ 85 | List noEnabledUsers = this.userGaeDAO.findAllEnabledUsers(false); 86 | 87 | List> noEnabledAccounts = new ArrayList>(); 88 | for (Iterator iterator = noEnabledUsers.iterator(); iterator.hasNext();) { 89 | UserGAE enabledUser = (UserGAE) iterator.next(); 90 | noEnabledAccounts.add(new Pair(this.accountDAO.findByUsername(enabledUser.getUsername()), enabledUser)); 91 | } 92 | return noEnabledAccounts; 93 | } 94 | 95 | @Override 96 | public boolean deactivateUserByUsername(String username) { 97 | 98 | UserGAE user = this.userGaeDAO.findByUsername(username); 99 | user.setEnabled(false); 100 | try { 101 | return this.userGaeDAO.update(user); 102 | } catch (Exception e) { 103 | return false; 104 | } 105 | } 106 | 107 | @Override 108 | public boolean deleteUserByUsername(String username) { 109 | UserGAE user = this.userGaeDAO.findByUsername(username); 110 | Account account = this.accountDAO.findByUsername(username); 111 | 112 | try { 113 | return this.userGaeDAO.remove(user) && this.accountDAO.remove(account); 114 | } catch (Exception e) { 115 | return false; 116 | } 117 | } 118 | 119 | @Override 120 | public UserGAE getUserByUsername(String username) { 121 | return this.userGaeDAO.findByUsername(username); 122 | } 123 | 124 | @Override 125 | public boolean updateUserDetails(UserGAE user, Account account) { 126 | try { 127 | return updateUser(user) && this.accountDAO.update(account); 128 | } catch (Exception e) { 129 | return false; 130 | } 131 | } 132 | 133 | @Override 134 | public boolean updateUser(UserGAE user) { 135 | 136 | try { 137 | return this.userGaeDAO.update(user); 138 | } catch (Exception e) { 139 | return false; 140 | } 141 | } 142 | } 143 | 144 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/repository/UserGaeDAOImpl.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Component; 10 | 11 | import com.googlecode.objectify.Key; 12 | import com.googlecode.objectify.Objectify; 13 | import com.googlecode.objectify.ObjectifyFactory; 14 | import com.googlecode.objectify.Query; 15 | import com.namespace.domain.Account; 16 | import com.namespace.domain.UserGAE; 17 | 18 | @Component 19 | public class UserGaeDAOImpl implements UserGaeDAO { 20 | 21 | @Autowired private ObjectifyFactory objectifyFactory; 22 | 23 | private static final Logger logger = LoggerFactory.getLogger(UserGaeDAOImpl.class); 24 | 25 | public UserGaeDAOImpl() { 26 | } 27 | 28 | public UserGaeDAOImpl(ObjectifyFactory objectifyFactory) { 29 | this.objectifyFactory = objectifyFactory; 30 | } 31 | 32 | @Override 33 | public List findAll() { 34 | Objectify ofy = objectifyFactory.begin(); 35 | 36 | Query q = ofy.query(UserGAE.class); 37 | ArrayList users = (ArrayList) q.list(); 38 | 39 | return users; 40 | } 41 | 42 | @Override 43 | public List findAllEnabledUsers(boolean isEnabled){ 44 | try { 45 | Objectify ofy = objectifyFactory.begin(); 46 | 47 | Query q = ofy.query(UserGAE.class).filter("enabled", isEnabled); 48 | 49 | UserGAE user = ofy.query(UserGAE.class).get(); 50 | logger.info("**********************user:" + user.toString()); 51 | 52 | ArrayList users = (ArrayList) q.list(); 53 | 54 | 55 | logger.info("retrieving the users list from the datastore: " 56 | + users.toString()); 57 | 58 | return users; 59 | 60 | } catch (Exception e) { 61 | logger.info("cannot retrieve the users " + 62 | "from the datastore. Should be for two reasons: " + 63 | "The account associated with this user doest'n exist, of " + 64 | "they are not any accounts in the datastore"); 65 | return new ArrayList(); 66 | } 67 | 68 | } 69 | 70 | @Override 71 | public void create(UserGAE user) throws Exception { 72 | if(user != null){ 73 | Objectify ofy = objectifyFactory.begin(); 74 | ofy.put(user); 75 | }else{ 76 | throw new Exception("You can't create a null user"); 77 | } 78 | } 79 | 80 | @Override 81 | public boolean update(UserGAE user) { 82 | 83 | if(user == null) 84 | return false; 85 | 86 | Objectify ofy = objectifyFactory.begin(); 87 | 88 | boolean thisAccountAlreadyExist = ofy.query(UserGAE.class).get() != null; 89 | 90 | if(thisAccountAlreadyExist){ 91 | ofy.put(user); 92 | return true; 93 | }else{ 94 | return false; 95 | } 96 | 97 | } 98 | 99 | @Override 100 | public boolean remove(UserGAE user) { 101 | Objectify ofy = objectifyFactory.begin(); 102 | ofy.delete(user); 103 | return true; 104 | } 105 | 106 | @Override 107 | public UserGAE findByUsername(String username){ 108 | try { 109 | Objectify ofy = objectifyFactory.begin(); 110 | UserGAE user = ofy.get(UserGAE.class, username); 111 | return user; 112 | } catch (Exception e) { 113 | return null; 114 | } 115 | } 116 | 117 | //TODO:Eliminar esta clase 118 | @Override 119 | public void createUserAccount(UserGAE user, Account account){ 120 | 121 | Objectify ofy = objectifyFactory.beginTransaction(); 122 | try { 123 | logger.info("ofy.put(user) will be realized now"); 124 | ofy.put(user); 125 | logger.info("ofy.put(user) was realized sucessfully"); 126 | 127 | Key userGaeKey = new Key(UserGAE.class, user.getUsername()); 128 | logger.info("The username to be stored is:" + user.getUsername()); 129 | account.setUser(userGaeKey); 130 | logger.info("ofy.put(account) will be realized now"); 131 | ofy.put(account); 132 | logger.info("ofy.put(account) was realized sucessfully"); 133 | 134 | // Key accountKey = new Key(Account.class, account.getId()); 135 | 136 | // logger.info("accountKey:" + accountKey.toString()); 137 | // scheduler.setAccount(new Key(Account.class, account.getId())); 138 | logger.info("ofy.put(scheduler) will be realized now"); 139 | //ofy.put(scheduler); 140 | logger.info("ofy.put(scheduler) was realized sucessfully"); 141 | 142 | ofy.getTxn().commit(); 143 | 144 | } catch (Exception e) { 145 | logger.info("The transaction createUserAccount() failed"); 146 | logger.info("\nThe error: \n" + e.getMessage() ); 147 | }finally{ 148 | if(ofy.getTxn().isActive()) 149 | ofy.getTxn().rollback(); 150 | } 151 | 152 | throw new UnsupportedOperationException(); 153 | 154 | 155 | } 156 | 157 | @Override 158 | public UserGAE findByAccount(Account account) { 159 | Objectify ofy = this.objectifyFactory.begin(); 160 | 161 | UserGAE user = ofy.find(account.getUser()); 162 | 163 | return user; 164 | } 165 | 166 | } 167 | 168 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/domain/UserGAE.java: -------------------------------------------------------------------------------- 1 | package com.namespace.domain; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import javax.persistence.Id; 8 | 9 | import org.springframework.security.core.GrantedAuthority; 10 | import org.springframework.security.core.authority.GrantedAuthorityImpl; 11 | import org.springframework.security.core.userdetails.UserDetails; 12 | 13 | @SuppressWarnings("serial") 14 | public class UserGAE implements UserDetails{ 15 | 16 | @Id 17 | private String username; 18 | 19 | private String password; 20 | 21 | private boolean admin; 22 | 23 | private boolean enabled; 24 | 25 | private boolean bannedUser; 26 | 27 | private boolean accountNonExpired; 28 | 29 | public void setAccountNonExpired(boolean accountNonExpired) { 30 | this.accountNonExpired = accountNonExpired; 31 | } 32 | 33 | public String getPassword() { 34 | return password; 35 | } 36 | 37 | public void setPassword(String password) { 38 | this.password = password; 39 | } 40 | 41 | public UserGAE(String username, String password, boolean admin, boolean enabled, boolean bannedUser, boolean accountNonExpired) { 42 | this.username = username; 43 | this.password = password; 44 | this.admin = admin; 45 | this.enabled = enabled; 46 | this.bannedUser = bannedUser; 47 | this.accountNonExpired = accountNonExpired; 48 | } 49 | 50 | public UserGAE(String username, String password, boolean admin, boolean enabled, boolean bannedUser) { 51 | this.username = username; 52 | this.password = password; 53 | this.admin = admin; 54 | this.enabled = enabled; 55 | this.bannedUser = bannedUser; 56 | } 57 | 58 | public UserGAE(String username, String password, boolean admin, boolean enabled) { 59 | this.username = username; 60 | this.password = password; 61 | this.admin = admin; 62 | this.enabled = enabled; 63 | } 64 | 65 | public UserGAE(String username, String password, boolean admin) { 66 | this.username = username; 67 | this.password = password; 68 | this.admin = admin; 69 | } 70 | 71 | public UserGAE(String username){ 72 | this.username = username; 73 | } 74 | 75 | public UserGAE() { 76 | } 77 | 78 | public boolean isAdmin() { 79 | return admin; 80 | } 81 | 82 | public void setAdmin(boolean admin) { 83 | this.admin = admin; 84 | } 85 | 86 | public boolean isBannedUser() { 87 | return bannedUser; 88 | } 89 | 90 | public void setBannedUser(boolean bannedUser) { 91 | this.bannedUser = bannedUser; 92 | } 93 | 94 | @Override 95 | public Collection getAuthorities() { 96 | List authorityList = new ArrayList(); 97 | authorityList.add(new GrantedAuthorityImpl("ROLE_USER")); 98 | if(admin){ 99 | authorityList.add(new GrantedAuthorityImpl("ROLE_ADMIN")); 100 | } 101 | return authorityList; 102 | } 103 | 104 | @Override 105 | public String getUsername() { 106 | return username; 107 | } 108 | 109 | @Override 110 | public boolean isAccountNonExpired() { 111 | // return true; 112 | return accountNonExpired; 113 | } 114 | 115 | @Override 116 | public boolean isAccountNonLocked() { 117 | return !bannedUser; 118 | } 119 | 120 | @Override 121 | public boolean isCredentialsNonExpired() { 122 | return true; 123 | } 124 | 125 | @Override 126 | public boolean isEnabled() { 127 | return enabled; 128 | } 129 | 130 | public void setEnabled(boolean enabled) { 131 | this.enabled = enabled; 132 | } 133 | 134 | @Override 135 | public String toString() { 136 | return "UserGAE [username=" + username + ", password=" + password 137 | + ", admin=" + admin + ", enabled=" + enabled + ", bannedUser=" 138 | + bannedUser + ", accountNonExpired=" + accountNonExpired + "]"; 139 | } 140 | 141 | @Override 142 | public int hashCode() { 143 | final int prime = 31; 144 | int result = 1; 145 | result = prime * result + (accountNonExpired ? 1231 : 1237); 146 | result = prime * result + (admin ? 1231 : 1237); 147 | result = prime * result + (bannedUser ? 1231 : 1237); 148 | result = prime * result + (enabled ? 1231 : 1237); 149 | result = prime * result 150 | + ((password == null) ? 0 : password.hashCode()); 151 | result = prime * result 152 | + ((username == null) ? 0 : username.hashCode()); 153 | return result; 154 | } 155 | 156 | @Override 157 | public boolean equals(Object obj) { 158 | if (this == obj) 159 | return true; 160 | if (obj == null) 161 | return false; 162 | if (getClass() != obj.getClass()) 163 | return false; 164 | UserGAE other = (UserGAE) obj; 165 | if (accountNonExpired != other.accountNonExpired) 166 | return false; 167 | if (admin != other.admin) 168 | return false; 169 | if (bannedUser != other.bannedUser) 170 | return false; 171 | if (enabled != other.enabled) 172 | return false; 173 | if (password == null) { 174 | if (other.password != null) 175 | return false; 176 | } else if (!password.equals(other.password)) 177 | return false; 178 | if (username == null) { 179 | if (other.username != null) 180 | return false; 181 | } else if (!username.equals(other.username)) 182 | return false; 183 | return true; 184 | } 185 | 186 | 187 | 188 | 189 | } 190 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/repository/AccountDAOTest.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | import static org.junit.Assert.assertTrue; 6 | import static org.junit.Assert.assertFalse; 7 | import static org.junit.Assert.fail; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Iterator; 11 | import java.util.List; 12 | 13 | import org.junit.Before; 14 | import org.junit.Test; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import com.googlecode.objectify.Key; 19 | import com.googlecode.objectify.Objectify; 20 | import com.namespace.domain.Account; 21 | import com.namespace.domain.UserGAE; 22 | import com.namespace.repository.AccountDAOImpl; 23 | 24 | public class AccountDAOTest extends TestBase{ 25 | 26 | @SuppressWarnings("unused") 27 | private static final Logger logger = LoggerFactory.getLogger(AccountDAOTest.class); 28 | 29 | private AccountDAOImpl dao; 30 | 31 | @Override 32 | @Before 33 | public void setUp(){ 34 | super.setUp(); 35 | 36 | this.objectifyFactory.register(UserGAE.class); 37 | this.objectifyFactory.register(Account.class); 38 | 39 | dao = new AccountDAOImpl(super.objectifyFactory); 40 | } 41 | 42 | @Test 43 | public void findAll_BoundaryConditions(){ 44 | assertTrue(true); 45 | } 46 | 47 | @Test 48 | public void findAll_RightResults() throws InterruptedException{ 49 | List acountListToPersist = generateAccountsAndPersistThem(); 50 | 51 | List accountFromDatastoreList = this.dao.findAll(); 52 | 53 | assertEquals(accountFromDatastoreList.size(), acountListToPersist.size()); 54 | 55 | compareIfList1ContainsList2Objects(accountFromDatastoreList, acountListToPersist); 56 | } 57 | 58 | @Test 59 | public void findByUsername_BoundaryConditions(){ 60 | assertNull(this.dao.findByUsername(null)); 61 | 62 | generateAccountsAndPersistThem(); 63 | assertNull(this.dao.findByUsername("")); 64 | assertNull(this.dao.findByUsername("xyz")); 65 | assertNull(this.dao.findByUsername("$$�!%&%/%&)=&$?*^�")); 66 | } 67 | 68 | @Test 69 | public void findByUsername_RightResults(){ 70 | 71 | Objectify ofy = this.objectifyFactory.begin(); 72 | UserGAE user = new UserGAE("user3", "33333", false); 73 | ofy.put(user); 74 | Key userKey = new Key(UserGAE.class, user.getUsername()); 75 | 76 | Account account = new Account(null, "David", "D.", "example@example.com", userKey); 77 | 78 | ofy.put(account); 79 | 80 | /* 81 | * It must work just if Account is at the same UserGAE entity group 82 | */ 83 | Account accountFromDatastore = ofy.query(Account.class).ancestor(userKey).get(); 84 | // Account accountFromDatastore = ofy.query(Account.class).filter("user", userKey).get(); //without @Parent in Account.java 85 | 86 | assertEquals(accountFromDatastore, account); 87 | } 88 | 89 | @Test public void create_BoundaryConditions(){ 90 | Account account = null; 91 | try { 92 | this.dao.create(account); 93 | fail("You have been persisted a null object!"); 94 | } catch (Exception e) { 95 | assertTrue(true); 96 | } 97 | } 98 | 99 | @Test 100 | public void create_RightResults(){ 101 | List accountListToPersist = generateAccountsAndPersistThem(); 102 | List accountFromDatastoreList = this.objectifyFactory.begin() 103 | .query(Account.class).list(); 104 | compareIfList1ContainsList2Objects(accountFromDatastoreList, 105 | accountListToPersist); 106 | assertEquals(accountFromDatastoreList.size(), accountListToPersist.size()); 107 | } 108 | 109 | @Test 110 | public void update_BoundaryConditions(){ 111 | Account account = null; 112 | assertFalse(this.dao.update(account)); 113 | // try { 114 | // ; 115 | // fail("You have been persisted a null object!"); 116 | // } catch (Exception e) { 117 | // assertTrue(true); 118 | // } 119 | } 120 | 121 | @Test 122 | public void update_RightResults(){ 123 | generateAccountsAndPersistThem(); 124 | Objectify ofy = this.objectifyFactory.begin(); 125 | Account account = ofy.query(Account.class).get(); 126 | try { 127 | this.dao.update(account); 128 | } catch (Exception e) { 129 | fail(); 130 | }finally{ 131 | assertTrue(true); 132 | } 133 | Key userKey = new Key(UserGAE.class, "user"); 134 | Account updatedAccount = ofy.query(Account.class).ancestor(userKey).get(); 135 | // Account updatedAccount = ofy.get(Account.class, account.getId()); 136 | assertEquals(updatedAccount, account); 137 | } 138 | 139 | private void compareIfList1ContainsList2Objects( 140 | List list1, List list2) { 141 | for (Iterator iterator = list2.iterator(); iterator 142 | .hasNext();) { 143 | Account account = (Account) iterator.next(); 144 | assertTrue(list1.contains(account)); 145 | } 146 | } 147 | 148 | private List generateAccountsAndPersistThem(){ 149 | List acountListToPersist = generateAccountList(); 150 | persistAccountList(acountListToPersist); 151 | return acountListToPersist; 152 | 153 | } 154 | 155 | private void persistAccountList(List list){ 156 | Objectify ofy = this.objectifyFactory.begin(); 157 | for (Iterator iterator = list.iterator(); iterator.hasNext();) { 158 | Account account = (Account) iterator.next(); 159 | ofy.put(account); 160 | } 161 | } 162 | 163 | private List generateAccountList(){ 164 | UserGAE user = new UserGAE("user", "12345", true); 165 | Key userKey = new Key(UserGAE.class, user.getUsername()); 166 | Account account1 = new Account(null, "David", "D.", "example@example.com", userKey); 167 | 168 | Account account2 = new Account(null, "David", "D.", "example@example.com", userKey); 169 | List accountList = new ArrayList(); 170 | accountList.add(account1); 171 | accountList.add(account2); 172 | return accountList; 173 | } 174 | 175 | } 176 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/service/UserAdministrationManagerTest.java: -------------------------------------------------------------------------------- 1 | package com.namespace.service; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | import static org.junit.Assert.assertEquals; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | 10 | import org.junit.Before; 11 | import org.junit.Test; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | import com.googlecode.objectify.Key; 16 | import com.googlecode.objectify.Objectify; 17 | import com.namespace.domain.Account; 18 | import com.namespace.domain.UserGAE; 19 | import com.namespace.repository.AccountDAO; 20 | import com.namespace.repository.UserGaeDAO; 21 | import com.namespace.repository.TestBase; 22 | import com.namespace.repository.mock.AccountDAOMock; 23 | import com.namespace.repository.mock.UserGaeDAOMock; 24 | import com.namespace.service.UserAdministrationManager; 25 | import com.namespace.service.UserAdministrationManagerImpl; 26 | 27 | public class UserAdministrationManagerTest extends TestBase { 28 | 29 | @SuppressWarnings("unused") 30 | private static final Logger logger = LoggerFactory.getLogger(UserAdministrationManagerTest.class); 31 | 32 | private UserAdministrationManager manager; 33 | 34 | private UserGaeDAO userGaeDAO; 35 | private AccountDAO accountDAO; 36 | 37 | @Before 38 | public void setUp(){ 39 | // TestBase daoTestBase = new TestBase(); 40 | // daoTestBase.setUp(); 41 | super.setUp(); 42 | // super.objectifyFactory.register(UserGAE.class); 43 | // userGaeDAO = new UserGaeDAO(super.objectifyFactory); 44 | 45 | this.userGaeDAO = new UserGaeDAOMock(super.objectifyFactory); 46 | this.accountDAO = new AccountDAOMock(super.objectifyFactory); 47 | 48 | this.manager = new UserAdministrationManagerImpl(this.userGaeDAO, 49 | this.accountDAO 50 | ); 51 | } 52 | 53 | // @Test 54 | // public void createNewUserAccount_BoundaryConditions(){ 55 | // try { 56 | // this.manager.createNewUserAccount(null, null); 57 | // fail(); 58 | // } catch (Exception e) { 59 | // assertTrue(true); 60 | // } 61 | // 62 | // UserGAE user = new UserGAE("user", "12345", true); 63 | // try { 64 | // this.manager.createNewUserAccount(user, null); 65 | // fail(); 66 | // } catch (Exception e) { 67 | // assertTrue(true); 68 | // } 69 | // 70 | // Account account = new Account(null, "David", "D.", "ME", "example@a.com", null, null, null, null, null, null, AccountType.Diamond, null); 71 | // try { 72 | // this.manager.createNewUserAccount(user, account); 73 | // fail(); 74 | // } catch (Exception e) { 75 | // assertTrue(true); 76 | // } 77 | // 78 | // } 79 | 80 | @Test 81 | public void createNewUserAccount_RightResults(){ 82 | Objectify ofy = super.objectifyFactory.begin(); 83 | 84 | UserGAE user = new UserGAE("user", "12345", true); 85 | Account account = new Account(null, "David", "D.", "example@example.com", null); 86 | 87 | this.manager.createNewUserAccount(user, account); 88 | 89 | UserGAE userFromDatastore = ofy.query(UserGAE.class) 90 | .filter("username", user.getUsername()) 91 | .get(); 92 | Account accountFromDatastore = ofy.query(Account.class) 93 | .ancestor(user) 94 | .get(); 95 | assertEquals(user, userFromDatastore); 96 | assertEquals(account, accountFromDatastore); 97 | } 98 | 99 | 100 | @Test 101 | public void getEnabledUsers_BoundaryConditions(){ 102 | assertEquals(0, this.manager.getEnabledUsers().size()); 103 | } 104 | 105 | 106 | @Test 107 | public void getEnabledUsers_RightResults(){ 108 | // List accounts = generateManyAccountsAndPersistThem(); 109 | // 110 | // List userAccountList = this.manager.getEnabledUsers(); 111 | // 112 | // compareIfList1ContainsList2Objects(accounts, userAccountList); 113 | // int enabledUsers = accounts.size() - 1; 114 | // assertEquals(enabledUsers, userAccountList.size()); 115 | 116 | // throw new UnsupportedOperationException(); 117 | 118 | } 119 | 120 | @Test 121 | public void getDisabledUsers_BoundaryConditions(){ 122 | assertEquals(0, this.manager.getDisabledUsers().size()); 123 | } 124 | 125 | @Test 126 | public void getDisabledUsers_RightResults(){ 127 | // List accounts = generateManyAccountsAndPersistThem(); 128 | // 129 | // List userAccountList = this.manager.getDisabledUsers(); 130 | // 131 | // compareIfList1ContainsList2Objects(accounts, userAccountList); 132 | // assertEquals(1, userAccountList.size()); 133 | 134 | // throw new UnsupportedOperationException(); 135 | 136 | } 137 | 138 | @SuppressWarnings("unused") 139 | private List generateManyAccountsAndPersistThem() { 140 | Objectify ofy = super.objectifyFactory.begin(); 141 | 142 | // List users = new ArrayList(); 143 | List accounts = new ArrayList(); 144 | 145 | UserGAE user1 = new UserGAE("user1", "12345", true, false); 146 | UserGAE user2 = new UserGAE("user2", "142345", false, true); 147 | UserGAE user3 = new UserGAE("user3", "012345", false, true); 148 | Key userKey1 = new Key(UserGAE.class, "user1"); 149 | Key userKey2 = new Key(UserGAE.class, "user2"); 150 | Key userKey3 = new Key(UserGAE.class, "user3"); 151 | ofy.put(user1); 152 | ofy.put(user2); 153 | ofy.put(user3); 154 | // users.add(user2); 155 | // users.add(user); 156 | 157 | Account account1 = new Account(null, "David", "D.", "example@example.com", userKey1); 158 | Account account2 = new Account(null, "David", "D.", "example@example.com", userKey2); 159 | Account account3 = new Account(null, "David", "D.", "example@example.com", userKey3); 160 | accounts.add(account1); 161 | accounts.add(account2); 162 | accounts.add(account3); 163 | ofy.put(account1); 164 | ofy.put(account2); 165 | ofy.put(account3); 166 | return accounts; 167 | } 168 | 169 | @SuppressWarnings("unused") 170 | private void compareIfList1ContainsList2Objects( 171 | List list1, List list2) { 172 | for (Iterator iterator = list2.iterator(); iterator 173 | .hasNext();) { 174 | Account account = (Account) iterator.next(); 175 | assertTrue(list1.contains(account)); 176 | } 177 | } 178 | 179 | } 180 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/web/UsersControllerIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.namespace.web; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | 6 | import java.util.List; 7 | 8 | import javax.inject.Inject; 9 | 10 | import org.junit.Before; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.context.ApplicationContext; 17 | import org.springframework.mock.web.MockHttpServletRequest; 18 | import org.springframework.mock.web.MockHttpServletResponse; 19 | import org.springframework.test.context.ContextConfiguration; 20 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 21 | import org.springframework.ui.ModelMap; 22 | import org.springframework.web.servlet.HandlerAdapter; 23 | import org.springframework.web.servlet.ModelAndView; 24 | import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter; 25 | 26 | import com.googlecode.objectify.Key; 27 | import com.googlecode.objectify.Objectify; 28 | import com.namespace.domain.Account; 29 | import com.namespace.domain.UserGAE; 30 | import com.namespace.repository.TestBase; 31 | import com.namespace.repository.UserGaeDAOImpl; 32 | import com.namespace.service.validator.UserAdministrationValidator; 33 | import com.namespace.util.SecurityUtil; 34 | import com.namespace.web.UsersController; 35 | 36 | @RunWith(SpringJUnit4ClassRunner.class) 37 | @ContextConfiguration({ 38 | "file:src/main/resources/META-INF/spring/applicationContext.xml", 39 | "file:src/main/resources/META-INF/spring/applicationContext-security.xml", 40 | "file:src/main/webapp/WEB-INF/spring/exampleServlet/mvc-config.xml", 41 | "file:src/main/webapp/WEB-INF/spring/exampleServlet/controllers.xml" 42 | }) 43 | @SuppressWarnings("unused") 44 | public class UsersControllerIntegrationTest extends TestBase { 45 | 46 | private static final Logger logger = LoggerFactory.getLogger(UsersControllerIntegrationTest.class); 47 | 48 | private static final String USER_USERNAME = "user"; 49 | private static final String USER_PASSWORD = "12345"; 50 | private static final String ACCOUNT_FIRST_NAME = "John"; 51 | private static final String ACCOUNT_LAST_NAME = "Doe"; 52 | private static final String ACCOUNT_EMAIL = "a@a.com"; 53 | 54 | private MockHttpServletRequest request; 55 | private MockHttpServletResponse response; 56 | private HandlerAdapter handlerAdapter; 57 | 58 | @Inject private ApplicationContext applicationContext; 59 | @Autowired private UsersController controller; 60 | @Autowired private UserAdministrationValidator userAdministrationValidator; 61 | @Autowired private UserGaeDAOImpl userGaeDAOImpl; 62 | 63 | @Before 64 | public void setUp(){ 65 | super.setUp(); 66 | super.objectifyFactory.register(UserGAE.class); 67 | super.objectifyFactory.register(Account.class); 68 | 69 | request = new MockHttpServletRequest(); 70 | response = new MockHttpServletResponse(); 71 | handlerAdapter = applicationContext.getBean(HttpRequestHandlerAdapter.class); 72 | controller = applicationContext.getBean(UsersController.class); 73 | 74 | SecurityUtil.authenticateUser(new UserGAE(USER_USERNAME, USER_PASSWORD, true, true)); 75 | createAccountAndPutIntoDatastore(); 76 | } 77 | 78 | // @Test 79 | // public void newUseForm(){ 80 | // ModelAndView modelAndView = this.controller.addNewUserHome(); 81 | // assertEquals("users/addNewUser", modelAndView.getViewName()); 82 | // assertNotNull(modelAndView.getModel()); 83 | // 84 | // UserAdministrationForm model = (UserAdministrationForm) modelAndView.getModel().get("user"); 85 | // assertNotNull(model); 86 | // System.out.println(model); 87 | // assertNull(model.getUsername()); 88 | // 89 | // WebDataBinder binder = BinderUtil.setUpBinder(new UserAdministrationForm(), 90 | // userAdministrationValidator, 91 | // request); 92 | // assertEquals(4, binder.getBindingResult().getErrorCount()); 93 | // String viewName = this.controller.createNewUser((UserAdministrationForm) binder.getTarget(), binder.getBindingResult()); 94 | // assertEquals("users/addNewUser", viewName); 95 | // 96 | // 97 | // /* 98 | // * Right results 99 | // */ 100 | // request.setParameter("username", USER_USERNAME); 101 | // request.setParameter("firstName", ACCOUNT_FIRST_NAME); 102 | // request.setParameter("lastName", ACCOUNT_LAST_NAME); 103 | // request.setParameter("email", ACCOUNT_EMAIL); 104 | // request.setParameter("schedulingEmail", ACCOUNT_EMAIL); 105 | // request.setParameter("accountType", AccountType.Premium.toString()); 106 | // 107 | // binder = BinderUtil.setUpBinder(new UserAdministrationForm(), 108 | // userAdministrationValidator, 109 | // request); 110 | // assertEquals(0, binder.getBindingResult().getErrorCount()); 111 | // 112 | // viewName = this.controller.createNewUser((UserAdministrationForm) binder.getTarget(), binder.getBindingResult()); 113 | // assertEquals("redirect:newUser", viewName); 114 | // 115 | // UserAdministrationForm target = (UserAdministrationForm) binder.getTarget(); 116 | // 117 | // assertEquals(USER_USERNAME, target.getUsername()); 118 | // assertEquals(ACCOUNT_FIRST_NAME, target.getFirstName()); 119 | // assertEquals(ACCOUNT_LAST_NAME, target.getLastName()); 120 | // assertEquals(ACCOUNT_EMAIL, target.getEmail()); 121 | // assertEquals(ACCOUNT_EMAIL, target.getSchedulingEmail()); 122 | // assertEquals(AccountType.Premium, target.getAccountType()); 123 | // 124 | // } 125 | 126 | @Test 127 | public void enabledUsers(){ 128 | 129 | //TODO: I need to uncomment and fix that 130 | // ModelAndView modelAndView = this.controller.enabledUserListHome(new ModelMap()); 131 | // assertEquals("users/listEnabledUser", modelAndView.getViewName()); 132 | // assertNotNull(modelAndView.getModel()); 133 | // 134 | // checkUsers(modelAndView); 135 | 136 | } 137 | 138 | @Test 139 | public void disabledUsers(){ 140 | // throw new UnsupportedOperationException(); 141 | // ModelAndView modelAndView = this.controller.disabledUserListHome(new ModelMap()); 142 | // assertEquals("users/listDisabledUser", modelAndView.getViewName()); 143 | // assertNotNull(modelAndView.getModel()); 144 | // 145 | // Objectify ofy = this.objectifyFactory.begin(); 146 | // UserGAE user = ofy.query(UserGAE.class).get(); 147 | // user.setEnabled(false); 148 | // ofy.put(user); 149 | 150 | /* 151 | * TODO I need to test the boundary conditions too. 152 | */ 153 | /* 154 | * TODO: Fix this bug. I need to investigate what happens. 155 | */ 156 | // checkUsers(modelAndView); 157 | 158 | } 159 | 160 | private void checkUsers(ModelAndView modelAndView) { 161 | ModelMap model = (ModelMap) modelAndView.getModel().get("user"); 162 | @SuppressWarnings("unchecked") 163 | List usersList = (List) model.get("usersList"); 164 | assertNotNull(model); 165 | assertNotNull(usersList); 166 | assertEquals(usersList.get(0).getFirstName(), ACCOUNT_FIRST_NAME); 167 | assertEquals(usersList.get(0).getLastName(), ACCOUNT_LAST_NAME); 168 | assertEquals(usersList.get(0).getEmail(), ACCOUNT_EMAIL); 169 | } 170 | 171 | private void createAccountAndPutIntoDatastore(){ 172 | Objectify ofy = this.objectifyFactory.begin(); 173 | Key userKey = ofy.put(new UserGAE(USER_USERNAME, USER_PASSWORD, true, true)); 174 | ofy.put(new Account(null, ACCOUNT_FIRST_NAME, ACCOUNT_LAST_NAME, ACCOUNT_EMAIL, userKey)); 175 | 176 | } 177 | 178 | } 179 | -------------------------------------------------------------------------------- /src/test/java/com/namespace/repository/UserGaeDAOTest.java: -------------------------------------------------------------------------------- 1 | package com.namespace.repository; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | import static org.junit.Assert.assertFalse; 6 | import static org.junit.Assert.fail; 7 | import static org.junit.Assert.assertNull; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Iterator; 11 | import java.util.List; 12 | 13 | import org.junit.Before; 14 | import org.junit.Test; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import com.google.appengine.api.datastore.DatastoreTimeoutException; 19 | import com.googlecode.objectify.Objectify; 20 | import com.namespace.domain.UserGAE; 21 | import com.namespace.repository.UserGaeDAOImpl; 22 | 23 | public class UserGaeDAOTest extends TestBase{ 24 | 25 | @SuppressWarnings("unused") 26 | private static final Logger logger = LoggerFactory.getLogger(UserGaeDAOTest.class); 27 | 28 | private UserGaeDAOImpl dao; 29 | 30 | @Before 31 | @Override 32 | public void setUp(){ 33 | super.setUp(); 34 | super.objectifyFactory.register(UserGAE.class); 35 | dao = new UserGaeDAOImpl(super.objectifyFactory); 36 | } 37 | 38 | @Test 39 | public void findAll_BoundaryConditions(){ 40 | assertEquals(0, this.dao.findAll().size()); 41 | } 42 | 43 | @Test 44 | public void findAll_RightResults() throws InterruptedException{ 45 | List userListToPersist = generateUsersAndPersistThem(); 46 | 47 | List userFromDatastoreList = this.dao.findAll(); 48 | 49 | assertEquals(userFromDatastoreList.size(), userListToPersist.size()); 50 | 51 | compareIfList1ContainsList2Objects(userListToPersist, userFromDatastoreList); 52 | } 53 | 54 | @Test 55 | /* 56 | * TODO: write the forced errors that dispatch exceptions 57 | * Some exceptions are: 58 | * 59 | * http://code.google.com/intl/es-ES/appengine/docs/java/howto/maintenance.html 60 | * com.google.appengine.api.memcache.MemcacheServiceException 61 | * 62 | * http://united-coders.com/christian-harms/top-7-exceptions-in-my-google-app-engine-described 63 | * 64 | * http://code.google.com/intl/es-ES/appengine/articles/scaling/contention.html 65 | * 66 | * http://code.google.com/intl/es-ES/appengine/articles/handling_datastore_errors.html 67 | * google.appengine.ext.db.Timeout 68 | * com.google.appengine.api.datastore.DatastoreTimeoutException 69 | * http://code.google.com/intl/es-ES/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreTimeoutException.html 70 | * http://stackoverflow.com/questions/2123376/google-app-engine-how-do-you-handle-a-datastoretimeoutexception 71 | * 72 | * http://code.google.com/intl/es-ES/appengine/docs/python/datastore/exceptions.html 73 | * 74 | */ 75 | public void findAll_ForceErrorConditions() throws InterruptedException{ 76 | 77 | try { 78 | //coming soon 79 | 80 | } catch (DatastoreTimeoutException e) { 81 | // TODO: handle exception 82 | } catch (Exception e){ 83 | 84 | } 85 | 86 | } 87 | 88 | @Test 89 | public void findAllEnabledUsers_BoundaryConditions()throws InterruptedException{ 90 | List userEnabledFromDatastoreList = this.dao.findAllEnabledUsers(true); 91 | assertEquals(0, userEnabledFromDatastoreList.size()); 92 | 93 | List userNotEnabledFromDatastoreList = this.dao.findAllEnabledUsers(false); 94 | assertEquals(0, userNotEnabledFromDatastoreList.size()); 95 | 96 | List userListToPersist = generateUsersAndPersistThem(); 97 | 98 | assertEquals(0, this.dao.findAllEnabledUsers(true).size()); 99 | assertEquals(userListToPersist.size(), this.dao.findAllEnabledUsers(false).size()); 100 | 101 | UserGAE userEnabled = new UserGAE("userEnabled", "12345", true, true); 102 | Objectify ofy = this.objectifyFactory.begin(); 103 | ofy.put(userEnabled); 104 | assertEquals(1, this.dao.findAllEnabledUsers(true).size()); 105 | assertEquals(userEnabled, this.dao.findAllEnabledUsers(true).get(0)); 106 | } 107 | 108 | @Test 109 | public void findAllEnabledUsers_RightResults() throws InterruptedException{ 110 | List userListToPersist = generateUsersAndPersistThem(); 111 | List userFromDatastoreList = this.dao.findAllEnabledUsers(false); 112 | 113 | compareIfList1ContainsList2Objects(userFromDatastoreList, userListToPersist); 114 | assertTrue(true); 115 | 116 | UserGAE user = new UserGAE("user", "12345", true, true); 117 | this.objectifyFactory.begin().put(user); 118 | List userFromDatastoreList2 = this.dao.findAllEnabledUsers(true); 119 | assertTrue(userFromDatastoreList2.contains(user)); 120 | } 121 | 122 | @Test 123 | public void create_BoundaryConditions() throws InterruptedException{ 124 | UserGAE user = null; 125 | 126 | try { 127 | this.dao.create(user); 128 | fail("You have been persisted a null object!"); 129 | } catch (Exception e) { 130 | assertTrue(true); 131 | } 132 | 133 | } 134 | 135 | @Test 136 | public void create_RightResults(){ 137 | List userListToPersist = generateUsersAndPersistThem(); 138 | 139 | List userFromDatastoreList = this.objectifyFactory.begin() 140 | .query(UserGAE.class).list(); 141 | 142 | compareIfList1ContainsList2Objects(userListToPersist, userFromDatastoreList); 143 | assertEquals(userListToPersist.size(), userFromDatastoreList.size()); 144 | } 145 | 146 | @Test 147 | public void create_ForceErrorConditions(){ 148 | //TODO: create_ForceErrorConditions() Complete it. 149 | } 150 | 151 | @Test 152 | public void update_BoundaryConditions(){ 153 | UserGAE user = null; 154 | assertFalse(this.dao.update(user)); 155 | 156 | // try { 157 | // this.dao.update(user); 158 | // fail("You have been persisted a null object!"); 159 | // } catch (Exception e) { 160 | // assertTrue(true); 161 | // } 162 | 163 | } 164 | 165 | @Test 166 | public void update_RightResults(){ 167 | generateUsersAndPersistThem(); 168 | Objectify ofy = this.objectifyFactory.begin(); 169 | UserGAE user = ofy.query(UserGAE.class).get(); 170 | user.setPassword("0000"); 171 | try { 172 | this.dao.update(user); 173 | } catch (Exception e) { 174 | fail(); 175 | } finally { 176 | assertTrue(true); 177 | } 178 | UserGAE updatedUser = ofy.get(UserGAE.class, user.getUsername()); 179 | assertEquals(updatedUser, user); 180 | } 181 | 182 | 183 | 184 | @Test 185 | public void update_ForceErrorConditions(){ 186 | //TODO: update_ForceErrorConditions() Complete it. 187 | } 188 | 189 | @Test 190 | public void findByUsername_BoundaryConditions(){ 191 | assertNull(this.dao.findByUsername(null)); 192 | 193 | generateUsersAndPersistThem(); 194 | assertNull(this.dao.findByUsername("")); 195 | assertNull(this.dao.findByUsername("xyz")); 196 | assertNull(this.dao.findByUsername("$$�!%&%/%&)=&$?*^�")); 197 | } 198 | 199 | @Test 200 | public void findByUsername_RightResults(){ 201 | List userList = generateUsersAndPersistThem(); 202 | 203 | assertEquals(userList.get(0), 204 | this.dao.findByUsername(userList.get(0).getUsername())); 205 | } 206 | 207 | @Test 208 | public void findByUsername_ForceErrorConditions(){ 209 | //TODO: findByUsername_ForceErrorConditions() Complete it. 210 | 211 | } 212 | private void compareIfList1ContainsList2Objects( 213 | List list1, List list2) { 214 | for (Iterator iterator = list2.iterator(); iterator 215 | .hasNext();) { 216 | UserGAE user = (UserGAE) iterator.next(); 217 | assertTrue(list1.contains(user)); 218 | } 219 | } 220 | 221 | private List generateUsersAndPersistThem() { 222 | List userListToPersist = generateUserList(); 223 | persistUserList(userListToPersist); 224 | return userListToPersist; 225 | } 226 | 227 | private List generateUserList() { 228 | UserGAE user1 = new UserGAE("user", "12345", false); 229 | UserGAE user2 = new UserGAE("admin", "12345", true); 230 | List userListToPersist = new ArrayList(); 231 | userListToPersist.add(user1); 232 | userListToPersist.add(user2); 233 | return userListToPersist; 234 | } 235 | 236 | private void persistUserList(List userListToPersist) { 237 | Objectify ofy = this.objectifyFactory.begin(); 238 | for (Iterator iterator = userListToPersist.iterator(); iterator 239 | .hasNext();) { 240 | UserGAE user = (UserGAE) iterator.next(); 241 | ofy.put(user); 242 | } 243 | } 244 | 245 | 246 | } 247 | -------------------------------------------------------------------------------- /src/main/java/com/namespace/web/UsersController.java: -------------------------------------------------------------------------------- 1 | package com.namespace.web; 2 | 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.security.access.annotation.Secured; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.validation.BindingResult; 13 | import org.springframework.web.bind.annotation.ModelAttribute; 14 | import org.springframework.web.bind.annotation.PathVariable; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.RequestMethod; 17 | import org.springframework.web.servlet.ModelAndView; 18 | 19 | import com.namespace.domain.Account; 20 | import com.namespace.domain.UserGAE; 21 | import com.namespace.service.AccountManager; 22 | import com.namespace.service.UserAdministrationManager; 23 | import com.namespace.service.dto.EnabledUserForm; 24 | import com.namespace.service.dto.UserAdministrationForm; 25 | import com.namespace.service.dto.UserAdministrationFormAssembler; 26 | import com.namespace.service.validator.UserAdministrationDetailsValidator; 27 | import com.namespace.service.validator.UserAdministrationPasswordValidator; 28 | import com.namespace.service.validator.UserAdministrationValidator; 29 | import com.namespace.util.Pair; 30 | 31 | @Controller 32 | @Secured({"ROLE_ADMIN"}) 33 | public class UsersController { 34 | 35 | private static final Logger logger = LoggerFactory.getLogger(UsersController.class); 36 | 37 | @Autowired private UserAdministrationFormAssembler userAdministrationFormAssembler; 38 | @Autowired private UserAdministrationValidator userAdministrationValidator; 39 | @Autowired private UserAdministrationDetailsValidator userAdministrationDetailsValidator; 40 | @Autowired private UserAdministrationPasswordValidator userAdministrationPasswordValidator; 41 | @Autowired private UserAdministrationManager userAdministrationManager; 42 | @Autowired private AccountManager accountManager; 43 | 44 | public UsersController(UserAdministrationFormAssembler userAdministrationFormAssembler, 45 | UserAdministrationValidator userAdministrationValidator, 46 | UserAdministrationManager userAdministrationManager) { 47 | this.userAdministrationFormAssembler = userAdministrationFormAssembler; 48 | this.userAdministrationValidator = userAdministrationValidator; 49 | this.userAdministrationManager = userAdministrationManager; 50 | } 51 | 52 | public UsersController() { 53 | } 54 | 55 | /** 56 | * New user form 57 | */ 58 | @RequestMapping(value="/newUser", method=RequestMethod.GET) 59 | public ModelAndView addNewUserHome() { 60 | 61 | UserAdministrationForm model = new UserAdministrationForm(); 62 | return new ModelAndView("users/addNewUser", "user", model); 63 | //return new ModelAndView("users/addNewUser", "command", "S"); 64 | } 65 | 66 | @RequestMapping(value="createUser", method=RequestMethod.POST) 67 | public String createNewUser(@ModelAttribute("user") UserAdministrationForm model, 68 | BindingResult result){ 69 | 70 | this.userAdministrationValidator.validate(model, result); 71 | 72 | if(result.hasErrors()){ 73 | return "users/addNewUser"; 74 | }else{ 75 | HashMap domainModelMap = new HashMap(); 76 | domainModelMap = (HashMap) this.userAdministrationFormAssembler.copyNewUserFromUserAdministrationForm(model); 77 | UserGAE user = (UserGAE) domainModelMap.get("user"); 78 | user.setEnabled(true); 79 | user.setBannedUser(false); 80 | user.setAccountNonExpired(true); 81 | Account account = (Account) domainModelMap.get("account"); 82 | 83 | this.userAdministrationManager.createNewUserAccount(user, account); 84 | 85 | // Account enabledAccount = this.accountManager.getEnabledAccount(); 86 | // Product product = this.productFormAssembler.copyNewProductFormFormtoProduct(model, new Product(), enabledAccount); 87 | // this.productManager.updateProduct(product); 88 | 89 | return "redirect:udpateUser/" + user.getUsername() + "/"; 90 | } 91 | } 92 | 93 | 94 | /** 95 | * Update user form 96 | */ 97 | @RequestMapping(value="/udpateUser/{username}/", method=RequestMethod.GET) 98 | public ModelAndView updateUserHome(@PathVariable String username) { 99 | 100 | UserGAE user = this.userAdministrationManager.getUserByUsername(username); 101 | Account account = this.accountManager.getAccountByUsername(username); 102 | 103 | UserAdministrationForm userAdministrationModel = this.userAdministrationFormAssembler 104 | .createUserAdministrationForm(user, account); 105 | 106 | ModelAndView mv = new ModelAndView("users/updateUser"); 107 | mv.addObject("userDetailsModel", userAdministrationModel); 108 | 109 | UserAdministrationForm userEmptyModel = new UserAdministrationForm(); 110 | userEmptyModel.setUsername(username); 111 | 112 | mv.addObject("userPasswordModel", userAdministrationModel); 113 | mv.addObject("enableUserModel", userEmptyModel); 114 | mv.addObject("deleteBanUserModel", userEmptyModel); 115 | 116 | return mv; 117 | } 118 | 119 | @RequestMapping(value="/udpateUser/{username}/updateUserDetails", method=RequestMethod.POST) 120 | public String updateUserDetails(@PathVariable String username, @ModelAttribute("userDetailsModel") UserAdministrationForm model, 121 | BindingResult result){ 122 | 123 | logger.info("updateUserDetails()"); 124 | 125 | this.userAdministrationDetailsValidator.validate(model, result); 126 | 127 | if(result.hasErrors()){ 128 | return "udpateUser/" + username + "/"; 129 | }else{ 130 | HashMap domainModelMap = new HashMap(); 131 | domainModelMap = (HashMap) this.userAdministrationFormAssembler.updateUserDetailsFromUserAdministrationForm(model, this.userAdministrationManager.getUserByUsername(username), this.accountManager.getAccountByUsername(username)); 132 | 133 | UserGAE user = (UserGAE) domainModelMap.get("user"); 134 | Account account= (Account) domainModelMap.get("account"); 135 | 136 | this.userAdministrationManager.updateUserDetails(user, account); 137 | 138 | return "redirect:./"; 139 | } 140 | } 141 | 142 | @RequestMapping(value="/udpateUser/{username}/updatePasswordAdministrationForm", method=RequestMethod.POST) 143 | public String updatePassowrd(@PathVariable String username, @ModelAttribute("userPasswordModel") UserAdministrationForm model, 144 | BindingResult result){ 145 | 146 | logger.info("updatePassowrd()"); 147 | 148 | this.userAdministrationPasswordValidator.validate(model, result); 149 | 150 | if(result.hasErrors()){ 151 | logger.info("validation error!"); 152 | return "../../udpateUser/" + username + "/"; 153 | }else{ 154 | UserGAE user = this.userAdministrationManager.getUserByUsername(username); 155 | user.setPassword(model.getPassword()); 156 | 157 | this.userAdministrationManager.updateUser(user); 158 | 159 | return "redirect:./"; 160 | } 161 | } 162 | 163 | 164 | 165 | /** 166 | * Enabled users 167 | */ 168 | @RequestMapping(value="/enabledUsersList", method=RequestMethod.GET) 169 | public ModelAndView enabledUserListHome() { 170 | List> enabledUsers = this.userAdministrationManager.getEnabledUsers(); 171 | 172 | ModelAndView mv = new ModelAndView("users/listEnabledUser"); 173 | mv.addObject("usersList", enabledUsers); 174 | mv.addObject("enabledUsersToDeactivateModel", new EnabledUserForm()); 175 | 176 | return mv; 177 | } 178 | 179 | @RequestMapping(value="deactivateUsers", method=RequestMethod.POST) 180 | public String deactivateUsers(@ModelAttribute("enabledUsersToDeactivateModel") EnabledUserForm model, 181 | BindingResult result){ 182 | 183 | logger.info("Enabled users (account IDs) to be deactivated: " + model); 184 | 185 | List deactivatedUsers = model.getDeactivate(); 186 | 187 | logger.info("deactivatedUsers: " + deactivatedUsers); 188 | 189 | if(deactivatedUsers != null){ 190 | for (Iterator iterator = deactivatedUsers.iterator(); iterator.hasNext();) { 191 | String username = (String) iterator.next(); 192 | this.userAdministrationManager.deactivateUserByUsername(username); 193 | } 194 | } 195 | 196 | return "redirect:enabledUsersList"; 197 | } 198 | 199 | 200 | 201 | /** 202 | * Disabled users 203 | */ 204 | @RequestMapping(value="/disabledUsersList", method=RequestMethod.GET) 205 | public ModelAndView disabledUserListHome() { 206 | 207 | List> disabledUsers = this.userAdministrationManager.getDisabledUsers(); 208 | 209 | ModelAndView mv = new ModelAndView("users/listDisabledUser"); 210 | mv.addObject("usersList", disabledUsers); 211 | mv.addObject("enabledUsersToDeleteModel", new EnabledUserForm()); 212 | 213 | return mv; 214 | } 215 | 216 | @RequestMapping(value="deleteUsers", method=RequestMethod.POST) 217 | public String deleteUsers(@ModelAttribute("enabledUsersToDeleteModel") EnabledUserForm model, 218 | BindingResult result){ 219 | 220 | logger.info("Enabled users (account IDs) to be deleted: " + model); 221 | 222 | List deletedUsers = model.getDeactivate(); 223 | 224 | logger.info("deactivatedUsers: " + deletedUsers); 225 | 226 | if(deletedUsers != null){ 227 | for (Iterator iterator = deletedUsers.iterator(); iterator.hasNext();) { 228 | String username = (String) iterator.next(); 229 | this.userAdministrationManager.deleteUserByUsername(username); 230 | } 231 | } 232 | 233 | return "redirect:disabledUsersList"; 234 | } 235 | 236 | 237 | } 238 | -------------------------------------------------------------------------------- /src/main/webapp/js/jquery/jquery.tablesorter.min.js: -------------------------------------------------------------------------------- 1 | 2 | (function($){$.extend({tablesorter:new 3 | function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",cssChildRow:"expand-child",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,sortLocaleCompare:true,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'/\.|\,/g',onRenderHeader:null,selectorHeaders:'thead th',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}if(table.tBodies.length==0)return;var rows=table.tBodies[0].rows;if(rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function checkHeaderOptionsSortingLocked(table,i){if((table.config.headers[i])&&(table.config.headers[i].lockedOrder))return table.config.headers[i].lockedOrder;return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;i b["+i+"]) ? 1 : 0));";};function makeSortTextDesc(i){return"((b["+i+"] < a["+i+"]) ? -1 : ((b["+i+"] > a["+i+"]) ? 1 : 0));";};function makeSortNumeric(i){return"a["+i+"]-b["+i+"];";};function makeSortNumericDesc(i){return"b["+i+"]-a["+i+"];";};function sortText(a,b){if(table.config.sortLocaleCompare)return a.localeCompare(b);return((ab)?1:0));};function sortTextDesc(a,b){if(table.config.sortLocaleCompare)return b.localeCompare(a);return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$.data(this,"tablesorter",config);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){$this.trigger("sortStart");var $cell=$(this);var i=this.column;this.order=this.count++%2;if(this.lockedOrder)this.order=this.lockedOrder;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i 2 | 3 | 4.0.0 4 | com.namespace 5 | Spring3-GAE-boilerplate 6 | war 7 | 0.1.0.BUILD-SNAPSHOT 8 | Spring3-GAE-boilerplate 9 | 10 | 1.2.1.RELEASE 11 | 3.1.0.RELEASE 12 | 1.6 13 | 1.6.12 14 | 1.6.4 15 | UTF-8 16 | ${user.home}/.m2/repository/com/google/appengine/appengine-java-sdk/1.7.7/appengine-java-sdk-1.7.7 17 | 1.7.7 18 | 3.1.0.RELEASE 19 | 20 | 21 | 22 | spring-maven-release 23 | Spring Maven Release Repository 24 | http://maven.springframework.org/release 25 | 26 | 27 | spring-maven-milestone 28 | Spring Maven Milestone Repository 29 | http://maven.springframework.org/milestone 30 | 31 | 32 | spring-roo-repository 33 | Spring Roo Repository 34 | http://spring-roo-repository.springsource.org/release 35 | 36 | 37 | maven-gae-plugin-repo 38 | http://maven-gae-plugin.googlecode.com/svn/repository 39 | maven-gae-plugin repository 40 | 41 | 42 | JBoss Repo 43 | https://repository.jboss.org/nexus/content/repositories/releases 44 | JBoss Repo 45 | 46 | 47 | 48 | objectify-appengine 49 | http://objectify-appengine.googlecode.com/svn/maven 50 | 51 | 52 | 53 | 54 | spring-maven-release 55 | Spring Maven Release Repository 56 | http://maven.springframework.org/release 57 | 58 | 59 | spring-maven-milestone 60 | Spring Maven Milestone Repository 61 | http://maven.springframework.org/milestone 62 | 63 | 64 | maven-gae-plugin-repo 65 | http://maven-gae-plugin.googlecode.com/svn/repository 66 | maven-gae-plugin repository 67 | 68 | 69 | 70 | 71 | 72 | junit 73 | junit 74 | 4.10 75 | test 76 | 77 | 78 | log4j 79 | log4j 80 | 1.2.16 81 | 82 | 83 | org.slf4j 84 | slf4j-api 85 | ${slf4j.version} 86 | 87 | 88 | org.slf4j 89 | jcl-over-slf4j 90 | ${slf4j.version} 91 | 92 | 93 | org.slf4j 94 | slf4j-log4j12 95 | ${slf4j.version} 96 | 97 | 98 | org.aspectj 99 | aspectjrt 100 | ${aspectj.version} 101 | 102 | 103 | org.aspectj 104 | aspectjweaver 105 | ${aspectj.version} 106 | 107 | 108 | javax.servlet 109 | servlet-api 110 | 2.5 111 | provided 112 | 113 | 114 | net.sf.flexjson 115 | flexjson 116 | 2.1 117 | 118 | 119 | org.apache.commons 120 | commons-lang3 121 | 3.1 122 | 123 | 124 | 125 | 126 | org.springframework 127 | spring-core 128 | ${spring.version} 129 | 130 | 131 | commons-logging 132 | commons-logging 133 | 134 | 135 | 136 | 137 | org.springframework 138 | spring-test 139 | ${spring.version} 140 | test 141 | 142 | 143 | commons-logging 144 | commons-logging 145 | 146 | 147 | 148 | 149 | org.springframework 150 | spring-context 151 | ${spring.version} 152 | 153 | 154 | org.springframework 155 | spring-aop 156 | ${spring.version} 157 | 158 | 159 | org.springframework 160 | spring-aspects 161 | ${spring.version} 162 | 163 | 164 | org.springframework 165 | spring-tx 166 | ${spring.version} 167 | 168 | 169 | 170 | 171 | org.springframework 172 | spring-context-support 173 | ${spring.version} 174 | 175 | 176 | 177 | 178 | com.google.appengine 179 | appengine-api-1.0-sdk 180 | ${gae.version} 181 | 182 | 183 | com.google.appengine 184 | appengine-testing 185 | ${gae.version} 186 | test 187 | 188 | 189 | com.google.appengine 190 | appengine-api-stubs 191 | ${gae.version} 192 | test 193 | 194 | 195 | com.google.appengine 196 | appengine-api-labs 197 | ${gae.version} 198 | test 199 | 200 | 201 | javax.persistence 202 | persistence-api 203 | 1.0 204 | 205 | 206 | org.hibernate 207 | hibernate-validator 208 | 4.2.0.Final 209 | 210 | 211 | javax.xml.bind 212 | jaxb-api 213 | 214 | 215 | com.sun.xml.bind 216 | jaxb-impl 217 | 218 | 219 | 220 | 221 | javax.validation 222 | validation-api 223 | 1.0.0.GA 224 | 225 | 226 | cglib 227 | cglib-nodep 228 | 2.2.2 229 | 230 | 231 | javax.transaction 232 | jta 233 | 1.1 234 | 235 | 236 | commons-pool 237 | commons-pool 238 | 1.5.6 239 | 240 | 241 | commons-logging 242 | commons-logging 243 | 244 | 245 | 246 | 247 | org.springframework 248 | spring-web 249 | ${spring.version} 250 | 251 | 252 | commons-logging 253 | commons-logging 254 | 255 | 256 | 257 | 258 | org.springframework 259 | spring-webmvc 260 | ${spring.version} 261 | 262 | 263 | commons-logging 264 | commons-logging 265 | 266 | 267 | 268 | 269 | commons-digester 270 | commons-digester 271 | 2.0 272 | 273 | 274 | commons-logging 275 | commons-logging 276 | 277 | 278 | 279 | 280 | commons-fileupload 281 | commons-fileupload 282 | 1.2.2 283 | 284 | 285 | commons-logging 286 | commons-logging 287 | 288 | 289 | 290 | 291 | javax.servlet 292 | jstl 293 | 1.2 294 | 295 | 296 | javax.el 297 | el-api 298 | 2.2 299 | provided 300 | 301 | 302 | joda-time 303 | joda-time 304 | 2.1 305 | 306 | 307 | 308 | javax.inject 309 | javax.inject 310 | 1 311 | 312 | 313 | 314 | javax.servlet.jsp 315 | jsp-api 316 | 2.1 317 | provided 318 | 319 | 320 | commons-codec 321 | commons-codec 322 | 1.5 323 | 324 | 325 | org.apache.tiles 326 | tiles-core 327 | 2.2.2 328 | 329 | 330 | commons-logging 331 | commons-logging 332 | 333 | 334 | 335 | 336 | org.apache.tiles 337 | tiles-jsp 338 | 2.2.2 339 | 340 | 341 | org.springframework.security 342 | spring-security-core 343 | ${spring-security.version} 344 | 345 | 346 | commons-logging 347 | commons-logging 348 | 349 | 350 | 351 | 352 | org.springframework.security 353 | spring-security-config 354 | ${spring-security.version} 355 | 356 | 357 | commons-logging 358 | commons-logging 359 | 360 | 361 | 362 | 363 | org.springframework.security 364 | spring-security-web 365 | ${spring-security.version} 366 | 367 | 368 | org.springframework.security 369 | spring-security-taglibs 370 | ${spring-security.version} 371 | 372 | 373 | 374 | 375 | com.googlecode.objectify 376 | objectify 377 | 3.0 378 | 379 | 380 | com.googlecode.objectify-appengine-spring 381 | objectify-appengine-spring 382 | 1.1.1 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | org.apache.maven.plugins 391 | maven-war-plugin 392 | 2.2 393 | 394 | 395 | 396 | org.apache.maven.plugins 397 | maven-compiler-plugin 398 | 2.3.2 399 | 400 | ${java.version} 401 | ${java.version} 402 | ${project.build.sourceEncoding} 403 | 404 | 405 | 406 | org.codehaus.mojo 407 | aspectj-maven-plugin 408 | 1.2 409 | 410 | 411 | 412 | org.aspectj 413 | aspectjrt 414 | ${aspectj.version} 415 | 416 | 417 | org.aspectj 418 | aspectjtools 419 | ${aspectj.version} 420 | 421 | 422 | 423 | 424 | 425 | compile 426 | test-compile 427 | 428 | 429 | 430 | 431 | true 432 | 433 | 434 | org.springframework 435 | spring-aspects 436 | 437 | 438 | ${java.version} 439 | ${java.version} 440 | 441 | 442 | 443 | org.apache.maven.plugins 444 | maven-resources-plugin 445 | 2.5 446 | 447 | ${project.build.sourceEncoding} 448 | 449 | 450 | 451 | org.apache.maven.plugins 452 | maven-surefire-plugin 453 | 2.12 454 | 455 | false 456 | true 457 | 458 | 459 | 460 | org.apache.maven.plugins 461 | maven-assembly-plugin 462 | 2.3 463 | 464 | 465 | jar-with-dependencies 466 | 467 | 468 | 469 | 470 | org.apache.maven.plugins 471 | maven-deploy-plugin 472 | 2.7 473 | 474 | 475 | 476 | org.apache.maven.plugins 477 | maven-eclipse-plugin 478 | 2.7 479 | 480 | true 481 | false 482 | 2.0 483 | 484 | 485 | org.eclipse.ajdt.core.ajbuilder 486 | 487 | org.springframework.aspects 488 | 489 | 490 | 491 | org.springframework.ide.eclipse.core.springbuilder 492 | 493 | 494 | com.google.appengine.eclipse.core.enhancerbuilder 495 | 496 | 497 | 498 | org.eclipse.ajdt.ui.ajnature 499 | com.springsource.sts.roo.core.nature 500 | org.springframework.ide.eclipse.core.springnature 501 | com.google.appengine.eclipse.core.gaeNature 502 | 503 | 504 | 505 | 506 | org.apache.maven.plugins 507 | maven-idea-plugin 508 | 2.2 509 | 510 | true 511 | true 512 | 513 | 514 | 515 | org.codehaus.mojo 516 | tomcat-maven-plugin 517 | 1.1 518 | 519 | 520 | org.mortbay.jetty 521 | jetty-maven-plugin 522 | 8.1.2.v20120308 523 | 524 | 525 | /${project.name} 526 | 527 | 528 | 529 | 530 | net.kindleit 531 | maven-gae-plugin 532 | 0.9.2 533 | 534 | ${gae.version} 535 | 536 | 537 | 538 | validate 539 | 540 | 541 | unpack 542 | 543 | 544 | 545 | 546 | 547 | net.kindleit 548 | gae-runtime 549 | 1.6.4 550 | pom 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | --------------------------------------------------------------------------------