diff --git a/.gitignore b/.gitignore
index 200bfbe2..a9e7e666 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@ Thumbs.db
.project
.classpath
.idea
+.mvn
*.iml
atlassian-ide-plugin.xml
target
diff --git a/pom.xml b/pom.xml
index 30247811..3bb3de1d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,8 +32,44 @@
org.springframework.boot
spring-boot-starter-web
-
+
+
+ org.springframework.boot
+ spring-boot-devtools
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+
+ org.webjars
+ bootstrap
+ 3.3.5
+
+
+ org.webjars
+ jquery
+ 2.1.4
+
+
+
+
+ org.jasypt
+ jasypt
+ 1.9.2
+
+
+
+
org.springframework.boot
spring-boot-starter-test
test
diff --git a/src/main/java/guru/springframework/SpringmvcApplication.java b/src/main/java/guru/springframework/SpringmvcApplication.java
index b3a27dd9..d73706cb 100644
--- a/src/main/java/guru/springframework/SpringmvcApplication.java
+++ b/src/main/java/guru/springframework/SpringmvcApplication.java
@@ -2,11 +2,18 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class SpringmvcApplication {
public static void main(String[] args) {
- SpringApplication.run(SpringmvcApplication.class, args);
+ ApplicationContext ctx = SpringApplication.run(SpringmvcApplication.class, args);
+
+// for (String name : ctx.getBeanDefinitionNames()){
+// System.out.println(name);
+// }
+// System.out.println("******* Bean Count *******");
+// System.out.println(ctx.getBeanDefinitionCount());
}
}
diff --git a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java
new file mode 100644
index 00000000..91e63c5b
--- /dev/null
+++ b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java
@@ -0,0 +1,191 @@
+package guru.springframework.bootstrap;
+
+import guru.springframework.domain.*;
+import guru.springframework.domain.security.Role;
+import guru.springframework.enums.OrderStatus;
+import guru.springframework.services.ProductService;
+import guru.springframework.services.RoleService;
+import guru.springframework.services.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * Created by jt on 12/9/15.
+ */
+@Component
+public class SpringJPABootstrap implements ApplicationListener{
+
+ private ProductService productService;
+ private UserService userService;
+ private RoleService roleService;
+
+ @Autowired
+ public void setProductService(ProductService productService) {
+ this.productService = productService;
+ }
+
+ @Autowired
+ public void setUserService(UserService userService) {
+ this.userService = userService;
+ }
+
+ @Autowired
+ public void setRoleService(RoleService roleService) {
+ this.roleService = roleService;
+ }
+
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
+ loadProducts();
+ loadUsersAndCustomers();
+ loadCarts();
+ loadOrderHistory();
+ loadRoles();
+ assignUsersToDefaultRole();
+
+ }
+
+ private void assignUsersToDefaultRole() {
+ List roles = (List) roleService.listAll();
+ List users = (List) userService.listAll();
+
+ roles.forEach(role ->{
+ if(role.getRole().equalsIgnoreCase("CUSTOMER")){
+ users.forEach(user -> {
+ user.addRole(role);
+ userService.saveOrUpdate(user);
+ });
+ }
+ });
+ }
+
+ private void loadRoles() {
+ Role role = new Role();
+ role.setRole("CUSTOMER");
+ roleService.saveOrUpdate(role);
+ }
+
+ private void loadOrderHistory() {
+ List users = (List) userService.listAll();
+ List products = (List) productService.listAll();
+
+ users.forEach(user ->{
+ Order order = new Order();
+ order.setCustomer(user.getCustomer());
+ order.setOrderStatus(OrderStatus.SHIPPED);
+
+ products.forEach(product -> {
+ OrderDetail orderDetail = new OrderDetail();
+ orderDetail.setProduct(product);
+ orderDetail.setQuantity(1);
+ order.addToOrderDetails(orderDetail);
+ });
+ });
+ }
+
+ private void loadCarts() {
+ List users = (List) userService.listAll();
+ List products = (List) productService.listAll();
+
+ users.forEach(user -> {
+ user.setCart(new Cart());
+ CartDetail cartDetail = new CartDetail();
+ cartDetail.setProduct(products.get(0));
+ cartDetail.setQuantity(2);
+ user.getCart().addCartDetail(cartDetail);
+ userService.saveOrUpdate(user);
+ });
+ }
+
+ public void loadUsersAndCustomers() {
+ User user1 = new User();
+ user1.setUsername("mweston");
+ user1.setPassword("password");
+
+ Customer customer1 = new Customer();
+ customer1.setFirstName("Micheal");
+ customer1.setLastName("Weston");
+ customer1.setBillingAddress(new Address());
+ customer1.getBillingAddress().setAddressLine1("1 Main St");
+ customer1.getBillingAddress().setCity("Miami");
+ customer1.getBillingAddress().setState("Florida");
+ customer1.getBillingAddress().setZipCode("33101");
+ customer1.setEmail("micheal@burnnotice.com");
+ customer1.setPhoneNumber("305.333.0101");
+ user1.setCustomer(customer1);
+ userService.saveOrUpdate(user1);
+
+ User user2 = new User();
+ user2.setUsername("fglenanne");
+ user2.setPassword("password");
+
+ Customer customer2 = new Customer();
+ customer2.setFirstName("Fiona");
+ customer2.setLastName("Glenanne");
+ customer2.setBillingAddress(new Address());
+ customer2.getBillingAddress().setAddressLine1("1 Key Biscane Ave");
+ customer2.getBillingAddress().setCity("Miami");
+ customer2.getBillingAddress().setState("Florida");
+ customer2.getBillingAddress().setZipCode("33101");
+ customer2.setEmail("fiona@burnnotice.com");
+ customer2.setPhoneNumber("305.323.0233");
+ user2.setCustomer(customer2);
+ userService.saveOrUpdate(user2);
+
+ User user3 = new User();
+ user3.setUsername("saxe");
+ user3.setPassword("password");
+ Customer customer3 = new Customer();
+ customer3.setFirstName("Sam");
+ customer3.setLastName("Axe");
+ customer3.setBillingAddress(new Address());
+ customer3.getBillingAddress().setAddressLine1("1 Little Cuba Road");
+ customer3.getBillingAddress().setCity("Miami");
+ customer3.getBillingAddress().setState("Florida");
+ customer3.getBillingAddress().setZipCode("33101");
+ customer3.setEmail("sam@burnnotice.com");
+ customer3.setPhoneNumber("305.426.9832");
+
+ user3.setCustomer(customer3);
+ userService.saveOrUpdate(user3);
+ }
+
+ public void loadProducts(){
+
+ Product product1 = new Product();
+ product1.setDescription("Product 1");
+ product1.setPrice(new BigDecimal("12.99"));
+ product1.setImageUrl("http://example.com/product1");
+ productService.saveOrUpdate(product1);
+
+ Product product2 = new Product();
+ product2.setDescription("Product 2");
+ product2.setPrice(new BigDecimal("14.99"));
+ product2.setImageUrl("http://example.com/product2");
+ productService.saveOrUpdate(product2);
+
+ Product product3 = new Product();
+ product3.setDescription("Product 3");
+ product3.setPrice(new BigDecimal("34.99"));
+ product3.setImageUrl("http://example.com/product3");
+ productService.saveOrUpdate(product3);
+
+ Product product4 = new Product();
+ product4.setDescription("Product 4");
+ product4.setPrice(new BigDecimal("44.99"));
+ product4.setImageUrl("http://example.com/product4");
+ productService.saveOrUpdate(product4);
+
+ Product product5 = new Product();
+ product5.setDescription("Product 5");
+ product5.setPrice(new BigDecimal("25.99"));
+ product5.setImageUrl("http://example.com/product5");
+ productService.saveOrUpdate(product5);
+
+ }
+}
diff --git a/src/main/java/guru/springframework/config/CommonBeanConfig.java b/src/main/java/guru/springframework/config/CommonBeanConfig.java
new file mode 100644
index 00000000..48912dcb
--- /dev/null
+++ b/src/main/java/guru/springframework/config/CommonBeanConfig.java
@@ -0,0 +1,18 @@
+package guru.springframework.config;
+
+import org.jasypt.util.password.StrongPasswordEncryptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Configuration
+public class CommonBeanConfig {
+
+ @Bean
+ public StrongPasswordEncryptor strongEncryptor(){
+ StrongPasswordEncryptor encryptor = new StrongPasswordEncryptor();
+ return encryptor;
+ }
+}
diff --git a/src/main/java/guru/springframework/controllers/CustomerController.java b/src/main/java/guru/springframework/controllers/CustomerController.java
new file mode 100644
index 00000000..5b835c0c
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/CustomerController.java
@@ -0,0 +1,61 @@
+package guru.springframework.controllers;
+
+import guru.springframework.domain.Customer;
+import guru.springframework.services.CustomerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * Created by jt on 11/15/15.
+ */
+@RequestMapping("/customer")
+@Controller
+public class CustomerController {
+
+ private CustomerService customerService;
+
+ @Autowired
+ public void setCustomerService(CustomerService customerService) {
+ this.customerService = customerService;
+ }
+
+ @RequestMapping({"/list", "/"})
+ public String listCustomers(Model model){
+ model.addAttribute("customers", customerService.listAll());
+ return "customer/list";
+ }
+
+ @RequestMapping("/show/{id}")
+ public String showCustomer(@PathVariable Integer id, Model model){
+ model.addAttribute("customer", customerService.getById(id));
+ return "customer/show";
+ }
+
+ @RequestMapping("/edit/{id}")
+ public String edit(@PathVariable Integer id, Model model){
+ model.addAttribute("customer", customerService.getById(id));
+ return "customer/customerform";
+ }
+
+ @RequestMapping("/new")
+ public String newCustomer(Model model){
+ model.addAttribute("customer", new Customer());
+ return "customer/customerform";
+ }
+
+ @RequestMapping(method = RequestMethod.POST)
+ public String saveOrUpdate(Customer customer){
+ Customer newCustomer = customerService.saveOrUpdate(customer);
+ return "redirect:customer/show/" + newCustomer.getId();
+ }
+
+ @RequestMapping("/delete/{id}")
+ public String delete(@PathVariable Integer id){
+ customerService.delete(id);
+ return "redirect:/customer/list";
+ }
+}
diff --git a/src/main/java/guru/springframework/controllers/IndexController.java b/src/main/java/guru/springframework/controllers/IndexController.java
new file mode 100644
index 00000000..4bbb072b
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/IndexController.java
@@ -0,0 +1,16 @@
+package guru.springframework.controllers;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * Created by jt on 11/6/15.
+ */
+@Controller
+public class IndexController {
+
+ @RequestMapping({"/", ""})
+ public String index(){
+ return "index";
+ }
+}
diff --git a/src/main/java/guru/springframework/controllers/ProductController.java b/src/main/java/guru/springframework/controllers/ProductController.java
new file mode 100644
index 00000000..4c60ff50
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/ProductController.java
@@ -0,0 +1,60 @@
+package guru.springframework.controllers;
+
+import guru.springframework.domain.Product;
+import guru.springframework.services.ProductService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * Created by jt on 11/6/15.
+ */
+@Controller
+public class ProductController {
+
+ private ProductService productService;
+
+ @Autowired
+ public void setProductService(ProductService productService) {
+ this.productService = productService;
+ }
+
+ @RequestMapping("/product/list")
+ public String listProducts(Model model){
+ model.addAttribute("products", productService.listAll());
+ return "product/list";
+ }
+
+ @RequestMapping("/product/show/{id}")
+ public String getProduct(@PathVariable Integer id, Model model){
+ model.addAttribute("product", productService.getById(id));
+ return "product/show";
+ }
+
+ @RequestMapping("product/edit/{id}")
+ public String edit(@PathVariable Integer id, Model model){
+ model.addAttribute("product", productService.getById(id));
+ return "product/productform";
+ }
+
+ @RequestMapping("/product/new")
+ public String newProduct(Model model){
+ model.addAttribute("product", new Product());
+ return "product/productform";
+ }
+
+ @RequestMapping(value = "/product", method = RequestMethod.POST)
+ public String saveOrUpdateProduct(Product product){
+ Product savedProduct = productService.saveOrUpdate(product);
+ return "redirect:/product/show/" + savedProduct.getId();
+ }
+
+ @RequestMapping("/product/delete/{id}")
+ public String delete(@PathVariable Integer id){
+ productService.delete(id);
+ return "redirect:/product/list";
+ }
+}
diff --git a/src/main/java/guru/springframework/controllers/UserController.java b/src/main/java/guru/springframework/controllers/UserController.java
new file mode 100644
index 00000000..4fea3115
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/UserController.java
@@ -0,0 +1,61 @@
+package guru.springframework.controllers;
+
+import guru.springframework.domain.User;
+import guru.springframework.services.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * Created by jt on 12/17/15.
+ */
+@Controller
+@RequestMapping("/user")
+public class UserController {
+
+ private UserService userService;
+
+ @Autowired
+ public void setUserService(UserService userService) {
+ this.userService = userService;
+ }
+
+ @RequestMapping({"/list", "/"})
+ public String listUsers(Model model){
+ model.addAttribute("users", userService.listAll());
+ return "user/list";
+ }
+
+ @RequestMapping("/show/{id}")
+ public String getUser(@PathVariable Integer id, Model model){
+ model.addAttribute("user", userService.getById(id));
+ return "user/show";
+ }
+
+ @RequestMapping("/edit/{id}")
+ public String edit(@PathVariable Integer id, Model model){
+ model.addAttribute("user", userService.getById(id));
+ return "user/userform";
+ }
+
+ @RequestMapping("/new")
+ public String newUser(Model model){
+ model.addAttribute("user", new User());
+ return "user/userform";
+ }
+
+ @RequestMapping(value = "/", method = RequestMethod.POST)
+ public String saveOrUpdate(User user){
+ User savedUser = userService.saveOrUpdate(user);
+ return "redirect:/user/show/" + savedUser.getId();
+ }
+
+ @RequestMapping("/delete/{id}")
+ public String delete(@PathVariable Integer id){
+ userService.delete(id);
+ return "redirect:/user/list";
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/AbstractDomainClass.java b/src/main/java/guru/springframework/domain/AbstractDomainClass.java
new file mode 100644
index 00000000..2497cb1d
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/AbstractDomainClass.java
@@ -0,0 +1,56 @@
+package guru.springframework.domain;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Created by jt on 12/16/15.
+ */
+@MappedSuperclass
+public class AbstractDomainClass implements DomainObject {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ Integer id;
+
+ @Version
+ private Integer version;
+
+ private Date dateCreated;
+ private Date lastUpdated;
+
+ @Override
+ public Integer getId() {
+ return this.id;
+ }
+
+ @Override
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
+
+ public Date getDateCreated() {
+ return dateCreated;
+ }
+
+ public Date getLastUpdated() {
+ return lastUpdated;
+ }
+
+ @PreUpdate
+ @PrePersist
+ public void updateTimeStamps() {
+ lastUpdated = new Date();
+ if (dateCreated==null) {
+ dateCreated = new Date();
+ }
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/Address.java b/src/main/java/guru/springframework/domain/Address.java
new file mode 100644
index 00000000..e8bdb1b0
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/Address.java
@@ -0,0 +1,56 @@
+package guru.springframework.domain;
+
+import javax.persistence.Embeddable;
+
+/**
+ * Created by jt on 12/15/15.
+ */
+@Embeddable
+public class Address {
+
+ private String addressLine1;
+ private String addressLine2;
+ private String city;
+ private String state;
+ private String zipCode;
+
+ public String getAddressLine1() {
+ return addressLine1;
+ }
+
+ public void setAddressLine1(String addressLine1) {
+ this.addressLine1 = addressLine1;
+ }
+
+ public String getAddressLine2() {
+ return addressLine2;
+ }
+
+ public void setAddressLine2(String addressLine2) {
+ this.addressLine2 = addressLine2;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getZipCode() {
+ return zipCode;
+ }
+
+ public void setZipCode(String zipCode) {
+ this.zipCode = zipCode;
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/Cart.java b/src/main/java/guru/springframework/domain/Cart.java
new file mode 100644
index 00000000..7bdca06c
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/Cart.java
@@ -0,0 +1,47 @@
+package guru.springframework.domain;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by jt on 12/15/15.
+ */
+@Entity
+public class Cart extends AbstractDomainClass{
+
+ @OneToOne
+ private User user;
+
+ @OneToMany(cascade = CascadeType.ALL, mappedBy = "cart", orphanRemoval = true)
+ private List cartDetails = new ArrayList<>();
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public List getCartDetails() {
+ return cartDetails;
+ }
+
+ public void setCartDetails(List cartDetails) {
+ this.cartDetails = cartDetails;
+ }
+
+ public void addCartDetail(CartDetail cartDetail){
+ cartDetails.add(cartDetail);
+ cartDetail.setCart(this);
+ }
+
+ public void removeCartDetail(CartDetail cartDetail){
+ cartDetail.setCart(null);
+ this.cartDetails.remove(cartDetail);
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/CartDetail.java b/src/main/java/guru/springframework/domain/CartDetail.java
new file mode 100644
index 00000000..b2c2b310
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/CartDetail.java
@@ -0,0 +1,44 @@
+package guru.springframework.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+
+/**
+ * Created by jt on 12/15/15.
+ */
+@Entity
+public class CartDetail extends AbstractDomainClass {
+
+ @ManyToOne
+ private Cart cart;
+
+ @OneToOne
+ private Product product;
+
+ private Integer quantity;
+
+ public Cart getCart() {
+ return cart;
+ }
+
+ public void setCart(Cart cart) {
+ this.cart = cart;
+ }
+
+ public Product getProduct() {
+ return product;
+ }
+
+ public void setProduct(Product product) {
+ this.product = product;
+ }
+
+ public Integer getQuantity() {
+ return quantity;
+ }
+
+ public void setQuantity(Integer quantity) {
+ this.quantity = quantity;
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/Customer.java b/src/main/java/guru/springframework/domain/Customer.java
new file mode 100644
index 00000000..a077495d
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/Customer.java
@@ -0,0 +1,88 @@
+package guru.springframework.domain;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.OneToOne;
+
+/**
+ * Created by jt on 11/14/15.
+ */
+@Entity
+public class Customer extends AbstractDomainClass {
+
+ private String firstName;
+ private String lastName;
+ private String email;
+ private String phoneNumber;
+
+ @Embedded
+ private Address billingAddress;
+
+ @Embedded
+ private Address shippingAddress;
+
+ @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
+ private User user;
+
+ @Override
+ public Integer getId() {
+ return id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPhoneNumber() {
+ return phoneNumber;
+ }
+
+ public void setPhoneNumber(String phoneNumber) {
+ this.phoneNumber = phoneNumber;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public Address getBillingAddress() {
+ return billingAddress;
+ }
+
+ public void setBillingAddress(Address billingAddress) {
+ this.billingAddress = billingAddress;
+ }
+
+ public Address getShippingAddress() {
+ return shippingAddress;
+ }
+
+ public void setShippingAddress(Address shippingAddress) {
+ this.shippingAddress = shippingAddress;
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/DomainObject.java b/src/main/java/guru/springframework/domain/DomainObject.java
new file mode 100644
index 00000000..5744c4e7
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/DomainObject.java
@@ -0,0 +1,11 @@
+package guru.springframework.domain;
+
+/**
+ * Created by jt on 11/14/15.
+ */
+public interface DomainObject {
+
+ Integer getId();
+
+ void setId(Integer id);
+}
diff --git a/src/main/java/guru/springframework/domain/Order.java b/src/main/java/guru/springframework/domain/Order.java
new file mode 100644
index 00000000..2dffae4e
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/Order.java
@@ -0,0 +1,78 @@
+package guru.springframework.domain;
+
+import guru.springframework.enums.OrderStatus;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by jt on 12/16/15.
+ */
+@Entity
+@Table(name = "ORDER_HEADER")
+public class Order extends AbstractDomainClass {
+
+ @OneToOne
+ private Customer customer;
+
+ @Embedded
+ private Address shipToAddress;
+
+ @OneToMany(cascade = CascadeType.ALL, mappedBy = "order", orphanRemoval = true)
+ private List orderDetails = new ArrayList<>();
+
+ private OrderStatus orderStatus;
+ private Date dateShipped;
+
+ public Customer getCustomer() {
+ return customer;
+ }
+
+ public void setCustomer(Customer customer) {
+ this.customer = customer;
+ }
+
+ public Address getShipToAddress() {
+ return shipToAddress;
+ }
+
+ public void setShipToAddress(Address shipToAddress) {
+ this.shipToAddress = shipToAddress;
+ }
+
+ public List getOrderDetails() {
+ return orderDetails;
+ }
+
+ public void setOrderDetails(List orderDetails) {
+ this.orderDetails = orderDetails;
+ }
+
+ public void addToOrderDetails(OrderDetail orderDetail){
+ orderDetail.setOrder(this);
+ orderDetails.add(orderDetail);
+ }
+
+ public void removeOrderDetail(OrderDetail orderDetail){
+ orderDetail.setOrder(null);
+ orderDetails.remove(orderDetail);
+ }
+
+ public OrderStatus getOrderStatus() {
+ return orderStatus;
+ }
+
+ public void setOrderStatus(OrderStatus orderStatus) {
+ this.orderStatus = orderStatus;
+ }
+
+ public Date getDateShipped() {
+ return dateShipped;
+ }
+
+ public void setDateShipped(Date dateShipped) {
+ this.dateShipped = dateShipped;
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/OrderDetail.java b/src/main/java/guru/springframework/domain/OrderDetail.java
new file mode 100644
index 00000000..e2e71f19
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/OrderDetail.java
@@ -0,0 +1,44 @@
+package guru.springframework.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+
+/**
+ * Created by jt on 12/16/15.
+ */
+@Entity
+public class OrderDetail extends AbstractDomainClass {
+
+ @ManyToOne
+ private Order order;
+
+ @OneToOne
+ private Product product;
+
+ private Integer quantity;
+
+ public Order getOrder() {
+ return order;
+ }
+
+ public void setOrder(Order order) {
+ this.order = order;
+ }
+
+ public Product getProduct() {
+ return product;
+ }
+
+ public void setProduct(Product product) {
+ this.product = product;
+ }
+
+ public Integer getQuantity() {
+ return quantity;
+ }
+
+ public void setQuantity(Integer quantity) {
+ this.quantity = quantity;
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/Product.java b/src/main/java/guru/springframework/domain/Product.java
new file mode 100644
index 00000000..4e6a7a4d
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/Product.java
@@ -0,0 +1,40 @@
+package guru.springframework.domain;
+
+import javax.persistence.Entity;
+import java.math.BigDecimal;
+
+/**
+ * Created by jt on 11/6/15.
+ */
+@Entity
+public class Product extends AbstractDomainClass {
+
+ private String description;
+ private BigDecimal price;
+ private String imageUrl;
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public BigDecimal getPrice() {
+ return price;
+ }
+
+ public void setPrice(BigDecimal price) {
+ this.price = price;
+ }
+
+ public String getImageUrl() {
+ return imageUrl;
+ }
+
+ public void setImageUrl(String imageUrl) {
+ this.imageUrl = imageUrl;
+ }
+
+}
diff --git a/src/main/java/guru/springframework/domain/User.java b/src/main/java/guru/springframework/domain/User.java
new file mode 100644
index 00000000..c4723f0e
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/User.java
@@ -0,0 +1,106 @@
+package guru.springframework.domain;
+
+import guru.springframework.domain.security.Role;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Entity
+public class User extends AbstractDomainClass {
+
+ private String username;
+
+ @Transient
+ private String password;
+
+ private String encryptedPassword;
+ private Boolean enabled = true;
+
+ @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
+ private Customer customer;
+
+ @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
+ private Cart cart;
+
+ @ManyToMany
+ @JoinTable
+ // ~ defaults to @JoinTable(name = "USER_ROLE", joinColumns = @JoinColumn(name = "user_id"),
+ // inverseJoinColumns = @joinColumn(name = "role_id"))
+ private List roles = new ArrayList<>();
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getEncryptedPassword() {
+ return encryptedPassword;
+ }
+
+ public void setEncryptedPassword(String encryptedPassword) {
+ this.encryptedPassword = encryptedPassword;
+ }
+
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public Customer getCustomer() {
+ return customer;
+ }
+
+ public void setCustomer(Customer customer) {
+ this.customer = customer;
+ customer.setUser(this);
+ }
+
+ public Cart getCart() {
+ return cart;
+ }
+
+ public void setCart(Cart cart) {
+ this.cart = cart;
+ }
+
+ public List getRoles() {
+ return roles;
+ }
+
+ public void setRoles(List roles) {
+ this.roles = roles;
+ }
+
+ public void addRole(Role role){
+ if(!this.roles.contains(role)){
+ this.roles.add(role);
+ }
+
+ if(!role.getUsers().contains(this)){
+ role.getUsers().add(this);
+ }
+ }
+
+ public void removeRole(Role role){
+ this.roles.remove(role);
+ role.getUsers().remove(this);
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/security/Role.java b/src/main/java/guru/springframework/domain/security/Role.java
new file mode 100644
index 00000000..33d5df2c
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/security/Role.java
@@ -0,0 +1,57 @@
+package guru.springframework.domain.security;
+
+import guru.springframework.domain.AbstractDomainClass;
+import guru.springframework.domain.User;
+
+import javax.persistence.Entity;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by jt on 12/18/15.
+ */
+@Entity
+public class Role extends AbstractDomainClass {
+
+ private String role;
+
+ @ManyToMany
+ @JoinTable
+ // ~ defaults to @JoinTable(name = "USER_ROLE", joinColumns = @JoinColumn(name = "role_id"),
+ // inverseJoinColumns = @joinColumn(name = "user_id"))
+ private List users = new ArrayList<>();
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public List getUsers() {
+ return users;
+ }
+
+ public void setUsers(List users) {
+ this.users = users;
+ }
+
+ public void addUser(User user){
+ if(!this.users.contains(user)){
+ this.users.add(user);
+ }
+
+ if(!user.getRoles().contains(this)){
+ user.getRoles().add(this);
+ }
+ }
+
+ public void removeUser(User user){
+ this.users.remove(user);
+ user.getRoles().remove(this);
+ }
+
+}
diff --git a/src/main/java/guru/springframework/enums/OrderStatus.java b/src/main/java/guru/springframework/enums/OrderStatus.java
new file mode 100644
index 00000000..3dd3904a
--- /dev/null
+++ b/src/main/java/guru/springframework/enums/OrderStatus.java
@@ -0,0 +1,8 @@
+package guru.springframework.enums;
+
+/**
+ * Created by jt on 12/16/15.
+ */
+public enum OrderStatus {
+ NEW, ALLOCATED, SHIPPED
+}
diff --git a/src/main/java/guru/springframework/services/CRUDService.java b/src/main/java/guru/springframework/services/CRUDService.java
new file mode 100644
index 00000000..7355d122
--- /dev/null
+++ b/src/main/java/guru/springframework/services/CRUDService.java
@@ -0,0 +1,16 @@
+package guru.springframework.services;
+
+import java.util.List;
+
+/**
+ * Created by jt on 11/14/15.
+ */
+public interface CRUDService {
+ List> listAll();
+
+ T getById(Integer id);
+
+ T saveOrUpdate(T domainObject);
+
+ void delete(Integer id);
+}
diff --git a/src/main/java/guru/springframework/services/CustomerService.java b/src/main/java/guru/springframework/services/CustomerService.java
new file mode 100644
index 00000000..441b15bd
--- /dev/null
+++ b/src/main/java/guru/springframework/services/CustomerService.java
@@ -0,0 +1,10 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.Customer;
+
+/**
+ * Created by jt on 11/14/15.
+ */
+public interface CustomerService extends CRUDService{
+
+}
diff --git a/src/main/java/guru/springframework/services/OrderService.java b/src/main/java/guru/springframework/services/OrderService.java
new file mode 100644
index 00000000..54aed9d1
--- /dev/null
+++ b/src/main/java/guru/springframework/services/OrderService.java
@@ -0,0 +1,9 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.Order;
+
+/**
+ * Created by jt on 12/16/15.
+ */
+public interface OrderService extends CRUDService {
+}
diff --git a/src/main/java/guru/springframework/services/ProductService.java b/src/main/java/guru/springframework/services/ProductService.java
new file mode 100644
index 00000000..62a35310
--- /dev/null
+++ b/src/main/java/guru/springframework/services/ProductService.java
@@ -0,0 +1,10 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.Product;
+
+/**
+ * Created by jt on 11/6/15.
+ */
+public interface ProductService extends CRUDService {
+
+}
diff --git a/src/main/java/guru/springframework/services/RoleService.java b/src/main/java/guru/springframework/services/RoleService.java
new file mode 100644
index 00000000..fd05a569
--- /dev/null
+++ b/src/main/java/guru/springframework/services/RoleService.java
@@ -0,0 +1,9 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.security.Role;
+
+/**
+ * Created by jt on 12/18/15.
+ */
+public interface RoleService extends CRUDService {
+}
diff --git a/src/main/java/guru/springframework/services/UserService.java b/src/main/java/guru/springframework/services/UserService.java
new file mode 100644
index 00000000..5ed009a9
--- /dev/null
+++ b/src/main/java/guru/springframework/services/UserService.java
@@ -0,0 +1,10 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.User;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+public interface UserService extends CRUDService {
+
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/AbstractJpaDaoService.java b/src/main/java/guru/springframework/services/jpaservices/AbstractJpaDaoService.java
new file mode 100644
index 00000000..e5396554
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/AbstractJpaDaoService.java
@@ -0,0 +1,17 @@
+package guru.springframework.services.jpaservices;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnit;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+public class AbstractJpaDaoService {
+
+ protected EntityManagerFactory emf;
+
+ @PersistenceUnit
+ public void setEmf(EntityManagerFactory emf) {
+ this.emf = emf;
+ }
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/CustomerServiceJPADaoImpl.java b/src/main/java/guru/springframework/services/jpaservices/CustomerServiceJPADaoImpl.java
new file mode 100644
index 00000000..876957da
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/CustomerServiceJPADaoImpl.java
@@ -0,0 +1,66 @@
+package guru.springframework.services.jpaservices;
+
+import guru.springframework.domain.Customer;
+import guru.springframework.services.CustomerService;
+import guru.springframework.services.security.EncryptionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Service
+@Profile("jpadao")
+public class CustomerServiceJPADaoImpl extends AbstractJpaDaoService implements CustomerService {
+
+ private EncryptionService encryptionService;
+
+ @Autowired
+ public void setEncryptionService(EncryptionService encryptionService) {
+ this.encryptionService = encryptionService;
+ }
+
+ @Override
+ public List listAll() {
+ EntityManager em = emf.createEntityManager();
+
+ return em.createQuery("from Customer", Customer.class).getResultList();
+ }
+
+ @Override
+ public Customer getById(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ return em.find(Customer.class, id);
+ }
+
+ @Override
+ public Customer saveOrUpdate(Customer domainObject) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+
+ if (domainObject.getUser() != null && domainObject.getUser().getPassword() != null) {
+ domainObject.getUser().setEncryptedPassword(
+ encryptionService.encryptString(domainObject.getUser().getPassword()));
+ }
+
+ Customer savedCustomer = em.merge(domainObject);
+ em.getTransaction().commit();
+
+ return savedCustomer;
+ }
+
+ @Override
+ public void delete(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ em.remove(em.find(Customer.class, id));
+ em.getTransaction().commit();
+ }
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/OrderServiceJpaDaoImpl.java b/src/main/java/guru/springframework/services/jpaservices/OrderServiceJpaDaoImpl.java
new file mode 100644
index 00000000..955be282
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/OrderServiceJpaDaoImpl.java
@@ -0,0 +1,51 @@
+package guru.springframework.services.jpaservices;
+
+import guru.springframework.domain.Order;
+import guru.springframework.services.OrderService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+/**
+ * Created by jt on 12/16/15.
+ */
+@Service
+@Profile("jpadao")
+public class OrderServiceJpaDaoImpl extends AbstractJpaDaoService implements OrderService {
+
+ @Override
+ public List listAll() {
+ EntityManager em = emf.createEntityManager();
+
+ return em.createQuery("from Order", Order.class).getResultList();
+ }
+
+ @Override
+ public Order getById(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ return em.find(Order.class, id);
+ }
+
+ @Override
+ public Order saveOrUpdate(Order domainObject) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ Order savedProduct = em.merge(domainObject);
+ em.getTransaction().commit();
+
+ return savedProduct;
+ }
+
+ @Override
+ public void delete(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ em.remove(em.find(Order.class, id));
+ em.getTransaction().commit();
+ }
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/ProductServiceJpaDaoImpl.java b/src/main/java/guru/springframework/services/jpaservices/ProductServiceJpaDaoImpl.java
new file mode 100644
index 00000000..7816288a
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/ProductServiceJpaDaoImpl.java
@@ -0,0 +1,51 @@
+package guru.springframework.services.jpaservices;
+
+import guru.springframework.domain.Product;
+import guru.springframework.services.ProductService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+/**
+ * Created by jt on 12/9/15.
+ */
+@Service
+@Profile("jpadao")
+public class ProductServiceJpaDaoImpl extends AbstractJpaDaoService implements ProductService {
+
+ @Override
+ public List listAll() {
+ EntityManager em = emf.createEntityManager();
+
+ return em.createQuery("from Product", Product.class).getResultList();
+ }
+
+ @Override
+ public Product getById(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ return em.find(Product.class, id);
+ }
+
+ @Override
+ public Product saveOrUpdate(Product domainObject) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ Product savedProduct = em.merge(domainObject);
+ em.getTransaction().commit();
+
+ return savedProduct;
+ }
+
+ @Override
+ public void delete(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ em.remove(em.find(Product.class, id));
+ em.getTransaction().commit();
+ }
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/RoleServiceJpaImpl.java b/src/main/java/guru/springframework/services/jpaservices/RoleServiceJpaImpl.java
new file mode 100644
index 00000000..9e71140e
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/RoleServiceJpaImpl.java
@@ -0,0 +1,51 @@
+package guru.springframework.services.jpaservices;
+
+import guru.springframework.domain.security.Role;
+import guru.springframework.services.RoleService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+/**
+ * Created by jt on 12/18/15.
+ */
+@Service
+@Profile("jpadao")
+public class RoleServiceJpaImpl extends AbstractJpaDaoService implements RoleService {
+
+ @Override
+ public List> listAll() {
+ EntityManager em = emf.createEntityManager();
+
+ return em.createQuery("from Role", Role.class).getResultList();
+ }
+
+ @Override
+ public Role getById(Integer id) {
+ EntityManager em = emf.createEntityManager();
+ return em.find(Role.class, id);
+ }
+
+ @Override
+ public Role saveOrUpdate(Role domainObject) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+
+ Role saveRole = em.merge(domainObject);
+ em.getTransaction().commit();
+
+ return saveRole;
+ }
+
+ @Override
+ public void delete(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ em.remove(em.find(Role.class, id));
+ em.getTransaction().commit();
+ }
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/UserServiceJpaDaoImpl.java b/src/main/java/guru/springframework/services/jpaservices/UserServiceJpaDaoImpl.java
new file mode 100644
index 00000000..e39c1802
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/UserServiceJpaDaoImpl.java
@@ -0,0 +1,65 @@
+package guru.springframework.services.jpaservices;
+
+import guru.springframework.domain.User;
+import guru.springframework.services.UserService;
+import guru.springframework.services.security.EncryptionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Service
+@Profile("jpadao")
+public class UserServiceJpaDaoImpl extends AbstractJpaDaoService implements UserService {
+
+ private EncryptionService encryptionService;
+
+ @Autowired
+ public void setEncryptionService(EncryptionService encryptionService) {
+ this.encryptionService = encryptionService;
+ }
+
+ @Override
+ public List> listAll() {
+ EntityManager em = emf.createEntityManager();
+
+ return em.createQuery("from User", User.class).getResultList();
+ }
+
+ @Override
+ public User getById(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ return em.find(User.class, id);
+ }
+
+ @Override
+ public User saveOrUpdate(User domainObject) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+
+ if(domainObject.getPassword() != null){
+ domainObject.setEncryptedPassword(encryptionService.encryptString(domainObject.getPassword()));
+ }
+
+ User saveduser = em.merge(domainObject);
+ em.getTransaction().commit();
+
+ return saveduser;
+ }
+
+ @Override
+ public void delete(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ em.remove(em.find(User.class, id));
+ em.getTransaction().commit();
+ }
+}
diff --git a/src/main/java/guru/springframework/services/mapservices/AbstractMapService.java b/src/main/java/guru/springframework/services/mapservices/AbstractMapService.java
new file mode 100644
index 00000000..5a4832c7
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/AbstractMapService.java
@@ -0,0 +1,47 @@
+package guru.springframework.services.mapservices;
+
+import guru.springframework.domain.DomainObject;
+
+import java.util.*;
+
+/**
+ * Created by jt on 11/14/15.
+ */
+public abstract class AbstractMapService {
+ protected Map domainMap;
+
+ public AbstractMapService() {
+ domainMap = new HashMap<>();
+ }
+
+ public List listAll() {
+ return new ArrayList<>(domainMap.values());
+ }
+
+ public DomainObject getById(Integer id) {
+ return domainMap.get(id);
+ }
+
+ public DomainObject saveOrUpdate(DomainObject domainObject) {
+ if (domainObject != null){
+
+ if (domainObject.getId() == null){
+ domainObject.setId(getNextKey());
+ }
+ domainMap.put(domainObject.getId(), domainObject);
+
+ return domainObject;
+ } else {
+ throw new RuntimeException("Object Can't be null");
+ }
+ }
+
+ public void delete(Integer id) {
+ domainMap.remove(id);
+ }
+
+ private Integer getNextKey(){
+ return Collections.max(domainMap.keySet()) + 1;
+ }
+
+}
diff --git a/src/main/java/guru/springframework/services/mapservices/CustomerServiceImpl.java b/src/main/java/guru/springframework/services/mapservices/CustomerServiceImpl.java
new file mode 100644
index 00000000..d332373d
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/CustomerServiceImpl.java
@@ -0,0 +1,38 @@
+package guru.springframework.services.mapservices;
+
+import guru.springframework.domain.Customer;
+import guru.springframework.domain.DomainObject;
+import guru.springframework.services.CustomerService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Created by jt on 11/14/15.
+ */
+@Service
+@Profile("map")
+public class CustomerServiceImpl extends AbstractMapService implements CustomerService {
+
+ @Override
+ public List listAll() {
+ return super.listAll();
+ }
+
+ @Override
+ public Customer getById(Integer id) {
+ return (Customer) super.getById(id);
+ }
+
+ @Override
+ public Customer saveOrUpdate(Customer domainObject) {
+ return (Customer) super.saveOrUpdate(domainObject);
+ }
+
+ @Override
+ public void delete(Integer id) {
+ super.delete(id);
+ }
+
+}
diff --git a/src/main/java/guru/springframework/services/mapservices/OrderServiceMapImpl.java b/src/main/java/guru/springframework/services/mapservices/OrderServiceMapImpl.java
new file mode 100644
index 00000000..4aa977b0
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/OrderServiceMapImpl.java
@@ -0,0 +1,36 @@
+package guru.springframework.services.mapservices;
+
+import guru.springframework.domain.DomainObject;
+import guru.springframework.domain.Order;
+import guru.springframework.services.OrderService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Created by jt on 12/16/15.
+ */
+@Service
+@Profile("map")
+public class OrderServiceMapImpl extends AbstractMapService implements OrderService {
+ @Override
+ public List listAll() {
+ return super.listAll();
+ }
+
+ @Override
+ public Order getById(Integer id) {
+ return (Order) super.getById(id);
+ }
+
+ @Override
+ public Order saveOrUpdate(Order domainObject) {
+ return (Order) super.saveOrUpdate(domainObject);
+ }
+
+ @Override
+ public void delete(Integer id) {
+ super.delete(id);
+ }
+}
diff --git a/src/main/java/guru/springframework/services/mapservices/ProductServiceImpl.java b/src/main/java/guru/springframework/services/mapservices/ProductServiceImpl.java
new file mode 100644
index 00000000..cfa76e81
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/ProductServiceImpl.java
@@ -0,0 +1,38 @@
+package guru.springframework.services.mapservices;
+
+import guru.springframework.domain.DomainObject;
+import guru.springframework.domain.Product;
+import guru.springframework.services.ProductService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Created by jt on 11/6/15.
+ */
+@Service
+@Profile("map")
+public class ProductServiceImpl extends AbstractMapService implements ProductService {
+
+ @Override
+ public List listAll() {
+ return super.listAll();
+ }
+
+ @Override
+ public Product getById(Integer id) {
+ return (Product) super.getById(id);
+ }
+
+ @Override
+ public Product saveOrUpdate(Product domainObject) {
+ return (Product) super.saveOrUpdate(domainObject);
+ }
+
+ @Override
+ public void delete(Integer id) {
+ super.delete(id);
+ }
+
+ }
diff --git a/src/main/java/guru/springframework/services/mapservices/RoleServiceMapImpl.java b/src/main/java/guru/springframework/services/mapservices/RoleServiceMapImpl.java
new file mode 100644
index 00000000..2260c649
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/RoleServiceMapImpl.java
@@ -0,0 +1,12 @@
+package guru.springframework.services.mapservices;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+/**
+ * Created by jt on 12/18/15.
+ */
+@Service
+@Profile("map")
+public class RoleServiceMapImpl extends AbstractMapService {
+}
diff --git a/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java b/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java
new file mode 100644
index 00000000..dc67f218
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java
@@ -0,0 +1,37 @@
+package guru.springframework.services.mapservices;
+
+import guru.springframework.domain.DomainObject;
+import guru.springframework.domain.User;
+import guru.springframework.services.UserService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Service
+@Profile("map")
+public class UserServiceMapImpl extends AbstractMapService implements UserService {
+
+ @Override
+ public List listAll() {
+ return super.listAll();
+ }
+
+ @Override
+ public User getById(Integer id) {
+ return (User) super.getById(id);
+ }
+
+ @Override
+ public User saveOrUpdate(User domainObject) {
+ return (User) super.saveOrUpdate(domainObject);
+ }
+
+ @Override
+ public void delete(Integer id) {
+ super.delete(id);
+ }
+}
diff --git a/src/main/java/guru/springframework/services/security/EncryptionService.java b/src/main/java/guru/springframework/services/security/EncryptionService.java
new file mode 100644
index 00000000..33ea850b
--- /dev/null
+++ b/src/main/java/guru/springframework/services/security/EncryptionService.java
@@ -0,0 +1,9 @@
+package guru.springframework.services.security;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+public interface EncryptionService {
+ String encryptString(String input);
+ boolean checkPassword(String plainPassword, String encryptedPassword);
+}
diff --git a/src/main/java/guru/springframework/services/security/EncryptionServiceImpl.java b/src/main/java/guru/springframework/services/security/EncryptionServiceImpl.java
new file mode 100644
index 00000000..acda5997
--- /dev/null
+++ b/src/main/java/guru/springframework/services/security/EncryptionServiceImpl.java
@@ -0,0 +1,27 @@
+package guru.springframework.services.security;
+
+import org.jasypt.util.password.StrongPasswordEncryptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Service
+public class EncryptionServiceImpl implements EncryptionService {
+
+ private StrongPasswordEncryptor strongEncryptor;
+
+ @Autowired
+ public void setStrongEncryptor(StrongPasswordEncryptor strongEncryptor) {
+ this.strongEncryptor = strongEncryptor;
+ }
+
+ public String encryptString(String input){
+ return strongEncryptor.encryptPassword(input);
+ }
+
+ public boolean checkPassword(String plainPassword, String encryptedPassword){
+ return strongEncryptor.checkPassword(plainPassword, encryptedPassword);
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e69de29b..740b550b 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+spring.profiles.active=jpadao
+spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy
\ No newline at end of file
diff --git a/src/main/resources/static/css/spring-core.css b/src/main/resources/static/css/spring-core.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/main/resources/templates/customer/customerform.html b/src/main/resources/templates/customer/customerform.html
new file mode 100644
index 00000000..90314f7b
--- /dev/null
+++ b/src/main/resources/templates/customer/customerform.html
@@ -0,0 +1,86 @@
+
+
+
+ Spring Core Online Tutorial - Customer Form
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/customer/list.html b/src/main/resources/templates/customer/list.html
new file mode 100644
index 00000000..4904641b
--- /dev/null
+++ b/src/main/resources/templates/customer/list.html
@@ -0,0 +1,50 @@
+
+
+
+ Spring Core Online Tutorial - List Customers
+
+
+
+
+
+
+
+
+
+
+
+
Customer List
+
+
+ | Id |
+ First Name |
+ Last Name |
+ Email |
+ Show |
+ Edit |
+ Delete |
+
+
+ |
+ |
+ |
+ |
+ View |
+ Edit |
+ Delete |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/customer/show.html b/src/main/resources/templates/customer/show.html
new file mode 100644
index 00000000..1d9ab89a
--- /dev/null
+++ b/src/main/resources/templates/customer/show.html
@@ -0,0 +1,94 @@
+
+
+
+ Spring Core Online Tutorial - Show Customer
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html
new file mode 100644
index 00000000..18fb0bf3
--- /dev/null
+++ b/src/main/resources/templates/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+ Spring Core Online Tutorial
+
+
+
+
+
+
+
+
+
+
+
Hello World
+
+
This is my Thymeleaf index page.
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/product/list.html b/src/main/resources/templates/product/list.html
new file mode 100644
index 00000000..b7ca555c
--- /dev/null
+++ b/src/main/resources/templates/product/list.html
@@ -0,0 +1,50 @@
+
+
+
+ Spring Core Online Tutorial - List Products
+
+
+
+
+
+
+
+
+
+
+
+
Product List
+
+
+ | Id |
+ Description |
+ Price |
+ Image URL |
+ List |
+ Edit |
+ Delete |
+
+
+ |
+ |
+ |
+ |
+ View |
+ Edit |
+ Delete |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/product/productform.html b/src/main/resources/templates/product/productform.html
new file mode 100644
index 00000000..568517db
--- /dev/null
+++ b/src/main/resources/templates/product/productform.html
@@ -0,0 +1,51 @@
+
+
+
+ Spring Core Online Tutorial - Product Form
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/product/show.html b/src/main/resources/templates/product/show.html
new file mode 100644
index 00000000..069ea3c9
--- /dev/null
+++ b/src/main/resources/templates/product/show.html
@@ -0,0 +1,58 @@
+
+
+
+ Spring Core Online Tutorial - Show Product
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/user/list.html b/src/main/resources/templates/user/list.html
new file mode 100644
index 00000000..2ea615a6
--- /dev/null
+++ b/src/main/resources/templates/user/list.html
@@ -0,0 +1,50 @@
+
+
+
+ Spring Core Online Tutorial - List Users
+
+
+
+
+
+
+
+
+
+
+
+
User List
+
+
+ | Id |
+ User Name |
+ First Name |
+ Last Name |
+ List |
+ Edit |
+ Delete |
+
+
+ |
+ |
+ |
+ |
+ View |
+ Edit |
+ Delete |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/user/show.html b/src/main/resources/templates/user/show.html
new file mode 100644
index 00000000..e2187ef3
--- /dev/null
+++ b/src/main/resources/templates/user/show.html
@@ -0,0 +1,95 @@
+
+
+
+ Spring Core Online Tutorial - Show User
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/user/userform.html b/src/main/resources/templates/user/userform.html
new file mode 100644
index 00000000..c25487ee
--- /dev/null
+++ b/src/main/resources/templates/user/userform.html
@@ -0,0 +1,102 @@
+
+
+
+ Spring Core Online Tutorial - User Form
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/guru/springframework/config/JpaIntegrationConfig.java b/src/test/java/guru/springframework/config/JpaIntegrationConfig.java
new file mode 100644
index 00000000..02ce698a
--- /dev/null
+++ b/src/test/java/guru/springframework/config/JpaIntegrationConfig.java
@@ -0,0 +1,14 @@
+package guru.springframework.config;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Configuration
+@EnableAutoConfiguration
+@ComponentScan("guru.springframework")
+public class JpaIntegrationConfig {
+}
diff --git a/src/test/java/guru/springframework/controllers/CustomerControllerTest.java b/src/test/java/guru/springframework/controllers/CustomerControllerTest.java
new file mode 100644
index 00000000..b2827ae5
--- /dev/null
+++ b/src/test/java/guru/springframework/controllers/CustomerControllerTest.java
@@ -0,0 +1,161 @@
+package guru.springframework.controllers;
+
+import guru.springframework.domain.Address;
+import guru.springframework.domain.Customer;
+import guru.springframework.services.CustomerService;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.*;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.hamcrest.Matchers.*;
+import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+/**
+ * Created by jt on 11/17/15.
+ */
+public class CustomerControllerTest {
+
+ @Mock
+ private CustomerService customerService;
+
+ @InjectMocks
+ private CustomerController customerController;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup(){
+ MockitoAnnotations.initMocks(this);
+
+ mockMvc = MockMvcBuilders.standaloneSetup(customerController).build();
+ }
+
+ @Test
+ public void testList() throws Exception{
+ List customers = new ArrayList<>();
+ customers.add(new Customer());
+ customers.add(new Customer());
+
+ when(customerService.listAll()).thenReturn((List) customers);
+
+ mockMvc.perform(get("/customer/list"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("customer/list"))
+ .andExpect(model().attribute("customers", hasSize(2)));
+ }
+
+ @Test
+ public void testShow() throws Exception {
+ Integer id = 1;
+
+ when(customerService.getById(id)).thenReturn(new Customer());
+
+ mockMvc.perform(get("/customer/show/1"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("customer/show"))
+ .andExpect(model().attribute("customer", instanceOf(Customer.class)));
+ }
+
+ @Test
+ public void testEdit() throws Exception {
+ Integer id = 1;
+
+ when(customerService.getById(id)).thenReturn(new Customer());
+
+ mockMvc.perform(get("/customer/edit/1"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("customer/customerform"))
+ .andExpect(model().attribute("customer", instanceOf(Customer.class)));
+ }
+
+ @Test
+ public void testNewCustomer() throws Exception {
+ verifyZeroInteractions(customerService);
+
+ mockMvc.perform(get("/customer/new"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("customer/customerform"))
+ .andExpect(model().attribute("customer", instanceOf(Customer.class)));
+ }
+
+ @Test
+ public void testSaveOrUpdate() throws Exception {
+ Integer id = 1;
+ Customer returnCustomer = new Customer();
+ String firstName = "Micheal";
+ String lastName = "Weston";
+ String addressLine1 = "1 Main St";
+ String addressLine2 = "Apt 301";
+ String city = "Miami";
+ String state = "Florida";
+ String zipCode = "33101";
+ String email = "micheal@burnnotice.com";
+ String phoneNumber = "305.333.0101";
+
+ returnCustomer.setId(id);
+ returnCustomer.setFirstName(firstName);
+ returnCustomer.setLastName(lastName);
+ returnCustomer.setBillingAddress(new Address());
+ returnCustomer.getBillingAddress().setAddressLine1(addressLine1);
+ returnCustomer.getBillingAddress().setAddressLine2(addressLine2);
+ returnCustomer.getBillingAddress().setCity(city);
+ returnCustomer.getBillingAddress().setState(state);
+ returnCustomer.getBillingAddress().setZipCode(zipCode);
+ returnCustomer.setEmail(email);
+ returnCustomer.setPhoneNumber(phoneNumber);
+
+ when(customerService.saveOrUpdate(Matchers.any())).thenReturn(returnCustomer);
+
+ mockMvc.perform(post("/customer")
+ .param("id", "1")
+ .param("firstName", firstName)
+ .param("lastName", lastName)
+ .param("shippingAddress.addressLine1", addressLine1)
+ .param("shippingAddress.addressLine2", addressLine2)
+ .param("shippingAddress.city", city)
+ .param("shippingAddress.state", state)
+ .param("shippingAddress.zipCode", zipCode)
+ .param("email", email)
+ .param("phoneNumber", phoneNumber))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(view().name("redirect:customer/show/1"))
+ .andExpect(model().attribute("customer", instanceOf(Customer.class)))
+ .andExpect(model().attribute("customer", hasProperty("firstName", is(firstName))))
+ .andExpect(model().attribute("customer", hasProperty("lastName", is(lastName))))
+ .andExpect(model().attribute("customer", hasProperty("shippingAddress", hasProperty("addressLine1", is(addressLine1)))))
+ .andExpect(model().attribute("customer", hasProperty("shippingAddress", hasProperty("addressLine2", is(addressLine2)))))
+ .andExpect(model().attribute("customer", hasProperty("shippingAddress", hasProperty("city", is(city)))))
+ .andExpect(model().attribute("customer", hasProperty("shippingAddress", hasProperty("state", is(state)))))
+ .andExpect(model().attribute("customer", hasProperty("shippingAddress", hasProperty("zipCode", is(zipCode)))))
+ .andExpect(model().attribute("customer", hasProperty("email", is(email))))
+ .andExpect(model().attribute("customer", hasProperty("phoneNumber", is(phoneNumber))));
+
+ ArgumentCaptor customerCaptor = ArgumentCaptor.forClass(Customer.class);
+ verify(customerService).saveOrUpdate(customerCaptor.capture());
+
+ Customer boundCustomer = customerCaptor.getValue();
+
+ assertEquals(id, boundCustomer.getId());
+ assertEquals(firstName, boundCustomer.getFirstName());
+ assertEquals(lastName, boundCustomer.getLastName());
+ assertEquals(addressLine1, boundCustomer.getShippingAddress().getAddressLine1());
+ assertEquals(addressLine2, boundCustomer.getShippingAddress().getAddressLine2());
+ assertEquals(city, boundCustomer.getShippingAddress().getCity());
+ assertEquals(state, boundCustomer.getShippingAddress().getState());
+ assertEquals(zipCode, boundCustomer.getShippingAddress().getZipCode());
+ assertEquals(email, boundCustomer.getEmail());
+ assertEquals(phoneNumber, boundCustomer.getPhoneNumber());
+
+
+ }
+}
diff --git a/src/test/java/guru/springframework/controllers/IndexControllerTest.java b/src/test/java/guru/springframework/controllers/IndexControllerTest.java
new file mode 100644
index 00000000..2ddb1255
--- /dev/null
+++ b/src/test/java/guru/springframework/controllers/IndexControllerTest.java
@@ -0,0 +1,35 @@
+package guru.springframework.controllers;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
+
+/**
+ * Created by jt on 11/16/15.
+ */
+public class IndexControllerTest {
+
+ private MockMvc mockMvc;
+
+ private IndexController indexController;
+
+ @Before
+ public void setup(){
+ indexController = new IndexController();
+ mockMvc = MockMvcBuilders.standaloneSetup(indexController).build();
+
+ }
+
+ @Test
+ public void testIndex() throws Exception{
+ mockMvc.perform(get("/"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("index"));
+ }
+
+}
diff --git a/src/test/java/guru/springframework/controllers/ProductControllerTest.java b/src/test/java/guru/springframework/controllers/ProductControllerTest.java
new file mode 100644
index 00000000..278a96d6
--- /dev/null
+++ b/src/test/java/guru/springframework/controllers/ProductControllerTest.java
@@ -0,0 +1,144 @@
+package guru.springframework.controllers;
+
+import guru.springframework.domain.Product;
+import guru.springframework.services.ProductService;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.*;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+/**
+ * Created by jt on 11/16/15.
+ */
+public class ProductControllerTest {
+
+ @Mock //Mockito Mock object
+ private ProductService productService;
+
+ @InjectMocks //setups up controller, and injects mock objects into it.
+ private ProductController productController;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup(){
+ MockitoAnnotations.initMocks(this); //initilizes controller and mocks
+
+ mockMvc = MockMvcBuilders.standaloneSetup(productController).build();
+ }
+
+ @Test
+ public void testList() throws Exception{
+
+ List products = new ArrayList<>();
+ products.add(new Product());
+ products.add(new Product());
+
+ //specific Mockito interaction, tell stub to return list of products
+ when(productService.listAll()).thenReturn((List) products); //need to strip generics to keep Mockito happy.
+
+ mockMvc.perform(get("/product/list"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("product/list"))
+ .andExpect(model().attribute("products", hasSize(2)));
+ }
+
+ @Test
+ public void testShow() throws Exception{
+ Integer id = 1;
+
+ //Tell Mockito stub to return new product for ID 1
+ when(productService.getById(id)).thenReturn(new Product());
+
+ mockMvc.perform(get("/product/show/1"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("product/show"))
+ .andExpect(model().attribute("product", instanceOf(Product.class)));
+ }
+
+ @Test
+ public void testEdit() throws Exception{
+ Integer id = 1;
+
+ //Tell Mockito stub to return new product for ID 1
+ when(productService.getById(id)).thenReturn(new Product());
+
+ mockMvc.perform(get("/product/edit/1"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("product/productform"))
+ .andExpect(model().attribute("product", instanceOf(Product.class)));
+ }
+
+ @Test
+ public void testNewProduct() throws Exception {
+ Integer id = 1;
+
+ //should not call service
+ verifyZeroInteractions(productService);
+
+ mockMvc.perform(get("/product/new"))
+ .andExpect(status().isOk())
+ .andExpect(view().name("product/productform"))
+ .andExpect(model().attribute("product", instanceOf(Product.class)));
+ }
+
+ @Test
+ public void testSaveOrUpdate() throws Exception {
+ Integer id = 1;
+ String description = "Test Description";
+ BigDecimal price = new BigDecimal("12.00");
+ String imageUrl = "example.com";
+
+ Product returnProduct = new Product();
+ returnProduct.setId(id);
+ returnProduct.setDescription(description);
+ returnProduct.setPrice(price);
+ returnProduct.setImageUrl(imageUrl);
+
+ when(productService.saveOrUpdate(Matchers.any())).thenReturn(returnProduct);
+
+ mockMvc.perform(post("/product")
+ .param("id", "1")
+ .param("description", description)
+ .param("price", "12.00")
+ .param("imageUrl", "example.com"))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(view().name("redirect:/product/show/1"))
+ .andExpect(model().attribute("product", instanceOf(Product.class)))
+ .andExpect(model().attribute("product", hasProperty("id", is(id))))
+ .andExpect(model().attribute("product", hasProperty("description", is(description))))
+ .andExpect(model().attribute("product", hasProperty("price", is(price))))
+ .andExpect(model().attribute("product", hasProperty("imageUrl", is(imageUrl))));
+
+ //verify properties of bound object
+ ArgumentCaptor boundProduct = ArgumentCaptor.forClass(Product.class);
+ verify(productService).saveOrUpdate(boundProduct.capture());
+
+ assertEquals(id, boundProduct.getValue().getId());
+ assertEquals(description, boundProduct.getValue().getDescription());
+ assertEquals(price, boundProduct.getValue().getPrice());
+ assertEquals(imageUrl, boundProduct.getValue().getImageUrl());
+ }
+
+ @Test
+ public void testDelete() throws Exception{
+ Integer id = 1;
+
+ mockMvc.perform(get("/product/delete/1"))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(view().name("redirect:/product/list"));
+
+ verify(productService, times(1)).delete(id);
+ }
+}
diff --git a/src/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java b/src/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java
new file mode 100644
index 00000000..d2201972
--- /dev/null
+++ b/src/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java
@@ -0,0 +1,51 @@
+package guru.springframework.services;
+
+import guru.springframework.config.JpaIntegrationConfig;
+import guru.springframework.domain.Customer;
+import guru.springframework.domain.User;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(JpaIntegrationConfig.class)
+@ActiveProfiles("jpadao")
+public class CustomerServiceJpaDaoImplTest {
+
+ private CustomerService customerService;
+
+ @Autowired
+ public void setCustomerService(CustomerService customerService) {
+ this.customerService = customerService;
+ }
+
+ @Test
+ public void testList() throws Exception {
+ List customers = (List) customerService.listAll();
+
+ assert customers.size() == 3;
+
+ }
+
+ @Test
+ public void testSaveWithUser() {
+
+ Customer customer = new Customer();
+ User user = new User();
+ user.setUsername("This is my user name");
+ user.setPassword("MyAwesomePassword");
+ customer.setUser(user);
+
+ Customer savedCustomer = customerService.saveOrUpdate(customer);
+
+ assert savedCustomer.getUser().getId() != null;
+ }
+}
diff --git a/src/test/java/guru/springframework/services/ProductServiceJpaDaoImplTest.java b/src/test/java/guru/springframework/services/ProductServiceJpaDaoImplTest.java
new file mode 100644
index 00000000..4e8db442
--- /dev/null
+++ b/src/test/java/guru/springframework/services/ProductServiceJpaDaoImplTest.java
@@ -0,0 +1,37 @@
+package guru.springframework.services;
+
+import guru.springframework.config.JpaIntegrationConfig;
+import guru.springframework.domain.Product;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(JpaIntegrationConfig.class)
+@ActiveProfiles("jpadao")
+public class ProductServiceJpaDaoImplTest {
+
+ private ProductService productService;
+
+ @Autowired
+ public void setProductService(ProductService productService) {
+ this.productService = productService;
+ }
+
+ @Test
+ public void testListMethod() throws Exception {
+
+ List products = (List) productService.listAll();
+
+ assert products.size() == 5;
+
+ }
+}
diff --git a/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java b/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java
new file mode 100644
index 00000000..8412ec74
--- /dev/null
+++ b/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java
@@ -0,0 +1,149 @@
+package guru.springframework.services;
+
+import guru.springframework.config.JpaIntegrationConfig;
+import guru.springframework.domain.*;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(JpaIntegrationConfig.class)
+@ActiveProfiles("jpadao")
+public class UserServiceJpaDaoImplTest {
+
+ private UserService userService;
+ private ProductService productService;
+
+ @Autowired
+ public void setUserService(UserService userService) {
+ this.userService = userService;
+ }
+
+ @Autowired
+ public void setProductService(ProductService productService) {
+ this.productService = productService;
+ }
+
+ @Test
+ public void testSaveOfUser() throws Exception {
+ User user = new User();
+
+ user.setUsername("someusername");
+ user.setPassword("myPassword");
+
+ User savedUser = userService.saveOrUpdate(user);
+
+ assert savedUser.getId() != null;
+ assert savedUser.getEncryptedPassword() != null;
+
+ System.out.println("Encrypted Password");
+ System.out.println(savedUser.getEncryptedPassword());
+
+ }
+
+ @Test
+ public void testSaveOfUserWithCustomer() throws Exception {
+
+ User user = new User();
+
+ user.setUsername("someusername");
+ user.setPassword("myPassword");
+
+ Customer customer = new Customer();
+ customer.setFirstName("Chevy");
+ customer.setLastName("Chase");
+
+ user.setCustomer(customer);
+
+ User savedUser = userService.saveOrUpdate(user);
+
+ assert savedUser.getId() != null;
+ assert savedUser.getVersion() != null;
+ assert savedUser.getCustomer() != null;
+ assert savedUser.getCustomer().getId() != null;
+
+ }
+
+ @Test
+ public void testAddCartToUser() throws Exception {
+ User user = new User();
+
+ user.setUsername("someusername");
+ user.setPassword("myPassword");
+
+ user.setCart(new Cart());
+
+ User savedUser = userService.saveOrUpdate(user);
+
+ assert savedUser.getId() != null;
+ assert savedUser.getVersion() != null;
+ assert savedUser.getCart() != null;
+ assert savedUser.getCart().getId() != null;
+ }
+
+ @Test
+ public void testAddCartToUserWithCartDetails() throws Exception {
+ User user = new User();
+
+ user.setUsername("someusername");
+ user.setPassword("myPassword");
+
+ user.setCart(new Cart());
+
+ List storedProducts = (List) productService.listAll();
+
+ CartDetail cartItemOne = new CartDetail();
+ cartItemOne.setProduct(storedProducts.get(0));
+ user.getCart().addCartDetail(cartItemOne);
+
+ CartDetail cartItemTwo = new CartDetail();
+ cartItemTwo.setProduct(storedProducts.get(1));
+ user.getCart().addCartDetail(cartItemTwo);
+
+ User savedUser = userService.saveOrUpdate(user);
+
+ assert savedUser.getId() != null;
+ assert savedUser.getVersion() != null;
+ assert savedUser.getCart() != null;
+ assert savedUser.getCart().getId() != null;
+ assert savedUser.getCart().getCartDetails().size() == 2;
+ }
+
+ @Test
+ public void testAddAndRemoveCartToUserWithCartDetails() throws Exception {
+ User user = new User();
+
+ user.setUsername("someusername");
+ user.setPassword("myPassword");
+
+ user.setCart(new Cart());
+
+ List storedProducts = (List) productService.listAll();
+
+ CartDetail cartItemOne = new CartDetail();
+ cartItemOne.setProduct(storedProducts.get(0));
+ user.getCart().addCartDetail(cartItemOne);
+
+ CartDetail cartItemTwo = new CartDetail();
+ cartItemTwo.setProduct(storedProducts.get(1));
+ user.getCart().addCartDetail(cartItemTwo);
+
+ User savedUser = userService.saveOrUpdate(user);
+
+ assert savedUser.getCart().getCartDetails().size() == 2;
+
+ savedUser.getCart().removeCartDetail(savedUser.getCart().getCartDetails().get(0));
+
+ userService.saveOrUpdate(savedUser);
+
+ assert savedUser.getCart().getCartDetails().size() == 1;
+ }
+}