diff --git a/.gitignore b/.gitignore
index 200bfbe2..a9e7e666 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@ Thumbs.db
.project
.classpath
.idea
+.mvn
*.iml
atlassian-ide-plugin.xml
target
diff --git a/pom.xml b/pom.xml
index 30247811..dbe4aaf7 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/java/guru/springframework/controllers/CustomerController.java b/src/main/java/guru/springframework/controllers/CustomerController.java
new file mode 100644
index 00000000..5b835c0c
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/CustomerController.java
@@ -0,0 +1,61 @@
+package guru.springframework.controllers;
+
+import guru.springframework.domain.Customer;
+import guru.springframework.services.CustomerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * Created by jt on 11/15/15.
+ */
+@RequestMapping("/customer")
+@Controller
+public class CustomerController {
+
+ private CustomerService customerService;
+
+ @Autowired
+ public void setCustomerService(CustomerService customerService) {
+ this.customerService = customerService;
+ }
+
+ @RequestMapping({"/list", "/"})
+ public String listCustomers(Model model){
+ model.addAttribute("customers", customerService.listAll());
+ return "customer/list";
+ }
+
+ @RequestMapping("/show/{id}")
+ public String showCustomer(@PathVariable Integer id, Model model){
+ model.addAttribute("customer", customerService.getById(id));
+ return "customer/show";
+ }
+
+ @RequestMapping("/edit/{id}")
+ public String edit(@PathVariable Integer id, Model model){
+ model.addAttribute("customer", customerService.getById(id));
+ return "customer/customerform";
+ }
+
+ @RequestMapping("/new")
+ public String newCustomer(Model model){
+ model.addAttribute("customer", new Customer());
+ return "customer/customerform";
+ }
+
+ @RequestMapping(method = RequestMethod.POST)
+ public String saveOrUpdate(Customer customer){
+ Customer newCustomer = customerService.saveOrUpdate(customer);
+ return "redirect:customer/show/" + newCustomer.getId();
+ }
+
+ @RequestMapping("/delete/{id}")
+ public String delete(@PathVariable Integer id){
+ customerService.delete(id);
+ return "redirect:/customer/list";
+ }
+}
diff --git a/src/main/java/guru/springframework/controllers/IndexController.java b/src/main/java/guru/springframework/controllers/IndexController.java
new file mode 100644
index 00000000..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/java/guru/springframework/controllers/ProductController.java b/src/main/java/guru/springframework/controllers/ProductController.java
new file mode 100644
index 00000000..4c60ff50
--- /dev/null
+++ b/src/main/java/guru/springframework/controllers/ProductController.java
@@ -0,0 +1,60 @@
+package guru.springframework.controllers;
+
+import guru.springframework.domain.Product;
+import guru.springframework.services.ProductService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * Created by jt on 11/6/15.
+ */
+@Controller
+public class ProductController {
+
+ private ProductService productService;
+
+ @Autowired
+ public void setProductService(ProductService productService) {
+ this.productService = productService;
+ }
+
+ @RequestMapping("/product/list")
+ public String listProducts(Model model){
+ model.addAttribute("products", productService.listAll());
+ return "product/list";
+ }
+
+ @RequestMapping("/product/show/{id}")
+ public String getProduct(@PathVariable Integer id, Model model){
+ model.addAttribute("product", productService.getById(id));
+ return "product/show";
+ }
+
+ @RequestMapping("product/edit/{id}")
+ public String edit(@PathVariable Integer id, Model model){
+ model.addAttribute("product", productService.getById(id));
+ return "product/productform";
+ }
+
+ @RequestMapping("/product/new")
+ public String newProduct(Model model){
+ model.addAttribute("product", new Product());
+ return "product/productform";
+ }
+
+ @RequestMapping(value = "/product", method = RequestMethod.POST)
+ public String saveOrUpdateProduct(Product product){
+ Product savedProduct = productService.saveOrUpdate(product);
+ return "redirect:/product/show/" + savedProduct.getId();
+ }
+
+ @RequestMapping("/product/delete/{id}")
+ public String delete(@PathVariable Integer id){
+ productService.delete(id);
+ return "redirect:/product/list";
+ }
+}
diff --git a/src/main/java/guru/springframework/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
new file mode 100644
index 00000000..79bff2a7
--- /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 implements DomainObject{
+ 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/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
new file mode 100644
index 00000000..62a35310
--- /dev/null
+++ b/src/main/java/guru/springframework/services/ProductService.java
@@ -0,0 +1,10 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.Product;
+
+/**
+ * Created by jt on 11/6/15.
+ */
+public interface ProductService extends CRUDService {
+
+}
diff --git a/src/main/java/guru/springframework/services/ProductServiceImpl.java b/src/main/java/guru/springframework/services/ProductServiceImpl.java
new file mode 100644
index 00000000..1382aad2
--- /dev/null
+++ b/src/main/java/guru/springframework/services/ProductServiceImpl.java
@@ -0,0 +1,80 @@
+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.HashMap;
+import java.util.List;
+
+/**
+ * Created by jt on 11/6/15.
+ */
+@Service
+public class ProductServiceImpl extends AbstractMapService implements ProductService {
+
+ @Override
+ public List listAll() {
+ return super.listAll();
+ }
+
+ @Override
+ public Product getById(Integer id) {
+ return (Product) super.getById(id);
+ }
+
+ @Override
+ public Product saveOrUpdate(Product domainObject) {
+ return (Product) super.saveOrUpdate(domainObject);
+ }
+
+ @Override
+ public void delete(Integer id) {
+ super.delete(id);
+ }
+
+ 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 2");
+ product5.setPrice(new BigDecimal("25.99"));
+ product5.setImageUrl("http://example.com/product5");
+
+ domainMap.put(5, product5);
+ }
+}
diff --git a/src/main/resources/static/css/spring-core.css b/src/main/resources/static/css/spring-core.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/main/resources/templates/customer/customerform.html b/src/main/resources/templates/customer/customerform.html
new file mode 100644
index 00000000..c3b6fe1a
--- /dev/null
+++ b/src/main/resources/templates/customer/customerform.html
@@ -0,0 +1,86 @@
+
+
+
+ Spring Core Online Tutorial - Customer Form
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/customer/list.html b/src/main/resources/templates/customer/list.html
new file mode 100644
index 00000000..4904641b
--- /dev/null
+++ b/src/main/resources/templates/customer/list.html
@@ -0,0 +1,50 @@
+
+
+
+ Spring Core Online Tutorial - List Customers
+
+
+
+
+
+
+
+
+
+
+
+
Customer List
+
+
+ | Id |
+ First Name |
+ Last Name |
+ Email |
+ Show |
+ Edit |
+ Delete |
+
+
+ |
+ |
+ |
+ |
+ View |
+ Edit |
+ Delete |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/customer/show.html b/src/main/resources/templates/customer/show.html
new file mode 100644
index 00000000..5dadfa44
--- /dev/null
+++ b/src/main/resources/templates/customer/show.html
@@ -0,0 +1,94 @@
+
+
+
+ Spring Core Online Tutorial - Show Customer
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html
new file mode 100644
index 00000000..9622d970
--- /dev/null
+++ b/src/main/resources/templates/index.html
@@ -0,0 +1,32 @@
+
+
+
+
+ Spring Core Online Tutorial
+
+
+
+
+
+
+
+
+
+
+
Hello World
+
+
This is my Thymeleaf index page.
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/product/list.html b/src/main/resources/templates/product/list.html
new file mode 100644
index 00000000..b7ca555c
--- /dev/null
+++ b/src/main/resources/templates/product/list.html
@@ -0,0 +1,50 @@
+
+
+
+ Spring Core Online Tutorial - List Products
+
+
+
+
+
+
+
+
+
+
+
+
Product List
+
+
+ | Id |
+ Description |
+ Price |
+ Image URL |
+ List |
+ Edit |
+ Delete |
+
+
+ |
+ |
+ |
+ |
+ View |
+ Edit |
+ Delete |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/product/productform.html b/src/main/resources/templates/product/productform.html
new file mode 100644
index 00000000..cd9d9b6e
--- /dev/null
+++ b/src/main/resources/templates/product/productform.html
@@ -0,0 +1,50 @@
+
+
+
+ Spring Core Online Tutorial - Product Form
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/product/show.html b/src/main/resources/templates/product/show.html
new file mode 100644
index 00000000..069ea3c9
--- /dev/null
+++ b/src/main/resources/templates/product/show.html
@@ -0,0 +1,58 @@
+
+
+
+ Spring Core Online Tutorial - Show Product
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file