├── .gitignore ├── Readme.md ├── example-spring-core ├── pom.xml └── src │ ├── main │ ├── config │ │ └── tomcat │ │ │ └── context.xml │ ├── java │ │ └── example │ │ │ ├── domain │ │ │ ├── iam │ │ │ │ ├── bootstrap │ │ │ │ │ └── RoleBootstrapListener.java │ │ │ │ └── model │ │ │ │ │ ├── Role.java │ │ │ │ │ ├── RoleIdentifier.java │ │ │ │ │ ├── RoleRepository.java │ │ │ │ │ ├── User.java │ │ │ │ │ ├── UserIdentifier.java │ │ │ │ │ └── UserRepository.java │ │ │ ├── shared │ │ │ │ ├── audit │ │ │ │ │ ├── Audit.java │ │ │ │ │ └── Auditable.java │ │ │ │ ├── bootstrap │ │ │ │ │ ├── BootstrapEvent.java │ │ │ │ │ └── BootstrapOrder.java │ │ │ │ ├── date │ │ │ │ │ └── DateTimeProvider.java │ │ │ │ ├── ddd │ │ │ │ │ ├── AbstractAggregateEntity.java │ │ │ │ │ ├── AbstractEntity.java │ │ │ │ │ ├── AbstractEvent.java │ │ │ │ │ ├── AbstractValueObject.java │ │ │ │ │ ├── AggregateEntity.java │ │ │ │ │ ├── DomainFactory.java │ │ │ │ │ ├── DomainRepository.java │ │ │ │ │ ├── DomainService.java │ │ │ │ │ ├── Entity.java │ │ │ │ │ ├── EntityFunctions.java │ │ │ │ │ ├── Event.java │ │ │ │ │ ├── EventListener.java │ │ │ │ │ └── EventPublisher.java │ │ │ │ ├── json │ │ │ │ │ ├── JsonHolder.java │ │ │ │ │ ├── JsonSerializationException.java │ │ │ │ │ └── JsonSerializationService.java │ │ │ │ └── security │ │ │ │ │ ├── AuthenticatedUserDetails.java │ │ │ │ │ └── AuthenticatedUserDetailsProvider.java │ │ │ └── todo │ │ │ │ ├── application │ │ │ │ └── TodoService.java │ │ │ │ ├── bootstrap │ │ │ │ └── TodoBootstrapListener.java │ │ │ │ └── domain │ │ │ │ ├── Todo.java │ │ │ │ ├── TodoIllegalStateException.java │ │ │ │ ├── TodoRepository.java │ │ │ │ └── TodoState.java │ │ │ ├── infrastructure │ │ │ ├── common │ │ │ │ ├── AjaxHeaderMatcher.java │ │ │ │ └── ApplicationBootstrap.java │ │ │ ├── date │ │ │ │ └── DefaultDateTimeProvider.java │ │ │ ├── events │ │ │ │ └── EventBusBeanPostProcessor.java │ │ │ ├── jackson │ │ │ │ ├── Jackson2Configuration.java │ │ │ │ ├── Jackson2JsonSerializationService.java │ │ │ │ ├── MoneyDeserializer.java │ │ │ │ ├── MoneyModule.java │ │ │ │ └── MoneySerializer.java │ │ │ ├── jms │ │ │ │ └── ObjectMessageCreator.java │ │ │ ├── jpa │ │ │ │ ├── AbstractCustomType.java │ │ │ │ ├── AuditListener.java │ │ │ │ ├── CustomTypes.java │ │ │ │ ├── DateTimeType.java │ │ │ │ ├── FixedPrefixNamingStrategy.java │ │ │ │ ├── JsonHolderType.java │ │ │ │ └── MoneyType.java │ │ │ └── security │ │ │ │ ├── NonAjaxRequestMatcher.java │ │ │ │ ├── OpenIdUserDetails.java │ │ │ │ ├── OpenIdUserDetailsProvider.java │ │ │ │ └── OpenIdUserDetailsService.java │ │ │ └── web │ │ │ ├── ExceptionHandlerAdvice.java │ │ │ ├── RequestMappings.java │ │ │ ├── TodoController.java │ │ │ └── WebConfiguration.java │ ├── resources │ │ ├── META-INF │ │ │ └── spring │ │ │ │ ├── applicationContext-domain-iam.xml │ │ │ │ ├── applicationContext-domain-shared.xml │ │ │ │ ├── applicationContext-domain-todo.xml │ │ │ │ ├── applicationContext-domain.xml │ │ │ │ ├── applicationContext-infrastructure-cache.xml │ │ │ │ ├── applicationContext-infrastructure-common.xml │ │ │ │ ├── applicationContext-infrastructure-date.xml │ │ │ │ ├── applicationContext-infrastructure-events.xml │ │ │ │ ├── applicationContext-infrastructure-jackson.xml │ │ │ │ ├── applicationContext-infrastructure-jms.xml │ │ │ │ ├── applicationContext-infrastructure-jmx.xml │ │ │ │ ├── applicationContext-infrastructure-jpa.xml │ │ │ │ ├── applicationContext-infrastructure-security.xml │ │ │ │ ├── applicationContext-infrastructure.xml │ │ │ │ ├── applicationContext-properties.xml │ │ │ │ └── applicationContext-web.xml │ │ ├── application-local.properties │ │ ├── application-remote.properties │ │ ├── application.properties │ │ ├── ehcache.xml │ │ ├── logback-local.xml │ │ ├── logback-remote.xml │ │ ├── logback.xml │ │ ├── messages.properties │ │ └── orm.xml │ └── webapp │ │ ├── 404.html │ │ ├── WEB-INF │ │ ├── views │ │ │ └── test.jsp │ │ └── web.xml │ │ └── index.html │ └── test │ ├── java │ ├── example │ │ ├── Assertions.java │ │ ├── EntitiesAssert.java │ │ ├── EntityAssert.java │ │ ├── TestGroups.java │ │ ├── domain │ │ │ ├── iam │ │ │ │ └── domain │ │ │ │ │ └── UserTest.java │ │ │ ├── shared │ │ │ │ └── audit │ │ │ │ │ └── AuditTest.java │ │ │ └── todo │ │ │ │ └── domain │ │ │ │ ├── TodoStatusTest.java │ │ │ │ └── TodoTest.java │ │ ├── infrastructure │ │ │ ├── cache │ │ │ │ ├── CacheTest.java │ │ │ │ └── CacheTestConfiguration.java │ │ │ ├── date │ │ │ │ └── DefaultDateTimeProviderTest.java │ │ │ ├── events │ │ │ │ └── EventsTests.java │ │ │ ├── jackson │ │ │ │ └── Jackson2JsonSerializationServiceTest.java │ │ │ ├── jms │ │ │ │ ├── AbstractJmsTest.java │ │ │ │ ├── JmsPerformanceTest.java │ │ │ │ ├── JmsQueueTest.java │ │ │ │ ├── JmsTestConfiguration.java │ │ │ │ ├── JmsTestListener.java │ │ │ │ ├── JmsTestMessage.java │ │ │ │ └── JmsTopicTest.java │ │ │ └── jpa │ │ │ │ ├── AbstractJpaRepositoryTest.java │ │ │ │ ├── JpaTestConfiguration.java │ │ │ │ ├── JpaTestRepositoryTest.java │ │ │ │ ├── TestEntity.java │ │ │ │ ├── TestRepository.java │ │ │ │ ├── TestValueObject.java │ │ │ │ ├── iam │ │ │ │ ├── JpaRoleRepositoryTest.java │ │ │ │ └── JpaUserRepositoryTest.java │ │ │ │ └── todo │ │ │ │ └── JpaTodoRepositoryTest.java │ │ └── web │ │ │ ├── AbstractContollerTest.java │ │ │ ├── TodoControllerTest.java │ │ │ └── WebTestConfiguration.java │ └── org │ │ └── mockito │ │ └── testng │ │ ├── MockitoAfterTestNGMethod.java │ │ ├── MockitoBeforeTestNGMethod.java │ │ └── MockitoTestNGListener.java │ └── resources │ ├── META-INF │ └── spring │ │ ├── testContext-infrastructure-cache.xml │ │ ├── testContext-infrastructure-date.xml │ │ ├── testContext-infrastructure-events.xml │ │ ├── testContext-infrastructure-jackson.xml │ │ ├── testContext-infrastructure-jms.xml │ │ ├── testContext-infrastructure-jpa.xml │ │ └── testContext-web.xml │ ├── logback-test.xml │ ├── test-jms.properties │ ├── test-jpa.properties │ └── test-web.properties ├── example-spring-deploy ├── pom.xml └── src │ └── main │ └── webapp │ └── WEB-INF │ └── cloudbees-web.xml ├── example-spring-test ├── pom.xml └── src │ └── main │ ├── java │ └── example │ │ └── acceptance │ │ ├── steps │ │ ├── Steps.java │ │ └── TodoSteps.java │ │ └── stories │ │ ├── AbstractSpringJBehaveStory.java │ │ └── TodoStory.java │ └── resources │ ├── META-INF │ └── spring │ │ └── storiesContext.xml │ ├── example │ └── acceptance │ │ └── stories │ │ └── todo_story.story │ └── logback-test.xml ├── example-spring-ui ├── .bowerrc ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── app │ ├── .buildignore │ ├── .htaccess │ ├── 404.html │ ├── favicon.ico │ ├── images │ │ ├── glyphicons-halflings-white.png │ │ └── glyphicons-halflings.png │ ├── index.html │ ├── robots.txt │ ├── scripts │ │ ├── app.js │ │ ├── controllers │ │ │ ├── main.js │ │ │ └── todo.js │ │ └── services │ │ │ └── todo.js │ ├── styles │ │ └── main.scss │ └── views │ │ ├── main.html │ │ └── todo.html ├── bower.json ├── karma-e2e.conf.js ├── karma.conf.js ├── package.json ├── pom.xml └── test │ ├── .jshintrc │ ├── runner.html │ └── spec │ ├── controllers │ ├── main.js │ └── todo.js │ └── services │ └── todo.js └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.iws 2 | *Db.properties 3 | *Db.script 4 | .settings 5 | .pmd 6 | stacktrace.log 7 | *.zip 8 | /plugin.xml 9 | *.log 10 | *DB.* 11 | cobertura.ser 12 | .DS_Store 13 | target/ 14 | test-output/ 15 | out/ 16 | web-app/plugins 17 | web-app/WEB-INF/classes 18 | 19 | # STS 20 | .classpath 21 | .project 22 | .springBeans 23 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Enterprise Spring Showcase 2 | 3 | Collects best practices of the JEE applications based on Spring Framework and AngularJS. 4 | The showcase borrows also many concepts from another platforms and languages. 5 | Focuses on developer productivity, even if Java and JEE are not well suited for rapid development. 6 | 7 | [![Build Status](https://mkuthan.ci.cloudbees.com/job/Example%20Spring/badge/icon)](https://mkuthan.ci.cloudbees.com/job/Example%20Spring/) 8 | 9 | # Key Acronyms 10 | 11 | ## DDD 12 | 13 | Project structure and setup aligned with Domain Driven Design methodology. Package structure reflects domain concepts not technical details. This is only a top of iceberg in DDD, for more details see: [Domain-Driven Design: Tackling Complexity in the Heart of Software](http://www.goodreads.com/book/show/179133.Domain_Driven_Design). 14 | 15 | ## BDD 16 | 17 | The technical infrastructure and configuration for Behavior Driven Development with JBehave. Please remember that the most important part of BDD is communication not tools and automation, for more details see: [Specification by Example](http://www.goodreads.com/book/show/10288718-specification-by-example). 18 | 19 | ## TDD 20 | 21 | The best of the beast tools for testing: TestNG, Mockito and FestAssert are the key players. They make the tests first class citizen in your projects. For more details see: [Practical Unit Testing With TestNG and Mockito](http://www.goodreads.com/book/show/15737558-practical-unit-testing-with-testng-and-mockito). 22 | 23 | # Key Frameworks, Libraries and Runtimes 24 | 25 | * Spring, Spring MVC, Spring Security, Spring Data are the backbone of the showcase. 26 | * Hibernate as a persistence. I have plans to integrate NoSQL storages as well. 27 | * Guava as a swiss army knife, if you like functional programming, you are impatiently waiting for closures in Java, you will love this library. 28 | * JodaTime where SDK sucks. 29 | * SLF4J + Logback where SDK sucks. 30 | * JBehave for doing BDD not test scripts. 31 | * TestNG for testing on steroids, no more JUnit. 32 | * Mockito the best library for mocking, developed by Polish guy! 33 | * FestAssert to address a little bit not so flexible Java syntax. 34 | * TwitterBootstrap give a good support for developer with strong server side background (me). 35 | * AngularJS as JS MVC platform. 36 | * ActiveMQ for asynchronous processing, integration with WebSockets is comming ... 37 | * CloudBees as a awesome runtime platform and continuous delivery automation tool (Jenkins). 38 | * MySql as a default database, but in memory H2 for integration tests. 39 | * Hexagonal architecture 40 | * And last but not least: old good Maven. I will migrate project to Gradle eventually ... 41 | -------------------------------------------------------------------------------- /example-spring-core/src/main/config/tomcat/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/iam/bootstrap/RoleBootstrapListener.java: -------------------------------------------------------------------------------- 1 | package example.domain.iam.bootstrap; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.ApplicationListener; 5 | import org.springframework.core.Ordered; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.google.common.collect.Lists; 9 | 10 | import example.domain.iam.model.Role; 11 | import example.domain.iam.model.RoleIdentifier; 12 | import example.domain.iam.model.RoleRepository; 13 | import example.domain.shared.bootstrap.BootstrapEvent; 14 | import example.domain.shared.bootstrap.BootstrapOrder; 15 | 16 | @Component 17 | public class RoleBootstrapListener implements ApplicationListener, Ordered { 18 | 19 | public static final RoleIdentifier USER = new RoleIdentifier("ROLE_USER"); 20 | public static final RoleIdentifier ADMIN = new RoleIdentifier("ROLE_ADMIN"); 21 | 22 | @Autowired 23 | private RoleRepository roleRepository; 24 | 25 | @Override 26 | public void onApplicationEvent(BootstrapEvent event) { 27 | if (!rolesExist()) { 28 | Role user = new Role(USER, "Application User"); 29 | Role admin = new Role(ADMIN, "Application Admin"); 30 | 31 | roleRepository.save(Lists.newArrayList(user, admin)); 32 | roleRepository.flush(); 33 | } 34 | } 35 | 36 | @Override 37 | public int getOrder() { 38 | return BootstrapOrder.IAM_ROLES; 39 | } 40 | 41 | public boolean rolesExist() { 42 | return roleRepository.count() > 0; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/iam/model/Role.java: -------------------------------------------------------------------------------- 1 | package example.domain.iam.model; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | import javax.persistence.AttributeOverride; 6 | import javax.persistence.Cacheable; 7 | import javax.persistence.Column; 8 | import javax.persistence.Embedded; 9 | import javax.persistence.Entity; 10 | 11 | import org.hibernate.annotations.CacheConcurrencyStrategy; 12 | 13 | import example.domain.shared.ddd.AbstractAggregateEntity; 14 | 15 | @Entity 16 | @Cacheable 17 | @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 18 | public class Role extends AbstractAggregateEntity { 19 | 20 | @Embedded 21 | @AttributeOverride(name = RoleIdentifier.IDENTIFIER_PROPERTY, column = @Column(nullable = false, unique = true)) 22 | private RoleIdentifier identifier; 23 | 24 | @Column(nullable = false) 25 | private String name; 26 | 27 | protected Role() { 28 | } 29 | 30 | public Role(RoleIdentifier identifier, String name) { 31 | this.identifier = checkNotNull(identifier); 32 | this.name = checkNotNull(name); 33 | } 34 | 35 | public RoleIdentifier getIdentifier() { 36 | return identifier; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/iam/model/RoleIdentifier.java: -------------------------------------------------------------------------------- 1 | package example.domain.iam.model; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | import javax.persistence.Access; 6 | import javax.persistence.AccessType; 7 | import javax.persistence.Embeddable; 8 | 9 | import example.domain.shared.ddd.AbstractValueObject; 10 | 11 | @Embeddable 12 | @Access(AccessType.FIELD) 13 | public class RoleIdentifier extends AbstractValueObject { 14 | 15 | public static final String IDENTIFIER_PROPERTY = "identifier"; 16 | 17 | private String identifier; 18 | 19 | protected RoleIdentifier() { 20 | } 21 | 22 | public RoleIdentifier(String identifier) { 23 | this.identifier = checkNotNull(identifier); 24 | } 25 | 26 | public String getIdentifier() { 27 | return identifier; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/iam/model/RoleRepository.java: -------------------------------------------------------------------------------- 1 | package example.domain.iam.model; 2 | 3 | import javax.persistence.QueryHint; 4 | 5 | import org.springframework.data.jpa.repository.QueryHints; 6 | 7 | import example.domain.shared.ddd.DomainRepository; 8 | 9 | public interface RoleRepository extends DomainRepository { 10 | 11 | @QueryHints(@QueryHint(name = org.hibernate.ejb.QueryHints.HINT_CACHEABLE, value = "true")) 12 | Role findByIdentifier(RoleIdentifier identifier); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/iam/model/User.java: -------------------------------------------------------------------------------- 1 | package example.domain.iam.model; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | import static com.google.common.base.Preconditions.checkState; 5 | 6 | import java.util.Collections; 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | import javax.persistence.AttributeOverride; 11 | import javax.persistence.Cacheable; 12 | import javax.persistence.CollectionTable; 13 | import javax.persistence.Column; 14 | import javax.persistence.ElementCollection; 15 | import javax.persistence.Embedded; 16 | import javax.persistence.Entity; 17 | import javax.persistence.FetchType; 18 | 19 | import org.hibernate.annotations.CacheConcurrencyStrategy; 20 | 21 | import example.domain.shared.ddd.AbstractAggregateEntity; 22 | 23 | @Entity 24 | @Cacheable 25 | @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 26 | public class User extends AbstractAggregateEntity { 27 | 28 | @Embedded 29 | @AttributeOverride(name = UserIdentifier.IDENTIFIER_PROPERTY, column = @Column(nullable = false, unique = true)) 30 | private UserIdentifier identifier; 31 | 32 | @Column(nullable = false) 33 | private String email; 34 | 35 | @Column(nullable = false) 36 | private String firstname; 37 | 38 | @Column(nullable = false) 39 | private String lastname; 40 | 41 | @Column(nullable = false) 42 | private String fullname; 43 | 44 | @Column(nullable = false) 45 | private Boolean enabled; 46 | 47 | @CollectionTable 48 | @ElementCollection(fetch = FetchType.EAGER) 49 | private Set roles = new HashSet<>(); 50 | 51 | protected User() { 52 | } 53 | 54 | protected User(Builder builder) { 55 | this.identifier = checkNotNull(builder.identifier); 56 | this.email = checkNotNull(builder.email); 57 | this.firstname = checkNotNull(builder.firstname); 58 | this.lastname = checkNotNull(builder.lastname); 59 | 60 | if (builder.fullname != null) { 61 | this.fullname = builder.fullname; 62 | } else { 63 | this.fullname = String.format("%s %s", firstname, lastname); 64 | } 65 | 66 | if (builder.enabled != null) { 67 | this.enabled = builder.enabled; 68 | } else { 69 | this.enabled = Boolean.TRUE; 70 | } 71 | 72 | this.roles.addAll(builder.roles); 73 | } 74 | 75 | public UserIdentifier getIdentifier() { 76 | return identifier; 77 | } 78 | 79 | public String getEmail() { 80 | return email; 81 | } 82 | 83 | public String getFirstname() { 84 | return firstname; 85 | } 86 | 87 | public String getLastname() { 88 | return lastname; 89 | } 90 | 91 | public String getFullname() { 92 | return fullname; 93 | } 94 | 95 | public void disable() { 96 | checkState(isEnabled()); 97 | enabled = Boolean.FALSE; 98 | } 99 | 100 | public void enable() { 101 | checkState(isDisabled()); 102 | enabled = Boolean.TRUE; 103 | } 104 | 105 | public Boolean isEnabled() { 106 | return enabled; 107 | } 108 | 109 | public Boolean isDisabled() { 110 | return !enabled; 111 | } 112 | 113 | public Set getRoles() { 114 | return Collections.unmodifiableSet(roles); 115 | } 116 | 117 | public static class Builder { 118 | 119 | private UserIdentifier identifier; 120 | 121 | private String email; 122 | 123 | private String firstname; 124 | 125 | private String lastname; 126 | 127 | private String fullname; 128 | 129 | private Boolean enabled; 130 | 131 | private Set roles = new HashSet<>(); 132 | 133 | public Builder withIdentifier(UserIdentifier identifier) { 134 | this.identifier = identifier; 135 | return this; 136 | } 137 | 138 | public Builder withEmail(String email) { 139 | this.email = email; 140 | return this; 141 | } 142 | 143 | public Builder withFirstname(String firstname) { 144 | this.firstname = firstname; 145 | return this; 146 | } 147 | 148 | public Builder withLastname(String lastname) { 149 | this.lastname = lastname; 150 | return this; 151 | } 152 | 153 | public Builder withFullname(String fullname) { 154 | this.fullname = fullname; 155 | return this; 156 | } 157 | 158 | public Builder withEnabled(Boolean enabled) { 159 | this.enabled = enabled; 160 | return this; 161 | } 162 | 163 | public Builder addRole(RoleIdentifier role) { 164 | this.roles.add(role); 165 | return this; 166 | } 167 | 168 | public Builder addRoles(Set roles) { 169 | this.roles.addAll(roles); 170 | return this; 171 | } 172 | 173 | public User build() { 174 | return new User(this); 175 | } 176 | 177 | } 178 | 179 | } 180 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/iam/model/UserIdentifier.java: -------------------------------------------------------------------------------- 1 | package example.domain.iam.model; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | import javax.persistence.Access; 6 | import javax.persistence.AccessType; 7 | import javax.persistence.Embeddable; 8 | 9 | import example.domain.shared.ddd.AbstractValueObject; 10 | 11 | @Embeddable 12 | @Access(AccessType.FIELD) 13 | public class UserIdentifier extends AbstractValueObject { 14 | 15 | public static final String IDENTIFIER_PROPERTY = "identifier"; 16 | 17 | private String identifier; 18 | 19 | protected UserIdentifier() { 20 | } 21 | 22 | public UserIdentifier(String identifier) { 23 | this.identifier = checkNotNull(identifier); 24 | } 25 | 26 | public String getIdentifier() { 27 | return identifier; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/iam/model/UserRepository.java: -------------------------------------------------------------------------------- 1 | package example.domain.iam.model; 2 | 3 | import javax.persistence.QueryHint; 4 | 5 | import org.springframework.data.jpa.repository.QueryHints; 6 | 7 | import example.domain.shared.ddd.DomainRepository; 8 | 9 | public interface UserRepository extends DomainRepository { 10 | 11 | @QueryHints(@QueryHint(name = org.hibernate.ejb.QueryHints.HINT_CACHEABLE, value = "true")) 12 | User findByIdentifier(UserIdentifier identifier); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/audit/Audit.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.audit; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | import static com.google.common.base.Preconditions.checkState; 5 | 6 | import javax.persistence.Access; 7 | import javax.persistence.AccessType; 8 | import javax.persistence.Column; 9 | import javax.persistence.Embeddable; 10 | 11 | import org.joda.time.DateTime; 12 | 13 | import example.domain.shared.ddd.AbstractValueObject; 14 | 15 | @Embeddable 16 | @Access(AccessType.FIELD) 17 | public class Audit extends AbstractValueObject { 18 | 19 | public static final Audit NULL = new Audit(); 20 | 21 | @Column(name = "audit_creation_date", nullable = false, updatable = false) 22 | private DateTime creationDate; 23 | 24 | @Column(name = "audit_creator", nullable = false, updatable = false) 25 | private String creator; 26 | 27 | @Column(name = "audit_modification_date", nullable = false) 28 | private DateTime modificationDate; 29 | 30 | @Column(name = "audit_modifier", nullable = false) 31 | private String modifier; 32 | 33 | protected Audit() { 34 | } 35 | 36 | public Audit(DateTime creationDate, String creator, DateTime modificationDate, String modifier) { 37 | this.creationDate = checkNotNull(creationDate); 38 | this.creator = checkNotNull(creator); 39 | this.modificationDate = checkNotNull(modificationDate); 40 | this.modifier = checkNotNull(modifier); 41 | } 42 | 43 | public Audit update(DateTime modificationDate, String modifier) { 44 | DateTime creationDate = (this.creationDate == null) ? modificationDate : this.creationDate; 45 | String creator = (this.creator == null) ? modifier : this.modifier; 46 | 47 | return new Audit(creationDate, creator, modificationDate, modifier); 48 | } 49 | 50 | public DateTime getCreationDate() { 51 | checkState(!isNull()); 52 | return creationDate; 53 | } 54 | 55 | public String getCreator() { 56 | checkState(!isNull()); 57 | return creator; 58 | } 59 | 60 | public DateTime getModificationDate() { 61 | checkState(!isNull()); 62 | return modificationDate; 63 | } 64 | 65 | public String getModifier() { 66 | checkState(!isNull()); 67 | return modifier; 68 | } 69 | 70 | private boolean isNull() { 71 | return equals(NULL); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/audit/Auditable.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.audit; 2 | 3 | import org.joda.time.DateTime; 4 | 5 | public interface Auditable { 6 | 7 | Audit getAudit(); 8 | 9 | void updateAudit(DateTime now, String modifier); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/bootstrap/BootstrapEvent.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.bootstrap; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.event.ApplicationContextEvent; 5 | 6 | public class BootstrapEvent extends ApplicationContextEvent { 7 | 8 | private static final long serialVersionUID = 1L; 9 | 10 | public BootstrapEvent(ApplicationContext source) { 11 | super(source); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/bootstrap/BootstrapOrder.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.bootstrap; 2 | 3 | import org.springframework.core.Ordered; 4 | 5 | public interface BootstrapOrder { 6 | 7 | int IAM_ROLES = Ordered.HIGHEST_PRECEDENCE; 8 | 9 | int TODO = Ordered.HIGHEST_PRECEDENCE + 1; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/date/DateTimeProvider.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.date; 2 | 3 | import org.joda.time.DateTime; 4 | 5 | public interface DateTimeProvider { 6 | DateTime now(); 7 | } 8 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/AbstractAggregateEntity.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import javax.persistence.MappedSuperclass; 4 | import javax.persistence.Version; 5 | 6 | @MappedSuperclass 7 | public class AbstractAggregateEntity extends AbstractEntity implements AggregateEntity { 8 | 9 | @Version 10 | private Integer entityVersion; 11 | 12 | @Override 13 | public Integer getEntityVersion() { 14 | return this.entityVersion; 15 | } 16 | 17 | protected void publish(Event event) { 18 | EventPublisher.publish(event); 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/AbstractEntity.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import javax.persistence.GeneratedValue; 4 | import javax.persistence.Id; 5 | import javax.persistence.MappedSuperclass; 6 | 7 | @MappedSuperclass 8 | public abstract class AbstractEntity implements Entity { 9 | 10 | @Id 11 | @GeneratedValue 12 | private Long entityId; 13 | 14 | @Override 15 | public Long getEntityId() { 16 | return this.entityId; 17 | } 18 | 19 | @Override 20 | public boolean isManaged() { 21 | // Access entityId property directly to avoid entity loading from database 22 | return this.entityId != null; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/AbstractEvent.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | public class AbstractEvent implements Event { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | private T payload; 10 | 11 | public AbstractEvent(T payload) { 12 | this.payload = checkNotNull(payload); 13 | } 14 | 15 | public T getPayload() { 16 | return payload; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/AbstractValueObject.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import org.apache.commons.lang3.builder.EqualsBuilder; 4 | import org.apache.commons.lang3.builder.HashCodeBuilder; 5 | import org.apache.commons.lang3.builder.ToStringBuilder; 6 | import org.apache.commons.lang3.builder.ToStringStyle; 7 | 8 | public abstract class AbstractValueObject { 9 | 10 | @Override 11 | public boolean equals(Object that) { 12 | return EqualsBuilder.reflectionEquals(this, that); 13 | } 14 | 15 | @Override 16 | public int hashCode() { 17 | return HashCodeBuilder.reflectionHashCode(this); 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/AggregateEntity.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | public interface AggregateEntity extends Entity { 4 | 5 | Integer getEntityVersion(); 6 | 7 | } -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/DomainFactory.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface DomainFactory { 11 | } 12 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/DomainRepository.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | public interface DomainRepository extends JpaRepository { 6 | } 7 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/DomainService.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import org.springframework.stereotype.Component; 4 | import org.springframework.transaction.annotation.Transactional; 5 | 6 | @Component 7 | @Transactional 8 | public @interface DomainService { 9 | } 10 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/Entity.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | public interface Entity { 4 | 5 | Long getEntityId(); 6 | 7 | boolean isManaged(); 8 | 9 | } -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/EntityFunctions.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import com.google.common.base.Function; 4 | 5 | public final class EntityFunctions { 6 | 7 | private EntityFunctions() { 8 | } 9 | 10 | public static Function toEntityId() { 11 | return new Function() { 12 | @Override 13 | public Long apply(Entity input) { 14 | return input.getEntityId(); 15 | } 16 | }; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/Event.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import java.io.Serializable; 4 | 5 | public interface Event extends Serializable { 6 | } 7 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/EventListener.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | public interface EventListener { 4 | void listen(E event); 5 | } 6 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/ddd/EventPublisher.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.ddd; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | import java.util.List; 6 | import java.util.concurrent.CopyOnWriteArrayList; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Component; 10 | 11 | import com.google.common.eventbus.EventBus; 12 | 13 | @Component 14 | public class EventPublisher { 15 | 16 | private static EventBus eventBus; 17 | 18 | private static List> listeners = new CopyOnWriteArrayList>(); 19 | 20 | @edu.umd.cs.findbugs.annotations.SuppressWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") 21 | @Autowired 22 | public void setEventBus(EventBus eventBus) { 23 | EventPublisher.eventBus = eventBus; 24 | } 25 | 26 | public static void addEventListener(EventListener listener) { 27 | listeners.add(checkNotNull(listener)); 28 | } 29 | 30 | public static void removeEventListener(EventListener listener) { 31 | listeners.remove(checkNotNull(listener)); 32 | } 33 | 34 | public static void publish(Event event) { 35 | if (eventBus != null) { 36 | eventBus.post(event); 37 | } 38 | fireEventPublished(event); 39 | } 40 | 41 | @SuppressWarnings({ "rawtypes", "unchecked" }) 42 | private static void fireEventPublished(Event event) { 43 | for (EventListener listener : listeners) { 44 | listener.listen(event); 45 | } 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/json/JsonHolder.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.json; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | import java.io.Serializable; 6 | 7 | public class JsonHolder implements Serializable { 8 | 9 | private static final long serialVersionUID = 1L; 10 | 11 | private T value; 12 | 13 | protected JsonHolder() { 14 | } 15 | 16 | public static JsonHolder of(T value) { 17 | JsonHolder jsonHolder = new JsonHolder(); 18 | jsonHolder.value = checkNotNull(value); 19 | return jsonHolder; 20 | } 21 | 22 | public static JsonHolder absent() { 23 | return new JsonHolder(); 24 | } 25 | 26 | public T getValue() { 27 | return value; 28 | } 29 | 30 | public boolean hasValue() { 31 | return value != null; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/json/JsonSerializationException.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.json; 2 | 3 | public class JsonSerializationException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public JsonSerializationException() { 8 | super(); 9 | } 10 | 11 | public JsonSerializationException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public JsonSerializationException(String message) { 16 | super(message); 17 | } 18 | 19 | public JsonSerializationException(Throwable cause) { 20 | super(cause); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/json/JsonSerializationService.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.json; 2 | 3 | public interface JsonSerializationService { 4 | 5 | String toJson(T object) throws JsonSerializationException; 6 | 7 | T fromJson(String json, String type) throws JsonSerializationException; 8 | 9 | T fromJson(String json, Class type) throws JsonSerializationException; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/security/AuthenticatedUserDetails.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.security; 2 | 3 | public interface AuthenticatedUserDetails { 4 | 5 | String getUsername(); 6 | 7 | String getEmail(); 8 | 9 | String getFirstname(); 10 | 11 | String getLastname(); 12 | 13 | String getFullname(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/shared/security/AuthenticatedUserDetailsProvider.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.security; 2 | 3 | public interface AuthenticatedUserDetailsProvider { 4 | 5 | AuthenticatedUserDetails authenticated(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/todo/application/TodoService.java: -------------------------------------------------------------------------------- 1 | package example.domain.todo.application; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.orm.ObjectRetrievalFailureException; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import example.domain.todo.domain.Todo; 11 | import example.domain.todo.domain.TodoRepository; 12 | 13 | @Component 14 | public class TodoService { 15 | 16 | @Autowired 17 | private TodoRepository todoRepository; 18 | 19 | @Transactional(readOnly = true) 20 | public Todo findOne(Long id) { 21 | Todo todo = todoRepository.findOne(id); 22 | if (todo == null) { 23 | throw new ObjectRetrievalFailureException(Todo.class, id); 24 | } 25 | return todo; 26 | } 27 | 28 | @Transactional(readOnly = true) 29 | public List findAll() { 30 | return todoRepository.findAll(); 31 | } 32 | 33 | @Transactional 34 | public void add(String title) { 35 | Todo todo = new Todo("title"); 36 | todoRepository.saveAndFlush(todo); 37 | } 38 | 39 | @Transactional 40 | public void delete(Long id) { 41 | Todo todo = findOne(id); 42 | todoRepository.delete(todo); 43 | } 44 | 45 | @Transactional 46 | public void updateTitle(Long id, String title) { 47 | Todo todo = findOne(id); 48 | todo.updateTitle(title); 49 | todoRepository.saveAndFlush(todo); 50 | } 51 | 52 | @Transactional 53 | public void done(Long id) { 54 | Todo todo = findOne(id); 55 | todo.done(); 56 | todoRepository.saveAndFlush(todo); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/todo/bootstrap/TodoBootstrapListener.java: -------------------------------------------------------------------------------- 1 | package example.domain.todo.bootstrap; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.ApplicationListener; 5 | import org.springframework.core.Ordered; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.google.common.collect.Lists; 9 | 10 | import example.domain.shared.bootstrap.BootstrapEvent; 11 | import example.domain.shared.bootstrap.BootstrapOrder; 12 | import example.domain.todo.domain.Todo; 13 | import example.domain.todo.domain.TodoRepository; 14 | 15 | @Component 16 | public class TodoBootstrapListener implements ApplicationListener, Ordered { 17 | 18 | @Autowired 19 | private TodoRepository todoRepository; 20 | 21 | @Override 22 | public void onApplicationEvent(BootstrapEvent event) { 23 | if (!todosExist()) { 24 | todoRepository.save(Lists.newArrayList(new Todo("Remember the milk"), new Todo("Clean the carpet"))); 25 | todoRepository.flush(); 26 | } 27 | } 28 | 29 | @Override 30 | public int getOrder() { 31 | return BootstrapOrder.TODO; 32 | } 33 | 34 | public boolean todosExist() { 35 | return todoRepository.count() > 0; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/todo/domain/Todo.java: -------------------------------------------------------------------------------- 1 | package example.domain.todo.domain; 2 | 3 | import static com.google.common.base.Preconditions.*; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.EnumType; 8 | import javax.persistence.Enumerated; 9 | 10 | import example.domain.shared.ddd.AbstractAggregateEntity; 11 | 12 | @Entity 13 | public class Todo extends AbstractAggregateEntity { 14 | 15 | public final static Status DEFAULT_STATUS = Status.ACTIVE; 16 | 17 | @Column 18 | @Enumerated(EnumType.STRING) 19 | private Status status = DEFAULT_STATUS; 20 | 21 | @Column 22 | private String title; 23 | 24 | protected Todo() { 25 | } 26 | 27 | public Todo(String title) { 28 | this.title = checkNotNull(title); 29 | } 30 | 31 | public Status getStatus() { 32 | return status; 33 | } 34 | 35 | public String getTitle() { 36 | return title; 37 | } 38 | 39 | public boolean isActive() { 40 | return status.isActive(); 41 | } 42 | 43 | public boolean isDone() { 44 | return status.isDone(); 45 | } 46 | 47 | public void done() { 48 | status.done(this); 49 | } 50 | 51 | public void updateTitle(String title) { 52 | status.updateTitle(this, title); 53 | } 54 | 55 | private void doUpdateTitle(String title) { 56 | this.title = checkNotNull(title); 57 | } 58 | 59 | private void doDone() { 60 | this.status = Status.DONE; 61 | } 62 | 63 | public enum Status implements TodoState { 64 | 65 | ACTIVE(new ActiveTodoState()), DONE(new DoneTodoState()); 66 | 67 | private TodoState state; 68 | 69 | private Status(TodoState state) { 70 | this.state = checkNotNull(state); 71 | } 72 | 73 | @Override 74 | public boolean isActive() { 75 | return state.isActive(); 76 | } 77 | 78 | @Override 79 | public boolean isDone() { 80 | return state.isDone(); 81 | } 82 | 83 | @Override 84 | public void updateTitle(Todo todo, String title) { 85 | state.updateTitle(todo, title); 86 | } 87 | 88 | @Override 89 | public void done(Todo todo) { 90 | state.done(todo); 91 | } 92 | 93 | } 94 | 95 | public static class TodoStateAdapter implements TodoState { 96 | 97 | @Override 98 | public boolean isActive() { 99 | return false; 100 | } 101 | 102 | @Override 103 | public boolean isDone() { 104 | return false; 105 | } 106 | 107 | @Override 108 | public void updateTitle(Todo todo, String title) { 109 | throw new TodoIllegalStateException(todo, "updateTitle"); 110 | } 111 | 112 | @Override 113 | public void done(Todo todo) { 114 | throw new TodoIllegalStateException(todo, "done"); 115 | } 116 | 117 | } 118 | 119 | public static class ActiveTodoState extends TodoStateAdapter { 120 | 121 | @Override 122 | public boolean isActive() { 123 | return true; 124 | } 125 | 126 | @Override 127 | public void updateTitle(Todo todo, String title) { 128 | todo.doUpdateTitle(title); 129 | } 130 | 131 | @Override 132 | public void done(Todo todo) { 133 | todo.doDone(); 134 | } 135 | 136 | } 137 | 138 | public static class DoneTodoState extends TodoStateAdapter { 139 | 140 | @Override 141 | public boolean isDone() { 142 | return true; 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/todo/domain/TodoIllegalStateException.java: -------------------------------------------------------------------------------- 1 | package example.domain.todo.domain; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | public class TodoIllegalStateException extends RuntimeException { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | private Todo todo; 10 | 11 | private String operation; 12 | 13 | public TodoIllegalStateException(Todo todo, String operation) { 14 | this.todo = checkNotNull(todo); 15 | this.operation = checkNotNull(operation); 16 | } 17 | 18 | @Override 19 | public String getMessage() { 20 | return "Cannot " + operation + ", todo status is: " + todo.getStatus() + "."; 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/todo/domain/TodoRepository.java: -------------------------------------------------------------------------------- 1 | package example.domain.todo.domain; 2 | 3 | import example.domain.shared.ddd.DomainRepository; 4 | 5 | public interface TodoRepository extends DomainRepository { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/domain/todo/domain/TodoState.java: -------------------------------------------------------------------------------- 1 | package example.domain.todo.domain; 2 | 3 | public interface TodoState { 4 | 5 | boolean isActive(); 6 | 7 | boolean isDone(); 8 | 9 | void updateTitle(Todo todo, String title); 10 | 11 | void done(Todo todo); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/common/AjaxHeaderMatcher.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.common; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.context.request.WebRequest; 7 | 8 | @Component 9 | public class AjaxHeaderMatcher { 10 | 11 | private static final String DEFAULT_HEADER_NAME = "X-Requested-With"; 12 | 13 | private static final String DEFAULT_HEADER_VALUE = "XmlHttpRequest"; 14 | 15 | private String headerName = DEFAULT_HEADER_NAME; 16 | 17 | private String headerValue = DEFAULT_HEADER_VALUE; 18 | 19 | public boolean isAjaxRequest(HttpServletRequest request) { 20 | return isAjaxRequest(request.getHeader(headerName)); 21 | } 22 | 23 | public boolean isAjaxRequest(WebRequest request) { 24 | return isAjaxRequest(request.getHeader(headerName)); 25 | } 26 | 27 | public void setHeaderName(String headerName) { 28 | this.headerName = headerName; 29 | } 30 | 31 | public void setHeaderValue(String headerValue) { 32 | this.headerValue = headerValue; 33 | } 34 | 35 | private boolean isAjaxRequest(String value) { 36 | return headerValue.equalsIgnoreCase(value); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/common/ApplicationBootstrap.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.common; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.ApplicationListener; 5 | import org.springframework.context.event.ContextRefreshedEvent; 6 | import org.springframework.stereotype.Component; 7 | 8 | import example.domain.shared.bootstrap.BootstrapEvent; 9 | 10 | @Component 11 | public class ApplicationBootstrap implements ApplicationListener { 12 | 13 | @Override 14 | public void onApplicationEvent(ContextRefreshedEvent event) { 15 | ApplicationContext applicationContext = event.getApplicationContext(); 16 | 17 | if (isRootApplicationContext(applicationContext)) { 18 | event.getApplicationContext().publishEvent(new BootstrapEvent(applicationContext)); 19 | } 20 | 21 | } 22 | 23 | private boolean isRootApplicationContext(ApplicationContext applicationContext) { 24 | return applicationContext.getParent() == null; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/date/DefaultDateTimeProvider.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.date; 2 | 3 | import org.joda.time.DateTime; 4 | import org.springframework.stereotype.Component; 5 | 6 | import example.domain.shared.date.DateTimeProvider; 7 | 8 | @Component 9 | public class DefaultDateTimeProvider implements DateTimeProvider { 10 | 11 | @Override 12 | public DateTime now() { 13 | return new DateTime(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/events/EventBusBeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.events; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.config.BeanPostProcessor; 6 | import org.springframework.context.ApplicationContext; 7 | import org.springframework.stereotype.Component; 8 | 9 | import com.google.common.eventbus.EventBus; 10 | 11 | @Component 12 | public class EventBusBeanPostProcessor implements BeanPostProcessor { 13 | 14 | @Autowired 15 | private ApplicationContext applicationContext; 16 | 17 | @Autowired 18 | private EventBus eventBus; 19 | 20 | @Override 21 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 22 | if (applicationContext.containsBean(beanName) && applicationContext.isSingleton(beanName)) { 23 | eventBus.register(bean); 24 | } 25 | return bean; 26 | } 27 | 28 | @Override 29 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 30 | // do nothing 31 | return bean; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jackson/Jackson2Configuration.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jackson; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | import com.fasterxml.jackson.datatype.joda.JodaModule; 8 | 9 | @Configuration 10 | public class Jackson2Configuration { 11 | 12 | @Bean 13 | public ObjectMapper objectMapper() { 14 | ObjectMapper objectMapper = new ObjectMapper(); 15 | 16 | objectMapper.registerModule(new JodaModule()); 17 | objectMapper.registerModule(new MoneyModule()); 18 | 19 | return objectMapper; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jackson/Jackson2JsonSerializationService.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jackson; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | import com.fasterxml.jackson.databind.ObjectReader; 10 | import com.fasterxml.jackson.databind.ObjectWriter; 11 | 12 | import example.domain.shared.json.JsonSerializationException; 13 | import example.domain.shared.json.JsonSerializationService; 14 | 15 | @Component 16 | public class Jackson2JsonSerializationService implements JsonSerializationService { 17 | 18 | private ObjectMapper objectMapper; 19 | 20 | @Autowired 21 | public Jackson2JsonSerializationService(ObjectMapper objectMapper) { 22 | this.objectMapper = checkNotNull(objectMapper); 23 | } 24 | 25 | @Override 26 | public String toJson(T object) { 27 | try { 28 | ObjectWriter objectWriter = objectMapper.writer(); 29 | return objectWriter.writeValueAsString(object); 30 | } catch (Exception e) { 31 | throw new JsonSerializationException(e.getMessage(), e); 32 | } 33 | } 34 | 35 | @Override 36 | public T fromJson(String json, Class type) { 37 | try { 38 | ObjectReader objectReader = objectMapper.reader(type); 39 | return objectReader. readValue(json); 40 | } catch (Exception e) { 41 | throw new JsonSerializationException(e.getMessage(), e); 42 | } 43 | } 44 | 45 | @SuppressWarnings("unchecked") 46 | @Override 47 | public T fromJson(String json, String type) { 48 | try { 49 | Class typeClass = (Class) Class.forName(type); 50 | return fromJson(json, typeClass); 51 | } catch (ClassNotFoundException e) { 52 | throw new JsonSerializationException(e.getMessage(), e); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jackson/MoneyDeserializer.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jackson; 2 | 3 | import java.io.IOException; 4 | 5 | import org.joda.money.Money; 6 | 7 | import com.fasterxml.jackson.core.JsonParser; 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.core.JsonToken; 10 | import com.fasterxml.jackson.databind.DeserializationContext; 11 | import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer; 12 | 13 | public class MoneyDeserializer extends StdScalarDeserializer { 14 | 15 | protected MoneyDeserializer() { 16 | super(Money.class); 17 | } 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @Override 22 | public Money deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 23 | JsonToken t = jp.getCurrentToken(); 24 | 25 | if (t == JsonToken.VALUE_STRING) { 26 | String str = jp.getText().trim(); 27 | if (str.isEmpty()) { 28 | return null; 29 | } else { 30 | return Money.parse(str); 31 | } 32 | } 33 | throw ctxt.mappingException(getValueClass()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jackson/MoneyModule.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jackson; 2 | 3 | import org.joda.money.Money; 4 | 5 | import com.fasterxml.jackson.core.Version; 6 | import com.fasterxml.jackson.databind.module.SimpleModule; 7 | 8 | public class MoneyModule extends SimpleModule { 9 | 10 | private static final long serialVersionUID = 1L; 11 | 12 | public MoneyModule() { 13 | super(Version.unknownVersion()); 14 | 15 | addDeserializer(Money.class, new MoneyDeserializer()); 16 | addSerializer(Money.class, new MoneySerializer()); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jackson/MoneySerializer.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jackson; 2 | 3 | import java.io.IOException; 4 | 5 | import org.joda.money.Money; 6 | 7 | import com.fasterxml.jackson.core.JsonGenerationException; 8 | import com.fasterxml.jackson.core.JsonGenerator; 9 | import com.fasterxml.jackson.databind.SerializerProvider; 10 | import com.fasterxml.jackson.databind.ser.std.StdSerializer; 11 | 12 | public class MoneySerializer extends StdSerializer { 13 | 14 | protected MoneySerializer() { 15 | super(Money.class); 16 | } 17 | 18 | @Override 19 | public void serialize(Money value, JsonGenerator jgen, SerializerProvider provider) throws IOException, 20 | JsonGenerationException { 21 | jgen.writeString(value.toString()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jms/ObjectMessageCreator.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jms; 2 | 3 | import static com.google.common.base.Preconditions.*; 4 | 5 | import java.io.Serializable; 6 | 7 | import javax.jms.JMSException; 8 | import javax.jms.Message; 9 | import javax.jms.Session; 10 | 11 | import org.springframework.jms.core.MessageCreator; 12 | 13 | public class ObjectMessageCreator implements MessageCreator { 14 | 15 | private Serializable object; 16 | 17 | public ObjectMessageCreator(Serializable object) { 18 | this.object = checkNotNull(object); 19 | } 20 | 21 | @Override 22 | public Message createMessage(Session session) throws JMSException { 23 | return session.createObjectMessage(object); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jpa/AbstractCustomType.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.hibernate.HibernateException; 6 | import org.hibernate.engine.spi.SessionImplementor; 7 | 8 | import com.google.common.base.Objects; 9 | 10 | public abstract class AbstractCustomType { 11 | 12 | public void setPropertyValue(Object component, int propertyIndex, Object value) throws HibernateException { 13 | throw new HibernateException("Called setPropertyValue on an immutable type {" + component.getClass() + "}"); 14 | } 15 | 16 | @SuppressWarnings("PMD.SuspiciousEqualsMethodName") 17 | public boolean equals(Object x, Object y) throws HibernateException { 18 | return Objects.equal(x, y); 19 | } 20 | 21 | public int hashCode(Object x) throws HibernateException { 22 | return Objects.hashCode(x); 23 | } 24 | 25 | public Object deepCopy(Object value) throws HibernateException { 26 | return value; 27 | } 28 | 29 | public boolean isMutable() { 30 | return false; 31 | } 32 | 33 | public Serializable disassemble(Object value) throws HibernateException { 34 | return (Serializable) value; 35 | } 36 | 37 | public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException { 38 | return (Serializable) value; 39 | } 40 | 41 | public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException { 42 | return cached; 43 | } 44 | 45 | public Object assemble(Serializable cached, Object value) throws HibernateException { 46 | return cached; 47 | } 48 | 49 | public Object replace(Object original, Object target, SessionImplementor session, Object owner) 50 | throws HibernateException { 51 | return original; 52 | } 53 | 54 | public Object replace(Object original, Object target, Object owner) throws HibernateException { 55 | return original; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jpa/AuditListener.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import javax.persistence.PrePersist; 4 | import javax.persistence.PreUpdate; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Component; 8 | 9 | import example.domain.shared.audit.Auditable; 10 | import example.domain.shared.date.DateTimeProvider; 11 | import example.domain.shared.security.AuthenticatedUserDetails; 12 | import example.domain.shared.security.AuthenticatedUserDetailsProvider; 13 | 14 | @Component 15 | public class AuditListener { 16 | 17 | private static DateTimeProvider dateTimeProvider; 18 | 19 | private static AuthenticatedUserDetailsProvider authenticatedUserDetailsProvider; 20 | 21 | @edu.umd.cs.findbugs.annotations.SuppressWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") 22 | @Autowired 23 | public void setDateTimeProvider(DateTimeProvider dateTimeProvider) { 24 | AuditListener.dateTimeProvider = dateTimeProvider; 25 | } 26 | 27 | @edu.umd.cs.findbugs.annotations.SuppressWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") 28 | @Autowired 29 | public void setUserProvider(AuthenticatedUserDetailsProvider authenticatedUserDetailsProvider) { 30 | AuditListener.authenticatedUserDetailsProvider = authenticatedUserDetailsProvider; 31 | } 32 | 33 | @PrePersist 34 | @PreUpdate 35 | public void updateAudit(Object o) { 36 | if (o instanceof Auditable) { 37 | Auditable auditable = (Auditable) o; 38 | 39 | AuthenticatedUserDetails userDetails = authenticatedUserDetailsProvider.authenticated(); 40 | String modifier = (userDetails != null) ? userDetails.getEmail() : "N/A"; 41 | 42 | auditable.updateAudit(dateTimeProvider.now(), modifier); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jpa/CustomTypes.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import javax.persistence.MappedSuperclass; 4 | 5 | import org.hibernate.annotations.TypeDef; 6 | import org.hibernate.annotations.TypeDefs; 7 | import org.joda.money.Money; 8 | import org.joda.time.DateTime; 9 | 10 | import example.domain.shared.json.JsonHolder; 11 | 12 | @MappedSuperclass 13 | @TypeDefs({ @TypeDef(defaultForType = Money.class, typeClass = MoneyType.class), 14 | @TypeDef(defaultForType = DateTime.class, typeClass = DateTimeType.class), 15 | @TypeDef(defaultForType = JsonHolder.class, typeClass = JsonHolderType.class) }) 16 | public class CustomTypes { 17 | } 18 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jpa/DateTimeType.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.sql.Types; 7 | 8 | import org.hibernate.HibernateException; 9 | import org.hibernate.engine.spi.SessionImplementor; 10 | import org.hibernate.type.StandardBasicTypes; 11 | import org.hibernate.usertype.UserType; 12 | import org.joda.time.DateTime; 13 | 14 | public class DateTimeType extends AbstractCustomType implements UserType { 15 | 16 | public int[] sqlTypes() { 17 | return new int[] { Types.TIMESTAMP }; 18 | } 19 | 20 | @Override 21 | public Class returnedClass() { 22 | return DateTime.class; 23 | } 24 | 25 | @Override 26 | public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner) 27 | throws HibernateException, SQLException { 28 | Object timestamp = StandardBasicTypes.TIMESTAMP.nullSafeGet(resultSet, names, session, owner); 29 | if (timestamp == null) { 30 | return null; 31 | } 32 | 33 | return new DateTime(timestamp); 34 | } 35 | 36 | @Override 37 | public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SessionImplementor session) 38 | throws HibernateException, SQLException { 39 | if (value == null) { 40 | StandardBasicTypes.TIMESTAMP.nullSafeSet(preparedStatement, null, index, session); 41 | } else { 42 | StandardBasicTypes.TIMESTAMP.nullSafeSet(preparedStatement, ((DateTime) value).toDate(), index, session); 43 | } 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jpa/FixedPrefixNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import org.hibernate.cfg.ImprovedNamingStrategy; 4 | 5 | public class FixedPrefixNamingStrategy extends ImprovedNamingStrategy { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | private static final String TABLE_PREFIX = "t_"; 10 | 11 | private static final String COLUMN_PREFIX = "c_"; 12 | 13 | @Override 14 | public String classToTableName(String className) { 15 | return TABLE_PREFIX + super.classToTableName(className); 16 | } 17 | 18 | @Override 19 | public String collectionTableName(String ownerEntity, String ownerEntityTable, String associatedEntity, 20 | String associatedEntityTable, String propertyName) { 21 | return TABLE_PREFIX 22 | + super.collectionTableName(ownerEntity, ownerEntityTable, associatedEntity, associatedEntityTable, 23 | propertyName); 24 | } 25 | 26 | @Override 27 | public String propertyToColumnName(String propertyName) { 28 | return COLUMN_PREFIX + super.propertyToColumnName(propertyName); 29 | } 30 | 31 | @Override 32 | public String joinKeyColumnName(String joinedColumn, String joinedTable) { 33 | return COLUMN_PREFIX + super.joinKeyColumnName(joinedColumn, joinedTable); 34 | } 35 | 36 | @Override 37 | public String columnName(String columnName) { 38 | return COLUMN_PREFIX + super.columnName(columnName); 39 | } 40 | } -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jpa/JsonHolderType.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | 7 | import org.hibernate.HibernateException; 8 | import org.hibernate.engine.spi.SessionImplementor; 9 | import org.hibernate.type.StringType; 10 | import org.hibernate.type.TextType; 11 | import org.hibernate.type.Type; 12 | import org.hibernate.usertype.CompositeUserType; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Component; 15 | 16 | import example.domain.shared.json.JsonHolder; 17 | import example.domain.shared.json.JsonSerializationService; 18 | 19 | @Component 20 | public class JsonHolderType extends AbstractCustomType implements CompositeUserType { 21 | 22 | private static JsonSerializationService jsonSerializationService; 23 | 24 | @edu.umd.cs.findbugs.annotations.SuppressWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") 25 | @Autowired 26 | void setJsonSerializationService(JsonSerializationService jsonSerializationService) { 27 | JsonHolderType.jsonSerializationService = jsonSerializationService; 28 | } 29 | 30 | @Override 31 | public String[] getPropertyNames() { 32 | return new String[] { "type", "data" }; 33 | } 34 | 35 | @Override 36 | public Type[] getPropertyTypes() { 37 | return new Type[] { StringType.INSTANCE, TextType.INSTANCE }; 38 | } 39 | 40 | @SuppressWarnings("rawtypes") 41 | @Override 42 | public Class returnedClass() { 43 | return JsonHolder.class; 44 | } 45 | 46 | @SuppressWarnings("rawtypes") 47 | @Override 48 | public Object getPropertyValue(Object component, int propertyIndex) throws HibernateException { 49 | if (component == null) { 50 | return null; 51 | } 52 | 53 | JsonHolder jsonHolder = (JsonHolder) component; 54 | if (!jsonHolder.hasValue()) { 55 | return null; 56 | } 57 | 58 | switch (propertyIndex) { 59 | case 0: 60 | return jsonHolder.getValue().getClass().getName(); 61 | case 1: 62 | return jsonSerializationService.toJson(jsonHolder.getValue()); 63 | default: 64 | throw new HibernateException("Invalid property index [" + propertyIndex + "]"); 65 | } 66 | } 67 | 68 | @Override 69 | public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) 70 | throws HibernateException, SQLException { 71 | 72 | String type = StringType.INSTANCE.nullSafeGet(rs, names[0], session); 73 | String data = TextType.INSTANCE.nullSafeGet(rs, names[1], session); 74 | 75 | if (type == null && data == null) { 76 | return null; 77 | } else { 78 | Object json = jsonSerializationService.fromJson(data, type); 79 | return JsonHolder.of(json); 80 | } 81 | } 82 | 83 | @SuppressWarnings("rawtypes") 84 | @Override 85 | public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) 86 | throws HibernateException, SQLException { 87 | JsonHolder jsonHolder = (JsonHolder) value; 88 | 89 | if (jsonHolder != null && jsonHolder.getValue() != null) { 90 | StringType.INSTANCE.set(st, jsonHolder.getValue().getClass().getName(), index, session); 91 | TextType.INSTANCE.set(st, jsonSerializationService.toJson(jsonHolder.getValue()), index + 1, session); 92 | } else { 93 | StringType.INSTANCE.set(st, null, index, session); 94 | TextType.INSTANCE.set(st, null, index + 1, session); 95 | } 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/jpa/MoneyType.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import java.math.BigDecimal; 4 | import java.sql.PreparedStatement; 5 | import java.sql.ResultSet; 6 | import java.sql.SQLException; 7 | 8 | import org.hibernate.HibernateException; 9 | import org.hibernate.engine.spi.SessionImplementor; 10 | import org.hibernate.type.BigDecimalType; 11 | import org.hibernate.type.StringType; 12 | import org.hibernate.type.Type; 13 | import org.hibernate.usertype.CompositeUserType; 14 | import org.joda.money.CurrencyUnit; 15 | import org.joda.money.Money; 16 | 17 | public class MoneyType extends AbstractCustomType implements CompositeUserType { 18 | 19 | @Override 20 | public String[] getPropertyNames() { 21 | return new String[] { "amount", "currency" }; 22 | } 23 | 24 | @Override 25 | public Type[] getPropertyTypes() { 26 | return new Type[] { BigDecimalType.INSTANCE, StringType.INSTANCE }; 27 | } 28 | 29 | @Override 30 | public Class returnedClass() { 31 | return Money.class; 32 | } 33 | 34 | @Override 35 | public Object getPropertyValue(Object component, int propertyIndex) throws HibernateException { 36 | if (component == null) { 37 | return null; 38 | } 39 | final Money money = (Money) component; 40 | 41 | switch (propertyIndex) { 42 | case 0: 43 | return money.getAmount(); 44 | case 1: 45 | return money.getCurrencyUnit().getCurrencyCode(); 46 | default: 47 | throw new HibernateException("Invalid property index [" + propertyIndex + "]"); 48 | } 49 | } 50 | 51 | @Override 52 | public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) 53 | throws HibernateException, SQLException { 54 | 55 | BigDecimal amount = BigDecimalType.INSTANCE.nullSafeGet(rs, names[0], session); 56 | String currencyCode = StringType.INSTANCE.nullSafeGet(rs, names[1], session); 57 | 58 | return amount == null && currencyCode == null ? null : Money.of(CurrencyUnit.getInstance(currencyCode), amount); 59 | } 60 | 61 | @Override 62 | public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) 63 | throws HibernateException, SQLException { 64 | if (value == null) { 65 | BigDecimalType.INSTANCE.set(st, null, index, session); 66 | StringType.INSTANCE.set(st, null, index + 1, session); 67 | } else { 68 | Money money = (Money) value; 69 | BigDecimalType.INSTANCE.set(st, money.getAmount(), index, session); 70 | StringType.INSTANCE.set(st, money.getCurrencyUnit().getCurrencyCode(), index + 1, session); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/security/NonAjaxRequestMatcher.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.security; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.web.util.RequestMatcher; 7 | import org.springframework.stereotype.Component; 8 | 9 | import example.infrastructure.common.AjaxHeaderMatcher; 10 | 11 | @Component 12 | public class NonAjaxRequestMatcher implements RequestMatcher { 13 | 14 | private AjaxHeaderMatcher ajaxHeaderMatcher; 15 | 16 | @Autowired 17 | public NonAjaxRequestMatcher(AjaxHeaderMatcher ajaxHeaderMatcher) { 18 | this.ajaxHeaderMatcher = ajaxHeaderMatcher; 19 | } 20 | 21 | @Override 22 | public boolean matches(HttpServletRequest request) { 23 | return !ajaxHeaderMatcher.isAjaxRequest(request); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/security/OpenIdUserDetails.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.security; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collection; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | import org.springframework.security.core.GrantedAuthority; 11 | import org.springframework.security.core.userdetails.UserDetails; 12 | import org.springframework.security.openid.OpenIDAttribute; 13 | import org.springframework.security.openid.OpenIDAuthenticationToken; 14 | 15 | import example.domain.shared.security.AuthenticatedUserDetails; 16 | 17 | public class OpenIdUserDetails implements UserDetails, AuthenticatedUserDetails { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | private static final String UNUSED_PASSWORD = "N/A"; 22 | 23 | private static final boolean ACCOUNT_NON_EXPIRED = true; 24 | private static final boolean CREDENTIALS_NON_EXPIRED = true; 25 | private static final boolean ACCOUNT_NOT_LOCKED = true; 26 | 27 | private String username; 28 | 29 | private String email; 30 | 31 | private String firstname; 32 | 33 | private String lastname; 34 | 35 | private String fullname; 36 | 37 | private Boolean enabled; 38 | 39 | private List grantedAuthorities = new ArrayList<>(); 40 | 41 | protected OpenIdUserDetails(Builder builder) { 42 | this.username = checkNotNull(builder.username); 43 | this.email = checkNotNull(builder.email); 44 | this.firstname = checkNotNull(builder.firstname); 45 | this.lastname = checkNotNull(builder.lastname); 46 | 47 | if (builder.fullname != null) { 48 | this.fullname = builder.fullname; 49 | } else { 50 | this.fullname = String.format("%s %s", this.firstname, this.lastname); 51 | } 52 | 53 | if (builder.enabled != null) { 54 | this.enabled = builder.enabled; 55 | } else { 56 | this.enabled = Boolean.TRUE; 57 | } 58 | 59 | this.grantedAuthorities.addAll(builder.grantedAuthorities); 60 | } 61 | 62 | @Override 63 | public Collection getAuthorities() { 64 | return Collections.unmodifiableCollection(grantedAuthorities); 65 | } 66 | 67 | @Override 68 | public String getPassword() { 69 | return UNUSED_PASSWORD; 70 | } 71 | 72 | @Override 73 | public String getUsername() { 74 | return username; 75 | } 76 | 77 | @Override 78 | public boolean isAccountNonExpired() { 79 | return ACCOUNT_NON_EXPIRED; 80 | } 81 | 82 | @Override 83 | public boolean isAccountNonLocked() { 84 | return ACCOUNT_NOT_LOCKED; 85 | } 86 | 87 | @Override 88 | public boolean isCredentialsNonExpired() { 89 | return CREDENTIALS_NON_EXPIRED; 90 | } 91 | 92 | @Override 93 | public boolean isEnabled() { 94 | return enabled; 95 | } 96 | 97 | @Override 98 | public String getEmail() { 99 | return email; 100 | } 101 | 102 | @Override 103 | public String getFirstname() { 104 | return firstname; 105 | } 106 | 107 | @Override 108 | public String getLastname() { 109 | return lastname; 110 | } 111 | 112 | @Override 113 | public String getFullname() { 114 | return fullname; 115 | } 116 | 117 | public static class Builder { 118 | 119 | private String username; 120 | 121 | private String email; 122 | 123 | private String firstname; 124 | 125 | private String lastname; 126 | 127 | private String fullname; 128 | 129 | private Boolean enabled = true; 130 | 131 | private List grantedAuthorities = new ArrayList<>(); 132 | 133 | public Builder withAuthenticationToken(OpenIDAuthenticationToken token) { 134 | this.username = token.getIdentityUrl(); 135 | 136 | for (OpenIDAttribute attribute : token.getAttributes()) { 137 | if (attribute.getName().equals("email")) { 138 | this.email = attribute.getValues().get(0); 139 | } 140 | 141 | if (attribute.getName().equals("firstname")) { 142 | this.firstname = attribute.getValues().get(0); 143 | } 144 | 145 | if (attribute.getName().equals("lastname")) { 146 | this.lastname = attribute.getValues().get(0); 147 | } 148 | 149 | if (attribute.getName().equals("fullname")) { 150 | this.fullname = attribute.getValues().get(0); 151 | } 152 | } 153 | 154 | return this; 155 | } 156 | 157 | public Builder withEnabled(Boolean enabled) { 158 | this.enabled = enabled; 159 | return this; 160 | } 161 | 162 | public Builder addGrantedAuthority(GrantedAuthority grantedAuthority) { 163 | this.grantedAuthorities.add(grantedAuthority); 164 | return this; 165 | } 166 | 167 | public OpenIdUserDetails build() { 168 | return new OpenIdUserDetails(this); 169 | } 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/security/OpenIdUserDetailsProvider.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.security; 2 | 3 | import org.springframework.security.core.Authentication; 4 | import org.springframework.security.core.context.SecurityContextHolder; 5 | import org.springframework.stereotype.Component; 6 | 7 | import example.domain.shared.security.AuthenticatedUserDetails; 8 | import example.domain.shared.security.AuthenticatedUserDetailsProvider; 9 | 10 | @Component 11 | public class OpenIdUserDetailsProvider implements AuthenticatedUserDetailsProvider { 12 | 13 | @Override 14 | public AuthenticatedUserDetails authenticated() { 15 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 16 | if (authentication == null) { 17 | return null; 18 | } 19 | 20 | return (AuthenticatedUserDetails) authentication.getDetails(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/infrastructure/security/OpenIdUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.security; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 5 | import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; 6 | import org.springframework.security.core.userdetails.UserDetails; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | import org.springframework.security.openid.OpenIDAuthenticationToken; 9 | import org.springframework.stereotype.Component; 10 | 11 | import example.domain.iam.model.RoleIdentifier; 12 | import example.domain.iam.model.User; 13 | import example.domain.iam.model.UserIdentifier; 14 | import example.domain.iam.model.UserRepository; 15 | import example.infrastructure.security.OpenIdUserDetails.Builder; 16 | 17 | @Component 18 | public class OpenIdUserDetailsService implements AuthenticationUserDetailsService { 19 | 20 | @Autowired 21 | private UserRepository userRepository; 22 | 23 | @Override 24 | public UserDetails loadUserDetails(OpenIDAuthenticationToken token) throws UsernameNotFoundException { 25 | String identity = token.getIdentityUrl(); 26 | UserIdentifier identifier = new UserIdentifier(identity); 27 | 28 | User user = userRepository.findByIdentifier(identifier); 29 | if (user != null) { 30 | // TODO: update account 31 | } else { 32 | // TODO: add user 33 | } 34 | 35 | Builder builder = new Builder().withAuthenticationToken(token); 36 | if (user != null) { 37 | for (RoleIdentifier role : user.getRoles()) { 38 | builder.addGrantedAuthority(new SimpleGrantedAuthority(role.getIdentifier())); 39 | } 40 | } 41 | 42 | return builder.build(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/web/ExceptionHandlerAdvice.java: -------------------------------------------------------------------------------- 1 | package example.web; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.HttpHeaders; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.ControllerAdvice; 8 | import org.springframework.web.bind.annotation.ExceptionHandler; 9 | import org.springframework.web.context.request.WebRequest; 10 | import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; 11 | 12 | import example.infrastructure.common.AjaxHeaderMatcher; 13 | 14 | @ControllerAdvice 15 | public class ExceptionHandlerAdvice extends ResponseEntityExceptionHandler { 16 | 17 | private AjaxHeaderMatcher ajaxHeaderMatcher; 18 | 19 | @Autowired 20 | public ExceptionHandlerAdvice(AjaxHeaderMatcher ajaxHeaderMatcher) { 21 | this.ajaxHeaderMatcher = ajaxHeaderMatcher; 22 | } 23 | 24 | @ExceptionHandler(value = { RuntimeException.class }) 25 | public ResponseEntity handleRuntimeException(RuntimeException ex, WebRequest request) { 26 | HttpHeaders headers = new HttpHeaders(); 27 | HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; 28 | 29 | return handleExceptionInternal(ex, null, headers, status, request); 30 | } 31 | 32 | @Override 33 | protected ResponseEntity handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, 34 | HttpStatus status, WebRequest request) { 35 | if (ajaxHeaderMatcher.isAjaxRequest(request)) { 36 | return new ResponseEntity(ex.getMessage(), headers, status); 37 | } else { 38 | return super.handleExceptionInternal(ex, null, headers, status, request); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/web/RequestMappings.java: -------------------------------------------------------------------------------- 1 | package example.web; 2 | 3 | public interface RequestMappings { 4 | 5 | String TODOS = "/api/todos"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/web/TodoController.java: -------------------------------------------------------------------------------- 1 | package example.web; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | import org.springframework.web.bind.annotation.ResponseStatus; 13 | 14 | import example.domain.todo.application.TodoService; 15 | import example.domain.todo.domain.Todo; 16 | 17 | @Controller 18 | @RequestMapping(value = RequestMappings.TODOS) 19 | public class TodoController { 20 | 21 | @Autowired 22 | private TodoService todoService; 23 | 24 | @RequestMapping(method = RequestMethod.GET) 25 | @ResponseStatus(HttpStatus.OK) 26 | public @ResponseBody 27 | List list() { 28 | return todoService.findAll(); 29 | } 30 | 31 | @RequestMapping(method = RequestMethod.POST) 32 | @ResponseStatus(HttpStatus.CREATED) 33 | public void add(String title) { 34 | todoService.add(title); 35 | } 36 | 37 | @RequestMapping(value = "/{id}", method = RequestMethod.GET) 38 | @ResponseStatus(HttpStatus.OK) 39 | public @ResponseBody 40 | Todo get(@PathVariable("id") Long id) { 41 | return todoService.findOne(id); 42 | } 43 | 44 | @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) 45 | @ResponseStatus(HttpStatus.NO_CONTENT) 46 | public void delete(@PathVariable("id") Long id) { 47 | todoService.delete(id); 48 | } 49 | 50 | @RequestMapping(value = "/{id}/title", method = RequestMethod.PUT) 51 | @ResponseStatus(HttpStatus.NO_CONTENT) 52 | public void updateTitle(@PathVariable("id") Long id, String title) { 53 | todoService.updateTitle(id, title); 54 | } 55 | 56 | @RequestMapping(value = "/{id}/done", method = RequestMethod.PUT) 57 | @ResponseStatus(HttpStatus.NO_CONTENT) 58 | public void done(@PathVariable("id") Long id) { 59 | todoService.done(id); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /example-spring-core/src/main/java/example/web/WebConfiguration.java: -------------------------------------------------------------------------------- 1 | package example.web; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.context.annotation.Scope; 7 | 8 | import example.domain.shared.security.AuthenticatedUserDetailsProvider; 9 | 10 | @Configuration 11 | public class WebConfiguration { 12 | 13 | @Autowired 14 | private AuthenticatedUserDetailsProvider userProvider; 15 | 16 | @Bean 17 | @Scope("session") 18 | public String loggedUserDisplayName() { 19 | return userProvider.authenticated().getFullname(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-domain-iam.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-domain-shared.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-domain-todo.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-domain.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-cache.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-common.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-date.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-events.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-jackson.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-jms.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 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 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-jmx.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 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 | true 46 | true 47 | true 48 | true 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-jpa.xml: -------------------------------------------------------------------------------- 1 | 2 | 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 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure-security.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 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 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-infrastructure.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/META-INF/spring/applicationContext-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/application-local.properties: -------------------------------------------------------------------------------- 1 | jpa.driver=com.mysql.jdbc.Driver 2 | jpa.url=jdbc:mysql://localhost/example-spring 3 | jpa.username=example 4 | jpa.password=example 5 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/application-remote.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkuthan/example-spring/02dddda08af40f2a33b2a976c6178e830567cdde/example-spring-core/src/main/resources/application-remote.properties -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | jpa.database=MYSQL 2 | jpa.showSql=false 3 | jpa.generateDdl=true 4 | 5 | jms.initialRedeliveryDelay=1000 6 | jms.backOffMultiplier=2.0 7 | jms.maximumRedeliveries=10 8 | 9 | mvc.resourcesCachePeriod=0 10 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/ehcache.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 17 | 18 | 25 | 26 | 33 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/logback-local.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/logback-remote.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Example 4 | 5 | 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/messages.properties: -------------------------------------------------------------------------------- 1 | application_name=Example 2 | application_version=${project.version} 3 | application_buildDdate=${example.buildDate} 4 | 5 | application_copyright=© Marcin Kuthan 2013 6 | 7 | #exception 8 | exception_details=Details 9 | exception_date=Date: 10 | exception_type=Type: 11 | exception_request_uri=Request URI: 12 | exception_status_code=Status code: 13 | exception_user_agent=User agent: 14 | exception_stacktrace=Stack Trace: 15 | 16 | #dataAccessFailure_jsp 17 | error_dataaccessfailure_title=Data access failure 18 | error_dataaccessfailure_description=Sorry, a problem occurred while accessing the database. 19 | 20 | #resourceNotFound_jsp 21 | error_resourcenotfound_title=Resource Not Found 22 | error_resourcenotfound_description=Sorry, we did not find the resource you were looking for. 23 | 24 | #uncaughtException_jsp 25 | error_uncaughtexception_title=Internal Error 26 | error_uncaughtexception_description=Sorry, we encountered an internal error. 27 | 28 | #security 29 | security_login_title=Login 30 | security_login_form_legend=Login 31 | security_login_form_username_label=Username: 32 | security_login_form_username_message=Enter your username 33 | security_login_form_password_label=Password: 34 | security_login_form_password_message=Enter your password 35 | security_login_form_button=Login 36 | security_login_unsuccessful=Your login attempt was not successful, try again. 37 | security_logout=Logout 38 | security_logged_out_title=Logged Out 39 | security_logged_out_message=You have been successfully logged out. 40 | security_logged_out_again=Log in again 41 | -------------------------------------------------------------------------------- /example-spring-core/src/main/resources/orm.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example-spring-core/src/main/webapp/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Example Spring Application 4 | 5 | 6 | 7 |

