diff --git a/pom.xml b/pom.xml
index c8a1c78..64c3d6b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
ru.javawebinar
topjava
- jar
+ war
1.0-SNAPSHOT
@@ -15,16 +15,20 @@
1.8
UTF-8
UTF-8
+
+
+ 1.2.3
+ 1.7.25
topjava
- install
+ package
org.apache.maven.plugins
maven-compiler-plugin
- 3.1
+ 3.7.0
${java.version}
${java.version}
@@ -34,6 +38,35 @@
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ compile
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${slf4j.version}
+ runtime
+
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+ runtime
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 4.0.1
+ provided
+
diff --git a/src/main/java/ru/javawebinar/topjava/Main.java b/src/main/java/ru/javawebinar/topjava/Main.java
index b23a2f0..cb7e35a 100644
--- a/src/main/java/ru/javawebinar/topjava/Main.java
+++ b/src/main/java/ru/javawebinar/topjava/Main.java
@@ -1,11 +1,8 @@
package ru.javawebinar.topjava;
/**
- * User: gkislin
- * Date: 05.08.2015
- *
- * @link http://caloriesmng.herokuapp.com/
- * @link https://github.com/JavaOPs/topjava
+ * @see Demo
+ * @see Initial project
*/
public class Main {
public static void main(String[] args) {
diff --git a/src/main/java/ru/javawebinar/topjava/model/Meal.java b/src/main/java/ru/javawebinar/topjava/model/Meal.java
new file mode 100644
index 0000000..943ff5c
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/model/Meal.java
@@ -0,0 +1,39 @@
+package ru.javawebinar.topjava.model;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+public class Meal {
+ private final LocalDateTime dateTime;
+
+ private final String description;
+
+ private final int calories;
+
+ public Meal(LocalDateTime dateTime, String description, int calories) {
+ this.dateTime = dateTime;
+ this.description = description;
+ this.calories = calories;
+ }
+
+ public LocalDateTime getDateTime() {
+ return dateTime;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public int getCalories() {
+ return calories;
+ }
+
+ public LocalDate getDate() {
+ return dateTime.toLocalDate();
+ }
+
+ public LocalTime getTime() {
+ return dateTime.toLocalTime();
+ }
+}
diff --git a/src/main/java/ru/javawebinar/topjava/model/MealTo.java b/src/main/java/ru/javawebinar/topjava/model/MealTo.java
new file mode 100644
index 0000000..23f88ce
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/model/MealTo.java
@@ -0,0 +1,30 @@
+package ru.javawebinar.topjava.model;
+
+import java.time.LocalDateTime;
+
+public class MealTo {
+ private final LocalDateTime dateTime;
+
+ private final String description;
+
+ private final int calories;
+
+ private final boolean excess;
+
+ public MealTo(LocalDateTime dateTime, String description, int calories, boolean excess) {
+ this.dateTime = dateTime;
+ this.description = description;
+ this.calories = calories;
+ this.excess = excess;
+ }
+
+ @Override
+ public String toString() {
+ return "MealTo{" +
+ "dateTime=" + dateTime +
+ ", description='" + description + '\'' +
+ ", calories=" + calories +
+ ", excess=" + excess +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ru/javawebinar/topjava/util/MealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/MealsUtil.java
new file mode 100644
index 0000000..e251ba0
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/util/MealsUtil.java
@@ -0,0 +1,111 @@
+package ru.javawebinar.topjava.util;
+
+import ru.javawebinar.topjava.model.Meal;
+import ru.javawebinar.topjava.model.MealTo;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.Month;
+import java.util.*;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toList;
+
+public class MealsUtil {
+ public static void main(String[] args) {
+ List meals = Arrays.asList(
+ new Meal(LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500),
+ new Meal(LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000),
+ new Meal(LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500),
+ new Meal(LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 1000),
+ new Meal(LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 500),
+ new Meal(LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510)
+ );
+ List mealsWithExcess = getFilteredWithExcess(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000);
+ mealsWithExcess.forEach(System.out::println);
+
+ System.out.println(getFilteredWithExcessByCycle(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000));
+ System.out.println(getFilteredWithExcessInOnePass(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000));
+ System.out.println(getFilteredWithExcessInOnePass2(meals, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000));
+ }
+
+ public static List getFilteredWithExcess(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+ Map caloriesSumByDate = meals.stream()
+ .collect(
+ Collectors.groupingBy(Meal::getDate, Collectors.summingInt(Meal::getCalories))
+// Collectors.toMap(Meal::getDate, Meal::getCalories, Integer::sum)
+ );
+
+ return meals.stream()
+ .filter(meal -> TimeUtil.isBetween(meal.getTime(), startTime, endTime))
+ .map(meal -> createWithExcess(meal, caloriesSumByDate.get(meal.getDate()) > caloriesPerDay))
+ .collect(Collectors.toList());
+ }
+
+ public static List getFilteredWithExcessByCycle(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+
+ final Map caloriesSumByDate = new HashMap<>();
+ meals.forEach(meal -> caloriesSumByDate.merge(meal.getDate(), meal.getCalories(), Integer::sum));
+
+ final List mealsWithExcess = new ArrayList<>();
+ meals.forEach(meal -> {
+ if (TimeUtil.isBetween(meal.getTime(), startTime, endTime)) {
+ mealsWithExcess.add(createWithExcess(meal, caloriesSumByDate.get(meal.getDate()) > caloriesPerDay));
+ }
+ });
+ return mealsWithExcess;
+ }
+
+ public static List getFilteredWithExcessInOnePass(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+ Collection> list = meals.stream()
+ .collect(Collectors.groupingBy(Meal::getDate)).values();
+
+ return list.stream().flatMap(dayMeals -> {
+ boolean excess = dayMeals.stream().mapToInt(Meal::getCalories).sum() > caloriesPerDay;
+ return dayMeals.stream().filter(meal ->
+ TimeUtil.isBetween(meal.getTime(), startTime, endTime))
+ .map(meal -> createWithExcess(meal, excess));
+ }).collect(toList());
+ }
+
+ public static List getFilteredWithExcessInOnePass2(List meals, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+ final class Aggregate {
+ private final List dailyMeals = new ArrayList<>();
+ private int dailySumOfCalories;
+
+ private void accumulate(Meal meal) {
+ dailySumOfCalories += meal.getCalories();
+ if (TimeUtil.isBetween(meal.getDateTime().toLocalTime(), startTime, endTime)) {
+ dailyMeals.add(meal);
+ }
+ }
+
+ // never invoked if the upstream is sequential
+ private Aggregate combine(Aggregate that) {
+ this.dailySumOfCalories += that.dailySumOfCalories;
+ this.dailyMeals.addAll(that.dailyMeals);
+ return this;
+ }
+
+ private Stream finisher() {
+ final boolean excess = dailySumOfCalories > caloriesPerDay;
+ return dailyMeals.stream().map(meal -> createWithExcess(meal, excess));
+ }
+ }
+
+ Collection> values = meals.stream()
+ .collect(Collectors.groupingBy(Meal::getDate,
+ Collector.of(Aggregate::new, Aggregate::accumulate, Aggregate::combine, Aggregate::finisher))
+ ).values();
+
+ return values.stream().flatMap(identity()).collect(toList());
+ }
+
+ public static MealTo createWithExcess(Meal meal, boolean excess) {
+ return new MealTo(meal.getDateTime(), meal.getDescription(), meal.getCalories(), excess);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java
new file mode 100644
index 0000000..b7eb2af
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java
@@ -0,0 +1,9 @@
+package ru.javawebinar.topjava.util;
+
+import java.time.LocalTime;
+
+public class TimeUtil {
+ public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime endTime) {
+ return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) <= 0;
+ }
+}
diff --git a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java
new file mode 100644
index 0000000..ef52d67
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java
@@ -0,0 +1,23 @@
+package ru.javawebinar.topjava.web;
+
+import org.slf4j.Logger;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class UserServlet extends HttpServlet {
+ private static final Logger log = getLogger(UserServlet.class);
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ log.debug("redirect to users");
+
+// request.getRequestDispatcher("/users.jsp").forward(request, response);
+ response.sendRedirect("users.jsp");
+ }
+}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000..e9b900b
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+ ${TOPJAVA_ROOT}/log/topjava.log
+
+
+ UTF-8
+ %date %-5level %logger{0} [%file:%line] %msg%n
+
+
+
+
+
+ UTF-8
+ %-5level %logger{0} [%file:%line] %msg%n
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..c63810c
--- /dev/null
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,19 @@
+
+
+ Topjava
+
+
+ userServlet
+ ru.javawebinar.topjava.web.UserServlet
+ 0
+
+
+ userServlet
+ /users
+
+
+
diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html
new file mode 100644
index 0000000..6253517
--- /dev/null
+++ b/src/main/webapp/index.html
@@ -0,0 +1,13 @@
+
+
+
+ Java Enterprise (Topjava)
+
+
+
+
+
+
+
diff --git a/src/main/webapp/users.jsp b/src/main/webapp/users.jsp
new file mode 100644
index 0000000..acf19d7
--- /dev/null
+++ b/src/main/webapp/users.jsp
@@ -0,0 +1,10 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+
+ Users
+
+
+
+Users
+
+
\ No newline at end of file