diff --git a/lesson4-jsf-bootstrap/pom.xml b/lesson4-jsf-bootstrap/pom.xml
index 435e565..7469fbf 100644
--- a/lesson4-jsf-bootstrap/pom.xml
+++ b/lesson4-jsf-bootstrap/pom.xml
@@ -49,6 +49,17 @@
2.0.SP1
provided
+
+
+ javax.validation
+ validation-api
+ 2.0.1.Final
+
+
+ org.hibernate.validator
+ hibernate-validator
+ 6.0.13.Final
+
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/CategoriesBean.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/CategoriesBean.java
new file mode 100644
index 0000000..0896262
--- /dev/null
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/CategoriesBean.java
@@ -0,0 +1,69 @@
+package ru.geekbrains.servlet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import ru.geekbrains.servlet.entity.Category;
+import ru.geekbrains.servlet.entity.Category;
+import ru.geekbrains.servlet.repository.CategoryRepository;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.SessionScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.Collection;
+
+@Named("categories")
+@SessionScoped
+public class CategoriesBean {
+
+ private static final Logger logger = LoggerFactory.getLogger(CategoriesBean.class);
+
+ private Category category;
+
+ @Inject
+ private CategoryRepository categoryRepository;
+
+ public String getId() {
+ return category.getId();
+ }
+
+ public void setId(String id) {
+ category.setId(id);
+ }
+
+ public String getName() {
+ return category.getName();
+ }
+
+ public void setName(String name) {
+ category.setName(name);
+ }
+
+ public Collection getCategoryList() {
+ return categoryRepository.getAll();
+ }
+
+ public void deleteAction(Category category) {
+ logger.info("Delete category with id {} and name {}", category.getId(), category.getName());
+ categoryRepository.delete(category);
+ }
+
+ public String addAction() {
+ logger.info("Add category action");
+
+ category = new Category();
+ return "/category.xhtml?faces-redirect=true";
+ }
+
+ public String editAction(Category category) {
+ logger.info("Edit category with id {} and name {}", category.getId(), category.getName());
+
+ this.category = category;
+ return "/category.xhtml?faces-redirect=true";
+ }
+
+ public String saveCategory() {
+ categoryRepository.merge(category);
+ return "/categories.xhtml?faces-redirect=true";
+ }
+}
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/OrdersBean.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/OrdersBean.java
new file mode 100644
index 0000000..af063e2
--- /dev/null
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/OrdersBean.java
@@ -0,0 +1,60 @@
+package ru.geekbrains.servlet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import ru.geekbrains.servlet.entity.Order;
+import ru.geekbrains.servlet.repository.OrderRepository;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.SessionScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.Collection;
+
+@Named("orders")
+@SessionScoped
+public class OrdersBean {
+
+ private static final Logger logger = LoggerFactory.getLogger(OrdersBean.class);
+
+ private Order order;
+
+ @Inject
+ private OrderRepository orderRepository;
+
+ public String getId() {
+ return order.getId();
+ }
+
+ public void setId(String id) {
+ order.setId(id);
+ }
+
+ public Collection getOrderList() {
+ return orderRepository.getAll();
+ }
+
+ public void deleteAction(Order order) {
+ logger.info("Delete order with id {} and name {}", order.getId());
+ orderRepository.delete(order);
+ }
+
+ public String addAction() {
+ logger.info("Add order action");
+
+ orderRepository.merge(new Order());
+ return "/orders.xhtml?faces-redirect=true";
+ }
+
+ public String editAction(Order order) {
+ logger.info("Edit order with id {} and name {}", order.getId());
+
+ this.order = order;
+ return "/order.xhtml?faces-redirect=true";
+ }
+
+ public String saveOrder() {
+ orderRepository.merge(order);
+ return "/orders.xhtml?faces-redirect=true";
+ }
+}
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/ProductsBean.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/ProductsBean.java
index 30d3d3d..25bd4eb 100644
--- a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/ProductsBean.java
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/ProductsBean.java
@@ -3,10 +3,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.geekbrains.servlet.entity.Product;
+import ru.geekbrains.servlet.repository.ProductRepository;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.inject.Inject;
+import javax.inject.Named;
import java.util.Collection;
@ManagedBean(name = "products")
@@ -69,6 +71,6 @@ public String editAction(Product product) {
public String saveProduct() {
productRepository.merge(product);
- return "/index.xhtml?faces-redirect=true";
+ return "/products.xhtml?faces-redirect=true";
}
}
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Category.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Category.java
new file mode 100644
index 0000000..a79307e
--- /dev/null
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Category.java
@@ -0,0 +1,34 @@
+package ru.geekbrains.servlet.entity;
+
+import javax.validation.constraints.NotNull;
+
+public class Category {
+
+ private String id;
+
+ @NotNull
+ private String name;
+
+ public Category() {}
+
+ public Category(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Order.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Order.java
new file mode 100644
index 0000000..8cebfba
--- /dev/null
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Order.java
@@ -0,0 +1,41 @@
+package ru.geekbrains.servlet.entity;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Order {
+
+ private String id;
+ private Map orderMap;
+
+ public Order() {}
+
+ public Order(String id) {
+ this.id = id;
+ orderMap = new HashMap<>();
+ }
+
+ public void addProduct(Product product, int count) {
+ if (orderMap.containsKey(product)) {
+ orderMap.compute(product, (good, amount) -> amount + count);
+ } else {
+ orderMap.put(product, count);
+ }
+ }
+
+ public void setProductCount(Product product, int count) {
+ orderMap.put(product, count);
+ }
+
+ public void removeProduct(Product product) {
+ orderMap.remove(product);
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+}
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Product.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Product.java
index f32236e..6ef8c83 100644
--- a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Product.java
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/entity/Product.java
@@ -1,11 +1,16 @@
package ru.geekbrains.servlet.entity;
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.NotNull;
+
public class Product {
private String id;
+ @NotNull
private String name;
+ @Digits(integer = Integer.MAX_VALUE, fraction = 2)
private int price;
public Product() {
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/CategoryRepository.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/CategoryRepository.java
new file mode 100644
index 0000000..c4d1d28
--- /dev/null
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/CategoryRepository.java
@@ -0,0 +1,50 @@
+package ru.geekbrains.servlet.repository;
+
+import ru.geekbrains.servlet.entity.Category;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Класс-заглушка для репозитория
+ * через несколько уроков мы его заменим на
+ * полноценный JPA репозиторий
+ */
+@ApplicationScoped
+public class CategoryRepository {
+
+ private AtomicInteger sequence = new AtomicInteger();
+
+ private Map categoryMap = Collections.synchronizedMap(new LinkedHashMap<>());
+
+ public CategoryRepository() {
+ this.merge(new Category("1", "Books"));
+ this.merge(new Category("2", "Planes"));
+ this.merge(new Category("3", "Fruits"));
+ this.merge(new Category("4", "Clothes"));
+ sequence.set(categoryMap.size());
+ }
+
+ public Collection getAll() {
+ return categoryMap.values();
+ }
+
+ public Category getById(String id) {
+ return categoryMap.get(id);
+ }
+
+ public void merge(Category category) {
+ if (category.getId() == null || !categoryMap.containsKey(category.getId())) {
+ category.setId(String.valueOf(sequence.incrementAndGet()));
+ }
+ categoryMap.put(category.getId(), category);
+ }
+
+ public void delete(Category category) {
+ categoryMap.remove(category.getId());
+ }
+}
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/OrderRepository.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/OrderRepository.java
new file mode 100644
index 0000000..92a1486
--- /dev/null
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/OrderRepository.java
@@ -0,0 +1,50 @@
+package ru.geekbrains.servlet.repository;
+
+import ru.geekbrains.servlet.entity.Order;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Класс-заглушка для репозитория
+ * через несколько уроков мы его заменим на
+ * полноценный JPA репозиторий
+ */
+@ApplicationScoped
+public class OrderRepository {
+
+ private AtomicInteger sequence = new AtomicInteger();
+
+ private Map orderMap = Collections.synchronizedMap(new LinkedHashMap<>());
+
+ public OrderRepository() {
+ this.merge(new Order("1"));
+ this.merge(new Order("2"));
+ this.merge(new Order("3"));
+ this.merge(new Order("4"));
+ sequence.set(orderMap.size());
+ }
+
+ public Collection getAll() {
+ return orderMap.values();
+ }
+
+ public Order getById(String id) {
+ return orderMap.get(id);
+ }
+
+ public void merge(Order order) {
+ if (order.getId() == null || !orderMap.containsKey(order.getId())) {
+ order.setId(String.valueOf(sequence.incrementAndGet()));
+ }
+ orderMap.put(order.getId(), order);
+ }
+
+ public void delete(Order order) {
+ orderMap.remove(order.getId());
+ }
+}
diff --git a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/ProductRepository.java b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/ProductRepository.java
similarity index 97%
rename from lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/ProductRepository.java
rename to lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/ProductRepository.java
index bbe33ff..552c029 100644
--- a/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/ProductRepository.java
+++ b/lesson4-jsf-bootstrap/src/main/java/ru/geekbrains/servlet/repository/ProductRepository.java
@@ -1,4 +1,4 @@
-package ru.geekbrains.servlet;
+package ru.geekbrains.servlet.repository;
import ru.geekbrains.servlet.entity.Product;
diff --git a/lesson4-jsf-bootstrap/src/main/webapp/WEB-INF/header.xhtml b/lesson4-jsf-bootstrap/src/main/webapp/WEB-INF/header.xhtml
index 8b31b6b..c1ee968 100644
--- a/lesson4-jsf-bootstrap/src/main/webapp/WEB-INF/header.xhtml
+++ b/lesson4-jsf-bootstrap/src/main/webapp/WEB-INF/header.xhtml
@@ -16,7 +16,13 @@
Home (current)
- Product cards
+ Products
+
+
+ Categories
+
+
+ Orders