From 9d664418f18639b5f5455af73d52be6a639c3fd6 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 6 Nov 2015 16:02:39 -0500 Subject: [PATCH 01/31] Added Index Page and controller --- .../controllers/IndexController.java | 16 ++++++++++++++++ src/main/resources/templates/index.html | 13 +++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/main/java/guru/springframework/controllers/IndexController.java create mode 100644 src/main/resources/templates/index.html 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..d8cdf576 --- /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/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 00000000..f5bc0f9f --- /dev/null +++ b/src/main/resources/templates/index.html @@ -0,0 +1,13 @@ + + + + + Spring Core Online Tutorial + + + +

Hello World

+ +

This is my Thymeleaf index page. This is my changed.

+ + \ No newline at end of file From eecfc023334ad012543d08e22cd168720acceb0e Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 6 Nov 2015 16:10:03 -0500 Subject: [PATCH 02/31] Adding .mvn to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) 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 From d806ca99a63066d13016f8de436765f3ed7101c6 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 6 Nov 2015 16:12:38 -0500 Subject: [PATCH 03/31] Added Index Page and controller --- src/main/resources/templates/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index f5bc0f9f..4115bf52 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -1,5 +1,5 @@ - + Spring Core Online Tutorial From ab332736c3284f4aa83b400cb0cf172dd30046d6 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 6 Nov 2015 16:43:09 -0500 Subject: [PATCH 04/31] Added Web Jars --- pom.xml | 12 ++++++++++++ src/main/resources/static/css/spring-core.css | 0 src/main/resources/templates/index.html | 18 ++++++++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/static/css/spring-core.css diff --git a/pom.xml b/pom.xml index f138e8df..563ac6ee 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,18 @@ org.springframework.boot spring-boot-starter-web + + + + org.webjars + bootstrap + 3.3.5 + + + org.webjars + jquery + 2.1.4 + org.springframework.boot 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/index.html b/src/main/resources/templates/index.html index 4115bf52..a2ccb97f 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -4,10 +4,24 @@ Spring Core Online Tutorial + + + + + + -

Hello World

+
+

Hello World

+ +

This is my Thymeleaf index page. This is my changed.

+ +
-

This is my Thymeleaf index page. This is my changed.

