Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lesson4-jsf-bootstrap/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@
<version>2.0.SP1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Насколько я зная возможность полностью отказаться от managed бинов появилась только в версии JSF 2.3. Но этот момент нужно уточнить. Речь идет о довольно новых вещах.

public class CategoriesBean {

private static final Logger logger = LoggerFactory.getLogger(CategoriesBean.class);

private Category category;

@Inject
private CategoryRepository categoryRepository;

public String getId() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На всякий случай хочу сказать, что есть еще один подход к построению managed бинов. Можно не создавать геттеры для всех полей сущности, а создать только один геттер для поля с текущей сущностью. Тогда можно будет обращаться к полям из представлений #{categories.category.id}

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<Category> 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";
}
}
Original file line number Diff line number Diff line change
@@ -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<Order> 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";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ru.geekbrains.servlet.entity;

import javax.validation.constraints.NotNull;

public class Category {

private String id;

@NotNull
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Валидация будет работать только в бинах, а этот файл бином не является. На следующем уроке мы преобразуем его в сущность и все заработатет. Пока же предлагаю использовать валидацию в xhtml. Компоненту inputText можно добавить свойство required. Кроме того есть еще семейство вот таких тегов для валидации https://www.tutorialspoint.com/jsf/jsf_validation_tags.htm

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;
}
}
Original file line number Diff line number Diff line change
@@ -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<Product, Integer> orderMap;
Copy link
Owner

@usharik usharik Mar 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А переопределен ли hashCode у продукта?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мапа хранит для заказа пары продукт - количество. Хеш-функцию забыл. Сделаю по id.


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;
}
}
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String, Category> 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<Category> 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());
}
}
Original file line number Diff line number Diff line change
@@ -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<String, Order> 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<Order> 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());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ru.geekbrains.servlet;
package ru.geekbrains.servlet.repository;

import ru.geekbrains.servlet.entity.Product;

Expand Down
8 changes: 7 additions & 1 deletion lesson4-jsf-bootstrap/src/main/webapp/WEB-INF/header.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@
<a class="nav-link" href="index.xhtml">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="cards.xhtml">Product cards</a>
<a class="nav-link" href="products.xhtml">Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="categories.xhtml">Categories</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.xhtml">Orders</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0 mr-sm-2">
Expand Down
Loading