Skip to content

Commit d53ba11

Browse files
committed
2_2_HW1_optional applied
1 parent 650b7d3 commit d53ba11

8 files changed

Lines changed: 222 additions & 9 deletions

File tree

src/main/java/ru/javawebinar/topjava/model/Meal.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,33 @@
55
import java.time.LocalTime;
66

77
public class Meal {
8+
private Integer id;
9+
810
private final LocalDateTime dateTime;
911

1012
private final String description;
1113

1214
private final int calories;
1315

1416
public Meal(LocalDateTime dateTime, String description, int calories) {
17+
this(null, dateTime, description, calories);
18+
}
19+
20+
public Meal(Integer id, LocalDateTime dateTime, String description, int calories) {
21+
this.id = id;
1522
this.dateTime = dateTime;
1623
this.description = description;
1724
this.calories = calories;
1825
}
1926

27+
public Integer getId() {
28+
return id;
29+
}
30+
31+
public void setId(Integer id) {
32+
this.id = id;
33+
}
34+
2035
public LocalDateTime getDateTime() {
2136
return dateTime;
2237
}
@@ -36,4 +51,18 @@ public LocalDate getDate() {
3651
public LocalTime getTime() {
3752
return dateTime.toLocalTime();
3853
}
54+
55+
public boolean isNew() {
56+
return id == null;
57+
}
58+
59+
@Override
60+
public String toString() {
61+
return "Meal{" +
62+
"id=" + id +
63+
", dateTime=" + dateTime +
64+
", description='" + description + '\'' +
65+
", calories=" + calories +
66+
'}';
67+
}
3968
}

src/main/java/ru/javawebinar/topjava/model/MealTo.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.time.LocalDateTime;
44

55
public class MealTo {
6+
private final Integer id;
7+
68
private final LocalDateTime dateTime;
79

810
private final String description;
@@ -11,13 +13,18 @@ public class MealTo {
1113

1214
private final boolean excess;
1315

14-
public MealTo(LocalDateTime dateTime, String description, int calories, boolean excess) {
16+
public MealTo(Integer id, LocalDateTime dateTime, String description, int calories, boolean excess) {
17+
this.id = id;
1518
this.dateTime = dateTime;
1619
this.description = description;
1720
this.calories = calories;
1821
this.excess = excess;
1922
}
2023

24+
public Integer getId() {
25+
return id;
26+
}
27+
2128
public LocalDateTime getDateTime() {
2229
return dateTime;
2330
}
@@ -37,7 +44,8 @@ public boolean isExcess() {
3744
@Override
3845
public String toString() {
3946
return "MealTo{" +
40-
"dateTime=" + dateTime +
47+
"id=" + id +
48+
", dateTime=" + dateTime +
4149
", description='" + description + '\'' +
4250
", calories=" + calories +
4351
", excess=" + excess +
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ru.javawebinar.topjava.repository;
2+
3+
import ru.javawebinar.topjava.model.Meal;
4+
import ru.javawebinar.topjava.util.MealsUtil;
5+
6+
import java.util.Collection;
7+
import java.util.Map;
8+
import java.util.concurrent.ConcurrentHashMap;
9+
import java.util.concurrent.atomic.AtomicInteger;
10+
11+
public class InMemoryMealRepository implements MealRepository {
12+
private final Map<Integer, Meal> mealsMap = new ConcurrentHashMap<>();
13+
private final AtomicInteger counter = new AtomicInteger(0);
14+
15+
{
16+
MealsUtil.meals.forEach(this::save);
17+
}
18+
19+
@Override
20+
public Meal save(Meal meal) {
21+
if (meal.isNew()) {
22+
meal.setId(counter.incrementAndGet());
23+
mealsMap.put(meal.getId(), meal);
24+
return meal;
25+
}
26+
// handle case: update, but not present in storage
27+
return mealsMap.computeIfPresent(meal.getId(), (id, oldMeal) -> meal);
28+
}
29+
30+
@Override
31+
public boolean delete(int id) {
32+
return mealsMap.remove(id) != null;
33+
}
34+
35+
@Override
36+
public Meal get(int id) {
37+
return mealsMap.get(id);
38+
}
39+
40+
@Override
41+
public Collection<Meal> getAll() {
42+
return mealsMap.values();
43+
}
44+
}
45+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package ru.javawebinar.topjava.repository;
2+
3+
import ru.javawebinar.topjava.model.Meal;
4+
5+
import java.util.Collection;
6+
7+
public interface MealRepository {
8+
// null if not found, when updated
9+
Meal save(Meal meal);
10+
11+
// false if not found
12+
boolean delete(int id);
13+
14+
// null if not found
15+
Meal get(int id);
16+
17+
Collection<Meal> getAll();
18+
}

src/main/java/ru/javawebinar/topjava/util/MealsUtil.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.time.LocalTime;
99
import java.time.Month;
1010
import java.util.Arrays;
11+
import java.util.Collection;
1112
import java.util.List;
1213
import java.util.Map;
1314
import java.util.function.Predicate;
@@ -26,15 +27,15 @@ public class MealsUtil {
2627
new Meal(LocalDateTime.of(2020, Month.JANUARY, 31, 20, 0), "Ужин", 410)
2728
);
2829

29-
public static List<MealTo> getTos(List<Meal> meals, int caloriesPerDay) {
30+
public static List<MealTo> getTos(Collection<Meal> meals, int caloriesPerDay) {
3031
return filterByPredicate(meals, caloriesPerDay, meal -> true);
3132
}
3233

33-
public static List<MealTo> getFilteredTos(List<Meal> meals, int caloriesPerDay, LocalTime startTime, LocalTime endTime) {
34+
public static List<MealTo> getFilteredTos(Collection<Meal> meals, int caloriesPerDay, LocalTime startTime, LocalTime endTime) {
3435
return filterByPredicate(meals, caloriesPerDay, meal -> DateTimeUtil.isBetweenHalfOpen(meal.getTime(), startTime, endTime));
3536
}
3637

37-
private static List<MealTo> filterByPredicate(List<Meal> meals, int caloriesPerDay, Predicate<Meal> filter) {
38+
private static List<MealTo> filterByPredicate(Collection<Meal> meals, int caloriesPerDay, Predicate<Meal> filter) {
3839
Map<LocalDate, Integer> caloriesSumByDate = meals.stream()
3940
.collect(
4041
Collectors.groupingBy(Meal::getDate, Collectors.summingInt(Meal::getCalories))
@@ -48,6 +49,6 @@ private static List<MealTo> filterByPredicate(List<Meal> meals, int caloriesPerD
4849
}
4950

5051
private static MealTo createTo(Meal meal, boolean excess) {
51-
return new MealTo(meal.getDateTime(), meal.getDescription(), meal.getCalories(), excess);
52+
return new MealTo(meal.getId(), meal.getDateTime(), meal.getDescription(), meal.getCalories(), excess);
5253
}
5354
}

src/main/java/ru/javawebinar/topjava/web/MealServlet.java

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,76 @@
22

33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
5+
import ru.javawebinar.topjava.model.Meal;
6+
import ru.javawebinar.topjava.repository.InMemoryMealRepository;
7+
import ru.javawebinar.topjava.repository.MealRepository;
58
import ru.javawebinar.topjava.util.MealsUtil;
69

710
import javax.servlet.ServletException;
811
import javax.servlet.http.HttpServlet;
912
import javax.servlet.http.HttpServletRequest;
1013
import javax.servlet.http.HttpServletResponse;
1114
import java.io.IOException;
15+
import java.time.LocalDateTime;
16+
import java.time.temporal.ChronoUnit;
17+
import java.util.Objects;
1218

1319
public class MealServlet extends HttpServlet {
1420
private static final Logger log = LoggerFactory.getLogger(MealServlet.class);
1521

22+
private MealRepository repository;
23+
24+
@Override
25+
public void init() {
26+
repository = new InMemoryMealRepository();
27+
}
28+
29+
@Override
30+
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
31+
request.setCharacterEncoding("UTF-8");
32+
String id = request.getParameter("id");
33+
34+
Meal meal = new Meal(id.isEmpty() ? null : Integer.valueOf(id),
35+
LocalDateTime.parse(request.getParameter("dateTime")),
36+
request.getParameter("description"),
37+
Integer.parseInt(request.getParameter("calories")));
38+
39+
log.info(meal.isNew() ? "Create {}" : "Update {}", meal);
40+
repository.save(meal);
41+
response.sendRedirect("meals");
42+
}
43+
1644
@Override
1745
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
18-
log.info("forward to meals");
19-
request.setAttribute("meals", MealsUtil.getTos(MealsUtil.meals, MealsUtil.DEFAULT_CALORIES_PER_DAY));
20-
request.getRequestDispatcher("/meals.jsp").forward(request, response);
46+
String action = request.getParameter("action");
47+
48+
switch (action == null ? "all" : action) {
49+
case "delete":
50+
int id = getId(request);
51+
log.info("Delete id={}", id);
52+
repository.delete(id);
53+
response.sendRedirect("meals");
54+
break;
55+
case "create":
56+
case "update":
57+
final Meal meal = "create".equals(action) ?
58+
new Meal(LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES), "", 1000) :
59+
repository.get(getId(request));
60+
request.setAttribute("meal", meal);
61+
request.getRequestDispatcher("/mealForm.jsp").forward(request, response);
62+
break;
63+
case "all":
64+
default:
65+
log.info("getAll");
66+
request.setAttribute("meals",
67+
MealsUtil.getTos(repository.getAll(), MealsUtil.DEFAULT_CALORIES_PER_DAY));
68+
request.getRequestDispatcher("/meals.jsp").forward(request, response);
69+
break;
70+
}
71+
}
72+
73+
private int getId(HttpServletRequest request) {
74+
String paramId = Objects.requireNonNull(request.getParameter("id"));
75+
return Integer.parseInt(paramId);
2176
}
2277
}

src/main/webapp/mealForm.jsp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<%@ page contentType="text/html;charset=UTF-8" %>
2+
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3+
4+
<html>
5+
<head>
6+
<title>Meal</title>
7+
<style>
8+
dl {
9+
background: none repeat scroll 0 0 #FAFAFA;
10+
margin: 8px 0;
11+
padding: 0;
12+
}
13+
14+
dt {
15+
display: inline-block;
16+
width: 170px;
17+
}
18+
19+
dd {
20+
display: inline-block;
21+
margin-left: 8px;
22+
vertical-align: top;
23+
}
24+
</style>
25+
</head>
26+
<body>
27+
<section>
28+
<h3><a href="index.html">Home</a></h3>
29+
<hr>
30+
<h2>${param.action == 'create' ? 'Create meal' : 'Edit meal'}</h2>
31+
<jsp:useBean id="meal" type="ru.javawebinar.topjava.model.Meal" scope="request"/>
32+
<form method="post" action="meals">
33+
<input type="hidden" name="id" value="${meal.id}">
34+
<dl>
35+
<dt>DateTime:</dt>
36+
<dd><input type="datetime-local" value="${meal.dateTime}" name="dateTime" required></dd>
37+
</dl>
38+
<dl>
39+
<dt>Description:</dt>
40+
<dd><input type="text" value="${meal.description}" size=40 name="description" required></dd>
41+
</dl>
42+
<dl>
43+
<dt>Calories:</dt>
44+
<dd><input type="number" value="${meal.calories}" name="calories" required></dd>
45+
</dl>
46+
<button type="submit">Save</button>
47+
<button onclick="window.history.back()" type="button">Cancel</button>
48+
</form>
49+
</section>
50+
</body>
51+
</html>

src/main/webapp/meals.jsp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@
2121
<h3><a href="index.html">Home</a></h3>
2222
<hr/>
2323
<h2>Meals</h2>
24+
<a href="meals?action=create">Add Meal</a>
25+
<br><br>
2426
<table border="1" cellpadding="8" cellspacing="0">
2527
<thead>
2628
<tr>
2729
<th>Date</th>
2830
<th>Description</th>
2931
<th>Calories</th>
32+
<th></th>
33+
<th></th>
3034
</tr>
3135
</thead>
3236
<c:forEach items="${requestScope.meals}" var="meal">
@@ -40,6 +44,8 @@
4044
</td>
4145
<td>${meal.description}</td>
4246
<td>${meal.calories}</td>
47+
<td><a href="meals?action=update&id=${meal.id}">Update</a></td>
48+
<td><a href="meals?action=delete&id=${meal.id}">Delete</a></td>
4349
</tr>
4450
</c:forEach>
4551
</table>

0 commit comments

Comments
 (0)