\ No newline at end of file From 56f9fd5f33226201a42fd7f0604c5eb5ff56327a Mon Sep 17 00:00:00 2001 From: John Thompson Date: Sat, 7 Nov 2015 12:16:11 -0500 Subject: [PATCH 05/31] Added Product Listing --- .../controllers/ProductController.java | 29 ++++++++ .../guru/springframework/domain/Product.java | 45 ++++++++++++ .../services/ProductService.java | 13 ++++ .../services/ProductServiceImpl.java | 72 +++++++++++++++++++ src/main/resources/templates/products.html | 39 ++++++++++ 5 files changed, 198 insertions(+) create mode 100644 src/main/java/guru/springframework/controllers/ProductController.java create mode 100644 src/main/java/guru/springframework/domain/Product.java create mode 100644 src/main/java/guru/springframework/services/ProductService.java create mode 100644 src/main/java/guru/springframework/services/ProductServiceImpl.java create mode 100644 src/main/resources/templates/products.html 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..1786ba99 --- /dev/null +++ b/src/main/java/guru/springframework/controllers/ProductController.java @@ -0,0 +1,29 @@ +package guru.springframework.controllers; + +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.RequestMapping; + +/** + * Created by jt on 11/6/15. + */ +@Controller +public class ProductController { + + private ProductService productService; + + @Autowired + public void setProductService(ProductService productService) { + this.productService = productService; + } + + @RequestMapping("/products") + public String listProducts(Model model){ + + model.addAttribute("products", productService.listAllProducts()); + + return "products"; + } +} 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..d4bf7f75 --- /dev/null +++ b/src/main/java/guru/springframework/domain/Product.java @@ -0,0 +1,45 @@ +package guru.springframework.domain; + +import java.math.BigDecimal; + +/** + * Created by jt on 11/6/15. + */ +public class Product { + private Integer id; + private String description; + private BigDecimal price; + private String imageUrl; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + 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/services/ProductService.java b/src/main/java/guru/springframework/services/ProductService.java new file mode 100644 index 00000000..1ac18384 --- /dev/null +++ b/src/main/java/guru/springframework/services/ProductService.java @@ -0,0 +1,13 @@ +package guru.springframework.services; + +import guru.springframework.domain.Product; + +import java.util.List; + +/** + * Created by jt on 11/6/15. + */ +public interface ProductService { + + List listAllProducts(); +} diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java new file mode 100644 index 00000000..76ee193a --- /dev/null +++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java @@ -0,0 +1,72 @@ +package guru.springframework.services; + +import guru.springframework.domain.Product; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by jt on 11/6/15. + */ +@Service +public class ProductServiceImpl implements ProductService { + + private Map products; + + public ProductServiceImpl() { + loadProducts(); + } + + @Override + public List listAllProducts() { + return new ArrayList<>(products.values()); + } + + private void loadProducts(){ + products = new HashMap<>(); + + Product product1 = new Product(); + product1.setId(1); + product1.setDescription("Product 1"); + product1.setPrice(new BigDecimal("12.99")); + product1.setImageUrl("http://example.com/product1"); + + products.put(1, product1); + + Product product2 = new Product(); + product2.setId(2); + product2.setDescription("Product 2"); + product2.setPrice(new BigDecimal("14.99")); + product2.setImageUrl("http://example.com/product2"); + + products.put(2, product2); + + Product product3 = new Product(); + product3.setId(3); + product3.setDescription("Product 3"); + product3.setPrice(new BigDecimal("34.99")); + product3.setImageUrl("http://example.com/product3"); + + products.put(3, product3); + + Product product4 = new Product(); + product4.setId(4); + product4.setDescription("Product 4"); + product4.setPrice(new BigDecimal("44.99")); + product4.setImageUrl("http://example.com/product4"); + + products.put(4, product4); + + Product product5 = new Product(); + product5.setId(5); + product5.setDescription("Product 2"); + product5.setPrice(new BigDecimal("25.99")); + product5.setImageUrl("http://example.com/product5"); + + products.put(5, product5); + } +} diff --git a/src/main/resources/templates/products.html b/src/main/resources/templates/products.html new file mode 100644 index 00000000..49e0495c --- /dev/null +++ b/src/main/resources/templates/products.html @@ -0,0 +1,39 @@ + + + + Spring Core Online Tutorial - List Products + + + + + + + + + +
+
+

Product List

+ + + + + + + + + + + + + +
IdDescriptionPriceImage URL
+
+
+ + + \ No newline at end of file From 3e4eebeb845fa1dee7505ac0f149e1198d50fc64 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Mon, 9 Nov 2015 17:09:48 -0500 Subject: [PATCH 06/31] Added Display Product --- .../controllers/ProductController.java | 9 +++ .../services/ProductService.java | 2 + .../services/ProductServiceImpl.java | 5 ++ src/main/resources/templates/product.html | 58 +++++++++++++++++++ src/main/resources/templates/products.html | 2 + 5 files changed, 76 insertions(+) create mode 100644 src/main/resources/templates/product.html diff --git a/src/main/java/guru/springframework/controllers/ProductController.java b/src/main/java/guru/springframework/controllers/ProductController.java index 1786ba99..2168e231 100644 --- a/src/main/java/guru/springframework/controllers/ProductController.java +++ b/src/main/java/guru/springframework/controllers/ProductController.java @@ -4,6 +4,7 @@ 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; /** @@ -26,4 +27,12 @@ public String listProducts(Model model){ return "products"; } + + @RequestMapping("/product/{id}") + public String getProduct(@PathVariable Integer id, Model model){ + + model.addAttribute("product", productService.getProductById(id)); + + return "product"; + } } diff --git a/src/main/java/guru/springframework/services/ProductService.java b/src/main/java/guru/springframework/services/ProductService.java index 1ac18384..db3a69be 100644 --- a/src/main/java/guru/springframework/services/ProductService.java +++ b/src/main/java/guru/springframework/services/ProductService.java @@ -10,4 +10,6 @@ public interface ProductService { List listAllProducts(); + + Product getProductById(Integer id); } diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java index 76ee193a..66d9b757 100644 --- a/src/main/java/guru/springframework/services/ProductServiceImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java @@ -26,6 +26,11 @@ public List listAllProducts() { return new ArrayList<>(products.values()); } + @Override + public Product getProductById(Integer id) { + return products.get(id); + } + private void loadProducts(){ products = new HashMap<>(); diff --git a/src/main/resources/templates/product.html b/src/main/resources/templates/product.html new file mode 100644 index 00000000..e4e19485 --- /dev/null +++ b/src/main/resources/templates/product.html @@ -0,0 +1,58 @@ + + + + Spring Core Online Tutorial - Show Product + + + + + + + + + +
+ +
+
+

Show Product

+
+
+
+
+
+
+ +
+

Product Id

+
+
+
+ +
+

Description

+
+
+
+ +
+

Price

+
+
+
+ +
+

Image

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/products.html b/src/main/resources/templates/products.html index 49e0495c..a27f611b 100644 --- a/src/main/resources/templates/products.html +++ b/src/main/resources/templates/products.html @@ -24,12 +24,14 @@

Product List

Description Price Image URL + List + View From d75c97eb2947fbbc0ae43fc7b836b1ea47f9ff50 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Mon, 9 Nov 2015 17:44:59 -0500 Subject: [PATCH 07/31] Added Create a Product --- .../controllers/ProductController.java | 14 ++++++ .../services/ProductService.java | 2 + .../services/ProductServiceImpl.java | 23 +++++++-- src/main/resources/templates/productform.html | 50 +++++++++++++++++++ src/main/resources/templates/products.html | 5 ++ 5 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/templates/productform.html diff --git a/src/main/java/guru/springframework/controllers/ProductController.java b/src/main/java/guru/springframework/controllers/ProductController.java index 2168e231..9cdda52e 100644 --- a/src/main/java/guru/springframework/controllers/ProductController.java +++ b/src/main/java/guru/springframework/controllers/ProductController.java @@ -1,11 +1,13 @@ 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. @@ -35,4 +37,16 @@ public String getProduct(@PathVariable Integer id, Model model){ return "product"; } + + @RequestMapping("/product/new") + public String newProduct(Model model){ + model.addAttribute("product", new Product()); + return "productform"; + } + + @RequestMapping(value = "/product", method = RequestMethod.POST) + public String saveOrUpdateProduct(Product product){ + Product savedProduct = productService.saveOrUpdateProduct(product); + return "redirect:/product/" + savedProduct.getId(); + } } diff --git a/src/main/java/guru/springframework/services/ProductService.java b/src/main/java/guru/springframework/services/ProductService.java index db3a69be..1abcfd3a 100644 --- a/src/main/java/guru/springframework/services/ProductService.java +++ b/src/main/java/guru/springframework/services/ProductService.java @@ -12,4 +12,6 @@ public interface ProductService { List listAllProducts(); Product getProductById(Integer id); + + Product saveOrUpdateProduct(Product product); } diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java index 66d9b757..393ee674 100644 --- a/src/main/java/guru/springframework/services/ProductServiceImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java @@ -4,10 +4,7 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Created by jt on 11/6/15. @@ -31,6 +28,24 @@ public Product getProductById(Integer id) { return products.get(id); } + @Override + public Product saveOrUpdateProduct(Product product) { + if (product != null){ + if (product.getId() == null){ + product.setId(getNextKey()); + } + products.put(product.getId(), product); + + return product; + } else { + throw new RuntimeException("Product Can't be nill"); + } + } + + private Integer getNextKey(){ + return Collections.max(products.keySet()) + 1; + } + private void loadProducts(){ products = new HashMap<>(); diff --git a/src/main/resources/templates/productform.html b/src/main/resources/templates/productform.html new file mode 100644 index 00000000..1d080fa2 --- /dev/null +++ b/src/main/resources/templates/productform.html @@ -0,0 +1,50 @@ + + + + Spring Core Online Tutorial - Product Form + + + + + + + + + +
+ +

Product Details

+
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/products.html b/src/main/resources/templates/products.html index a27f611b..99c876c2 100644 --- a/src/main/resources/templates/products.html +++ b/src/main/resources/templates/products.html @@ -35,6 +35,11 @@

Product List

+
+ +
From b7b97e900f53bb84f0059fc6dcb70aec48814be5 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Mon, 9 Nov 2015 18:00:46 -0500 Subject: [PATCH 08/31] Added Create a Product --- .../guru/springframework/controllers/ProductController.java | 6 ++++++ src/main/resources/templates/products.html | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/guru/springframework/controllers/ProductController.java b/src/main/java/guru/springframework/controllers/ProductController.java index 9cdda52e..a4ee0ccf 100644 --- a/src/main/java/guru/springframework/controllers/ProductController.java +++ b/src/main/java/guru/springframework/controllers/ProductController.java @@ -38,6 +38,12 @@ public String getProduct(@PathVariable Integer id, Model model){ return "product"; } + @RequestMapping("product/edit/{id}") + public String edit(@PathVariable Integer id, Model model){ + model.addAttribute("product", productService.getProductById(id)); + return "productform"; + } + @RequestMapping("/product/new") public String newProduct(Model model){ model.addAttribute("product", new Product()); diff --git a/src/main/resources/templates/products.html b/src/main/resources/templates/products.html index 99c876c2..6dde5956 100644 --- a/src/main/resources/templates/products.html +++ b/src/main/resources/templates/products.html @@ -25,6 +25,7 @@

Product List

Price Image URL List + Edit @@ -32,6 +33,7 @@

Product List

View + Edit From 8be594aae0328e82c383678ff753ba30edd3880b Mon Sep 17 00:00:00 2001 From: John Thompson Date: Sat, 14 Nov 2015 14:17:50 -0500 Subject: [PATCH 09/31] Added delete a Product --- .../springframework/controllers/ProductController.java | 7 +++++++ .../java/guru/springframework/services/ProductService.java | 2 ++ .../guru/springframework/services/ProductServiceImpl.java | 5 +++++ src/main/resources/templates/products.html | 2 ++ 4 files changed, 16 insertions(+) diff --git a/src/main/java/guru/springframework/controllers/ProductController.java b/src/main/java/guru/springframework/controllers/ProductController.java index a4ee0ccf..f3352969 100644 --- a/src/main/java/guru/springframework/controllers/ProductController.java +++ b/src/main/java/guru/springframework/controllers/ProductController.java @@ -55,4 +55,11 @@ public String saveOrUpdateProduct(Product product){ Product savedProduct = productService.saveOrUpdateProduct(product); return "redirect:/product/" + savedProduct.getId(); } + + @RequestMapping("/product/delete/{id}") + public String delete(@PathVariable Integer id){ + productService.deleteProduct(id); + + return "redirect:/products"; + } } diff --git a/src/main/java/guru/springframework/services/ProductService.java b/src/main/java/guru/springframework/services/ProductService.java index 1abcfd3a..1f049a7e 100644 --- a/src/main/java/guru/springframework/services/ProductService.java +++ b/src/main/java/guru/springframework/services/ProductService.java @@ -14,4 +14,6 @@ public interface ProductService { Product getProductById(Integer id); Product saveOrUpdateProduct(Product product); + + void deleteProduct(Integer id); } diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java index 393ee674..b7fa098a 100644 --- a/src/main/java/guru/springframework/services/ProductServiceImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java @@ -46,6 +46,11 @@ private Integer getNextKey(){ return Collections.max(products.keySet()) + 1; } + @Override + public void deleteProduct(Integer id) { + products.remove(id); + } + private void loadProducts(){ products = new HashMap<>(); diff --git a/src/main/resources/templates/products.html b/src/main/resources/templates/products.html index 6dde5956..64a57a22 100644 --- a/src/main/resources/templates/products.html +++ b/src/main/resources/templates/products.html @@ -26,6 +26,7 @@

Product List

Image URL List Edit + Delete @@ -34,6 +35,7 @@

Product List

View Edit + Delete From c7f19c785c72f3aedde6a04577553d659e51b1fa Mon Sep 17 00:00:00 2001 From: John Thompson Date: Mon, 16 Nov 2015 18:15:54 -0500 Subject: [PATCH 10/31] added customer --- .../controllers/CustomerController.java | 61 +++++++++++ .../controllers/ProductController.java | 31 +++--- .../guru/springframework/domain/Customer.java | 100 ++++++++++++++++++ .../springframework/domain/DomainObject.java | 11 ++ .../guru/springframework/domain/Product.java | 2 +- .../services/AbstractMapService.java | 50 +++++++++ .../springframework/services/CRUDService.java | 16 +++ .../services/CustomerService.java | 10 ++ .../services/CustomerServiceImpl.java | 77 ++++++++++++++ .../services/ProductService.java | 11 +- .../services/ProductServiceImpl.java | 55 ++++------ .../templates/customer/customerform.html | 86 +++++++++++++++ .../resources/templates/customer/list.html | 50 +++++++++ .../resources/templates/customer/show.html | 94 ++++++++++++++++ src/main/resources/templates/index.html | 7 +- .../{products.html => product/list.html} | 4 +- .../templates/{ => product}/productform.html | 2 +- .../{product.html => product/show.html} | 2 +- 18 files changed, 599 insertions(+), 70 deletions(-) create mode 100644 src/main/java/guru/springframework/controllers/CustomerController.java create mode 100644 src/main/java/guru/springframework/domain/Customer.java create mode 100644 src/main/java/guru/springframework/domain/DomainObject.java create mode 100644 src/main/java/guru/springframework/services/AbstractMapService.java create mode 100644 src/main/java/guru/springframework/services/CRUDService.java create mode 100644 src/main/java/guru/springframework/services/CustomerService.java create mode 100644 src/main/java/guru/springframework/services/CustomerServiceImpl.java create mode 100644 src/main/resources/templates/customer/customerform.html create mode 100644 src/main/resources/templates/customer/list.html create mode 100644 src/main/resources/templates/customer/show.html rename src/main/resources/templates/{products.html => product/list.html} (92%) rename src/main/resources/templates/{ => product}/productform.html (97%) rename src/main/resources/templates/{product.html => product/show.html} (97%) 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/ProductController.java b/src/main/java/guru/springframework/controllers/ProductController.java index f3352969..4c60ff50 100644 --- a/src/main/java/guru/springframework/controllers/ProductController.java +++ b/src/main/java/guru/springframework/controllers/ProductController.java @@ -22,44 +22,39 @@ public void setProductService(ProductService productService) { this.productService = productService; } - @RequestMapping("/products") + @RequestMapping("/product/list") public String listProducts(Model model){ - - model.addAttribute("products", productService.listAllProducts()); - - return "products"; + model.addAttribute("products", productService.listAll()); + return "product/list"; } - @RequestMapping("/product/{id}") + @RequestMapping("/product/show/{id}") public String getProduct(@PathVariable Integer id, Model model){ - - model.addAttribute("product", productService.getProductById(id)); - - return "product"; + 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.getProductById(id)); - return "productform"; + model.addAttribute("product", productService.getById(id)); + return "product/productform"; } @RequestMapping("/product/new") public String newProduct(Model model){ model.addAttribute("product", new Product()); - return "productform"; + return "product/productform"; } @RequestMapping(value = "/product", method = RequestMethod.POST) public String saveOrUpdateProduct(Product product){ - Product savedProduct = productService.saveOrUpdateProduct(product); - return "redirect:/product/" + savedProduct.getId(); + Product savedProduct = productService.saveOrUpdate(product); + return "redirect:/product/show/" + savedProduct.getId(); } @RequestMapping("/product/delete/{id}") public String delete(@PathVariable Integer id){ - productService.deleteProduct(id); - - return "redirect:/products"; + productService.delete(id); + return "redirect:/product/list"; } } 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..cd53347e --- /dev/null +++ b/src/main/java/guru/springframework/domain/Customer.java @@ -0,0 +1,100 @@ +package guru.springframework.domain; + +/** + * Created by jt on 11/14/15. + */ +public class Customer implements DomainObject { + + private Integer id; + private String firstName; + private String lastName; + private String email; + private String phoneNumber; + private String addressLine1; + private String addressLine2; + private String city; + private String state; + private String zipCode; + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = 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 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/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/Product.java b/src/main/java/guru/springframework/domain/Product.java index d4bf7f75..79bff2a7 100644 --- a/src/main/java/guru/springframework/domain/Product.java +++ b/src/main/java/guru/springframework/domain/Product.java @@ -5,7 +5,7 @@ /** * Created by jt on 11/6/15. */ -public class Product { +public class Product implements DomainObject{ private Integer id; private String description; private BigDecimal price; diff --git a/src/main/java/guru/springframework/services/AbstractMapService.java b/src/main/java/guru/springframework/services/AbstractMapService.java new file mode 100644 index 00000000..1e21261e --- /dev/null +++ b/src/main/java/guru/springframework/services/AbstractMapService.java @@ -0,0 +1,50 @@ +package guru.springframework.services; + +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<>(); + loadDomainObjects(); + } + + 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; + } + + protected abstract void loadDomainObjects(); + +} 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/CustomerServiceImpl.java b/src/main/java/guru/springframework/services/CustomerServiceImpl.java new file mode 100644 index 00000000..c86adce5 --- /dev/null +++ b/src/main/java/guru/springframework/services/CustomerServiceImpl.java @@ -0,0 +1,77 @@ +package guru.springframework.services; + +import guru.springframework.domain.Customer; +import guru.springframework.domain.DomainObject; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; + +/** + * Created by jt on 11/14/15. + */ +@Service +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); + } + + @Override + protected void loadDomainObjects() { + domainMap = new HashMap<>(); + + Customer customer1 = new Customer(); + customer1.setId(1); + customer1.setFirstName("Micheal"); + customer1.setLastName("Weston"); + customer1.setAddressLine1("1 Main St"); + customer1.setCity("Miami"); + customer1.setState("Florida"); + customer1.setZipCode("33101"); + customer1.setEmail("micheal@burnnotice.com"); + customer1.setPhoneNumber("305.333.0101"); + + Customer customer2 = new Customer(); + customer2.setId(2); + customer2.setFirstName("Fiona"); + customer2.setLastName("Glenanne"); + customer2.setAddressLine1("1 Key Biscane Ave"); + customer2.setCity("Miami"); + customer2.setState("Florida"); + customer2.setZipCode("33101"); + customer2.setEmail("fiona@burnnotice.com"); + customer2.setPhoneNumber("305.323.0233"); + + Customer customer3 = new Customer(); + customer3.setId(3); + customer3.setFirstName("Sam"); + customer3.setLastName("Axe"); + customer3.setAddressLine1("1 Little Cuba Road"); + customer3.setCity("Miami"); + customer3.setState("Florida"); + customer3.setZipCode("33101"); + customer3.setEmail("sam@burnnotice.com"); + customer3.setPhoneNumber("305.426.9832"); + + domainMap.put(1, customer1); + domainMap.put(2, customer2); + domainMap.put(3, customer3); + } +} diff --git a/src/main/java/guru/springframework/services/ProductService.java b/src/main/java/guru/springframework/services/ProductService.java index 1f049a7e..62a35310 100644 --- a/src/main/java/guru/springframework/services/ProductService.java +++ b/src/main/java/guru/springframework/services/ProductService.java @@ -2,18 +2,9 @@ import guru.springframework.domain.Product; -import java.util.List; - /** * Created by jt on 11/6/15. */ -public interface ProductService { - - List listAllProducts(); - - Product getProductById(Integer id); - - Product saveOrUpdateProduct(Product product); +public interface ProductService extends CRUDService { - void deleteProduct(Integer id); } diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java index b7fa098a..1382aad2 100644 --- a/src/main/java/guru/springframework/services/ProductServiceImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java @@ -1,58 +1,41 @@ package guru.springframework.services; +import guru.springframework.domain.DomainObject; import guru.springframework.domain.Product; import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.*; +import java.util.HashMap; +import java.util.List; /** * Created by jt on 11/6/15. */ @Service -public class ProductServiceImpl implements ProductService { - - private Map products; - - public ProductServiceImpl() { - loadProducts(); - } +public class ProductServiceImpl extends AbstractMapService implements ProductService { @Override - public List listAllProducts() { - return new ArrayList<>(products.values()); + public List listAll() { + return super.listAll(); } @Override - public Product getProductById(Integer id) { - return products.get(id); + public Product getById(Integer id) { + return (Product) super.getById(id); } @Override - public Product saveOrUpdateProduct(Product product) { - if (product != null){ - if (product.getId() == null){ - product.setId(getNextKey()); - } - products.put(product.getId(), product); - - return product; - } else { - throw new RuntimeException("Product Can't be nill"); - } - } - - private Integer getNextKey(){ - return Collections.max(products.keySet()) + 1; + public Product saveOrUpdate(Product domainObject) { + return (Product) super.saveOrUpdate(domainObject); } @Override - public void deleteProduct(Integer id) { - products.remove(id); + public void delete(Integer id) { + super.delete(id); } - private void loadProducts(){ - products = new HashMap<>(); + protected void loadDomainObjects(){ + domainMap = new HashMap<>(); Product product1 = new Product(); product1.setId(1); @@ -60,7 +43,7 @@ private void loadProducts(){ product1.setPrice(new BigDecimal("12.99")); product1.setImageUrl("http://example.com/product1"); - products.put(1, product1); + domainMap.put(1, product1); Product product2 = new Product(); product2.setId(2); @@ -68,7 +51,7 @@ private void loadProducts(){ product2.setPrice(new BigDecimal("14.99")); product2.setImageUrl("http://example.com/product2"); - products.put(2, product2); + domainMap.put(2, product2); Product product3 = new Product(); product3.setId(3); @@ -76,7 +59,7 @@ private void loadProducts(){ product3.setPrice(new BigDecimal("34.99")); product3.setImageUrl("http://example.com/product3"); - products.put(3, product3); + domainMap.put(3, product3); Product product4 = new Product(); product4.setId(4); @@ -84,7 +67,7 @@ private void loadProducts(){ product4.setPrice(new BigDecimal("44.99")); product4.setImageUrl("http://example.com/product4"); - products.put(4, product4); + domainMap.put(4, product4); Product product5 = new Product(); product5.setId(5); @@ -92,6 +75,6 @@ private void loadProducts(){ product5.setPrice(new BigDecimal("25.99")); product5.setImageUrl("http://example.com/product5"); - products.put(5, product5); + domainMap.put(5, product5); } } diff --git a/src/main/resources/templates/customer/customerform.html b/src/main/resources/templates/customer/customerform.html new file mode 100644 index 00000000..c3b6fe1a --- /dev/null +++ b/src/main/resources/templates/customer/customerform.html @@ -0,0 +1,86 @@ + + + + Spring Core Online Tutorial - Customer Form + + + + + + + + + +
+ +

Customer Details

+
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+
+
+ + + \ 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

+ + + + + + + + + + + + + + + + + + + +
IdFirst NameLast NameEmailShowEditDelete
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..5dadfa44 --- /dev/null +++ b/src/main/resources/templates/customer/show.html @@ -0,0 +1,94 @@ + + + + Spring Core Online Tutorial - Show Customer + + + + + + + + + +
+ +
+
+

Show Customer

+
+
+
+
+
+
+ +
+

Customer Id

+
+
+
+ +
+

First Name

+
+
+
+ +
+

Last Name

+
+
+
+ +
+

Email

+
+
+
+ +
+

Phone

+
+
+
+ +
+

Address Line 1

+
+
+
+ +
+

Address Line 2

+
+
+
+ +
+

City

+
+
+
+ +
+

State

+
+
+
+ +
+

Zipcode

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index a2ccb97f..9622d970 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -19,7 +19,12 @@

Hello World

-

This is my Thymeleaf index page. This is my changed.

+

This is my Thymeleaf index page.

+ +
diff --git a/src/main/resources/templates/products.html b/src/main/resources/templates/product/list.html similarity index 92% rename from src/main/resources/templates/products.html rename to src/main/resources/templates/product/list.html index 64a57a22..b7ca555c 100644 --- a/src/main/resources/templates/products.html +++ b/src/main/resources/templates/product/list.html @@ -11,7 +11,7 @@ - @@ -33,7 +33,7 @@

Product List

- View + View Edit Delete diff --git a/src/main/resources/templates/productform.html b/src/main/resources/templates/product/productform.html similarity index 97% rename from src/main/resources/templates/productform.html rename to src/main/resources/templates/product/productform.html index 1d080fa2..cd9d9b6e 100644 --- a/src/main/resources/templates/productform.html +++ b/src/main/resources/templates/product/productform.html @@ -11,7 +11,7 @@ - diff --git a/src/main/resources/templates/product.html b/src/main/resources/templates/product/show.html similarity index 97% rename from src/main/resources/templates/product.html rename to src/main/resources/templates/product/show.html index e4e19485..069ea3c9 100644 --- a/src/main/resources/templates/product.html +++ b/src/main/resources/templates/product/show.html @@ -11,7 +11,7 @@ - From af80230d96a41e4d134d77e3b2c16629932c0c69 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Tue, 17 Nov 2015 20:57:18 -0500 Subject: [PATCH 11/31] added spring mvc test examples for index and crud (product only) --- .../controllers/IndexControllerTest.java | 35 +++++ .../controllers/ProductControllerTest.java | 145 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 src/test/java/guru/springframework/controllers/IndexControllerTest.java create mode 100644 src/test/java/guru/springframework/controllers/ProductControllerTest.java 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..a1ee14b1 --- /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("indexdd")); + } + +} 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..42b66bdc --- /dev/null +++ b/src/test/java/guru/springframework/controllers/ProductControllerTest.java @@ -0,0 +1,145 @@ +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); + } +} From 0caaa61e65ada52aa8e40cc7651d84cd91f3c20d Mon Sep 17 00:00:00 2001 From: John Thompson Date: Tue, 17 Nov 2015 22:31:32 -0500 Subject: [PATCH 12/31] added spring mvc test examples for index and crud (product only) --- .../controllers/CustomerControllerTest.java | 159 ++++++++++++++++++ .../controllers/ProductControllerTest.java | 1 - 2 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 src/test/java/guru/springframework/controllers/CustomerControllerTest.java 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..db23e3c3 --- /dev/null +++ b/src/test/java/guru/springframework/controllers/CustomerControllerTest.java @@ -0,0 +1,159 @@ +package guru.springframework.controllers; + +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.setAddressLine1(addressLine1); + returnCustomer.setAddressLine2(addressLine2); + returnCustomer.setCity(city); + returnCustomer.setState(state); + returnCustomer.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("addressLine1", addressLine1) + .param("addressLine2", addressLine2) + .param("city", city) + .param("state", state) + .param("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("addressLine1", is(addressLine1)))) + .andExpect(model().attribute("customer", hasProperty("addressLine2", is(addressLine2)))) + .andExpect(model().attribute("customer", hasProperty("city", is(city)))) + .andExpect(model().attribute("customer", hasProperty("state", is(state)))) + .andExpect(model().attribute("customer", 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.getAddressLine1()); + assertEquals(addressLine2, boundCustomer.getAddressLine2()); + assertEquals(city, boundCustomer.getCity()); + assertEquals(state, boundCustomer.getState()); + assertEquals(zipCode, boundCustomer.getZipCode()); + assertEquals(email, boundCustomer.getEmail()); + assertEquals(phoneNumber, boundCustomer.getPhoneNumber()); + + + } +} diff --git a/src/test/java/guru/springframework/controllers/ProductControllerTest.java b/src/test/java/guru/springframework/controllers/ProductControllerTest.java index 42b66bdc..278a96d6 100644 --- a/src/test/java/guru/springframework/controllers/ProductControllerTest.java +++ b/src/test/java/guru/springframework/controllers/ProductControllerTest.java @@ -52,7 +52,6 @@ public void testList() throws Exception{ .andExpect(status().isOk()) .andExpect(view().name("product/list")) .andExpect(model().attribute("products", hasSize(2))); - } @Test From 5f25fd987a5f4adbcf30f153b717d504f09ffa78 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 20 Nov 2015 17:12:08 -0500 Subject: [PATCH 13/31] fixed URL mapping issue for index --- .../java/guru/springframework/controllers/IndexController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/guru/springframework/controllers/IndexController.java b/src/main/java/guru/springframework/controllers/IndexController.java index d8cdf576..4bbb072b 100644 --- a/src/main/java/guru/springframework/controllers/IndexController.java +++ b/src/main/java/guru/springframework/controllers/IndexController.java @@ -9,7 +9,7 @@ @Controller public class IndexController { - @RequestMapping("/") + @RequestMapping({"/", ""}) public String index(){ return "index"; } From ab7bb066b718f119148a9081a25de9d5f756229d Mon Sep 17 00:00:00 2001 From: John Thompson Date: Tue, 1 Dec 2015 18:53:25 -0500 Subject: [PATCH 14/31] added dev tools --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index dbe4aaf7..b852be04 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,11 @@ spring-boot-starter-web
+ + org.springframework.boot + spring-boot-devtools + + org.webjars From 94d83899ff1ef4ffd60118b3a544ce810d1d36c5 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Wed, 9 Dec 2015 09:38:50 -0500 Subject: [PATCH 15/31] added jars for spring data jpa and h2 --- pom.xml | 11 +++++++++++ .../guru/springframework/SpringmvcApplication.java | 9 ++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b852be04..10d045f8 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,17 @@ spring-boot-devtools + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + runtime + + org.webjars 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()); } } From 171c8f4cdcd9fad76ccfab578074e14448217c0e Mon Sep 17 00:00:00 2001 From: John Thompson Date: Wed, 9 Dec 2015 12:03:17 -0500 Subject: [PATCH 16/31] Converted Product to JPA Entity --- src/main/java/guru/springframework/domain/Product.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/guru/springframework/domain/Product.java b/src/main/java/guru/springframework/domain/Product.java index 79bff2a7..d7726e09 100644 --- a/src/main/java/guru/springframework/domain/Product.java +++ b/src/main/java/guru/springframework/domain/Product.java @@ -1,11 +1,19 @@ package guru.springframework.domain; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; import java.math.BigDecimal; /** * Created by jt on 11/6/15. */ +@Entity public class Product implements DomainObject{ + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String description; private BigDecimal price; From 6ad1014da413fb214119c72218cebbbbfc6b8d5e Mon Sep 17 00:00:00 2001 From: John Thompson Date: Wed, 9 Dec 2015 12:30:47 -0500 Subject: [PATCH 17/31] Converted Product to JPA Entity --- .../guru/springframework/domain/Product.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/guru/springframework/domain/Product.java b/src/main/java/guru/springframework/domain/Product.java index d7726e09..ffadb179 100644 --- a/src/main/java/guru/springframework/domain/Product.java +++ b/src/main/java/guru/springframework/domain/Product.java @@ -1,9 +1,6 @@ package guru.springframework.domain; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import javax.persistence.*; import java.math.BigDecimal; /** @@ -15,6 +12,10 @@ public class Product implements DomainObject{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; + + @Version + private Integer version; + private String description; private BigDecimal price; private String imageUrl; @@ -27,6 +28,14 @@ public void setId(Integer id) { this.id = id; } + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + public String getDescription() { return description; } From 5be187c7c1231e0620c1a0cbd10b9fe2e5b331b6 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Wed, 9 Dec 2015 15:37:41 -0500 Subject: [PATCH 18/31] converted Customer Object to JPA Entity --- .../guru/springframework/domain/Customer.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/guru/springframework/domain/Customer.java b/src/main/java/guru/springframework/domain/Customer.java index cd53347e..450796bd 100644 --- a/src/main/java/guru/springframework/domain/Customer.java +++ b/src/main/java/guru/springframework/domain/Customer.java @@ -1,11 +1,20 @@ package guru.springframework.domain; +import javax.persistence.*; + /** * Created by jt on 11/14/15. */ +@Entity public class Customer implements DomainObject { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; + + @Version + private Integer version; + private String firstName; private String lastName; private String email; @@ -26,6 +35,14 @@ public void setId(Integer id) { this.id = id; } + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + public String getFirstName() { return firstName; } From 10c4cbc198b51065d9aaeb1d6a9ec1a0f51f7207 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Wed, 9 Dec 2015 18:03:25 -0500 Subject: [PATCH 19/31] Added JPA DAO serivce for products --- .../services/ProductServiceImpl.java | 2 + .../services/ProductServiceJapDaoImpl.java | 60 +++++++++++++++++++ src/main/resources/application.properties | 1 + .../templates/product/productform.html | 1 + 4 files changed, 64 insertions(+) create mode 100644 src/main/java/guru/springframework/services/ProductServiceJapDaoImpl.java diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java index 1382aad2..d0117ef9 100644 --- a/src/main/java/guru/springframework/services/ProductServiceImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java @@ -2,6 +2,7 @@ import guru.springframework.domain.DomainObject; import guru.springframework.domain.Product; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -12,6 +13,7 @@ * Created by jt on 11/6/15. */ @Service +@Profile("map") public class ProductServiceImpl extends AbstractMapService implements ProductService { @Override diff --git a/src/main/java/guru/springframework/services/ProductServiceJapDaoImpl.java b/src/main/java/guru/springframework/services/ProductServiceJapDaoImpl.java new file mode 100644 index 00000000..d4a23320 --- /dev/null +++ b/src/main/java/guru/springframework/services/ProductServiceJapDaoImpl.java @@ -0,0 +1,60 @@ +package guru.springframework.services; + +import guru.springframework.domain.Product; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.PersistenceUnit; +import java.util.List; + +/** + * Created by jt on 12/9/15. + */ +@Service +@Profile("jpadao") +public class ProductServiceJapDaoImpl implements ProductService { + + private EntityManagerFactory emf; + + @PersistenceUnit + public void setEmf(EntityManagerFactory emf) { + this.emf = emf; + } + + @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/resources/application.properties b/src/main/resources/application.properties index e69de29b..75ed4625 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.profiles.active=jpadao \ No newline at end of file diff --git a/src/main/resources/templates/product/productform.html b/src/main/resources/templates/product/productform.html index cd9d9b6e..568517db 100644 --- a/src/main/resources/templates/product/productform.html +++ b/src/main/resources/templates/product/productform.html @@ -21,6 +21,7 @@

Product Details

+
From 58751b1fa6758f399bd228150a27452eea590e21 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Wed, 9 Dec 2015 18:31:26 -0500 Subject: [PATCH 20/31] fixed typo in class name --- ...ductServiceJapDaoImpl.java => ProductServiceJpaDaoImpl.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/guru/springframework/services/{ProductServiceJapDaoImpl.java => ProductServiceJpaDaoImpl.java} (95%) diff --git a/src/main/java/guru/springframework/services/ProductServiceJapDaoImpl.java b/src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java similarity index 95% rename from src/main/java/guru/springframework/services/ProductServiceJapDaoImpl.java rename to src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java index d4a23320..83d850da 100644 --- a/src/main/java/guru/springframework/services/ProductServiceJapDaoImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java @@ -14,7 +14,7 @@ */ @Service @Profile("jpadao") -public class ProductServiceJapDaoImpl implements ProductService { +public class ProductServiceJpaDaoImpl implements ProductService { private EntityManagerFactory emf; From 3c7773cadfbda092947ff8145c4b67a36b2fd8c0 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Thu, 10 Dec 2015 17:38:21 -0500 Subject: [PATCH 21/31] adding classes for bootstrap --- .../bootstrap/SpringJPABootstrap.java | 64 +++++++++++++++++++ .../services/ProductServiceImpl.java | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java 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..b0353ffb --- /dev/null +++ b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java @@ -0,0 +1,64 @@ +package guru.springframework.bootstrap; + +import guru.springframework.domain.Product; +import guru.springframework.services.ProductService; +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; + +/** + * Created by jt on 12/9/15. + */ +@Component +public class SpringJPABootstrap implements ApplicationListener{ + + private ProductService productService; + + @Autowired + public void setProductService(ProductService productService) { + this.productService = productService; + } + + @Override + public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { + loadProducts(); + + } + + 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/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java index d0117ef9..44444726 100644 --- a/src/main/java/guru/springframework/services/ProductServiceImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java @@ -73,7 +73,7 @@ protected void loadDomainObjects(){ Product product5 = new Product(); product5.setId(5); - product5.setDescription("Product 2"); + product5.setDescription("Product 5"); product5.setPrice(new BigDecimal("25.99")); product5.setImageUrl("http://example.com/product5"); From 22d6467c9a55cbaa0b55fbaad95bb57747a88831 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Mon, 14 Dec 2015 12:44:50 -0500 Subject: [PATCH 22/31] adding intgration tests --- .../config/JpaIntegrationConfig.java | 14 +++++++ .../ProductServiceJapDaoImplTest.java | 37 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/test/java/guru/springframework/config/JpaIntegrationConfig.java create mode 100644 src/test/java/guru/springframework/services/ProductServiceJapDaoImplTest.java 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/services/ProductServiceJapDaoImplTest.java b/src/test/java/guru/springframework/services/ProductServiceJapDaoImplTest.java new file mode 100644 index 00000000..419064f6 --- /dev/null +++ b/src/test/java/guru/springframework/services/ProductServiceJapDaoImplTest.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 ProductServiceJapDaoImplTest { + + 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; + + } +} From ec6325ed18165a53445c33335049e8403e51667f Mon Sep 17 00:00:00 2001 From: John Thompson Date: Mon, 14 Dec 2015 13:32:01 -0500 Subject: [PATCH 23/31] Completed code assignemnt --- .../bootstrap/SpringJPABootstrap.java | 44 ++++++++++++++ .../services/AbstractMapService.java | 3 - .../services/CustomerServiceImpl.java | 44 +------------- .../services/CustomerServiceJPADaoImpl.java | 58 +++++++++++++++++++ .../services/ProductServiceImpl.java | 47 +-------------- .../services/ProductServiceJpaDaoImpl.java | 1 - .../CustomerServiceJpaDaoImplTest.java | 36 ++++++++++++ ...java => ProductServiceJpaDaoImplTest.java} | 2 +- 8 files changed, 142 insertions(+), 93 deletions(-) create mode 100644 src/main/java/guru/springframework/services/CustomerServiceJPADaoImpl.java create mode 100644 src/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java rename src/test/java/guru/springframework/services/{ProductServiceJapDaoImplTest.java => ProductServiceJpaDaoImplTest.java} (95%) diff --git a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java index b0353ffb..061eb2bf 100644 --- a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java +++ b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java @@ -1,6 +1,8 @@ package guru.springframework.bootstrap; +import guru.springframework.domain.Customer; import guru.springframework.domain.Product; +import guru.springframework.services.CustomerService; import guru.springframework.services.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; @@ -16,16 +18,58 @@ public class SpringJPABootstrap implements ApplicationListener{ private ProductService productService; + private CustomerService customerService; @Autowired public void setProductService(ProductService productService) { this.productService = productService; } + @Autowired + public void setCustomerService(CustomerService customerService) { + this.customerService = customerService; + } + @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { loadProducts(); + loadCustomers(); + + } + + public void loadCustomers() { + Customer customer1 = new Customer(); + customer1.setFirstName("Micheal"); + customer1.setLastName("Weston"); + customer1.setAddressLine1("1 Main St"); + customer1.setCity("Miami"); + customer1.setState("Florida"); + customer1.setZipCode("33101"); + customer1.setEmail("micheal@burnnotice.com"); + customer1.setPhoneNumber("305.333.0101"); + customerService.saveOrUpdate(customer1); + + Customer customer2 = new Customer(); + customer2.setFirstName("Fiona"); + customer2.setLastName("Glenanne"); + customer2.setAddressLine1("1 Key Biscane Ave"); + customer2.setCity("Miami"); + customer2.setState("Florida"); + customer2.setZipCode("33101"); + customer2.setEmail("fiona@burnnotice.com"); + customer2.setPhoneNumber("305.323.0233"); + customerService.saveOrUpdate(customer2); + Customer customer3 = new Customer(); + customer3.setFirstName("Sam"); + customer3.setLastName("Axe"); + customer3.setAddressLine1("1 Little Cuba Road"); + customer3.setCity("Miami"); + customer3.setState("Florida"); + customer3.setZipCode("33101"); + customer3.setEmail("sam@burnnotice.com"); + customer3.setPhoneNumber("305.426.9832"); + customerService.saveOrUpdate(customer3); } public void loadProducts(){ diff --git a/src/main/java/guru/springframework/services/AbstractMapService.java b/src/main/java/guru/springframework/services/AbstractMapService.java index 1e21261e..12b06923 100644 --- a/src/main/java/guru/springframework/services/AbstractMapService.java +++ b/src/main/java/guru/springframework/services/AbstractMapService.java @@ -12,7 +12,6 @@ public abstract class AbstractMapService { public AbstractMapService() { domainMap = new HashMap<>(); - loadDomainObjects(); } public List listAll() { @@ -45,6 +44,4 @@ private Integer getNextKey(){ return Collections.max(domainMap.keySet()) + 1; } - protected abstract void loadDomainObjects(); - } diff --git a/src/main/java/guru/springframework/services/CustomerServiceImpl.java b/src/main/java/guru/springframework/services/CustomerServiceImpl.java index c86adce5..c0247141 100644 --- a/src/main/java/guru/springframework/services/CustomerServiceImpl.java +++ b/src/main/java/guru/springframework/services/CustomerServiceImpl.java @@ -2,15 +2,16 @@ import guru.springframework.domain.Customer; import guru.springframework.domain.DomainObject; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -import java.util.HashMap; import java.util.List; /** * Created by jt on 11/14/15. */ @Service +@Profile("map") public class CustomerServiceImpl extends AbstractMapService implements CustomerService { @Override @@ -33,45 +34,4 @@ public void delete(Integer id) { super.delete(id); } - @Override - protected void loadDomainObjects() { - domainMap = new HashMap<>(); - - Customer customer1 = new Customer(); - customer1.setId(1); - customer1.setFirstName("Micheal"); - customer1.setLastName("Weston"); - customer1.setAddressLine1("1 Main St"); - customer1.setCity("Miami"); - customer1.setState("Florida"); - customer1.setZipCode("33101"); - customer1.setEmail("micheal@burnnotice.com"); - customer1.setPhoneNumber("305.333.0101"); - - Customer customer2 = new Customer(); - customer2.setId(2); - customer2.setFirstName("Fiona"); - customer2.setLastName("Glenanne"); - customer2.setAddressLine1("1 Key Biscane Ave"); - customer2.setCity("Miami"); - customer2.setState("Florida"); - customer2.setZipCode("33101"); - customer2.setEmail("fiona@burnnotice.com"); - customer2.setPhoneNumber("305.323.0233"); - - Customer customer3 = new Customer(); - customer3.setId(3); - customer3.setFirstName("Sam"); - customer3.setLastName("Axe"); - customer3.setAddressLine1("1 Little Cuba Road"); - customer3.setCity("Miami"); - customer3.setState("Florida"); - customer3.setZipCode("33101"); - customer3.setEmail("sam@burnnotice.com"); - customer3.setPhoneNumber("305.426.9832"); - - domainMap.put(1, customer1); - domainMap.put(2, customer2); - domainMap.put(3, customer3); - } } diff --git a/src/main/java/guru/springframework/services/CustomerServiceJPADaoImpl.java b/src/main/java/guru/springframework/services/CustomerServiceJPADaoImpl.java new file mode 100644 index 00000000..8007732c --- /dev/null +++ b/src/main/java/guru/springframework/services/CustomerServiceJPADaoImpl.java @@ -0,0 +1,58 @@ +package guru.springframework.services; + +import guru.springframework.domain.Customer; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.PersistenceUnit; +import java.util.List; + +/** + * Created by jt on 12/14/15. + */ +@Service +@Profile("jpadao") +public class CustomerServiceJPADaoImpl implements CustomerService{ + private EntityManagerFactory emf; + + @PersistenceUnit + public void setEmf(EntityManagerFactory emf) { + this.emf = emf; + } + + @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(); + 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/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java index 44444726..2af5c548 100644 --- a/src/main/java/guru/springframework/services/ProductServiceImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java @@ -5,8 +5,6 @@ import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -import java.math.BigDecimal; -import java.util.HashMap; import java.util.List; /** @@ -36,47 +34,4 @@ public void delete(Integer id) { super.delete(id); } - protected void loadDomainObjects(){ - domainMap = new HashMap<>(); - - Product product1 = new Product(); - product1.setId(1); - product1.setDescription("Product 1"); - product1.setPrice(new BigDecimal("12.99")); - product1.setImageUrl("http://example.com/product1"); - - domainMap.put(1, product1); - - Product product2 = new Product(); - product2.setId(2); - product2.setDescription("Product 2"); - product2.setPrice(new BigDecimal("14.99")); - product2.setImageUrl("http://example.com/product2"); - - domainMap.put(2, product2); - - Product product3 = new Product(); - product3.setId(3); - product3.setDescription("Product 3"); - product3.setPrice(new BigDecimal("34.99")); - product3.setImageUrl("http://example.com/product3"); - - domainMap.put(3, product3); - - Product product4 = new Product(); - product4.setId(4); - product4.setDescription("Product 4"); - product4.setPrice(new BigDecimal("44.99")); - product4.setImageUrl("http://example.com/product4"); - - domainMap.put(4, product4); - - Product product5 = new Product(); - product5.setId(5); - product5.setDescription("Product 5"); - product5.setPrice(new BigDecimal("25.99")); - product5.setImageUrl("http://example.com/product5"); - - domainMap.put(5, product5); - } -} + } diff --git a/src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java b/src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java index 83d850da..9e3b5702 100644 --- a/src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java +++ b/src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java @@ -55,6 +55,5 @@ public void delete(Integer id) { em.getTransaction().begin(); em.remove(em.find(Product.class, id)); em.getTransaction().commit(); - } } 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..8a1936f3 --- /dev/null +++ b/src/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java @@ -0,0 +1,36 @@ +package guru.springframework.services; + +import guru.springframework.config.JpaIntegrationConfig; +import guru.springframework.domain.Customer; +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; + + } +} diff --git a/src/test/java/guru/springframework/services/ProductServiceJapDaoImplTest.java b/src/test/java/guru/springframework/services/ProductServiceJpaDaoImplTest.java similarity index 95% rename from src/test/java/guru/springframework/services/ProductServiceJapDaoImplTest.java rename to src/test/java/guru/springframework/services/ProductServiceJpaDaoImplTest.java index 419064f6..4e8db442 100644 --- a/src/test/java/guru/springframework/services/ProductServiceJapDaoImplTest.java +++ b/src/test/java/guru/springframework/services/ProductServiceJpaDaoImplTest.java @@ -17,7 +17,7 @@ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(JpaIntegrationConfig.class) @ActiveProfiles("jpadao") -public class ProductServiceJapDaoImplTest { +public class ProductServiceJpaDaoImplTest { private ProductService productService; From 3e26e8a0f605a1f60df016bdc112c76df0f3a499 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Tue, 15 Dec 2015 09:02:52 -0500 Subject: [PATCH 24/31] Refactored services, added encryption service, created user domain object. --- pom.xml | 12 ++- .../config/CommonBeanConfig.java | 18 +++++ .../guru/springframework/domain/Customer.java | 11 +++ .../guru/springframework/domain/User.java | 75 +++++++++++++++++++ .../springframework/services/UserService.java | 10 +++ .../jpaservices/AbstractJpaDaoService.java | 17 +++++ .../CustomerServiceJPADaoImpl.java | 24 ++++-- .../ProductServiceJpaDaoImpl.java | 14 +--- .../jpaservices/UserServiceJpaDaoImpl.java | 65 ++++++++++++++++ .../{ => mapservices}/AbstractMapService.java | 2 +- .../CustomerServiceImpl.java | 3 +- .../{ => mapservices}/ProductServiceImpl.java | 3 +- .../mapservices/UserServiceMapImpl.java | 33 ++++++++ .../services/security/EncryptionService.java | 9 +++ .../security/EncryptionServiceImpl.java | 27 +++++++ .../CustomerServiceJpaDaoImplTest.java | 15 ++++ .../services/UserServiceJpaDaoImplTest.java | 43 +++++++++++ 17 files changed, 357 insertions(+), 24 deletions(-) create mode 100644 src/main/java/guru/springframework/config/CommonBeanConfig.java create mode 100644 src/main/java/guru/springframework/domain/User.java create mode 100644 src/main/java/guru/springframework/services/UserService.java create mode 100644 src/main/java/guru/springframework/services/jpaservices/AbstractJpaDaoService.java rename src/main/java/guru/springframework/services/{ => jpaservices}/CustomerServiceJPADaoImpl.java (60%) rename src/main/java/guru/springframework/services/{ => jpaservices}/ProductServiceJpaDaoImpl.java (77%) create mode 100644 src/main/java/guru/springframework/services/jpaservices/UserServiceJpaDaoImpl.java rename src/main/java/guru/springframework/services/{ => mapservices}/AbstractMapService.java (95%) rename src/main/java/guru/springframework/services/{ => mapservices}/CustomerServiceImpl.java (88%) rename src/main/java/guru/springframework/services/{ => mapservices}/ProductServiceImpl.java (88%) create mode 100644 src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java create mode 100644 src/main/java/guru/springframework/services/security/EncryptionService.java create mode 100644 src/main/java/guru/springframework/services/security/EncryptionServiceImpl.java create mode 100644 src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java diff --git a/pom.xml b/pom.xml index 10d045f8..3bb3de1d 100644 --- a/pom.xml +++ b/pom.xml @@ -60,8 +60,16 @@ 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/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/domain/Customer.java b/src/main/java/guru/springframework/domain/Customer.java index 450796bd..17be2306 100644 --- a/src/main/java/guru/springframework/domain/Customer.java +++ b/src/main/java/guru/springframework/domain/Customer.java @@ -25,6 +25,9 @@ public class Customer implements DomainObject { private String state; private String zipCode; + @OneToOne(cascade = {CascadeType.ALL}) + private User user; + @Override public Integer getId() { return id; @@ -114,4 +117,12 @@ public String getZipCode() { public void setZipCode(String zipCode) { this.zipCode = zipCode; } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } } 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..5b9ad98d --- /dev/null +++ b/src/main/java/guru/springframework/domain/User.java @@ -0,0 +1,75 @@ +package guru.springframework.domain; + +import javax.persistence.*; + +/** + * Created by jt on 12/14/15. + */ +@Entity +public class User implements DomainObject { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + + @Version + private Integer version; + + private String username; + + @Transient + private String password; + + private String encryptedPassword; + private Boolean enabled = true; + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + 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; + } +} 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/CustomerServiceJPADaoImpl.java b/src/main/java/guru/springframework/services/jpaservices/CustomerServiceJPADaoImpl.java similarity index 60% rename from src/main/java/guru/springframework/services/CustomerServiceJPADaoImpl.java rename to src/main/java/guru/springframework/services/jpaservices/CustomerServiceJPADaoImpl.java index 8007732c..876957da 100644 --- a/src/main/java/guru/springframework/services/CustomerServiceJPADaoImpl.java +++ b/src/main/java/guru/springframework/services/jpaservices/CustomerServiceJPADaoImpl.java @@ -1,12 +1,13 @@ -package guru.springframework.services; +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 javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceUnit; import java.util.List; /** @@ -14,12 +15,13 @@ */ @Service @Profile("jpadao") -public class CustomerServiceJPADaoImpl implements CustomerService{ - private EntityManagerFactory emf; +public class CustomerServiceJPADaoImpl extends AbstractJpaDaoService implements CustomerService { - @PersistenceUnit - public void setEmf(EntityManagerFactory emf) { - this.emf = emf; + private EncryptionService encryptionService; + + @Autowired + public void setEncryptionService(EncryptionService encryptionService) { + this.encryptionService = encryptionService; } @Override @@ -41,6 +43,12 @@ 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(); diff --git a/src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java b/src/main/java/guru/springframework/services/jpaservices/ProductServiceJpaDaoImpl.java similarity index 77% rename from src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java rename to src/main/java/guru/springframework/services/jpaservices/ProductServiceJpaDaoImpl.java index 9e3b5702..7816288a 100644 --- a/src/main/java/guru/springframework/services/ProductServiceJpaDaoImpl.java +++ b/src/main/java/guru/springframework/services/jpaservices/ProductServiceJpaDaoImpl.java @@ -1,12 +1,11 @@ -package guru.springframework.services; +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 javax.persistence.EntityManagerFactory; -import javax.persistence.PersistenceUnit; import java.util.List; /** @@ -14,14 +13,7 @@ */ @Service @Profile("jpadao") -public class ProductServiceJpaDaoImpl implements ProductService { - - private EntityManagerFactory emf; - - @PersistenceUnit - public void setEmf(EntityManagerFactory emf) { - this.emf = emf; - } +public class ProductServiceJpaDaoImpl extends AbstractJpaDaoService implements ProductService { @Override public List listAll() { 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/AbstractMapService.java b/src/main/java/guru/springframework/services/mapservices/AbstractMapService.java similarity index 95% rename from src/main/java/guru/springframework/services/AbstractMapService.java rename to src/main/java/guru/springframework/services/mapservices/AbstractMapService.java index 12b06923..5a4832c7 100644 --- a/src/main/java/guru/springframework/services/AbstractMapService.java +++ b/src/main/java/guru/springframework/services/mapservices/AbstractMapService.java @@ -1,4 +1,4 @@ -package guru.springframework.services; +package guru.springframework.services.mapservices; import guru.springframework.domain.DomainObject; diff --git a/src/main/java/guru/springframework/services/CustomerServiceImpl.java b/src/main/java/guru/springframework/services/mapservices/CustomerServiceImpl.java similarity index 88% rename from src/main/java/guru/springframework/services/CustomerServiceImpl.java rename to src/main/java/guru/springframework/services/mapservices/CustomerServiceImpl.java index c0247141..d332373d 100644 --- a/src/main/java/guru/springframework/services/CustomerServiceImpl.java +++ b/src/main/java/guru/springframework/services/mapservices/CustomerServiceImpl.java @@ -1,7 +1,8 @@ -package guru.springframework.services; +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; diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/mapservices/ProductServiceImpl.java similarity index 88% rename from src/main/java/guru/springframework/services/ProductServiceImpl.java rename to src/main/java/guru/springframework/services/mapservices/ProductServiceImpl.java index 2af5c548..cfa76e81 100644 --- a/src/main/java/guru/springframework/services/ProductServiceImpl.java +++ b/src/main/java/guru/springframework/services/mapservices/ProductServiceImpl.java @@ -1,7 +1,8 @@ -package guru.springframework.services; +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; 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..8de94d6e --- /dev/null +++ b/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java @@ -0,0 +1,33 @@ +package guru.springframework.services.mapservices; + +import guru.springframework.domain.DomainObject; +import guru.springframework.domain.User; +import guru.springframework.services.UserService; + +import java.util.List; + +/** + * Created by jt on 12/14/15. + */ +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/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java b/src/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java index 8a1936f3..d2201972 100644 --- a/src/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java +++ b/src/test/java/guru/springframework/services/CustomerServiceJpaDaoImplTest.java @@ -2,6 +2,7 @@ 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; @@ -33,4 +34,18 @@ public void testList() throws Exception { 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/UserServiceJpaDaoImplTest.java b/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java new file mode 100644 index 00000000..38f9beda --- /dev/null +++ b/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java @@ -0,0 +1,43 @@ +package guru.springframework.services; + +import guru.springframework.config.JpaIntegrationConfig; +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; + +/** + * Created by jt on 12/14/15. + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(JpaIntegrationConfig.class) +@ActiveProfiles("jpadao") +public class UserServiceJpaDaoImplTest { + + private UserService userService; + + @Autowired + public void setUserService(UserService userService) { + this.userService = userService; + } + + @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()); + + } +} From 72c5eca938972391264c2eb28f7b0ae00975a02e Mon Sep 17 00:00:00 2001 From: John Thompson Date: Tue, 15 Dec 2015 10:09:38 -0500 Subject: [PATCH 25/31] Refactored to use bidirectional one to one mapping for User/Customer --- .../guru/springframework/domain/Customer.java | 2 +- .../guru/springframework/domain/User.java | 12 ++++++++++ .../services/UserServiceJpaDaoImplTest.java | 24 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/guru/springframework/domain/Customer.java b/src/main/java/guru/springframework/domain/Customer.java index 17be2306..2b35ddde 100644 --- a/src/main/java/guru/springframework/domain/Customer.java +++ b/src/main/java/guru/springframework/domain/Customer.java @@ -25,7 +25,7 @@ public class Customer implements DomainObject { private String state; private String zipCode; - @OneToOne(cascade = {CascadeType.ALL}) + @OneToOne private User user; @Override diff --git a/src/main/java/guru/springframework/domain/User.java b/src/main/java/guru/springframework/domain/User.java index 5b9ad98d..bf71021c 100644 --- a/src/main/java/guru/springframework/domain/User.java +++ b/src/main/java/guru/springframework/domain/User.java @@ -23,6 +23,9 @@ public class User implements DomainObject { private String encryptedPassword; private Boolean enabled = true; + @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST}) + private Customer customer; + @Override public Integer getId() { return id; @@ -72,4 +75,13 @@ public Boolean getEnabled() { public void setEnabled(Boolean enabled) { this.enabled = enabled; } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + customer.setUser(this); + } } diff --git a/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java b/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java index 38f9beda..04cb9975 100644 --- a/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java +++ b/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java @@ -1,6 +1,7 @@ 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; @@ -40,4 +41,27 @@ public void testSaveOfUser() throws Exception { 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; + + } } From 433c246a1ac83c94eb640929a72723b274252df6 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Tue, 15 Dec 2015 15:06:50 -0500 Subject: [PATCH 26/31] added example to use ManytoOne JPA Mapping, plus entity mappings for Cart, and CartDetail to support a 'shopping' cart --- .../guru/springframework/domain/Cart.java | 69 +++++++++++++++ .../springframework/domain/CartDetail.java | 57 ++++++++++++ .../guru/springframework/domain/User.java | 11 +++ .../services/UserServiceJpaDaoImplTest.java | 86 ++++++++++++++++++- 4 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 src/main/java/guru/springframework/domain/Cart.java create mode 100644 src/main/java/guru/springframework/domain/CartDetail.java 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..230a19fd --- /dev/null +++ b/src/main/java/guru/springframework/domain/Cart.java @@ -0,0 +1,69 @@ +package guru.springframework.domain; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by jt on 12/15/15. + */ +@Entity +public class Cart implements DomainObject{ + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + + @Version + private Integer version; + + @OneToOne + private User user; + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "cart", orphanRemoval = true) + private List cartDetails = new ArrayList<>(); + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + 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..3dbc5dfb --- /dev/null +++ b/src/main/java/guru/springframework/domain/CartDetail.java @@ -0,0 +1,57 @@ +package guru.springframework.domain; + +import javax.persistence.*; + +/** + * Created by jt on 12/15/15. + */ +@Entity +public class CartDetail implements DomainObject { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + + @Version + private Integer version; + + @ManyToOne + private Cart cart; + + @OneToOne + private Product product; + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + 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; + } +} diff --git a/src/main/java/guru/springframework/domain/User.java b/src/main/java/guru/springframework/domain/User.java index bf71021c..05ad01ee 100644 --- a/src/main/java/guru/springframework/domain/User.java +++ b/src/main/java/guru/springframework/domain/User.java @@ -26,6 +26,9 @@ public class User implements DomainObject { @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST}) private Customer customer; + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) + private Cart cart; + @Override public Integer getId() { return id; @@ -84,4 +87,12 @@ public void setCustomer(Customer customer) { this.customer = customer; customer.setUser(this); } + + public Cart getCart() { + return cart; + } + + public void setCart(Cart cart) { + this.cart = cart; + } } diff --git a/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java b/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java index 04cb9975..8412ec74 100644 --- a/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java +++ b/src/test/java/guru/springframework/services/UserServiceJpaDaoImplTest.java @@ -1,8 +1,7 @@ package guru.springframework.services; import guru.springframework.config.JpaIntegrationConfig; -import guru.springframework.domain.Customer; -import guru.springframework.domain.User; +import guru.springframework.domain.*; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -10,6 +9,8 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import java.util.List; + /** * Created by jt on 12/14/15. */ @@ -19,12 +20,18 @@ 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(); @@ -64,4 +71,79 @@ public void testSaveOfUserWithCustomer() throws Exception { 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; + } } From 67dc23383b1da464e3ad2ba6c2f81381bb0a11ce Mon Sep 17 00:00:00 2001 From: John Thompson Date: Wed, 16 Dec 2015 17:42:10 -0500 Subject: [PATCH 27/31] Added Embedded JPA entity for address, refactored Customer to use Address Entity, updated boostrap to load data, changed hibernate mapping. --- .../bootstrap/SpringJPABootstrap.java | 28 +++++---- .../guru/springframework/domain/Address.java | 56 ++++++++++++++++++ .../guru/springframework/domain/Customer.java | 59 ++++++------------- src/main/resources/application.properties | 3 +- .../controllers/CustomerControllerTest.java | 22 +++---- 5 files changed, 104 insertions(+), 64 deletions(-) create mode 100644 src/main/java/guru/springframework/domain/Address.java diff --git a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java index 061eb2bf..3ed5f231 100644 --- a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java +++ b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java @@ -1,5 +1,6 @@ package guru.springframework.bootstrap; +import guru.springframework.domain.Address; import guru.springframework.domain.Customer; import guru.springframework.domain.Product; import guru.springframework.services.CustomerService; @@ -41,10 +42,11 @@ public void loadCustomers() { Customer customer1 = new Customer(); customer1.setFirstName("Micheal"); customer1.setLastName("Weston"); - customer1.setAddressLine1("1 Main St"); - customer1.setCity("Miami"); - customer1.setState("Florida"); - customer1.setZipCode("33101"); + 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"); customerService.saveOrUpdate(customer1); @@ -52,10 +54,11 @@ public void loadCustomers() { Customer customer2 = new Customer(); customer2.setFirstName("Fiona"); customer2.setLastName("Glenanne"); - customer2.setAddressLine1("1 Key Biscane Ave"); - customer2.setCity("Miami"); - customer2.setState("Florida"); - customer2.setZipCode("33101"); + 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"); customerService.saveOrUpdate(customer2); @@ -63,10 +66,11 @@ public void loadCustomers() { Customer customer3 = new Customer(); customer3.setFirstName("Sam"); customer3.setLastName("Axe"); - customer3.setAddressLine1("1 Little Cuba Road"); - customer3.setCity("Miami"); - customer3.setState("Florida"); - customer3.setZipCode("33101"); + 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"); customerService.saveOrUpdate(customer3); 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/Customer.java b/src/main/java/guru/springframework/domain/Customer.java index 2b35ddde..dabf6361 100644 --- a/src/main/java/guru/springframework/domain/Customer.java +++ b/src/main/java/guru/springframework/domain/Customer.java @@ -19,11 +19,12 @@ public class Customer implements DomainObject { private String lastName; private String email; private String phoneNumber; - private String addressLine1; - private String addressLine2; - private String city; - private String state; - private String zipCode; + + @Embedded + private Address billingAddress; + + @Embedded + private Address shippingAddress; @OneToOne private User user; @@ -78,51 +79,27 @@ public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } - 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 User getUser() { + return user; } - public void setState(String state) { - this.state = state; + public void setUser(User user) { + this.user = user; } - public String getZipCode() { - return zipCode; + public Address getBillingAddress() { + return billingAddress; } - public void setZipCode(String zipCode) { - this.zipCode = zipCode; + public void setBillingAddress(Address billingAddress) { + this.billingAddress = billingAddress; } - public User getUser() { - return user; + public Address getShippingAddress() { + return shippingAddress; } - public void setUser(User user) { - this.user = user; + public void setShippingAddress(Address shippingAddress) { + this.shippingAddress = shippingAddress; } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 75ed4625..740b550b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,2 @@ -spring.profiles.active=jpadao \ No newline at end of file +spring.profiles.active=jpadao +spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy \ No newline at end of file diff --git a/src/test/java/guru/springframework/controllers/CustomerControllerTest.java b/src/test/java/guru/springframework/controllers/CustomerControllerTest.java index db23e3c3..2a7725f4 100644 --- a/src/test/java/guru/springframework/controllers/CustomerControllerTest.java +++ b/src/test/java/guru/springframework/controllers/CustomerControllerTest.java @@ -1,5 +1,6 @@ package guru.springframework.controllers; +import guru.springframework.domain.Address; import guru.springframework.domain.Customer; import guru.springframework.services.CustomerService; import org.junit.Before; @@ -104,11 +105,12 @@ public void testSaveOrUpdate() throws Exception { returnCustomer.setId(id); returnCustomer.setFirstName(firstName); returnCustomer.setLastName(lastName); - returnCustomer.setAddressLine1(addressLine1); - returnCustomer.setAddressLine2(addressLine2); - returnCustomer.setCity(city); - returnCustomer.setState(state); - returnCustomer.setZipCode(zipCode); + 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); @@ -146,11 +148,11 @@ public void testSaveOrUpdate() throws Exception { assertEquals(id, boundCustomer.getId()); assertEquals(firstName, boundCustomer.getFirstName()); assertEquals(lastName, boundCustomer.getLastName()); - assertEquals(addressLine1, boundCustomer.getAddressLine1()); - assertEquals(addressLine2, boundCustomer.getAddressLine2()); - assertEquals(city, boundCustomer.getCity()); - assertEquals(state, boundCustomer.getState()); - assertEquals(zipCode, boundCustomer.getZipCode()); + assertEquals(addressLine1, boundCustomer.getBillingAddress().getAddressLine1()); + assertEquals(addressLine2, boundCustomer.getBillingAddress().getAddressLine2()); + assertEquals(city, boundCustomer.getBillingAddress().getCity()); + assertEquals(state, boundCustomer.getBillingAddress().getState()); + assertEquals(zipCode, boundCustomer.getBillingAddress().getZipCode()); assertEquals(email, boundCustomer.getEmail()); assertEquals(phoneNumber, boundCustomer.getPhoneNumber()); From 07db613f32ce9213b9ab724aeb007662643fa3b1 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 18 Dec 2015 10:55:51 -0500 Subject: [PATCH 28/31] Completed coding assignment for JPA Entities --- .../bootstrap/SpringJPABootstrap.java | 73 ++++++++++--- .../controllers/UserController.java | 61 +++++++++++ .../domain/AbstractDomainClass.java | 56 ++++++++++ .../guru/springframework/domain/Cart.java | 32 +----- .../springframework/domain/CartDetail.java | 39 +++---- .../guru/springframework/domain/Customer.java | 29 ++--- .../guru/springframework/domain/Order.java | 77 +++++++++++++ .../springframework/domain/OrderDetail.java | 44 ++++++++ .../guru/springframework/domain/Product.java | 28 +---- .../guru/springframework/domain/User.java | 33 ++---- .../springframework/enums/OrderStatus.java | 8 ++ .../services/OrderService.java | 9 ++ .../jpaservices/OrderServiceJpaDaoImpl.java | 51 +++++++++ .../mapservices/OrderServiceMapImpl.java | 36 +++++++ src/main/resources/templates/index.html | 1 + src/main/resources/templates/user/list.html | 50 +++++++++ src/main/resources/templates/user/show.html | 95 ++++++++++++++++ .../resources/templates/user/userform.html | 102 ++++++++++++++++++ .../controllers/CustomerControllerTest.java | 30 +++--- .../controllers/IndexControllerTest.java | 2 +- 20 files changed, 700 insertions(+), 156 deletions(-) create mode 100644 src/main/java/guru/springframework/controllers/UserController.java create mode 100644 src/main/java/guru/springframework/domain/AbstractDomainClass.java create mode 100644 src/main/java/guru/springframework/domain/Order.java create mode 100644 src/main/java/guru/springframework/domain/OrderDetail.java create mode 100644 src/main/java/guru/springframework/enums/OrderStatus.java create mode 100644 src/main/java/guru/springframework/services/OrderService.java create mode 100644 src/main/java/guru/springframework/services/jpaservices/OrderServiceJpaDaoImpl.java create mode 100644 src/main/java/guru/springframework/services/mapservices/OrderServiceMapImpl.java create mode 100644 src/main/resources/templates/user/list.html create mode 100644 src/main/resources/templates/user/show.html create mode 100644 src/main/resources/templates/user/userform.html diff --git a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java index 3ed5f231..7fef46af 100644 --- a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java +++ b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java @@ -1,16 +1,16 @@ package guru.springframework.bootstrap; -import guru.springframework.domain.Address; -import guru.springframework.domain.Customer; -import guru.springframework.domain.Product; -import guru.springframework.services.CustomerService; +import guru.springframework.domain.*; +import guru.springframework.enums.OrderStatus; import guru.springframework.services.ProductService; +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. @@ -19,7 +19,7 @@ public class SpringJPABootstrap implements ApplicationListener{ private ProductService productService; - private CustomerService customerService; + private UserService userService; @Autowired public void setProductService(ProductService productService) { @@ -27,18 +27,56 @@ public void setProductService(ProductService productService) { } @Autowired - public void setCustomerService(CustomerService customerService) { - this.customerService = customerService; + public void setUserService(UserService userService) { + this.userService = userService; } @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { loadProducts(); - loadCustomers(); + loadUsersAndCustomers(); + loadCarts(); + loadOrderHistory(); } - public void loadCustomers() { + 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"); @@ -49,7 +87,12 @@ public void loadCustomers() { customer1.getBillingAddress().setZipCode("33101"); customer1.setEmail("micheal@burnnotice.com"); customer1.setPhoneNumber("305.333.0101"); - customerService.saveOrUpdate(customer1); + user1.setCustomer(customer1); + userService.saveOrUpdate(user1); + + User user2 = new User(); + user2.setUsername("fglenanne"); + user2.setPassword("password"); Customer customer2 = new Customer(); customer2.setFirstName("Fiona"); @@ -61,8 +104,12 @@ public void loadCustomers() { customer2.getBillingAddress().setZipCode("33101"); customer2.setEmail("fiona@burnnotice.com"); customer2.setPhoneNumber("305.323.0233"); - customerService.saveOrUpdate(customer2); + 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"); @@ -73,7 +120,9 @@ public void loadCustomers() { customer3.getBillingAddress().setZipCode("33101"); customer3.setEmail("sam@burnnotice.com"); customer3.setPhoneNumber("305.426.9832"); - customerService.saveOrUpdate(customer3); + + user3.setCustomer(customer3); + userService.saveOrUpdate(user3); } public void loadProducts(){ 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/Cart.java b/src/main/java/guru/springframework/domain/Cart.java index 230a19fd..7bdca06c 100644 --- a/src/main/java/guru/springframework/domain/Cart.java +++ b/src/main/java/guru/springframework/domain/Cart.java @@ -1,6 +1,9 @@ package guru.springframework.domain; -import javax.persistence.*; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; import java.util.ArrayList; import java.util.List; @@ -8,14 +11,7 @@ * Created by jt on 12/15/15. */ @Entity -public class Cart implements DomainObject{ - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Integer id; - - @Version - private Integer version; +public class Cart extends AbstractDomainClass{ @OneToOne private User user; @@ -23,24 +19,6 @@ public class Cart implements DomainObject{ @OneToMany(cascade = CascadeType.ALL, mappedBy = "cart", orphanRemoval = true) private List cartDetails = new ArrayList<>(); - @Override - public Integer getId() { - return id; - } - - @Override - public void setId(Integer id) { - this.id = id; - } - - public Integer getVersion() { - return version; - } - - public void setVersion(Integer version) { - this.version = version; - } - public User getUser() { return user; } diff --git a/src/main/java/guru/springframework/domain/CartDetail.java b/src/main/java/guru/springframework/domain/CartDetail.java index 3dbc5dfb..b2c2b310 100644 --- a/src/main/java/guru/springframework/domain/CartDetail.java +++ b/src/main/java/guru/springframework/domain/CartDetail.java @@ -1,19 +1,14 @@ package guru.springframework.domain; -import javax.persistence.*; +import javax.persistence.Entity; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; /** * Created by jt on 12/15/15. */ @Entity -public class CartDetail implements DomainObject { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Integer id; - - @Version - private Integer version; +public class CartDetail extends AbstractDomainClass { @ManyToOne private Cart cart; @@ -21,23 +16,7 @@ public class CartDetail implements DomainObject { @OneToOne private Product product; - @Override - public Integer getId() { - return id; - } - - @Override - public void setId(Integer id) { - this.id = id; - } - - public Integer getVersion() { - return version; - } - - public void setVersion(Integer version) { - this.version = version; - } + private Integer quantity; public Cart getCart() { return cart; @@ -54,4 +33,12 @@ public Product getProduct() { 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 index dabf6361..a077495d 100644 --- a/src/main/java/guru/springframework/domain/Customer.java +++ b/src/main/java/guru/springframework/domain/Customer.java @@ -1,19 +1,15 @@ package guru.springframework.domain; -import javax.persistence.*; +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 implements DomainObject { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Integer id; - - @Version - private Integer version; +public class Customer extends AbstractDomainClass { private String firstName; private String lastName; @@ -26,7 +22,7 @@ public class Customer implements DomainObject { @Embedded private Address shippingAddress; - @OneToOne + @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST}) private User user; @Override @@ -34,19 +30,6 @@ public Integer getId() { return id; } - @Override - public void setId(Integer id) { - this.id = id; - } - - public Integer getVersion() { - return version; - } - - public void setVersion(Integer version) { - this.version = version; - } - public String getFirstName() { return firstName; } 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..91155a8a --- /dev/null +++ b/src/main/java/guru/springframework/domain/Order.java @@ -0,0 +1,77 @@ +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 +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 index ffadb179..4e6a7a4d 100644 --- a/src/main/java/guru/springframework/domain/Product.java +++ b/src/main/java/guru/springframework/domain/Product.java @@ -1,41 +1,18 @@ package guru.springframework.domain; -import javax.persistence.*; +import javax.persistence.Entity; import java.math.BigDecimal; /** * Created by jt on 11/6/15. */ @Entity -public class Product implements DomainObject{ - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Integer id; - - @Version - private Integer version; +public class Product extends AbstractDomainClass { private String description; private BigDecimal price; private String imageUrl; - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public Integer getVersion() { - return version; - } - - public void setVersion(Integer version) { - this.version = version; - } - public String getDescription() { return description; } @@ -59,4 +36,5 @@ public String getImageUrl() { 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 index 05ad01ee..6b49997a 100644 --- a/src/main/java/guru/springframework/domain/User.java +++ b/src/main/java/guru/springframework/domain/User.java @@ -1,19 +1,15 @@ package guru.springframework.domain; -import javax.persistence.*; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.OneToOne; +import javax.persistence.Transient; /** * Created by jt on 12/14/15. */ @Entity -public class User implements DomainObject { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Integer id; - - @Version - private Integer version; +public class User extends AbstractDomainClass { private String username; @@ -29,24 +25,6 @@ public class User implements DomainObject { @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) private Cart cart; - @Override - public Integer getId() { - return id; - } - - @Override - public void setId(Integer id) { - this.id = id; - } - - public Integer getVersion() { - return version; - } - - public void setVersion(Integer version) { - this.version = version; - } - public String getUsername() { return username; } @@ -95,4 +73,5 @@ public Cart getCart() { public void setCart(Cart cart) { this.cart = cart; } + } 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/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/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/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/resources/templates/index.html b/src/main/resources/templates/index.html index 9622d970..18fb0bf3 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -24,6 +24,7 @@

This is my Thymeleaf index page.

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

+ + + + + + + + + + + + + + + + + + + +
IdUser NameFirst NameLast NameListEditDelete
View Edit Delete
+
+
+
+ New User +
+
+
+ + + \ 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 + + + + + + + + + +
+ +
+
+

Show User

+
+
+
+
+ +
+ +
+

User Id

+
+
+
+ +
+

Description

+
+
+
+ +
+

Price

+
+
+
+ +
+

Image

+
+
+
+ +
+

Image

+
+
+

Billing Address

+
+ +
+

Image

+
+
+
+ +
+

Image

+
+
+
+ +
+

Image

+
+
+
+ +
+

Image

+
+
+
+ +
+

Image

+
+
+ +
+
+
+ + + \ 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 + + + + + + + + + +
+ +

User Details

+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+

Shipping Address

+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/src/test/java/guru/springframework/controllers/CustomerControllerTest.java b/src/test/java/guru/springframework/controllers/CustomerControllerTest.java index 2a7725f4..b2827ae5 100644 --- a/src/test/java/guru/springframework/controllers/CustomerControllerTest.java +++ b/src/test/java/guru/springframework/controllers/CustomerControllerTest.java @@ -120,11 +120,11 @@ public void testSaveOrUpdate() throws Exception { .param("id", "1") .param("firstName", firstName) .param("lastName", lastName) - .param("addressLine1", addressLine1) - .param("addressLine2", addressLine2) - .param("city", city) - .param("state", state) - .param("zipCode", zipCode) + .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()) @@ -132,11 +132,11 @@ public void testSaveOrUpdate() throws Exception { .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("addressLine1", is(addressLine1)))) - .andExpect(model().attribute("customer", hasProperty("addressLine2", is(addressLine2)))) - .andExpect(model().attribute("customer", hasProperty("city", is(city)))) - .andExpect(model().attribute("customer", hasProperty("state", is(state)))) - .andExpect(model().attribute("customer", hasProperty("zipCode", is(zipCode)))) + .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)))); @@ -148,11 +148,11 @@ public void testSaveOrUpdate() throws Exception { assertEquals(id, boundCustomer.getId()); assertEquals(firstName, boundCustomer.getFirstName()); assertEquals(lastName, boundCustomer.getLastName()); - assertEquals(addressLine1, boundCustomer.getBillingAddress().getAddressLine1()); - assertEquals(addressLine2, boundCustomer.getBillingAddress().getAddressLine2()); - assertEquals(city, boundCustomer.getBillingAddress().getCity()); - assertEquals(state, boundCustomer.getBillingAddress().getState()); - assertEquals(zipCode, boundCustomer.getBillingAddress().getZipCode()); + 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 index a1ee14b1..2ddb1255 100644 --- a/src/test/java/guru/springframework/controllers/IndexControllerTest.java +++ b/src/test/java/guru/springframework/controllers/IndexControllerTest.java @@ -29,7 +29,7 @@ public void setup(){ public void testIndex() throws Exception{ mockMvc.perform(get("/")) .andExpect(status().isOk()) - .andExpect(view().name("indexdd")); + .andExpect(view().name("index")); } } From 37acb523768f057e1df650ae5e245c7d25b47606 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 18 Dec 2015 11:37:07 -0500 Subject: [PATCH 29/31] Fixing Order table name --- src/main/java/guru/springframework/domain/Order.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/guru/springframework/domain/Order.java b/src/main/java/guru/springframework/domain/Order.java index 91155a8a..2dffae4e 100644 --- a/src/main/java/guru/springframework/domain/Order.java +++ b/src/main/java/guru/springframework/domain/Order.java @@ -11,6 +11,7 @@ * Created by jt on 12/16/15. */ @Entity +@Table(name = "ORDER_HEADER") public class Order extends AbstractDomainClass { @OneToOne From 40b5c14f453020109413c9f34901cd1b5ba85308 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 18 Dec 2015 13:12:26 -0500 Subject: [PATCH 30/31] added Role Entity, and related service objects --- .../bootstrap/SpringJPABootstrap.java | 30 ++++++++++ .../guru/springframework/domain/User.java | 37 ++++++++++-- .../springframework/domain/security/Role.java | 57 +++++++++++++++++++ .../springframework/services/RoleService.java | 9 +++ .../jpaservices/RoleServiceJpaImpl.java | 51 +++++++++++++++++ .../mapservices/RoleServiceMapImpl.java | 12 ++++ .../mapservices/UserServiceMapImpl.java | 4 ++ 7 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 src/main/java/guru/springframework/domain/security/Role.java create mode 100644 src/main/java/guru/springframework/services/RoleService.java create mode 100644 src/main/java/guru/springframework/services/jpaservices/RoleServiceJpaImpl.java create mode 100644 src/main/java/guru/springframework/services/mapservices/RoleServiceMapImpl.java diff --git a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java index 7fef46af..91e63c5b 100644 --- a/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java +++ b/src/main/java/guru/springframework/bootstrap/SpringJPABootstrap.java @@ -1,8 +1,10 @@ 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; @@ -20,6 +22,7 @@ public class SpringJPABootstrap implements ApplicationListener 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() { diff --git a/src/main/java/guru/springframework/domain/User.java b/src/main/java/guru/springframework/domain/User.java index 6b49997a..c4723f0e 100644 --- a/src/main/java/guru/springframework/domain/User.java +++ b/src/main/java/guru/springframework/domain/User.java @@ -1,9 +1,10 @@ package guru.springframework.domain; -import javax.persistence.CascadeType; -import javax.persistence.Entity; -import javax.persistence.OneToOne; -import javax.persistence.Transient; +import guru.springframework.domain.security.Role; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; /** * Created by jt on 12/14/15. @@ -25,6 +26,12 @@ public class User extends AbstractDomainClass { @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; } @@ -74,4 +81,26 @@ 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/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/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/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 index 8de94d6e..dc67f218 100644 --- a/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java +++ b/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java @@ -3,12 +3,16 @@ 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 From 835a541f765f7323639eb2a876cd73733df8af03 Mon Sep 17 00:00:00 2001 From: Peter Lorent Date: Tue, 17 Jan 2017 14:08:42 +0100 Subject: [PATCH 31/31] Fixed customer templates to get the correct data from the billing address. --- .../resources/templates/customer/customerform.html | 10 +++++----- src/main/resources/templates/customer/show.html | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/resources/templates/customer/customerform.html b/src/main/resources/templates/customer/customerform.html index c3b6fe1a..90314f7b 100644 --- a/src/main/resources/templates/customer/customerform.html +++ b/src/main/resources/templates/customer/customerform.html @@ -48,31 +48,31 @@

Customer Details

- +
- +
- +
- +
- +
diff --git a/src/main/resources/templates/customer/show.html b/src/main/resources/templates/customer/show.html index 5dadfa44..1d9ab89a 100644 --- a/src/main/resources/templates/customer/show.html +++ b/src/main/resources/templates/customer/show.html @@ -58,31 +58,31 @@

Show Customer

-

Address Line 1

+

Address Line 1

-

Address Line 2

+

Address Line 2

-

City

+

City

-

State

+

State

-

Zipcode

+

Zipcode