8 | The application you are looking for is hosted on http://localhost:9000/404.html.
9 | You will be redirected to the new location automatically in 5 seconds. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /example-spring-core/src/main/webapp/WEB-INF/views/test.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 | 3 | 4 | Test 5 | 6 | 7 |

Test

8 | 9 | -------------------------------------------------------------------------------- /example-spring-core/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | defaultHtmlEscape 7 | true 8 | 9 | 10 | contextConfigLocation 11 | 12 | classpath:/META-INF/spring/applicationContext-properties.xml, 13 | classpath:/META-INF/spring/applicationContext-infrastructure.xml, 14 | classpath:/META-INF/spring/applicationContext-domain.xml 15 | 16 | 17 | 18 | org.springframework.web.context.ContextLoaderListener 19 | 20 | 21 | org.springframework.web.context.request.RequestContextListener 22 | 23 | 24 | CharacterEncodingFilter 25 | org.springframework.web.filter.CharacterEncodingFilter 26 | 27 | encoding 28 | UTF-8 29 | 30 | 31 | forceEncoding 32 | true 33 | 34 | 35 | 36 | CharacterEncodingFilter 37 | /* 38 | 39 | 40 | springSecurityFilterChain 41 | org.springframework.web.filter.DelegatingFilterProxy 42 | 43 | 44 | springSecurityFilterChain 45 | /* 46 | 47 | 48 | example-spring 49 | org.springframework.web.servlet.DispatcherServlet 50 | 51 | contextConfigLocation 52 | 53 | classpath:/META-INF/spring/applicationContext-web.xml 54 | 55 | 56 | 1 57 | 58 | 59 | example-spring 60 | /* 61 | 62 | 63 | 30 64 | 65 | 66 | index.html 67 | 68 | 69 | 404 70 | /404.html 71 | 72 | -------------------------------------------------------------------------------- /example-spring-core/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Example Spring Application 4 | 5 | 6 | 7 |

8 | The application you are looking for is hosted on http://localhost:9000/.
9 | You will be redirected to the new location automatically in 5 seconds. 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/Assertions.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import example.domain.shared.ddd.Entity; 4 | 5 | public class Assertions { 6 | 7 | private Assertions() { 8 | } 9 | 10 | public static EntityAssert assertThat(Entity actual) { 11 | return new EntityAssert(actual); 12 | } 13 | 14 | public static EntitiesAssert assertThat(Iterable actual) { 15 | return new EntitiesAssert(actual); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/EntitiesAssert.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | 5 | import org.fest.assertions.GenericAssert; 6 | 7 | import com.google.common.collect.Iterables; 8 | 9 | import example.domain.shared.ddd.Entity; 10 | import example.domain.shared.ddd.EntityFunctions; 11 | 12 | public class EntitiesAssert extends GenericAssert> { 13 | 14 | public EntitiesAssert(Iterable actual) { 15 | super(EntitiesAssert.class, actual); 16 | } 17 | 18 | public EntitiesAssert containsWithSameIdentity(Entity entity) { 19 | assertThat(Iterables.transform(actual, EntityFunctions.toEntityId())).contains(entity.getEntityId()); 20 | 21 | return this; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/EntityAssert.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | 5 | import org.fest.assertions.GenericAssert; 6 | 7 | import example.domain.shared.ddd.Entity; 8 | 9 | public class EntityAssert extends GenericAssert { 10 | 11 | public EntityAssert(Entity actual) { 12 | super(EntityAssert.class, actual); 13 | } 14 | 15 | public EntityAssert hasSameIdentity(Entity entity) { 16 | assertThat(actual.getEntityId()).isEqualTo(entity.getEntityId()); 17 | 18 | return this; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/TestGroups.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | public interface TestGroups { 4 | String UNIT = "unit"; 5 | String INTEGRATION = "integration"; 6 | String PERFORMANCE = "performance"; 7 | } 8 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/domain/iam/domain/UserTest.java: -------------------------------------------------------------------------------- 1 | package example.domain.iam.domain; 2 | 3 | import static com.google.common.collect.Sets.newHashSet; 4 | import static org.fest.assertions.Assertions.assertThat; 5 | 6 | import java.util.Set; 7 | 8 | import org.testng.annotations.Test; 9 | 10 | import example.TestGroups; 11 | import example.domain.iam.model.RoleIdentifier; 12 | import example.domain.iam.model.User; 13 | import example.domain.iam.model.UserIdentifier; 14 | import example.domain.iam.model.User.Builder; 15 | 16 | @Test(groups = TestGroups.UNIT) 17 | public class UserTest { 18 | 19 | private static final UserIdentifier ANY_IDENTIFIER = new UserIdentifier("any identifier"); 20 | private static final String ANY_EMAIL = "any@domain.com"; 21 | private static final String ANY_FIRSTNAME = "any firstname"; 22 | private static final String ANY_LASTNAME = "any lastname"; 23 | 24 | public void shouldConstruct() { 25 | // given 26 | UserIdentifier identifier = new UserIdentifier("id"); 27 | String email = "email@domain.com"; 28 | String firstname = "John"; 29 | String lastname = "White"; 30 | String fullname = "John White"; 31 | Boolean enabled = Boolean.TRUE; 32 | Set roles = newHashSet(new RoleIdentifier("role1"), new RoleIdentifier("role2")); 33 | 34 | // when 35 | User user = createBuilder().withIdentifier(identifier).withEmail(email).withFirstname(firstname) 36 | .withLastname(lastname).withFullname(fullname).withEnabled(enabled).addRoles(roles).build(); 37 | 38 | // then 39 | assertThat(user.getIdentifier()).isEqualTo(identifier); 40 | assertThat(user.getEmail()).isEqualTo(email); 41 | assertThat(user.getFirstname()).isEqualTo(firstname); 42 | assertThat(user.getLastname()).isEqualTo(lastname); 43 | assertThat(user.getFullname()).isEqualTo(fullname); 44 | assertThat(user.isEnabled()).isEqualTo(enabled); 45 | assertThat(user.getRoles()).isEqualTo(roles); 46 | } 47 | 48 | public void shouldDisable() { 49 | // given 50 | User user = createBuilder().withEnabled(Boolean.TRUE).build(); 51 | 52 | // when 53 | user.disable(); 54 | 55 | // then 56 | assertThat(user.isDisabled()).isTrue(); 57 | } 58 | 59 | @Test(expectedExceptions = IllegalStateException.class) 60 | public void shouldNotDisableWhenDisabled() { 61 | // given 62 | User user = createBuilder().withEnabled(Boolean.FALSE).build(); 63 | 64 | // when 65 | user.disable(); 66 | } 67 | 68 | public void shouldEnable() { 69 | // given 70 | User user = createBuilder().withEnabled(Boolean.FALSE).build(); 71 | 72 | // when 73 | user.enable(); 74 | 75 | // then 76 | assertThat(user.isEnabled()).isTrue(); 77 | } 78 | 79 | @Test(expectedExceptions = IllegalStateException.class) 80 | public void shouldNotEnableWhenEnabled() { 81 | // given 82 | User user = createBuilder().withEnabled(Boolean.TRUE).build(); 83 | 84 | // when & then 85 | user.enable(); 86 | } 87 | 88 | private Builder createBuilder() { 89 | return new Builder().withIdentifier(ANY_IDENTIFIER).withEmail(ANY_EMAIL).withFirstname(ANY_FIRSTNAME) 90 | .withLastname(ANY_LASTNAME); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/domain/shared/audit/AuditTest.java: -------------------------------------------------------------------------------- 1 | package example.domain.shared.audit; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | 5 | import org.joda.time.DateTime; 6 | import org.testng.annotations.Test; 7 | 8 | import example.TestGroups; 9 | import example.domain.shared.audit.Audit; 10 | 11 | @Test(groups = TestGroups.UNIT) 12 | public class AuditTest { 13 | 14 | @Test 15 | public void shouldUpdateNullInstance() { 16 | // given 17 | DateTime now = new DateTime(); 18 | String creator = "creator"; 19 | 20 | Audit audit = Audit.NULL; 21 | 22 | // when 23 | Audit updatedAudit = audit.update(now, creator); 24 | 25 | // then 26 | assertThat(updatedAudit.getCreator()).isEqualTo(creator); 27 | assertThat(updatedAudit.getCreationDate()).isEqualTo(now); 28 | 29 | assertThat(updatedAudit.getModifier()).isEqualTo(creator); 30 | assertThat(updatedAudit.getModificationDate()).isEqualTo(now); 31 | } 32 | 33 | @Test 34 | public void shouldUpdateExistingInstance() { 35 | // given 36 | DateTime creationDate = new DateTime("2010-01-01"); 37 | String creator = "creator"; 38 | 39 | DateTime modificationDate = new DateTime("2011-01-01"); 40 | String modifier = "modifier"; 41 | 42 | Audit audit = new Audit(creationDate, creator, creationDate, creator); 43 | 44 | // when 45 | Audit updatedAudit = audit.update(modificationDate, modifier); 46 | 47 | // then 48 | assertThat(updatedAudit.getCreator()).isEqualTo(creator); 49 | assertThat(updatedAudit.getCreationDate()).isEqualTo(creationDate); 50 | 51 | assertThat(updatedAudit.getModifier()).isEqualTo(modifier); 52 | assertThat(updatedAudit.getModificationDate()).isEqualTo(modificationDate); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/domain/todo/domain/TodoStatusTest.java: -------------------------------------------------------------------------------- 1 | package example.domain.todo.domain; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | 5 | import org.testng.annotations.Test; 6 | 7 | import example.TestGroups; 8 | import example.domain.todo.domain.Todo; 9 | import example.domain.todo.domain.TodoIllegalStateException; 10 | import example.domain.todo.domain.Todo.Status; 11 | 12 | @Test(groups = TestGroups.UNIT) 13 | public class TodoStatusTest { 14 | 15 | private static final String ANY_TITLE = "any title"; 16 | 17 | @Test 18 | public void shouldUpdateTitleWhenActive() { 19 | // given 20 | Status status = Status.ACTIVE; 21 | Todo todo = new Todo(ANY_TITLE); 22 | 23 | // when 24 | status.updateTitle(todo, "title"); 25 | 26 | // then 27 | assertThat(todo.isActive()).isTrue(); 28 | } 29 | 30 | @Test 31 | public void shouldDoneWhenActive() { 32 | // given 33 | Status status = Status.ACTIVE; 34 | Todo todo = new Todo(ANY_TITLE); 35 | 36 | // when 37 | status.done(todo); 38 | 39 | // then 40 | assertThat(todo.isDone()).isTrue(); 41 | } 42 | 43 | @Test(expectedExceptions = TodoIllegalStateException.class) 44 | public void shouldNotUpdateTitleWhenDone() { 45 | // given 46 | Status status = Status.DONE; 47 | 48 | Todo todo = new Todo(ANY_TITLE); 49 | 50 | // when 51 | status.updateTitle(todo, "title"); 52 | } 53 | 54 | @Test(expectedExceptions = TodoIllegalStateException.class) 55 | public void shouldNotDoneWhenDone() { 56 | // given 57 | Status status = Status.DONE; 58 | 59 | Todo todo = new Todo(ANY_TITLE); 60 | 61 | // when 62 | status.done(todo); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/domain/todo/domain/TodoTest.java: -------------------------------------------------------------------------------- 1 | package example.domain.todo.domain; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | 5 | import org.testng.annotations.Test; 6 | 7 | import example.TestGroups; 8 | import example.domain.todo.domain.Todo; 9 | 10 | @Test(groups = TestGroups.UNIT) 11 | public class TodoTest { 12 | 13 | private static final String ANY_TITLE = "any title"; 14 | 15 | @Test 16 | public void shouldConstructTodo() { 17 | // given 18 | String title = "title"; 19 | 20 | // when 21 | Todo todo = new Todo(title); 22 | 23 | // then 24 | assertThat(todo.isActive()).isTrue(); 25 | assertThat(todo.isDone()).isFalse(); 26 | 27 | assertThat(todo.getTitle()).isEqualTo(title); 28 | } 29 | 30 | @Test 31 | public void shouldUpdateTitle() { 32 | // given 33 | Todo todo = new Todo(ANY_TITLE); 34 | String title = "title"; 35 | 36 | // when 37 | todo.updateTitle(title); 38 | 39 | // then 40 | assertThat(todo.getTitle()).isEqualTo(title); 41 | } 42 | 43 | @Test 44 | public void shouldDoneActiveTodo() { 45 | // given 46 | Todo todo = new Todo(ANY_TITLE); 47 | 48 | // when 49 | todo.done(); 50 | 51 | // then 52 | assertThat(todo.isActive()).isFalse(); 53 | assertThat(todo.isDone()).isTrue(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/cache/CacheTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.cache; 2 | 3 | import static org.mockito.Matchers.*; 4 | import static org.mockito.Mockito.*; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.cache.annotation.Cacheable; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.test.context.ActiveProfiles; 10 | import org.springframework.test.context.ContextConfiguration; 11 | import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 12 | import org.testng.annotations.BeforeMethod; 13 | import org.testng.annotations.Test; 14 | 15 | import example.TestGroups; 16 | 17 | @ContextConfiguration(locations = "classpath:/META-INF/spring/testContext-infrastructure-cache.xml") 18 | @Test(groups = { TestGroups.INTEGRATION }, singleThreaded = true) 19 | @ActiveProfiles("test") 20 | public class CacheTest extends AbstractTestNGSpringContextTests { 21 | 22 | private static final String ANY_NAME = "any name"; 23 | 24 | @Autowired 25 | private TestFascadeService testFascadeService; 26 | 27 | @Autowired 28 | private TestCachedService testCachedService; 29 | 30 | @BeforeMethod 31 | public void initializeMocks() { 32 | reset(testCachedService); 33 | 34 | when(testCachedService.sayHello(anyString())).thenReturn("any message"); 35 | } 36 | 37 | @Test 38 | public void firstExecutionShouldCallCachedService() { 39 | testFascadeService.sayHello(ANY_NAME); 40 | 41 | verify(testCachedService).sayHello(eq(ANY_NAME)); 42 | } 43 | 44 | @Test(dependsOnMethods = "firstExecutionShouldCallCachedService") 45 | public void secondExecutionShouldUseCache() { 46 | testFascadeService.sayHello(ANY_NAME); 47 | 48 | verifyZeroInteractions(testCachedService); 49 | } 50 | 51 | @Component 52 | public static class TestFascadeService { 53 | 54 | @Autowired 55 | private TestCachedService cachedService; 56 | 57 | @Cacheable("example") 58 | public String sayHello(String name) { 59 | return cachedService.sayHello(name); 60 | } 61 | } 62 | 63 | public static interface TestCachedService { 64 | public String sayHello(String name); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/cache/CacheTestConfiguration.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.cache; 2 | 3 | import org.mockito.Mockito; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | import example.infrastructure.cache.CacheTest.TestCachedService; 8 | 9 | @Configuration 10 | public class CacheTestConfiguration { 11 | 12 | @Bean 13 | public TestCachedService testCachedService() { 14 | return Mockito.mock(TestCachedService.class); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/date/DefaultDateTimeProviderTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.date; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.springframework.test.context.ContextConfiguration; 8 | import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 9 | import org.testng.annotations.Test; 10 | 11 | import example.TestGroups; 12 | 13 | @ContextConfiguration(locations = "classpath:/META-INF/spring/testContext-infrastructure-date.xml") 14 | @Test(groups = TestGroups.INTEGRATION, singleThreaded = true) 15 | @ActiveProfiles("test") 16 | public class DefaultDateTimeProviderTest extends AbstractTestNGSpringContextTests { 17 | 18 | @Autowired 19 | private DefaultDateTimeProvider defaultDateTimeProvider; 20 | 21 | @Test 22 | public void shouldNotBeNull() { 23 | assertThat(defaultDateTimeProvider.now()).isNotNull(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/events/EventsTests.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.events; 2 | 3 | import static org.fest.assertions.Assertions.*; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.test.context.ActiveProfiles; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 10 | import org.testng.annotations.Test; 11 | 12 | import com.google.common.eventbus.EventBus; 13 | import com.google.common.eventbus.Subscribe; 14 | 15 | import example.TestGroups; 16 | import example.domain.shared.ddd.AbstractEvent; 17 | 18 | @ContextConfiguration(locations = "classpath:/META-INF/spring/testContext-infrastructure-events.xml") 19 | @Test(groups = { TestGroups.INTEGRATION }, singleThreaded = true) 20 | @ActiveProfiles("test") 21 | public class EventsTests extends AbstractTestNGSpringContextTests { 22 | 23 | private static final String ANY_PAYLOAD = "any payload"; 24 | 25 | @Autowired 26 | private EventBus eventBus; 27 | 28 | @Autowired 29 | private TestEventSubscriber testEventSubscriber; 30 | 31 | @Test 32 | public void shouldReceiveEvent() { 33 | // given 34 | TestEvent event = new TestEvent(ANY_PAYLOAD); 35 | 36 | // when 37 | eventBus.post(event); 38 | 39 | // then 40 | assertThat(testEventSubscriber.getEvent()).isEqualTo(event); 41 | } 42 | 43 | public static class TestEvent extends AbstractEvent { 44 | 45 | private static final long serialVersionUID = 1L; 46 | 47 | public TestEvent(String payload) { 48 | super(payload); 49 | } 50 | 51 | } 52 | 53 | @Component 54 | public static class TestEventSubscriber { 55 | 56 | private TestEvent event; 57 | 58 | @Subscribe 59 | public void subscribe(TestEvent event) { 60 | this.event = event; 61 | } 62 | 63 | public TestEvent getEvent() { 64 | return event; 65 | } 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jackson/Jackson2JsonSerializationServiceTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jackson; 2 | 3 | import static org.fest.assertions.Assertions.*; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import org.joda.money.CurrencyUnit; 8 | import org.joda.money.Money; 9 | import org.joda.time.DateTime; 10 | import org.joda.time.DateTimeZone; 11 | import org.joda.time.LocalDate; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.test.context.ActiveProfiles; 14 | import org.springframework.test.context.ContextConfiguration; 15 | import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 16 | import org.testng.annotations.DataProvider; 17 | import org.testng.annotations.Test; 18 | 19 | import example.TestGroups; 20 | 21 | @ContextConfiguration(locations = "classpath:/META-INF/spring/testContext-infrastructure-jackson.xml") 22 | @Test(groups = TestGroups.INTEGRATION, singleThreaded = true) 23 | @ActiveProfiles("test") 24 | public class Jackson2JsonSerializationServiceTest extends AbstractTestNGSpringContextTests { 25 | 26 | @Autowired 27 | private Jackson2JsonSerializationService service; 28 | 29 | @DataProvider 30 | static final Object[][] objects() { 31 | return new Object[][] { { Money.of(CurrencyUnit.EUR, BigDecimal.ZERO) }, { new DateTime(DateTimeZone.UTC) }, 32 | { new LocalDate() } }; 33 | } 34 | 35 | @Test(dataProvider = "objects") 36 | public void shouldSerializeAndDeserialize(Object object) { 37 | assertThat(service.fromJson(service.toJson(object), object.getClass().getName())).isEqualTo(object); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jms/AbstractJmsTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jms; 2 | 3 | import org.springframework.test.context.ActiveProfiles; 4 | import org.springframework.test.context.ContextConfiguration; 5 | import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 6 | 7 | @ContextConfiguration(locations = "classpath:/META-INF/spring/testContext-infrastructure-jms.xml") 8 | @ActiveProfiles("test") 9 | public class AbstractJmsTest extends AbstractTestNGSpringContextTests { 10 | } 11 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jms/JmsPerformanceTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jms; 2 | 3 | import static org.mockito.Matchers.eq; 4 | import static org.mockito.Mockito.timeout; 5 | import static org.mockito.Mockito.verify; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Qualifier; 9 | import org.springframework.jms.core.JmsTemplate; 10 | import org.testng.annotations.Test; 11 | 12 | import example.TestGroups; 13 | 14 | @Test(groups = { TestGroups.PERFORMANCE }) 15 | public class JmsPerformanceTest extends AbstractJmsTest { 16 | 17 | private static final JmsTestMessage ANY_MESSAGE = new JmsTestMessage(); 18 | 19 | private static final int NO_OF_PRODUCERS = 10; 20 | 21 | private static final int NO_OF_MESSAGES = 5000; 22 | 23 | private static final int RECEIVE_TIMEOUT = 500; 24 | 25 | @Autowired 26 | @Qualifier("testPerformanceJmsTemplate") 27 | private JmsTemplate jmsTemplate; 28 | 29 | @Autowired 30 | @Qualifier("testPerformanceListener") 31 | private JmsTestListener listener; 32 | 33 | @Test(invocationCount = NO_OF_MESSAGES, threadPoolSize = NO_OF_PRODUCERS) 34 | public void shouldSendMessages() { 35 | jmsTemplate.convertAndSend(ANY_MESSAGE); 36 | } 37 | 38 | @Test(dependsOnMethods = "shouldSendMessages") 39 | public void shouldHandleMessages() { 40 | verify(listener, timeout(RECEIVE_TIMEOUT).times(NO_OF_MESSAGES)).handleMessage(eq(ANY_MESSAGE)); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jms/JmsQueueTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jms; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | import static org.mockito.Matchers.eq; 5 | import static org.mockito.Mockito.doThrow; 6 | import static org.mockito.Mockito.reset; 7 | import static org.mockito.Mockito.timeout; 8 | import static org.mockito.Mockito.verify; 9 | 10 | import java.util.concurrent.TimeUnit; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.beans.factory.annotation.Qualifier; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.jms.core.JmsTemplate; 16 | import org.testng.annotations.BeforeMethod; 17 | import org.testng.annotations.Test; 18 | 19 | import com.google.common.base.Stopwatch; 20 | 21 | import example.TestGroups; 22 | 23 | @Test(groups = { TestGroups.INTEGRATION }, singleThreaded = true) 24 | public class JmsQueueTest extends AbstractJmsTest { 25 | 26 | private static final JmsTestMessage ANY_MESSAGE = new JmsTestMessage(); 27 | 28 | private static final int RECEIVE_TIMEOUT = 10000; 29 | 30 | @Autowired 31 | @Qualifier("testQueueJmsTemplate") 32 | private JmsTemplate jmsTemplate; 33 | 34 | @Autowired 35 | @Qualifier("testDlqQueueJmsTemplate") 36 | private JmsTemplate dlqJmsTemplate; 37 | 38 | @Autowired 39 | @Qualifier("testQueueListener") 40 | private JmsTestListener listener; 41 | 42 | @Value("${jms.expectedTotalRedeliveryTime}") 43 | private int expectedTotalRedeliveryTime; 44 | 45 | @BeforeMethod 46 | public void resetListener() { 47 | reset(listener); 48 | } 49 | 50 | @Test 51 | public void listenerShouldHandleMessage() { 52 | // when 53 | jmsTemplate.convertAndSend(ANY_MESSAGE); 54 | 55 | // then 56 | verify(listener, timeout(RECEIVE_TIMEOUT)).handleMessage(eq(ANY_MESSAGE)); 57 | } 58 | 59 | @Test(dependsOnMethods = "listenerShouldHandleMessage") 60 | public void messageShouldBeRedelivered() { 61 | // given (first & second calls: throws exception, third call: handles message) 62 | doThrow(new RuntimeException("#1")).doThrow(new RuntimeException("#2")).doNothing().when(listener) 63 | .handleMessage(eq(ANY_MESSAGE)); 64 | 65 | Stopwatch stopwatch = new Stopwatch().start(); 66 | 67 | // when 68 | jmsTemplate.convertAndSend(ANY_MESSAGE); 69 | 70 | // then 71 | verify(listener, timeout(RECEIVE_TIMEOUT).times(3)).handleMessage(eq(ANY_MESSAGE)); 72 | 73 | assertThat(stopwatch.stop().elapsed(TimeUnit.MILLISECONDS)).isGreaterThan(expectedTotalRedeliveryTime); 74 | } 75 | 76 | @Test(dependsOnMethods = "messageShouldBeRedelivered", timeOut = RECEIVE_TIMEOUT) 77 | public void messageShouldBeInDlqAfterRedeliveries() { 78 | // given (always throws exception) 79 | doThrow(new RuntimeException()).when(listener).handleMessage(eq(ANY_MESSAGE)); 80 | 81 | Stopwatch stopwatch = new Stopwatch().start(); 82 | 83 | // when 84 | jmsTemplate.convertAndSend(ANY_MESSAGE); 85 | 86 | JmsTestMessage testMessage = (JmsTestMessage) dlqJmsTemplate.receiveAndConvert(); 87 | assertThat(testMessage).isEqualTo(ANY_MESSAGE); 88 | 89 | assertThat(stopwatch.stop().elapsed(TimeUnit.MILLISECONDS)).isGreaterThan(expectedTotalRedeliveryTime); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jms/JmsTestConfiguration.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jms; 2 | 3 | import org.mockito.Mockito; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class JmsTestConfiguration { 9 | 10 | @Bean 11 | public JmsTestListener testQueueListener() { 12 | return Mockito.mock(JmsTestListener.class); 13 | } 14 | 15 | @Bean 16 | public JmsTestListener testTopicListener1() { 17 | return Mockito.mock(JmsTestListener.class); 18 | } 19 | 20 | @Bean 21 | public JmsTestListener testTopicListener2() { 22 | return Mockito.mock(JmsTestListener.class); 23 | } 24 | 25 | @Bean 26 | public JmsTestListener testPerformanceListener() { 27 | return Mockito.mock(JmsTestListener.class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jms/JmsTestListener.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jms; 2 | 3 | public interface JmsTestListener { 4 | void handleMessage(JmsTestMessage message); 5 | } -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jms/JmsTestMessage.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jms; 2 | 3 | import java.util.UUID; 4 | 5 | import com.google.common.base.Objects; 6 | 7 | public class JmsTestMessage { 8 | 9 | private UUID uuid = UUID.randomUUID(); 10 | 11 | public UUID getUuid() { 12 | return uuid; 13 | } 14 | 15 | public void setUuid(UUID uuid) { 16 | this.uuid = uuid; 17 | } 18 | 19 | @Override 20 | public boolean equals(Object obj) { 21 | if (obj == null) { 22 | return false; 23 | } 24 | 25 | if (getClass() != obj.getClass()) { 26 | return false; 27 | } 28 | 29 | JmsTestMessage other = (JmsTestMessage) obj; 30 | return Objects.equal(uuid, other.uuid); 31 | } 32 | 33 | @Override 34 | public int hashCode() { 35 | return Objects.hashCode(uuid); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return Objects.toStringHelper(this).addValue(uuid).toString(); 41 | } 42 | } -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jms/JmsTopicTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jms; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | import static org.mockito.Matchers.eq; 5 | import static org.mockito.Mockito.doThrow; 6 | import static org.mockito.Mockito.reset; 7 | import static org.mockito.Mockito.timeout; 8 | import static org.mockito.Mockito.verify; 9 | 10 | import java.util.concurrent.TimeUnit; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.beans.factory.annotation.Qualifier; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.jms.core.JmsTemplate; 16 | import org.testng.annotations.BeforeMethod; 17 | import org.testng.annotations.Test; 18 | 19 | import com.google.common.base.Stopwatch; 20 | 21 | import example.TestGroups; 22 | 23 | @Test(groups = { TestGroups.INTEGRATION }, singleThreaded = true) 24 | public class JmsTopicTest extends AbstractJmsTest { 25 | 26 | private static final JmsTestMessage ANY_MESSAGE = new JmsTestMessage(); 27 | 28 | private static final int RECEIVE_TIMEOUT = 10000; 29 | 30 | @Autowired 31 | @Qualifier("testTopicJmsTemplate") 32 | private JmsTemplate jmsTemplate; 33 | 34 | @Autowired 35 | @Qualifier("testDlqTopicJmsTemplate") 36 | private JmsTemplate dlqJmsTemplate; 37 | 38 | @Autowired 39 | @Qualifier("testTopicListener1") 40 | private JmsTestListener listener1; 41 | 42 | @Autowired 43 | @Qualifier("testTopicListener1") 44 | private JmsTestListener listener2; 45 | 46 | @Value("${jms.expectedTotalRedeliveryTime}") 47 | private int expectedTotalRedeliveryTime; 48 | 49 | @BeforeMethod 50 | public void resetListener() { 51 | reset(listener1, listener2); 52 | } 53 | 54 | @Test 55 | public void listenersShouldHandleMessage() { 56 | // when 57 | jmsTemplate.convertAndSend(ANY_MESSAGE); 58 | 59 | // then 60 | verify(listener1, timeout(RECEIVE_TIMEOUT).times(1)).handleMessage(eq(ANY_MESSAGE)); 61 | verify(listener2, timeout(RECEIVE_TIMEOUT).times(1)).handleMessage(eq(ANY_MESSAGE)); 62 | } 63 | 64 | @Test(dependsOnMethods = "listenersShouldHandleMessage") 65 | public void messageShouldBeRedelivered() { 66 | // given (first & second calls: throws exception, third call: handles message) 67 | doThrow(new RuntimeException("#1")).doThrow(new RuntimeException("#2")).doNothing().when(listener1) 68 | .handleMessage(eq(ANY_MESSAGE)); 69 | doThrow(new RuntimeException("#1")).doThrow(new RuntimeException("#2")).doNothing().when(listener2) 70 | .handleMessage(eq(ANY_MESSAGE)); 71 | 72 | Stopwatch stopwatch = new Stopwatch().start(); 73 | 74 | // when 75 | jmsTemplate.convertAndSend(ANY_MESSAGE); 76 | 77 | // then 78 | verify(listener1, timeout(RECEIVE_TIMEOUT).times(3)).handleMessage(eq(ANY_MESSAGE)); 79 | verify(listener2, timeout(RECEIVE_TIMEOUT).times(3)).handleMessage(eq(ANY_MESSAGE)); 80 | 81 | assertThat(stopwatch.stop().elapsed(TimeUnit.MILLISECONDS)).isGreaterThan(expectedTotalRedeliveryTime); 82 | } 83 | 84 | // TODO: fix test 85 | @Test(dependsOnMethods = "messageShouldBeRedelivered", timeOut = RECEIVE_TIMEOUT, enabled = false) 86 | public void messageShouldBeInDlqAfterRedeliveries() { 87 | // given (always throws exception) 88 | doThrow(new RuntimeException()).when(listener1).handleMessage(eq(ANY_MESSAGE)); 89 | doThrow(new RuntimeException()).when(listener2).handleMessage(eq(ANY_MESSAGE)); 90 | 91 | Stopwatch stopwatch = new Stopwatch().start(); 92 | 93 | // when 94 | jmsTemplate.convertAndSend(ANY_MESSAGE); 95 | 96 | JmsTestMessage testMessage1 = (JmsTestMessage) dlqJmsTemplate.receiveAndConvert(); 97 | assertThat(testMessage1).isEqualTo(ANY_MESSAGE); 98 | 99 | JmsTestMessage testMessage2 = (JmsTestMessage) dlqJmsTemplate.receiveAndConvert(); 100 | assertThat(testMessage2).isEqualTo(ANY_MESSAGE); 101 | 102 | assertThat(stopwatch.stop().elapsed(TimeUnit.MILLISECONDS)).isGreaterThan(expectedTotalRedeliveryTime); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/AbstractJpaRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import static org.mockito.Mockito.when; 4 | 5 | import javax.persistence.EntityManager; 6 | import javax.persistence.PersistenceContext; 7 | 8 | import org.joda.time.DateTime; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.test.context.ActiveProfiles; 11 | import org.springframework.test.context.ContextConfiguration; 12 | import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; 13 | import org.testng.annotations.BeforeClass; 14 | import org.testng.annotations.Test; 15 | 16 | import example.TestGroups; 17 | import example.domain.shared.audit.Audit; 18 | import example.domain.shared.date.DateTimeProvider; 19 | import example.domain.shared.ddd.Entity; 20 | import example.domain.shared.security.AuthenticatedUserDetails; 21 | import example.domain.shared.security.AuthenticatedUserDetailsProvider; 22 | 23 | @ContextConfiguration(locations = "classpath:/META-INF/spring/testContext-infrastructure-jpa.xml") 24 | @Test(groups = { TestGroups.INTEGRATION }, singleThreaded = true) 25 | @ActiveProfiles("test") 26 | public abstract class AbstractJpaRepositoryTest extends AbstractTransactionalTestNGSpringContextTests { 27 | 28 | public static final DateTime AUDIT_DATE_TIME = new DateTime(); 29 | 30 | public static final AuthenticatedUserDetails AUDIT_USER_DETAILS = new TestUserDetails("any@domain.com"); 31 | 32 | public static final Audit EXPECTED_AUDIT = new Audit(AUDIT_DATE_TIME, AUDIT_USER_DETAILS.getEmail(), 33 | AUDIT_DATE_TIME, AUDIT_USER_DETAILS.getEmail()); 34 | 35 | @PersistenceContext 36 | protected EntityManager entityManager; 37 | 38 | @Autowired 39 | private DateTimeProvider dateTimeProvider; 40 | 41 | @Autowired 42 | private AuthenticatedUserDetailsProvider authenticatedUserDetailsProvider; 43 | 44 | @BeforeClass 45 | public void initializeDateProvider() { 46 | when(dateTimeProvider.now()).thenReturn(AUDIT_DATE_TIME); 47 | } 48 | 49 | @BeforeClass 50 | public void initializeAccountProvider() { 51 | when(authenticatedUserDetailsProvider.authenticated()).thenReturn(AUDIT_USER_DETAILS); 52 | } 53 | 54 | protected T saveFlushAndClear(T entity) { 55 | entityManager.persist(entity); 56 | flushAndClear(); 57 | 58 | return entity; 59 | } 60 | 61 | protected void flushAndClear() { 62 | entityManager.flush(); 63 | entityManager.clear(); 64 | } 65 | 66 | private static class TestUserDetails implements AuthenticatedUserDetails { 67 | 68 | private String email; 69 | 70 | public TestUserDetails(String email) { 71 | this.email = email; 72 | } 73 | 74 | @Override 75 | public String getUsername() { 76 | throw new UnsupportedOperationException(); 77 | } 78 | 79 | @Override 80 | public String getEmail() { 81 | return email; 82 | } 83 | 84 | @Override 85 | public String getFirstname() { 86 | throw new UnsupportedOperationException(); 87 | } 88 | 89 | @Override 90 | public String getLastname() { 91 | throw new UnsupportedOperationException(); 92 | } 93 | 94 | @Override 95 | public String getFullname() { 96 | throw new UnsupportedOperationException(); 97 | } 98 | 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/JpaTestConfiguration.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import org.mockito.Mockito; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | import example.domain.shared.date.DateTimeProvider; 8 | import example.domain.shared.security.AuthenticatedUserDetailsProvider; 9 | 10 | @Configuration 11 | public class JpaTestConfiguration { 12 | 13 | @Bean 14 | public AuthenticatedUserDetailsProvider userAuthenticatedUserDetailsProvider() { 15 | return Mockito.mock(AuthenticatedUserDetailsProvider.class); 16 | } 17 | 18 | @Bean 19 | public DateTimeProvider dateTimeProvider() { 20 | return Mockito.mock(DateTimeProvider.class); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/JpaTestRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import static com.google.common.collect.Lists.newArrayList; 4 | import static org.fest.assertions.Assertions.assertThat; 5 | 6 | import java.util.List; 7 | 8 | import org.joda.money.CurrencyUnit; 9 | import org.joda.money.Money; 10 | import org.joda.time.DateTime; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.dao.DataIntegrityViolationException; 13 | import org.testng.annotations.Test; 14 | 15 | import example.Assertions; 16 | 17 | public class JpaTestRepositoryTest extends AbstractJpaRepositoryTest { 18 | 19 | private static final String ANY_NAME = "any name"; 20 | 21 | private static final TestValueObject ANY_VALUE_OBJECT = new TestValueObject("any value", "any value"); 22 | 23 | private static final DateTime ANY_DATE_TIME = new DateTime(); 24 | 25 | private static final Money ANY_MONEY = Money.of(CurrencyUnit.EUR, 10); 26 | 27 | @Autowired 28 | private TestRepository testRepository; 29 | 30 | @Test 31 | public void shouldSaveExample() { 32 | // given 33 | TestEntity example = new TestEntity(ANY_NAME); 34 | example.setTestValueObjectEmbedded(ANY_VALUE_OBJECT); 35 | example.setTestValueObjectJson(ANY_VALUE_OBJECT); 36 | example.setDateTime(ANY_DATE_TIME); 37 | example.setMoney(ANY_MONEY); 38 | 39 | // when 40 | TestEntity savedExample = testRepository.save(example); 41 | flushAndClear(); 42 | 43 | // then 44 | assertThat(savedExample.isManaged()).isTrue(); 45 | assertThat(savedExample.getAudit()).isEqualTo(EXPECTED_AUDIT); 46 | 47 | assertThat(savedExample.getName()).isEqualTo(ANY_NAME); 48 | assertThat(savedExample.getTestValueObjectEmbedded()).isEqualTo(ANY_VALUE_OBJECT); 49 | assertThat(savedExample.getTestValueObjectJson()).isEqualTo(ANY_VALUE_OBJECT); 50 | assertThat(savedExample.getDateTime()).isEqualTo(ANY_DATE_TIME); 51 | assertThat(savedExample.getMoney()).isEqualTo(ANY_MONEY); 52 | } 53 | 54 | @Test(expectedExceptions = DataIntegrityViolationException.class) 55 | public void shouldNotSaveExampleDuplicates() { 56 | // given 57 | String name = "duplicate"; 58 | 59 | TestEntity exampleA = new TestEntity(name); 60 | TestEntity exampleB = new TestEntity(name); 61 | 62 | // when 63 | testRepository.save(newArrayList(exampleA, exampleB)); 64 | } 65 | 66 | @Test 67 | public void shouldFindByName() { 68 | // given 69 | String name = "name"; 70 | TestEntity expectedExample = saveFlushAndClear(new TestEntity("name")); 71 | 72 | // when 73 | List examples = testRepository.findByName(name); 74 | 75 | // then 76 | Assertions.assertThat(examples).containsWithSameIdentity(expectedExample); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/TestEntity.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import static com.google.common.base.Preconditions.*; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Embedded; 7 | import javax.persistence.Entity; 8 | 9 | import org.hibernate.annotations.Columns; 10 | import org.joda.money.Money; 11 | import org.joda.time.DateTime; 12 | 13 | import example.domain.shared.audit.Audit; 14 | import example.domain.shared.audit.Auditable; 15 | import example.domain.shared.ddd.AbstractAggregateEntity; 16 | import example.domain.shared.json.JsonHolder; 17 | 18 | @Entity 19 | public class TestEntity extends AbstractAggregateEntity implements Auditable { 20 | 21 | @Column(nullable = true, unique = true) 22 | private String name; 23 | 24 | @Embedded 25 | private TestValueObject testValueObjectEmbedded; 26 | 27 | @Columns(columns = { @Column(name = "test_value_object_json_class"), @Column(name = "test_value_object_json_value") }) 28 | private JsonHolder testValueObjectHolder = JsonHolder.absent(); 29 | 30 | @Column 31 | private DateTime dateTime; 32 | 33 | @Columns(columns = { @Column(name = "amount"), @Column(name = "currency") }) 34 | private Money money; 35 | 36 | @Embedded 37 | private Audit audit = Audit.NULL; 38 | 39 | protected TestEntity() { 40 | } 41 | 42 | public TestEntity(String name) { 43 | this.name = checkNotNull(name); 44 | } 45 | 46 | public String getName() { 47 | return name; 48 | } 49 | 50 | public TestValueObject getTestValueObjectEmbedded() { 51 | return testValueObjectEmbedded; 52 | } 53 | 54 | public void setTestValueObjectEmbedded(TestValueObject testValueObjectEmbedded) { 55 | this.testValueObjectEmbedded = testValueObjectEmbedded; 56 | } 57 | 58 | public TestValueObject getTestValueObjectJson() { 59 | return testValueObjectHolder.getValue(); 60 | } 61 | 62 | public void setTestValueObjectJson(TestValueObject testValueObjectJson) { 63 | this.testValueObjectHolder = JsonHolder.of(testValueObjectJson); 64 | } 65 | 66 | public DateTime getDateTime() { 67 | return dateTime; 68 | } 69 | 70 | public void setDateTime(DateTime dateTime) { 71 | this.dateTime = dateTime; 72 | } 73 | 74 | public Money getMoney() { 75 | return money; 76 | } 77 | 78 | public void setMoney(Money money) { 79 | this.money = money; 80 | } 81 | 82 | @Override 83 | public Audit getAudit() { 84 | return audit; 85 | } 86 | 87 | @Override 88 | public void updateAudit(DateTime now, String modifier) { 89 | audit = audit.update(now, modifier); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/TestRepository.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import java.util.List; 4 | 5 | import example.domain.shared.ddd.DomainRepository; 6 | 7 | public interface TestRepository extends DomainRepository { 8 | 9 | List findByName(String name); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/TestValueObject.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa; 2 | 3 | import static com.google.common.base.Preconditions.*; 4 | 5 | import javax.persistence.Access; 6 | import javax.persistence.AccessType; 7 | import javax.persistence.Column; 8 | import javax.persistence.Embeddable; 9 | 10 | import example.domain.shared.ddd.AbstractValueObject; 11 | 12 | @Embeddable 13 | @Access(AccessType.FIELD) 14 | public class TestValueObject extends AbstractValueObject { 15 | 16 | @Column(nullable = false) 17 | private String fieldA; 18 | 19 | @Column(nullable = true) 20 | private String fieldB; 21 | 22 | protected TestValueObject() { 23 | } 24 | 25 | public TestValueObject(String fieldA) { 26 | this.fieldA = checkNotNull(fieldA); 27 | } 28 | 29 | public TestValueObject(String fieldA, String fieldB) { 30 | this(fieldA); 31 | this.fieldB = checkNotNull(fieldB); 32 | } 33 | 34 | public String getFieldA() { 35 | return fieldA; 36 | } 37 | 38 | public String getFieldB() { 39 | return fieldB; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/iam/JpaRoleRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa.iam; 2 | 3 | import static com.google.common.collect.Lists.newArrayList; 4 | import static org.fest.assertions.Assertions.assertThat; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.dao.DataIntegrityViolationException; 8 | import org.testng.annotations.Test; 9 | 10 | import example.Assertions; 11 | import example.domain.iam.model.Role; 12 | import example.domain.iam.model.RoleIdentifier; 13 | import example.domain.iam.model.RoleRepository; 14 | import example.infrastructure.jpa.AbstractJpaRepositoryTest; 15 | 16 | public class JpaRoleRepositoryTest extends AbstractJpaRepositoryTest { 17 | 18 | private static final RoleIdentifier ANY_IDENTIFIER = new RoleIdentifier("any role"); 19 | private static final String ANY_NAME = "any role name"; 20 | 21 | @Autowired 22 | private RoleRepository roleRepository; 23 | 24 | public void shouldSave() { 25 | // given 26 | Role role = new Role(ANY_IDENTIFIER, ANY_NAME); 27 | 28 | // when 29 | Role savedRole = roleRepository.save(role); 30 | flushAndClear(); 31 | 32 | savedRole = roleRepository.findOne(savedRole.getEntityId()); 33 | 34 | // then 35 | assertThat(savedRole.isManaged()).isTrue(); 36 | 37 | assertThat(savedRole.getIdentifier()).isEqualTo(ANY_IDENTIFIER); 38 | assertThat(savedRole.getName()).isEqualTo(ANY_NAME); 39 | } 40 | 41 | @Test(expectedExceptions = DataIntegrityViolationException.class) 42 | public void shouldNotSaveDuplicates() { 43 | // given 44 | RoleIdentifier identifier = new RoleIdentifier("duplicate"); 45 | 46 | Role role1 = new Role(identifier, ANY_NAME); 47 | Role role2 = new Role(identifier, ANY_NAME); 48 | 49 | // when 50 | roleRepository.save(newArrayList(role1, role2)); 51 | } 52 | 53 | @Test 54 | public void shouldFindByIdentifier() { 55 | // given 56 | RoleIdentifier identifier = new RoleIdentifier("identifier"); 57 | 58 | Role expectedRole = saveFlushAndClear(new Role(identifier, ANY_NAME)); 59 | 60 | // when 61 | Role role = roleRepository.findByIdentifier(identifier); 62 | 63 | // then 64 | Assertions.assertThat(role).hasSameIdentity(expectedRole); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/iam/JpaUserRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa.iam; 2 | 3 | import static com.google.common.collect.Lists.newArrayList; 4 | import static com.google.common.collect.Sets.newHashSet; 5 | import static org.fest.assertions.Assertions.assertThat; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.dao.DataIntegrityViolationException; 9 | import org.testng.annotations.Test; 10 | 11 | import example.Assertions; 12 | import example.domain.iam.model.RoleIdentifier; 13 | import example.domain.iam.model.User; 14 | import example.domain.iam.model.UserIdentifier; 15 | import example.domain.iam.model.UserRepository; 16 | import example.domain.iam.model.User.Builder; 17 | import example.infrastructure.jpa.AbstractJpaRepositoryTest; 18 | 19 | public class JpaUserRepositoryTest extends AbstractJpaRepositoryTest { 20 | 21 | private static final UserIdentifier ANY_IDENTIFIER = new UserIdentifier("any user"); 22 | private static final String ANY_EMAIL = "any@domain.com"; 23 | private static final String ANY_FIRSTNAME = "any firstname"; 24 | private static final String ANY_LASTNAME = "any lastname"; 25 | private static final String ANY_FULLNAME = "any fullname"; 26 | private static final Boolean ANY_ENABLED = Boolean.TRUE; 27 | private static final RoleIdentifier ANY_ROLE = new RoleIdentifier("any role"); 28 | 29 | @Autowired 30 | private UserRepository userRepository; 31 | 32 | public void shouldSave() { 33 | // given 34 | User user = createBuilder().build(); 35 | 36 | // when 37 | User savedUser = userRepository.save(user); 38 | flushAndClear(); 39 | 40 | savedUser = userRepository.findOne(savedUser.getEntityId()); 41 | 42 | // then 43 | assertThat(savedUser.isManaged()).isTrue(); 44 | 45 | assertThat(savedUser.getIdentifier()).isEqualTo(ANY_IDENTIFIER); 46 | assertThat(savedUser.getEmail()).isEqualTo(ANY_EMAIL); 47 | assertThat(savedUser.getFirstname()).isEqualTo(ANY_FIRSTNAME); 48 | assertThat(savedUser.getLastname()).isEqualTo(ANY_LASTNAME); 49 | assertThat(savedUser.getFullname()).isEqualTo(ANY_FULLNAME); 50 | assertThat(savedUser.isEnabled()).isEqualTo(ANY_ENABLED); 51 | assertThat(savedUser.getRoles()).isEqualTo(newHashSet(ANY_ROLE)); 52 | } 53 | 54 | @Test(expectedExceptions = DataIntegrityViolationException.class) 55 | public void shouldNotSaveDuplicates() { 56 | // given 57 | UserIdentifier identifier = new UserIdentifier("duplicate"); 58 | 59 | User user1 = createBuilder().withIdentifier(identifier).build(); 60 | User user2 = createBuilder().withIdentifier(identifier).build(); 61 | 62 | // when 63 | userRepository.save(newArrayList(user1, user2)); 64 | } 65 | 66 | @Test 67 | public void shouldFindByIdentifier() { 68 | // given 69 | UserIdentifier identifier = new UserIdentifier("identifier"); 70 | 71 | User expectedUser = saveFlushAndClear(createBuilder().withIdentifier(identifier).build()); 72 | 73 | // when 74 | User user = userRepository.findByIdentifier(identifier); 75 | 76 | // then 77 | Assertions.assertThat(user).hasSameIdentity(expectedUser); 78 | } 79 | 80 | private Builder createBuilder() { 81 | return new Builder().withIdentifier(ANY_IDENTIFIER).withEmail(ANY_EMAIL).withFirstname(ANY_FIRSTNAME) 82 | .withLastname(ANY_LASTNAME).withFullname(ANY_FULLNAME).withEnabled(ANY_ENABLED).addRole(ANY_ROLE); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/infrastructure/jpa/todo/JpaTodoRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package example.infrastructure.jpa.todo; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | 7 | import example.domain.todo.domain.Todo; 8 | import example.domain.todo.domain.TodoRepository; 9 | import example.infrastructure.jpa.AbstractJpaRepositoryTest; 10 | 11 | public class JpaTodoRepositoryTest extends AbstractJpaRepositoryTest { 12 | 13 | private static final String ANY_TITLE = "any title"; 14 | 15 | @Autowired 16 | private TodoRepository todoRepository; 17 | 18 | public void shouldSaveTodo() { 19 | // given 20 | Todo todo = new Todo(ANY_TITLE); 21 | 22 | // when 23 | Todo savedTodo = todoRepository.save(todo); 24 | flushAndClear(); 25 | savedTodo = todoRepository.findOne(savedTodo.getEntityId()); 26 | 27 | // then 28 | assertThat(savedTodo.isManaged()).isTrue(); 29 | assertThat(savedTodo.getStatus()).isEqualTo(Todo.DEFAULT_STATUS); 30 | assertThat(savedTodo.getTitle()).isEqualTo(ANY_TITLE); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/web/AbstractContollerTest.java: -------------------------------------------------------------------------------- 1 | package example.web; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.test.context.ActiveProfiles; 5 | import org.springframework.test.context.ContextConfiguration; 6 | import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 7 | import org.springframework.test.context.web.WebAppConfiguration; 8 | import org.springframework.test.web.servlet.MockMvc; 9 | import org.springframework.test.web.servlet.RequestBuilder; 10 | import org.springframework.test.web.servlet.ResultActions; 11 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 12 | import org.springframework.web.context.WebApplicationContext; 13 | import org.testng.annotations.BeforeClass; 14 | import org.testng.annotations.Test; 15 | 16 | import example.TestGroups; 17 | 18 | @ContextConfiguration("classpath:/META-INF/spring/testContext-web.xml") 19 | @Test(groups = { TestGroups.INTEGRATION }) 20 | @ActiveProfiles("test") 21 | @WebAppConfiguration 22 | public abstract class AbstractContollerTest extends AbstractTestNGSpringContextTests { 23 | 24 | @Autowired 25 | private WebApplicationContext wac; 26 | 27 | private MockMvc mockMvc; 28 | 29 | @BeforeClass 30 | protected void initializeMockMvc() { 31 | mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); 32 | } 33 | 34 | protected ResultActions perform(RequestBuilder requestBuilder) throws Exception { 35 | return mockMvc.perform(requestBuilder); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/web/TodoControllerTest.java: -------------------------------------------------------------------------------- 1 | package example.web; 2 | 3 | import static com.google.common.collect.Lists.newArrayList; 4 | import static org.hamcrest.Matchers.equalTo; 5 | import static org.hamcrest.Matchers.hasSize; 6 | import static org.mockito.Matchers.eq; 7 | import static org.mockito.Mockito.verify; 8 | import static org.mockito.Mockito.when; 9 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; 10 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 11 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 12 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; 13 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 14 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 15 | 16 | import java.util.ArrayList; 17 | 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.http.MediaType; 20 | import org.testng.annotations.Test; 21 | 22 | import example.domain.todo.application.TodoService; 23 | import example.domain.todo.domain.Todo; 24 | import example.web.RequestMappings; 25 | 26 | public class TodoControllerTest extends AbstractContollerTest { 27 | 28 | @Autowired 29 | private TodoService todoService; 30 | 31 | @Test 32 | public void shouldList() throws Exception { 33 | // given 34 | Todo todo1 = new Todo("todo1"); 35 | Todo todo2 = new Todo("todo2"); 36 | ArrayList todos = newArrayList(todo1, todo2); 37 | 38 | when(todoService.findAll()).thenReturn(todos); 39 | 40 | // when & then 41 | perform(get(RequestMappings.TODOS).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) 42 | .andExpect(jsonPath("$.").value(hasSize(todos.size()))) 43 | .andExpect(jsonPath("$.[0].title").value(equalTo(todo1.getTitle()))) 44 | .andExpect(jsonPath("$.[1].title").value(equalTo(todo2.getTitle()))); 45 | } 46 | 47 | @Test 48 | public void shouldAdd() throws Exception { 49 | // given 50 | String title = "title"; 51 | 52 | // when & then 53 | perform(post(RequestMappings.TODOS).param("title", title).accept(MediaType.APPLICATION_JSON)).andExpect( 54 | status().isCreated()); 55 | 56 | verify(todoService).add(eq(title)); 57 | } 58 | 59 | @Test 60 | public void shouldGet() throws Exception { 61 | // given 62 | Long id = 1L; 63 | 64 | Todo todo = new Todo("todo"); 65 | when(todoService.findOne(eq(id))).thenReturn(todo); 66 | 67 | // when & then 68 | perform(get(RequestMappings.TODOS + "/{id}", id).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) 69 | .andExpect(jsonPath("$.title").value(equalTo(todo.getTitle()))); 70 | } 71 | 72 | @Test 73 | public void shouldDelete() throws Exception { 74 | // given 75 | Long id = 1L; 76 | 77 | // when & then 78 | perform(delete(RequestMappings.TODOS + "/{id}", id).accept(MediaType.APPLICATION_JSON)).andExpect( 79 | status().isNoContent()); 80 | 81 | verify(todoService).delete(eq(id)); 82 | } 83 | 84 | @Test 85 | public void shouldUpdateStatusToDone() throws Exception { 86 | // given 87 | Long id = 1L; 88 | 89 | // when & then 90 | perform(put(RequestMappings.TODOS + "/{id}/done", id).accept(MediaType.APPLICATION_JSON)).andExpect( 91 | status().isNoContent()); 92 | 93 | verify(todoService).done(eq(id)); 94 | } 95 | 96 | @Test 97 | public void shouldUpdateTitle() throws Exception { 98 | // given 99 | Long id = 1L; 100 | String title = "title"; 101 | 102 | // when & then 103 | perform(put(RequestMappings.TODOS + "/{id}/title", id).param("title", title).accept(MediaType.APPLICATION_JSON)) 104 | .andExpect(status().isNoContent()); 105 | 106 | verify(todoService).updateTitle(eq(id), eq(title)); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/example/web/WebTestConfiguration.java: -------------------------------------------------------------------------------- 1 | package example.web; 2 | 3 | import org.mockito.Mockito; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | import example.domain.shared.security.AuthenticatedUserDetailsProvider; 8 | import example.domain.todo.application.TodoService; 9 | import example.domain.todo.domain.TodoRepository; 10 | import example.infrastructure.jpa.TestRepository; 11 | 12 | @Configuration 13 | public class WebTestConfiguration { 14 | 15 | @Bean 16 | public AuthenticatedUserDetailsProvider userProvider() { 17 | return Mockito.mock(AuthenticatedUserDetailsProvider.class); 18 | } 19 | 20 | @Bean 21 | public TestRepository testRepository() { 22 | return Mockito.mock(TestRepository.class); 23 | } 24 | 25 | @Bean 26 | public TodoRepository todoRepository() { 27 | return Mockito.mock(TodoRepository.class); 28 | } 29 | 30 | @Bean 31 | public TodoService todoService() { 32 | return Mockito.mock(TodoService.class); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /example-spring-core/src/test/java/org/mockito/testng/MockitoAfterTestNGMethod.java: -------------------------------------------------------------------------------- 1 | package org.mockito.testng; 2 | 3 | import static org.mockito.internal.util.reflection.Fields.*; 4 | 5 | import java.lang.reflect.Field; 6 | import java.util.Collection; 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | import org.mockito.Mock; 11 | import org.mockito.Mockito; 12 | import org.mockito.MockitoAnnotations; 13 | import org.mockito.Spy; 14 | import org.mockito.exceptions.base.MockitoException; 15 | import org.mockito.internal.util.reflection.Fields; 16 | import org.testng.IInvokedMethod; 17 | import org.testng.ITestResult; 18 | 19 | public class MockitoAfterTestNGMethod { 20 | 21 | public void applyFor(IInvokedMethod method, ITestResult testResult) { 22 | Mockito.validateMockitoUsage(); 23 | 24 | if (method.isTestMethod()) { 25 | resetMocks(testResult.getInstance()); 26 | } 27 | } 28 | 29 | private void resetMocks(Object instance) { 30 | Mockito.reset(instanceMocksOf(instance).toArray()); 31 | } 32 | 33 | @SuppressWarnings({ "unchecked", "deprecation" }) 34 | private Collection instanceMocksOf(Object instance) { 35 | return Fields.allDeclaredFieldsOf(instance) 36 | .filter(annotatedBy(Mock.class, Spy.class, MockitoAnnotations.Mock.class)).notNull().assignedValues(); 37 | } 38 | 39 | @SuppressWarnings("unused") 40 | private Set instanceMocksIn(Object instance, Class clazz) { 41 | Set instanceMocks = new HashSet(); 42 | Field[] declaredFields = clazz.getDeclaredFields(); 43 | for (Field declaredField : declaredFields) { 44 | if (declaredField.isAnnotationPresent(Mock.class) || declaredField.isAnnotationPresent(Spy.class)) { 45 | declaredField.setAccessible(true); 46 | try { 47 | Object fieldValue = declaredField.get(instance); 48 | if (fieldValue != null) { 49 | instanceMocks.add(fieldValue); 50 | } 51 | } catch (IllegalAccessException e) { 52 | throw new MockitoException("Could not access field " + declaredField.getName()); 53 | } 54 | } 55 | } 56 | return instanceMocks; 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /example-spring-core/src/test/java/org/mockito/testng/MockitoBeforeTestNGMethod.java: -------------------------------------------------------------------------------- 1 | package org.mockito.testng; 2 | 3 | import static org.mockito.internal.util.reflection.Fields.annotatedBy; 4 | 5 | import java.util.List; 6 | import java.util.WeakHashMap; 7 | 8 | import org.mockito.Captor; 9 | import org.mockito.MockitoAnnotations; 10 | import org.mockito.internal.configuration.CaptorAnnotationProcessor; 11 | import org.mockito.internal.util.reflection.Fields; 12 | import org.mockito.internal.util.reflection.InstanceField; 13 | import org.testng.IInvokedMethod; 14 | import org.testng.ITestResult; 15 | 16 | public class MockitoBeforeTestNGMethod { 17 | 18 | private WeakHashMap initializedInstances = new WeakHashMap(); 19 | 20 | /** 21 | * Initialize mocks. 22 | * 23 | * @param method 24 | * Invoked method. 25 | * @param testResult 26 | * TestNG Test Result 27 | */ 28 | public void applyFor(IInvokedMethod method, ITestResult testResult) { 29 | initMocks(testResult); 30 | reinitCaptors(method, testResult); 31 | } 32 | 33 | private void reinitCaptors(IInvokedMethod method, ITestResult testResult) { 34 | if (method.isConfigurationMethod()) { 35 | return; 36 | } 37 | initializeCaptors(testResult.getInstance()); 38 | } 39 | 40 | private void initMocks(ITestResult testResult) { 41 | if (alreadyInitialized(testResult.getInstance())) { 42 | return; 43 | } 44 | MockitoAnnotations.initMocks(testResult.getInstance()); 45 | markAsInitialized(testResult.getInstance()); 46 | } 47 | 48 | @SuppressWarnings("unchecked") 49 | private void initializeCaptors(Object instance) { 50 | List instanceFields = Fields.allDeclaredFieldsOf(instance).filter(annotatedBy(Captor.class)) 51 | .instanceFields(); 52 | for (InstanceField instanceField : instanceFields) { 53 | new CaptorAnnotationProcessor().process(instanceField.annotation(Captor.class), instanceField.jdkField()); 54 | } 55 | } 56 | 57 | private void markAsInitialized(Object instance) { 58 | initializedInstances.put(instance, true); 59 | } 60 | 61 | private boolean alreadyInitialized(Object instance) { 62 | return initializedInstances.containsKey(instance); 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /example-spring-core/src/test/java/org/mockito/testng/MockitoTestNGListener.java: -------------------------------------------------------------------------------- 1 | package org.mockito.testng; 2 | 3 | import org.testng.IInvokedMethod; 4 | import org.testng.IInvokedMethodListener; 5 | import org.testng.ITestNGListener; 6 | import org.testng.ITestResult; 7 | import org.testng.annotations.Listeners; 8 | 9 | /** 10 | * Mockito TestNG Listener, this listener adds the following behavior to your test : 11 | *
    12 | *
  • 13 | * Initializes mocks annotated with {@link org.mockito.Mock}, so that explicit usage of 14 | * {@link org.mockito.MockitoAnnotations#initMocks(Object)} is not necessary. Note : With 15 | * TestNG, mocks are initialized before any TestNG method, either a configuration 16 | * method (@BeforeMethod, @BeforeClass, etc) or a test method, i.e. mocks are 17 | * initialized once only once for each test instance.
  • 18 | *
  • 19 | * As mocks are initialized only once, they will be reset after each test method. See javadoc 20 | * {@link org.mockito.Mockito#reset(Object[])}
  • 21 | *
  • 22 | * Validates framework usage after each test method. See javadoc for {@link org.mockito.Mockito#validateMockitoUsage()}. 23 | *
  • 24 | *
25 | * 26 | *

27 | * The listener is completely optional - there are other ways you can get @Mock working, for example by writing a 28 | * base class. Explicitly validating framework usage is also optional because it is triggered automatically by Mockito 29 | * every time you use the framework. See javadoc for {@link org.mockito.Mockito#validateMockitoUsage()}. 30 | * 31 | *

32 | * Read more about @Mock annotation in javadoc for {@link org.mockito.MockitoAnnotations} 33 | * 34 | *

35 |  * 
36 |  * @Listeners(MockitoTestNGListener.class)
37 |  * public class ExampleTest {
38 |  * 
39 |  *     @Mock
40 |  *     private List list;
41 |  * 
42 |  *     @Test
43 |  *     public void shouldDoSomething() {
44 |  *         list.add(100);
45 |  *     }
46 |  * }
47 |  * 
48 |  * 
49 | */ 50 | public class MockitoTestNGListener implements IInvokedMethodListener { 51 | 52 | private MockitoBeforeTestNGMethod beforeTest = new MockitoBeforeTestNGMethod(); 53 | private MockitoAfterTestNGMethod afterTest = new MockitoAfterTestNGMethod(); 54 | 55 | @Override 56 | public void beforeInvocation(IInvokedMethod method, ITestResult testResult) { 57 | if (hasMockitoTestNGListenerInTestHierarchy(testResult.getTestClass().getRealClass())) { 58 | beforeTest.applyFor(method, testResult); 59 | } 60 | } 61 | 62 | @Override 63 | public void afterInvocation(IInvokedMethod method, ITestResult testResult) { 64 | if (hasMockitoTestNGListenerInTestHierarchy(testResult.getTestClass().getRealClass())) { 65 | afterTest.applyFor(method, testResult); 66 | } 67 | } 68 | 69 | protected boolean hasMockitoTestNGListenerInTestHierarchy(Class testClass) { 70 | for (Class clazz = testClass; clazz != Object.class; clazz = clazz.getSuperclass()) { 71 | if (hasMockitoTestNGListener(clazz)) { 72 | return true; 73 | } 74 | } 75 | return false; 76 | } 77 | 78 | protected boolean hasMockitoTestNGListener(Class clazz) { 79 | Listeners listeners = clazz.getAnnotation(Listeners.class); 80 | if (listeners == null) { 81 | return false; 82 | } 83 | 84 | for (Class listenerClass : listeners.value()) { 85 | if (listenerClass() == listenerClass) { 86 | return true; 87 | } 88 | } 89 | return false; 90 | } 91 | 92 | protected Class listenerClass() { 93 | return MockitoTestNGListener.class; 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/META-INF/spring/testContext-infrastructure-cache.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/META-INF/spring/testContext-infrastructure-date.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/META-INF/spring/testContext-infrastructure-events.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/META-INF/spring/testContext-infrastructure-jackson.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/META-INF/spring/testContext-infrastructure-jms.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 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 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/META-INF/spring/testContext-infrastructure-jpa.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/META-INF/spring/testContext-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/test-jms.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Redelivery settings 3 | # 4 | # 0: t0 5 | # 1: t0 + 1000ms 6 | # 2: t0 + 3000ms (1000 + 2*1000) 7 | # 8 | jms.initialRedeliveryDelay=1000 9 | jms.backOffMultiplier=2.0 10 | jms.maximumRedeliveries=2 11 | 12 | jms.expectedTotalRedeliveryTime=3000 -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/test-jpa.properties: -------------------------------------------------------------------------------- 1 | jpa.database=MYSQL 2 | jpa.showSql=false 3 | jpa.generateDdl=true 4 | -------------------------------------------------------------------------------- /example-spring-core/src/test/resources/test-web.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkuthan/example-spring/02dddda08af40f2a33b2a976c6178e830567cdde/example-spring-core/src/test/resources/test-web.properties -------------------------------------------------------------------------------- /example-spring-deploy/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | example-spring 7 | example 8 | 1.0-SNAPSHOT 9 | .. 10 | 11 | 12 | example-spring-deploy 13 | ${project.artifactId} 14 | war 15 | 16 | 17 | 18 | false 19 | 20 | 21 | 22 | 23 | deploy 24 | 25 | 26 | 27 | environment 28 | 29 | 30 | 31 | 32 | example-spring 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-war-plugin 38 | 39 | 40 | 41 | ${project.groupId} 42 | example-spring-core 43 | 44 | 45 | ${project.groupId} 46 | example-spring-ui 47 | 48 | 49 | 50 | 51 | 52 | 53 | com.cloudbees 54 | bees-maven-plugin 55 | 1.3.2 56 | 57 | mkuthan/example-spring 58 | ${environment} 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | ${project.groupId} 67 | example-spring-core 68 | ${project.version} 69 | war 70 | runtime 71 | 72 | 73 | 74 | ${project.groupId} 75 | example-spring-ui 76 | ${project.version} 77 | war 78 | runtime 79 | 80 | 81 | 82 | 83 | javax.servlet 84 | jstl 85 | 1.2 86 | 87 | 88 | 89 | 90 | 91 | env-dev 92 | 93 | 94 | 95 | environment 96 | dev 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /example-spring-deploy/src/main/webapp/WEB-INF/cloudbees-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | mkuthan/example-spring-dev 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example-spring-test/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | example-spring 7 | example 8 | 1.0-SNAPSHOT 9 | .. 10 | 11 | 12 | example-spring-test 13 | ${project.artifactId} 14 | jar 15 | 16 | 17 | 18 | acceptance-tests 19 | 20 | 21 | 22 | 23 | src/main/resources 24 | true 25 | 26 | **/*.properties 27 | 28 | 29 | 30 | src/main/resources 31 | false 32 | 33 | **/*.properties 34 | 35 | 36 | 37 | 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-surefire-plugin 42 | 43 | ${basedir}/src/main/java/ 44 | ${project.build.directory}/classes/ 45 | 46 | **/*Story.java 47 | 48 | 49 | 50 | 51 | 52 | org.jbehave 53 | jbehave-maven-plugin 54 | ${jbehave.version} 55 | 56 | 57 | unpack-view-resources 58 | generate-resources 59 | 60 | unpack-view-resources 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | org.eclipse.m2e 71 | lifecycle-mapping 72 | 1.0.0 73 | 74 | 75 | 76 | 77 | 78 | org.jbehave 79 | jbehave-maven-plugin 80 | [3.7,) 81 | 82 | unpack-view-resources 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | ${project.groupId} 102 | example-spring-core 103 | ${project.version} 104 | ${example.webClassifier} 105 | 106 | 107 | 108 | org.springframework 109 | spring-test 110 | ${spring.version} 111 | 112 | 113 | 114 | com.h2database 115 | h2 116 | ${h2.version} 117 | 118 | 119 | 120 | org.jbehave 121 | jbehave-core 122 | ${jbehave.version} 123 | 124 | 125 | 126 | org.jbehave 127 | jbehave-spring 128 | ${jbehave.version} 129 | 130 | 131 | 132 | org.jbehave.site 133 | jbehave-site-resources 134 | 3.1.1 135 | zip 136 | 137 | 138 | 139 | org.jbehave 140 | jbehave-core 141 | ${jbehave.version} 142 | resources 143 | zip 144 | 145 | 146 | -------------------------------------------------------------------------------- /example-spring-test/src/main/java/example/acceptance/steps/Steps.java: -------------------------------------------------------------------------------- 1 | package example.acceptance.steps; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | import org.springframework.stereotype.Component; 10 | 11 | @Target(value = ElementType.TYPE) 12 | @Retention(value = RetentionPolicy.RUNTIME) 13 | @Documented 14 | @Component 15 | public @interface Steps { 16 | 17 | } -------------------------------------------------------------------------------- /example-spring-test/src/main/java/example/acceptance/steps/TodoSteps.java: -------------------------------------------------------------------------------- 1 | package example.acceptance.steps; 2 | 3 | import org.jbehave.core.annotations.Given; 4 | import org.jbehave.core.annotations.Then; 5 | import org.jbehave.core.annotations.When; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | 8 | import example.domain.todo.domain.TodoRepository; 9 | 10 | @Steps 11 | public class TodoSteps { 12 | 13 | @Autowired 14 | private TodoRepository todoRepository; 15 | 16 | @Given("a stock of symbol $symbol and a threshold of $threshold") 17 | public void aStock(String symbol, double threshold) { 18 | todoRepository.findOne(-1L); 19 | } 20 | 21 | @When("the stock is traded at $price") 22 | public void theStockIsTradedAt(double price) { 23 | } 24 | 25 | @Then("the alert status should be $status") 26 | public void theAlertStatusShouldBe(String status) { 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /example-spring-test/src/main/java/example/acceptance/stories/AbstractSpringJBehaveStory.java: -------------------------------------------------------------------------------- 1 | package example.acceptance.stories; 2 | 3 | import static org.jbehave.core.reporters.Format.HTML; 4 | import static org.jbehave.core.reporters.Format.IDE_CONSOLE; 5 | import static org.jbehave.core.reporters.Format.TXT; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | import org.jbehave.core.configuration.Configuration; 11 | import org.jbehave.core.embedder.Embedder; 12 | import org.jbehave.core.embedder.EmbedderControls; 13 | import org.jbehave.core.io.CodeLocations; 14 | import org.jbehave.core.io.LoadFromClasspath; 15 | import org.jbehave.core.io.StoryLoader; 16 | import org.jbehave.core.io.StoryPathResolver; 17 | import org.jbehave.core.io.UnderscoredCamelCaseResolver; 18 | import org.jbehave.core.junit.JUnitStory; 19 | import org.jbehave.core.reporters.CrossReference; 20 | import org.jbehave.core.reporters.FilePrintStreamFactory.ResolveToPackagedName; 21 | import org.jbehave.core.reporters.StoryReporterBuilder; 22 | import org.jbehave.core.steps.CandidateSteps; 23 | import org.jbehave.core.steps.spring.SpringStepsFactory; 24 | import org.junit.runner.RunWith; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.context.ApplicationContext; 27 | import org.springframework.context.ApplicationContextAware; 28 | import org.springframework.test.context.ActiveProfiles; 29 | import org.springframework.test.context.ContextConfiguration; 30 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 31 | 32 | @RunWith(SpringJUnit4ClassRunner.class) 33 | @ContextConfiguration(locations = { "classpath:/META-INF/spring/storiesContext.xml" }) 34 | @ActiveProfiles("test") 35 | public abstract class AbstractSpringJBehaveStory extends JUnitStory implements ApplicationContextAware { 36 | 37 | private static final int STORY_TIMEOUT = 120; 38 | 39 | @Autowired 40 | private ApplicationContext applicationContext; 41 | 42 | private CrossReference xref = new CrossReference(); 43 | 44 | public AbstractSpringJBehaveStory() { 45 | Embedder embedder = new Embedder(); 46 | embedder.useEmbedderControls(embedderControls()); 47 | embedder.useMetaFilters(Arrays.asList("-skip")); 48 | useEmbedder(embedder); 49 | } 50 | 51 | public final void setApplicationContext(ApplicationContext applicationContext) { 52 | this.applicationContext = applicationContext; 53 | } 54 | 55 | @Override 56 | public Configuration configuration() { 57 | return super.configuration().useStoryPathResolver(storyPathResolver()).useStoryLoader(storyLoader()) 58 | .useStoryReporterBuilder(storyReporterBuilder()).useStepMonitor(xref.getStepMonitor()); 59 | } 60 | 61 | @Override 62 | public List candidateSteps() { 63 | return new SpringStepsFactory(configuration(), applicationContext).createCandidateSteps(); 64 | } 65 | 66 | private EmbedderControls embedderControls() { 67 | return new EmbedderControls().doIgnoreFailureInView(true).useStoryTimeoutInSecs(STORY_TIMEOUT); 68 | } 69 | 70 | private StoryPathResolver storyPathResolver() { 71 | return new UnderscoredCamelCaseResolver(); 72 | } 73 | 74 | private StoryLoader storyLoader() { 75 | return new LoadFromClasspath(); 76 | } 77 | 78 | private StoryReporterBuilder storyReporterBuilder() { 79 | return new StoryReporterBuilder().withCodeLocation(CodeLocations.codeLocationFromClass(this.getClass())) 80 | .withPathResolver(new ResolveToPackagedName()).withFailureTrace(true).withFailureTraceCompression(true) 81 | .withDefaultFormats().withFormats(IDE_CONSOLE, TXT, HTML).withCrossReference(xref); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /example-spring-test/src/main/java/example/acceptance/stories/TodoStory.java: -------------------------------------------------------------------------------- 1 | package example.acceptance.stories; 2 | 3 | public class TodoStory extends AbstractSpringJBehaveStory { 4 | } 5 | -------------------------------------------------------------------------------- /example-spring-test/src/main/resources/META-INF/spring/storiesContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example-spring-test/src/main/resources/example/acceptance/stories/todo_story.story: -------------------------------------------------------------------------------- 1 | A story is a collection of scenarios 2 | 3 | Meta: 4 | @author Marcin Kuthan 5 | 6 | Narrative: 7 | In order to to communicate effectively to the business some functionality 8 | As a development team 9 | I want to use Behaviour-Driven Development 10 | 11 | Scenario: A scenario is a collection of executable steps of different type 12 | 13 | Given step represents a precondition to an event 14 | When step represents the occurrence of the event 15 | Then step represents the outcome of the event 16 | 17 | Scenario: Another scenario exploring different combination of events 18 | 19 | Given a [precondition] 20 | When a negative event occurs 21 | Then a the outcome should [be-captured] 22 | 23 | Examples: 24 | |precondition|be-captured| 25 | |abc|be captured | 26 | |xyz|not be captured| 27 | -------------------------------------------------------------------------------- /example-spring-test/src/main/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example-spring-ui/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /example-spring-ui/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /example-spring-ui/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /example-spring-ui/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .tmp 4 | .sass-cache 5 | app/bower_components 6 | -------------------------------------------------------------------------------- /example-spring-ui/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "globals": { 22 | "angular": false 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /example-spring-ui/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.8' 4 | - '0.10' 5 | before_script: 6 | - 'npm install -g bower grunt-cli' 7 | - 'bower install' 8 | -------------------------------------------------------------------------------- /example-spring-ui/app/.buildignore: -------------------------------------------------------------------------------- 1 | *.coffee -------------------------------------------------------------------------------- /example-spring-ui/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkuthan/example-spring/02dddda08af40f2a33b2a976c6178e830567cdde/example-spring-ui/app/favicon.ico -------------------------------------------------------------------------------- /example-spring-ui/app/images/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkuthan/example-spring/02dddda08af40f2a33b2a976c6178e830567cdde/example-spring-ui/app/images/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /example-spring-ui/app/images/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkuthan/example-spring/02dddda08af40f2a33b2a976c6178e830567cdde/example-spring-ui/app/images/glyphicons-halflings.png -------------------------------------------------------------------------------- /example-spring-ui/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 27 | 28 | 29 |
30 | 31 | 32 | 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 | -------------------------------------------------------------------------------- /example-spring-ui/app/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /example-spring-ui/app/scripts/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ExampleSpringApp', ['ngResource']) 4 | .config(function ($routeProvider) { 5 | $routeProvider 6 | .when('/', { 7 | templateUrl: 'views/main.html', 8 | controller: 'MainCtrl' 9 | }) 10 | .when('/todo', { 11 | templateUrl: 'views/todo.html', 12 | controller: 'TodoCtrl' 13 | }) 14 | .otherwise({ 15 | redirectTo: '/' 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /example-spring-ui/app/scripts/controllers/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ExampleSpringApp') 4 | .controller('MainCtrl', function ($scope) { 5 | $scope.awesomeThings = [ 6 | 'HTML5 Boilerplate', 7 | 'AngularJS', 8 | 'Karma' 9 | ]; 10 | }); 11 | -------------------------------------------------------------------------------- /example-spring-ui/app/scripts/controllers/todo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ExampleSpringApp').controller('TodoCtrl', [ '$scope', 'Todos', function($scope, Todos) { 4 | $scope.todos = Todos.query(); 5 | 6 | $scope.addTodo = function() { 7 | $scope.todos.push($scope.todo); 8 | $scope.todo = ''; 9 | }; 10 | 11 | $scope.done = function(index) { 12 | $scope.todos.splice(index, 1); 13 | }; 14 | 15 | $scope.remove = function(index) { 16 | $scope.todos.splice(index, 1); 17 | }; 18 | } ]); 19 | -------------------------------------------------------------------------------- /example-spring-ui/app/scripts/services/todo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('ExampleSpringApp').factory('Todos', [ '$resource', function($resource) { 4 | return $resource('/api/todos/:todoId', { 5 | todoId : '@id' 6 | }, { 7 | done : { 8 | method : 'PUT' 9 | }, 10 | isArray : false 11 | }); 12 | } ]); 13 | -------------------------------------------------------------------------------- /example-spring-ui/app/styles/main.scss: -------------------------------------------------------------------------------- 1 | $iconSpritePath: "../images/glyphicons-halflings.png"; 2 | $iconWhiteSpritePath: "../images/glyphicons-halflings-white.png"; 3 | 4 | @import "bootstrap-sass/lib/bootstrap"; 5 | 6 | /* Put your CSS here */ 7 | html, body { 8 | margin: 20px; 9 | } 10 | 11 | body { 12 | background: #fafafa; 13 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 14 | color: #333; 15 | } 16 | 17 | .hero-unit { 18 | margin: 50px auto 0 auto; 19 | width: 300px; 20 | font-size: 18px; 21 | font-weight: 200; 22 | line-height: 30px; 23 | background-color: #eee; 24 | border-radius: 6px; 25 | padding: 60px; 26 | } 27 | 28 | .hero-unit h1 { 29 | font-size: 60px; 30 | line-height: 1; 31 | letter-spacing: -1px; 32 | } 33 | -------------------------------------------------------------------------------- /example-spring-ui/app/views/main.html: -------------------------------------------------------------------------------- 1 |
2 |

'Allo, 'Allo!

3 |

You now have

4 |
    5 |
  • {{thing}}
  • 6 |
7 |

installed.

8 |

Enjoy coding! - Yeoman

9 |
10 | -------------------------------------------------------------------------------- /example-spring-ui/app/views/todo.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

My Todos

4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 | 18 |
19 |
20 |
-------------------------------------------------------------------------------- /example-spring-ui/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ExampleSpring", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "angular": "~1.0.7", 6 | "json3": "~3.2.4", 7 | "jquery": "~1.9.1", 8 | "bootstrap-sass": "~2.3.1", 9 | "es5-shim": "~2.0.8", 10 | "angular-resource": "~1.0.7", 11 | "angular-cookies": "~1.0.7", 12 | "angular-sanitize": "~1.0.7" 13 | }, 14 | "devDependencies": { 15 | "angular-mocks": "~1.0.7", 16 | "angular-scenario": "~1.0.7" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example-spring-ui/karma-e2e.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // http://karma-runner.github.io/0.10/config/configuration-file.html 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | // base path, that will be used to resolve files and exclude 7 | basePath: '', 8 | 9 | // testing framework to use (jasmine/mocha/qunit/...) 10 | frameworks: ['ng-scenario'], 11 | 12 | // list of files / patterns to load in the browser 13 | files: [ 14 | 'test/e2e/**/*.js' 15 | ], 16 | 17 | // list of files / patterns to exclude 18 | exclude: [], 19 | 20 | // web server port 21 | port: 8080, 22 | 23 | // level of logging 24 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 25 | logLevel: config.LOG_INFO, 26 | 27 | 28 | // enable / disable watching file and executing tests whenever any file changes 29 | autoWatch: false, 30 | 31 | 32 | // Start these browsers, currently available: 33 | // - Chrome 34 | // - ChromeCanary 35 | // - Firefox 36 | // - Opera 37 | // - Safari (only Mac) 38 | // - PhantomJS 39 | // - IE (only Windows) 40 | browsers: ['Chrome'], 41 | 42 | 43 | // Continuous Integration mode 44 | // if true, it capture browsers, run tests and exit 45 | singleRun: false, 46 | 47 | proxies: { 48 | '/': 'http://localhost:9000/' 49 | }, 50 | // URL root prevent conflicts with the site root 51 | urlRoot: '_karma_', 52 | }); 53 | }; 54 | -------------------------------------------------------------------------------- /example-spring-ui/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // http://karma-runner.github.io/0.10/config/configuration-file.html 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | // base path, that will be used to resolve files and exclude 7 | basePath: '', 8 | 9 | // testing framework to use (jasmine/mocha/qunit/...) 10 | frameworks: ['jasmine'], 11 | 12 | // list of files / patterns to load in the browser 13 | files: [ 14 | 'app/bower_components/angular/angular.js', 15 | 'app/bower_components/angular-*/*.js', 16 | 'app/scripts/*.js', 17 | 'app/scripts/**/*.js', 18 | 'test/mock/**/*.js', 19 | 'test/spec/**/*.js' 20 | ], 21 | 22 | // list of files / patterns to exclude 23 | exclude: [], 24 | 25 | // web server port 26 | port: 8080, 27 | 28 | // level of logging 29 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 30 | logLevel: config.LOG_INFO, 31 | 32 | 33 | // enable / disable watching file and executing tests whenever any file changes 34 | autoWatch: false, 35 | 36 | 37 | // Start these browsers, currently available: 38 | // - Chrome 39 | // - ChromeCanary 40 | // - Firefox 41 | // - Opera 42 | // - Safari (only Mac) 43 | // - PhantomJS 44 | // - IE (only Windows) 45 | browsers: ['PhantomJS'], 46 | 47 | 48 | // Continuous Integration mode 49 | // if true, it capture browsers, run tests and exit 50 | singleRun: false 51 | }); 52 | }; 53 | -------------------------------------------------------------------------------- /example-spring-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-spring", 3 | "version": "0.0.0", 4 | "dependencies": {}, 5 | "devDependencies": { 6 | "grunt": "~0.4.1", 7 | "grunt-contrib-copy": "~0.4.1", 8 | "grunt-contrib-concat": "~0.3.0", 9 | "grunt-contrib-coffee": "~0.7.0", 10 | "grunt-contrib-uglify": "~0.2.0", 11 | "grunt-contrib-compass": "~0.5.0", 12 | "grunt-contrib-jshint": "~0.6.0", 13 | "grunt-contrib-cssmin": "~0.6.0", 14 | "grunt-contrib-connect": "~0.3.0", 15 | "grunt-contrib-clean": "~0.5.0", 16 | "grunt-contrib-htmlmin": "~0.1.3", 17 | "grunt-contrib-imagemin": "~0.2.0", 18 | "grunt-contrib-watch": "~0.5.2", 19 | "grunt-autoprefixer": "~0.2.0", 20 | "grunt-usemin": "~0.1.11", 21 | "grunt-svgmin": "~0.2.0", 22 | "grunt-rev": "~0.1.0", 23 | "grunt-open": "~0.2.0", 24 | "grunt-concurrent": "~0.3.0", 25 | "load-grunt-tasks": "~0.1.0", 26 | "connect-livereload": "~0.2.0", 27 | "grunt-google-cdn": "~0.2.0", 28 | "grunt-ngmin": "~0.0.2", 29 | "time-grunt": "~0.1.0", 30 | "karma-ng-scenario": "~0.1.0", 31 | "grunt-karma": "~0.6.2", 32 | "karma-script-launcher": "~0.1.0", 33 | "karma-chrome-launcher": "~0.1.0", 34 | "karma-firefox-launcher": "~0.1.0", 35 | "karma-html2js-preprocessor": "~0.1.0", 36 | "karma-jasmine": "~0.1.3", 37 | "karma-requirejs": "~0.1.0", 38 | "karma-phantomjs-launcher": "~0.1.0", 39 | "karma-coffee-preprocessor": "~0.1.0", 40 | "karma": "~0.10.2", 41 | "karma-ng-html2js-preprocessor": "~0.1.0", 42 | "grunt-connect-proxy": "~0.1.5" 43 | }, 44 | "engines": { 45 | "node": ">=0.8.0" 46 | }, 47 | "scripts": { 48 | "test": "grunt test" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /example-spring-ui/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | example 7 | example-spring 8 | 1.0-SNAPSHOT 9 | .. 10 | 11 | 12 | example-spring-ui 13 | ${project.artifactId} 14 | war 15 | 16 | 17 | false 18 | 19 | 20 | 21 | 22 | 23 | com.github.trecloux 24 | yeoman-maven-plugin 25 | 0.1 26 | 27 | ${basedir} 28 | 29 | 30 | 31 | 32 | build 33 | 34 | 35 | 36 | 37 | 38 | 39 | maven-clean-plugin 40 | 41 | 42 | 43 | ${basedir}/app/bower_components 44 | 45 | 46 | ${basedir}/dist 47 | 48 | 49 | ${basedir}/node_modules 50 | 51 | 52 | 53 | 54 | 55 | 56 | maven-war-plugin 57 | 58 | 59 | 60 | ${basedir}/dist 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /example-spring-ui/test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "globals": { 22 | "after": false, 23 | "afterEach": false, 24 | "angular": false, 25 | "before": false, 26 | "beforeEach": false, 27 | "browser": false, 28 | "describe": false, 29 | "expect": false, 30 | "inject": false, 31 | "it": false, 32 | "spyOn": false 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /example-spring-ui/test/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | End2end Test Runner 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example-spring-ui/test/spec/controllers/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: MainCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('ExampleSpringApp')); 7 | 8 | var MainCtrl, 9 | scope; 10 | 11 | // Initialize the controller and a mock scope 12 | beforeEach(inject(function ($controller, $rootScope) { 13 | scope = $rootScope.$new(); 14 | MainCtrl = $controller('MainCtrl', { 15 | $scope: scope 16 | }); 17 | })); 18 | 19 | it('should attach a list of awesomeThings to the scope', function () { 20 | expect(scope.awesomeThings.length).toBe(3); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /example-spring-ui/test/spec/controllers/todo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: TodoCtrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('ExampleSpringApp')); 7 | 8 | var TodoCtrl, 9 | scope; 10 | 11 | // Initialize the controller and a mock scope 12 | beforeEach(inject(function ($controller, $rootScope) { 13 | scope = $rootScope.$new(); 14 | TodoCtrl = $controller('TodoCtrl', { 15 | $scope: scope 16 | }); 17 | })); 18 | 19 | it('should attach a list of awesomeThings to the scope', function () { 20 | expect(scope.todos.length).toBe(3); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /example-spring-ui/test/spec/services/todo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Service: todo', function () { 4 | 5 | // load the service's module 6 | beforeEach(module('ExampleSpringApp')); 7 | 8 | // instantiate service 9 | var todo; 10 | beforeEach(inject(function (_todo_) { 11 | todo = _todo_; 12 | })); 13 | 14 | it('should do something', function () { 15 | expect(!!todo).toBe(true); 16 | }); 17 | 18 | }); 19 | --------------------------------------------------------------------------------