diff --git a/.gitignore b/.gitignore
index 6ca05c4a5184..73e6d9e3dd11 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,6 @@ out
target
*.iml
log
-
+*.patch
diff --git a/README.md b/README.md
new file mode 100644
index 000000000000..ed8468410c48
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+Java Enterprise Online Project
+===============================
+Наиболее востребованные технологии /инструменты / фреймворки Java Enterprise:
+Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + plugins.
+
+## Вступительное занятие
+### Описание и план проекта
+### Требования к участникам, Wiki
+### Демо разрабатываемого приложения
diff --git a/config/setenv.bat b/config/setenv.bat
new file mode 100644
index 000000000000..d2ccfc564905
--- /dev/null
+++ b/config/setenv.bat
@@ -0,0 +1,4 @@
+rem run tomcat with JMX ability
+rem Run Tomcat as admin
+rem for remote connection add -Djava.rmi.server.hostname=TomcatServer_IP
+set CATALINA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
diff --git a/pom.xml b/pom.xml
index c8a1c78f3b29..c56f716d4cbf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
ru.javawebinar
topjava
- jar
+ war
1.0-SNAPSHOT
@@ -15,11 +15,15 @@
1.8
UTF-8
UTF-8
+
+
+ 1.1.6
+ 1.7.18
topjava
- install
+ package
org.apache.maven.plugins
@@ -34,6 +38,42 @@
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ compile
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${slf4j.version}
+ runtime
+
+
+
+ org.slf4j
+ jul-to-slf4j
+ ${slf4j.version}
+ runtime
+
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+ runtime
+
+
+
+
+ javax.servlet
+ servlet-api
+ 2.5
+ provided
+
diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java
new file mode 100644
index 000000000000..fde5448b93d8
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java
@@ -0,0 +1,33 @@
+package ru.javawebinar.topjava.model;
+
+import java.time.LocalDateTime;
+
+/**
+ * GKislin
+ * 11.01.2015.
+ */
+public class UserMeal {
+ protected final LocalDateTime dateTime;
+
+ protected final String description;
+
+ protected final int calories;
+
+ public UserMeal(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;
+ }
+}
diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java
new file mode 100644
index 000000000000..66c356922f6b
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java
@@ -0,0 +1,34 @@
+package ru.javawebinar.topjava.model;
+
+import java.time.LocalDateTime;
+
+/**
+ * GKislin
+ * 11.01.2015.
+ */
+public class UserMealWithExceed {
+ protected final LocalDateTime dateTime;
+
+ protected final String description;
+
+ protected final int calories;
+
+ protected final boolean exceed;
+
+ public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) {
+ this.dateTime = dateTime;
+ this.description = description;
+ this.calories = calories;
+ this.exceed = exceed;
+ }
+
+ @Override
+ public String toString() {
+ return "UserMealWithExceed{" +
+ "dateTime=" + dateTime +
+ ", description='" + description + '\'' +
+ ", calories=" + calories +
+ ", exceed=" + exceed +
+ '}';
+ }
+}
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 000000000000..02399b7288cf
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java
@@ -0,0 +1,13 @@
+package ru.javawebinar.topjava.util;
+
+import java.time.LocalTime;
+
+/**
+ * GKislin
+ * 07.01.2015.
+ */
+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/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java
new file mode 100644
index 000000000000..ed7fef004529
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java
@@ -0,0 +1,64 @@
+package ru.javawebinar.topjava.util;
+
+import ru.javawebinar.topjava.model.UserMeal;
+import ru.javawebinar.topjava.model.UserMealWithExceed;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.Month;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * GKislin
+ * 31.05.2015.
+ */
+public class UserMealsUtil {
+ public static void main(String[] args) {
+ List mealList = Arrays.asList(
+ new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500),
+ new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000),
+ new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500),
+ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 1000),
+ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 500),
+ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510)
+ );
+ List filteredMealsWithExceeded = getFilteredMealsWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000);
+ filteredMealsWithExceeded.forEach(System.out::println);
+
+ System.out.println(getFilteredMealsWithExceededByCycle(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000));
+ }
+
+ public static List getFilteredMealsWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+ Map caloriesSumByDate = mealList.stream()
+ .collect(
+ Collectors.groupingBy(um -> um.getDateTime().toLocalDate(),
+ Collectors.summingInt(UserMeal::getCalories))
+ );
+
+ return mealList.stream()
+ .filter(um -> TimeUtil.isBetween(um.getDateTime().toLocalTime(), startTime, endTime))
+ .map(um -> createWithExceed(um, caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay))
+ .collect(Collectors.toList());
+ }
+
+ public static List getFilteredMealsWithExceededByCycle(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {
+
+ final Map caloriesSumPerDate = new HashMap<>();
+ mealList.forEach(meal -> caloriesSumPerDate.merge(meal.getDateTime().toLocalDate(), meal.getCalories(), Integer::sum));
+
+ final List mealExceeded = new ArrayList<>();
+ mealList.forEach(meal -> {
+ final LocalDateTime dateTime = meal.getDateTime();
+ if (TimeUtil.isBetween(dateTime.toLocalTime(), startTime, endTime)) {
+ mealExceeded.add(createWithExceed(meal, caloriesSumPerDate.get(dateTime.toLocalDate()) > caloriesPerDay));
+ }
+ });
+ return mealExceeded;
+ }
+
+ public static UserMealWithExceed createWithExceed(UserMeal um, boolean exceeded) {
+ return new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), exceeded);
+ }
+}
\ No newline at end of file
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 000000000000..9f2490f822e3
--- /dev/null
+++ b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java
@@ -0,0 +1,27 @@
+package ru.javawebinar.topjava.web;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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;
+
+/**
+ * User: gkislin
+ * Date: 19.08.2014
+ */
+public class UserServlet extends HttpServlet {
+ private static final Logger LOG = getLogger(UserServlet.class);
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ LOG.debug("redirect to userList");
+
+// request.getRequestDispatcher("/userList.jsp").forward(request, response);
+ response.sendRedirect("userList.jsp");
+ }
+}
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 000000000000..86dea516174d
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ true
+
+
+
+
+
+
+ ${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 000000000000..d53249c1ac6d
--- /dev/null
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,18 @@
+
+
+ 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 000000000000..f8ff4d08be05
--- /dev/null
+++ b/src/main/webapp/index.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Top Java.
+
+
+Приложение вебинара "Top Java."
+
+
\ No newline at end of file
diff --git a/src/main/webapp/userList.jsp b/src/main/webapp/userList.jsp
new file mode 100644
index 000000000000..c5937284eee7
--- /dev/null
+++ b/src/main/webapp/userList.jsp
@@ -0,0 +1,9 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+
+ User list
+
+
+User list
+
+