From 94f9acf8c8308ed0a60c38664c07f8c5cabd9e0e Mon Sep 17 00:00:00 2001 From: "life@u-rise.com" Date: Tue, 7 Jun 2016 23:08:51 +0300 Subject: [PATCH 01/39] Add description --- README.md | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ cv.md | 68 +++++++++++++++++++++++++++ description.md | 67 +++++++++++++++++++++++++++ 3 files changed, 257 insertions(+) create mode 100644 README.md create mode 100644 cv.md create mode 100644 description.md diff --git a/README.md b/README.md new file mode 100644 index 000000000000..2cc45adedb00 --- /dev/null +++ b/README.md @@ -0,0 +1,122 @@ +Java Enterprise Online Project +=============================== +Наиболее востребованные технологии /инструменты / фреймворки Java Enterprise: +Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + plugins. + + Когда вы слышите что-то, вы забываете это. + Когда вы видите что-то, вы запоминаете это. + Но только когда вы начинаете делать это, + вы начинаете понимать это + + Старинная китайская поговорка + +## Описание и план проекта +### Демо разрабатываемого приложения +### Требования к участникам, Wiki +### Составление резюме, подготовка к интервью, поиск работы + +Вводное занятие +=============== +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) Системы управления версиями. Git. +- **Wiki по ведению проекта в Git** +- Система управления версиями. VCS/DVSC. +- Ресурсы: + - Интерактивная Git обучалка + - Книга Git + - Working with remote repositories + - Видео по обучению Git + - Git Overview + - Видеокурс по Git + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) Работа с проектом (выполнять инструкции) +- **Prepare_ to_ HW0.patch (скачать и положить в каталог вашего проекта)** +- Доступно о Java 8 Lambda + +## Инструкция по шагам (из видео): +- Установить ПО (git, JDK8, IntelliJ IDEA, Maven) +- Создать аккаунт на GitHub +- Сделать Fork ЭТОГО проекта (https://github.com/JavaOPs/topjava) +- Сделать локальный репозиторий проекта: +
git clone https://github.com/[Ваш аккаунт]/topjava.git
+- Открыть и настроить проект в IDEA +- По ходу видео сделать Apply Patch... скаченного патча Prepare_ to_ HW0.patch +- Закоммитить и запушить изменения (commit + push) +- Сделать ветку домашнего задания +- Выполнить задание и залить на GitHub (commit + push) +- Переключиться в основную ветку проекта master. + +## ![hw](https://cloud.githubusercontent.com/assets/13649199/13672719/09593080-e6e7-11e5-81d1-5cb629c438ca.png) Домашнее задание HW0 + +- Java 8 Date and Time API +- Алгоритмы и структуры данных для начинающих: сложность алгоритмов +- Time complexity +- Временная сложность алгоритма +- Вычислительная сложность +``` +Реализовать UserMealsUtil.getFilteredMealsWithExceeded: +- должны возвращаться только записи между startTime и endTime +- поле UserMealWithExceed.exceed должно показывать, + превышает ли сумма калорий за весь день параметра метода caloriesPerDay + +Т.е UserMealWithExceed - это запись одной еды, но поле exceeded будет одинаково для всех записей за этот день. + +- Проверте результат выполнения ДЗ (можно проверить логику в http://topjava.herokuapp.com , список еды) +- Оцените Time complexity вашего алгоритма, если он O(N*N)- попробуйте сделать O(N). +``` +Optional + +- Java 8: Lambda выражения +- Java 8: Потоки +- Pуководство по Java 8 Stream +- Лямбда-выражения в Java 8 +- A Guide to Java 8 +- Шпаргалка Java Stream API +- Алексея Владыкин: Элементы функционального программирования в Java +- stream.map vs forEach + +``` +Сделать реализация через Java 8 Stream API. Заменяйте forEach оператором stream.map(..) +``` +### Ресурсы для подготовки к проекту +> ВНИМАНИЕ: основы JavaSсript необходимы для понимания проекта, начиная с 8-го занятия! + +Все остальное - опционально. + +#### HTML, JavaScript, CSS +- Введение в программирование на JavaScript +- Основы работы с HTML/CSS/JavaScript +- JavaScript - Основы +- Bootstrap 3 - Основы +- jQuery для начинающих + +#### Java (базовые вещи) +- Интуит. Программирование на Java +- Основы Java garbage collection +- Размер Java объектов +- Блог о памяти, сборщике мусора, многопоточности и производительности в JAVA +- Введение в Java Reflection API +- Структуры данных в картинках +- Обзор java.util.concurrent.* +- Синхронизация потоков +- String literal pool +- Маленькие хитрости Java +- Как создать Servlet? Полное руководство. +- A Guide to Java 8 +- Java JUnit + +#### JDBC, SQL +- Уроки по JDBC +- Learn SQL +- Try SQL + +#### Разное +- Эффективная работа с кодом в IntelliJ IDEA +- Quizful- тесты онлайн + +#### Книги +- Джошуа Блох: Java. Эффективное программирование. Второе издание +- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования +- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL +- Brian Goetz: Java Concurrency in Practice +- G.L. McDowell: Cracking the Coding Interview diff --git a/cv.md b/cv.md new file mode 100644 index 000000000000..c7236867c665 --- /dev/null +++ b/cv.md @@ -0,0 +1,68 @@ +## Составление резюме, подготовка к интервью, поиск работы + +![cv](https://cloud.githubusercontent.com/assets/13649199/10877471/93ea86b8-8157-11e5-9bfa-95e3fba75c58.jpg) + +- Научиться программировать сложнее, чем кажется + +### Составление резюме: +- ОФОРМЛЕНИЕ IT-РЕЗЮМЕ для USA +- Идеальное резюме Junior’а +- Как продать свое резюме в 2 раза дороже +- Как правильно составить резюме +- Резюме программистов. Часть 1 (плохие) +- Резюме программистов. Часть 2 (хорошие) +- Как составить резюме на английском + +### Наши истории (делимся опытом и успехом) + +### Тесты онлайн: +- Codility lesson tests +- Quizful- тесты онлайн + +### Интервью: +- Михаил Портнов. Собеседование на работу: как продать себя грамотно +- Михаил Портнов. Какие вопросы мы задаем на собеседовании? +- Канал: Резюме, поиск работы, интервью +- Яков Файн: Как стать профессиональным Java разработчиком +- Список вопросов с ответами для собеседования по Java +- Сборка по вопросам на интервью +- Сборка вопросов-ответов от JavaStudy +- Тест на знание SQL +- Вопросы на собеседовании Java Junior Developer +- Java вопросы с собеседований на Android +- Сборка вопросов от JavaRush +> про clone и finalize объязательно прочтите Джошуа Блох: Java. Эффективное программирование (второе издание) + +- Cracking the Coding Interview +> Особенно обратите внимание на раздел: Часть VIII. Вопросы собеседования + + +### От себя: +- email, skype - очень желательно, чтобы по ним вы были узнаваемы. Заведите рабочие, если не так. +- написать ВЕСЬ IT опыт (исключая опыт пользователя: Windows, MS Word, Photophop, Yandex disk, Google docs, ..): технологии, какие задачи решали (конкретные), какие инструменты использовали, VCS, DB, инструменты сборки, ... включая опыт в ВУЗе. +- на English иметь желательно. Если вакансия опублинована на Englsih - шлите на нем. Часто могут на нем попросить, если работодатель иностранный. +- удобно иметь резюме где то в инете (hh, linkedin, google doc, чтобы им было удобно делиться). + +### Позиционирование проекта Topjava: +- После завершения проекта вы освоите все заявленные в нем технологии - вставьте в квалификацию (включая java 8 Stream and Time API) +- Делайте упор не на обучение, а на *участие в проекте*. Выполнение домашних заданий - это полноценное участие с написанием функционала по всем этим технологиям. Например: + + Участие в разработке Spring/JPA Enterprise приложения c авторизацией и правами доступа на основе ролей + на стеке Maven/ Spring MVC/ Security/ REST(Jackson)/ Java 8 Stream API: + - реализация сохранения в базы Postgres и HSQLDB на основе Spring JBDC, JPA(Hibernate) и Spring-Data-JPA + - реализация и тестирование REST и AJAX контроллеров + - реализация клиента на Bootstrap (css/js), datatables, jQuery + plugins. + - отлично будет, если вы его еще как то сами доработаете + +- По поводу обучения на курсах- можно упомянуть в разделе образования. Но на собеседовании меньше смотрят на то, что вы заканчивали, больше - на ваш опыт и то что вы знаете. +- Ссылку на организацию можно поставить: http://javaops.ru (или в linkedin: https://www.linkedin.com/company/java-online-projects) + +### В течении проекта заполните форму соискателя "Разработчик Java" +Я ее рассылаю всем знакомым HR, уже есть пинги и трудоустройство. + +Ближе к концу курса я вышлю приглашение в нашу общую группу slack: общение на все темы IT, обсуждение вступительных заданий, вакансии, цены на рынке труда, события, помощь, интересные видео по теме и пр. + +### Основные сайты поиска работы: +- HH +- LinkedIn +- djinni.co (более актуально для Украины) diff --git a/description.md b/description.md new file mode 100644 index 000000000000..cbb102fa72aa --- /dev/null +++ b/description.md @@ -0,0 +1,67 @@ +#### Разработка полнофункционального Spring/JPA Enterprise приложения c авторизацией и правами доступа на основе ролей с использованием наиболее популярных инструментов и технологий Java: Maven, Spring MVC, Security, JPA(Hibernate), REST(Jackson), Bootstrap (css,js), datatables, jQuery + plugins, Java 8 Stream and Time API +- Основное внимание будет уделяться способам решения многочисленных проблем разработки в Spring/JPA, а также структурному (красивому и надежному) java кодированию и архитектуре приложения. +- Каждая итерация проекта в закрепляется домашним заданием по реализации схожей функциональности. Следующее занятие начинается с разбора домашних заданий. +- Большое внимание уделяется тестированию кода: в проекте 88 JUnit тестов. +- Несмотря на относительно небольшой размер, приложение разрабатывается с нуля как большой проект (например мы используем кэш 2-го уровня Hibernate, настраиваем Jenkins для работы с ленивой загрузкой +Hibernate, делаем конверторы для типов LocalDateTime (Java 8 time API), которые еще не поддерживаются ни JPA/Hibernate, ни Jackson/json). + Разбираются архитектурные паттерны: слои приложения и как правильно разбивать логику по слоям, когда нужно применять Data Transfer Object. + Т.е на выходе получается не учебный проект, а хорошо маштабируемый шаблон для большого проекта на всех пройденных технологиях. +- Большое внимание уделяется деталям: популяция базы, использование транзакционности, тесты сервисов и REST + контроллеров, насторойка EntityManagerFactory, + выбор реализации пула коннектов. Особое внимание уделяется работе с базой: через Spring JDBC, Spring ORM и + Spring Data Jpa. +- Используются самые востребованные на сегодняшний момент фреймворки: Maven, Spring Security 4 + вместе с Spring Security Test, наиболее удобный для работы с базой проект Spring Data Jpa, библиотека логирования logback, реализующая SLF4J, повсеместно используемый Bootstrap и jQuery. + +#### Демо разрабатываемого приложения + +## План проекта (ссылки на некоторые темы открыты для просмотра) +### Архитектура проекта. Персистентность. +- Системы управления версиями +- Java 8: Lambda, Stream API +- Обзор используемых в проекте технологий и инструментов. +- Инструмент сборки Maven. +- WAR. Веб-контейнер Tomcat. Сервлеты. +- Логирование. +- Обзор стандартных библиотек. Apache Commons, Guava +- Слои приложения. Создание каркаса приложения. +- Обзор Spring Framework. Spring Context. +- Тестирование через JUnit. +- Spring Test +- Базы данных. PostgreSQL. Обзор NoSQL и Java persistence solution без ORM. +- Настройка Database в IDEA. +- Скрипты инициализации базы. Spring Jdbc Template. +- Spring: инициализация и популирование DB +- ORM. Hibernate. JPA. +- Поддержка HSQLDB +- Транзакции +- Профили Maven и Spring +- Пул коннектов +- Spring Data JPA +- Кэш Hibernate + +### Разработка WEB +- Spring кэш +- Spring Web +- JSP, JSTL, i18n +- Tomcat maven plugin. JNDI +- Spring Web MVC +- Spring Internationalization +- Тестирование Spring MVC +- REST контроллеры +- Тестирование REST контроллеров. Jackson. +- jackson-datatype-hibernate. Тестирование через матчеры. +- Тестирование через SoapUi. UTF-8 +- WebJars. +- Bootstrap. Datatables. +- AJAX. jQuery. Notifications. +- Spring Security +- Spring Binding/Validation +- Работа с Datatables через Ajax. +- Spring Security Test +- Encoding password +- CSRF (добавление в проект защиты от межсайтовой подделки запроса) +- form-login. Spring Security Taglib +- Handler interceptor +- Spring Exception Handling +- Деплой в Heroku From 4b658adc6ea0e84a843016b5cb7e45fae309ebbf Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 7 Jun 2016 23:17:31 +0300 Subject: [PATCH 02/39] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2cc45adedb00..435421f1d22d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Видеокурс по Git ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) Работа с проектом (выполнять инструкции) -- **Prepare_ to_ HW0.patch (скачать и положить в каталог вашего проекта)** +- **Prepare_ to_ HW0.patch (скачать и положить в каталог вашего проекта)** - Доступно о Java 8 Lambda ## Инструкция по шагам (из видео): @@ -54,7 +54,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Временная сложность алгоритма - Вычислительная сложность ``` -Реализовать UserMealsUtil.getFilteredMealsWithExceeded: +Реализовать метод UserMealsUtil.getFilteredWithExceeded: - должны возвращаться только записи между startTime и endTime - поле UserMealWithExceed.exceed должно показывать, превышает ли сумма калорий за весь день параметра метода caloriesPerDay From e8646657bb4d63f2250345006f7bf6408717784f Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 14 Jun 2016 00:03:34 +0300 Subject: [PATCH 03/39] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 435421f1d22d..a33a78e3956d 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery + - Сделать локальный репозиторий проекта:
git clone https://github.com/[Ваш аккаунт]/topjava.git
- Открыть и настроить проект в IDEA + - Выставить кодировку UTF-8 в консоли + - Поставить кодировку UTF-8 + - Поменять фонт по умолчанию (DejaVu) - По ходу видео сделать Apply Patch... скаченного патча Prepare_ to_ HW0.patch - Закоммитить и запушить изменения (commit + push) - Сделать ветку домашнего задания From f3e6adbddbbfe8721b8af0e98c70e046bd279fb4 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Wed, 15 Jun 2016 11:55:25 +0300 Subject: [PATCH 04/39] apply oreoaring patch --- patchs/0_Prepare_to_HW0.patch | 137 ++++++++++++++++++ patchs/1_1_HW0_stream.patch | 104 +++++++++++++ patchs/1_2_HW0_cycle.patch | 59 ++++++++ patchs/1_3_switch_to_war.patch | 82 +++++++++++ patchs/1_4_add_servlet_api.patch | 48 ++++++ patchs/1_5_forward_to_redirect.patch | 32 ++++ patchs/1_6_logging.patch | 128 ++++++++++++++++ patchs/1_7_remote_jmx.patch | 12 ++ .../javawebinar/topjava/model/UserMeal.java | 33 +++++ .../topjava/model/UserMealWithExceed.java | 24 +++ .../ru/javawebinar/topjava/util/TimeUtil.java | 13 ++ .../topjava/util/UserMealsUtil.java | 35 +++++ 12 files changed, 707 insertions(+) create mode 100644 patchs/0_Prepare_to_HW0.patch create mode 100644 patchs/1_1_HW0_stream.patch create mode 100644 patchs/1_2_HW0_cycle.patch create mode 100644 patchs/1_3_switch_to_war.patch create mode 100644 patchs/1_4_add_servlet_api.patch create mode 100644 patchs/1_5_forward_to_redirect.patch create mode 100644 patchs/1_6_logging.patch create mode 100644 patchs/1_7_remote_jmx.patch create mode 100644 src/main/java/ru/javawebinar/topjava/model/UserMeal.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/TimeUtil.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java diff --git a/patchs/0_Prepare_to_HW0.patch b/patchs/0_Prepare_to_HW0.patch new file mode 100644 index 000000000000..0801bfb789c4 --- /dev/null +++ b/patchs/0_Prepare_to_HW0.patch @@ -0,0 +1,137 @@ +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) +@@ -0,0 +1,35 @@ ++package ru.javawebinar.topjava.util; ++ ++import ru.javawebinar.topjava.model.UserMeal; ++import ru.javawebinar.topjava.model.UserMealWithExceed; ++ ++import java.time.LocalDateTime; ++import java.time.LocalTime; ++import java.time.Month; ++import java.util.Arrays; ++import java.util.List; ++ ++/** ++ * 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) ++ ); ++ getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000); ++// .toLocalDate(); ++// .toLocalTime(); ++ } ++ ++ public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { ++ // TODO return filtered list with correctly exceeded field ++ return null; ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision ) +@@ -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; ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision ) +@@ -0,0 +1,24 @@ ++package ru.javawebinar.topjava.model; ++ ++import java.time.LocalDateTime; ++ ++/** ++ * GKislin ++ * 11.01.2015. ++ */ ++public class UserMealWithExceed { ++ private final LocalDateTime dateTime; ++ ++ private final String description; ++ ++ private final int calories; ++ ++ private 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; ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/model/UserMeal.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMeal.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/model/UserMeal.java (revision ) +@@ -0,0 +1,33 @@ ++package ru.javawebinar.topjava.model; ++ ++import java.time.LocalDateTime; ++ ++/** ++ * GKislin ++ * 11.01.2015. ++ */ ++public class UserMeal { ++ private final LocalDateTime dateTime; ++ ++ private final String description; ++ ++ private 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/patchs/1_1_HW0_stream.patch b/patchs/1_1_HW0_stream.patch new file mode 100644 index 000000000000..f0374f5dab2b --- /dev/null +++ b/patchs/1_1_HW0_stream.patch @@ -0,0 +1,104 @@ +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision dbb6f02aa01015bf5dd7e976a74f22bb5bf3d6f3) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) +@@ -3,11 +3,14 @@ + 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.Arrays; + import java.util.List; ++import java.util.Map; ++import java.util.stream.Collectors; + + /** + * GKislin +@@ -16,20 +19,29 @@ + 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, 10, 0), "Завтрак", 500), +- new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,13,0), "Обед", 1000), ++ 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, 30, 20, 0), "Ужин", 500), +- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,10,0), "Завтрак", 1000), ++ 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, 13, 0), "Обед", 500), +- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,20,0), "Ужин", 510) ++ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510) + ); +- getFilteredMealsWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000); +-// .toLocalDate(); +-// .toLocalTime(); ++ List filteredMealsWithExceeded = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); ++ filteredMealsWithExceeded.forEach(System.out::println); + } + +- public static List getFilteredMealsWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { +- // TODO return filtered list with correctly exceeded field +- return null; ++ public static List getFilteredWithExceeded(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 -> ++ new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), ++ caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) ++ .collect(Collectors.toList()); + } + } +Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision dbb6f02aa01015bf5dd7e976a74f22bb5bf3d6f3) ++++ src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision ) +@@ -7,18 +7,28 @@ + * 11.01.2015. + */ + public class UserMealWithExceed { +- protected final LocalDateTime dateTime; ++ private final LocalDateTime dateTime; + +- protected final String description; ++ private final String description; + +- protected final int calories; ++ private final int calories; + +- protected final boolean exceed; ++ private 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/patchs/1_2_HW0_cycle.patch b/patchs/1_2_HW0_cycle.patch new file mode 100644 index 000000000000..49f6b9c10c7e --- /dev/null +++ b/patchs/1_2_HW0_cycle.patch @@ -0,0 +1,59 @@ +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (date 1464631839000) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) +@@ -7,9 +7,7 @@ + import java.time.LocalDateTime; + import java.time.LocalTime; + import java.time.Month; +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; ++import java.util.*; + import java.util.stream.Collectors; + + /** +@@ -28,6 +26,8 @@ + ); + List filteredMealsWithExceeded = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + filteredMealsWithExceeded.forEach(System.out::println); ++ ++ System.out.println(getFilteredWithExceededByCycle(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); + } + + public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { +@@ -39,9 +39,26 @@ + + return mealList.stream() + .filter(um -> TimeUtil.isBetween(um.getDateTime().toLocalTime(), startTime, endTime)) +- .map(um -> +- new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), +- caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) ++ .map(um -> createWithExceed(um, caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) + .collect(Collectors.toList()); ++ } ++ ++ public static List getFilteredWithExceededByCycle(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/patchs/1_3_switch_to_war.patch b/patchs/1_3_switch_to_war.patch new file mode 100644 index 000000000000..cf803628690f --- /dev/null +++ b/patchs/1_3_switch_to_war.patch @@ -0,0 +1,82 @@ +Index: src/main/webapp/WEB-INF/web.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/WEB-INF/web.xml (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) ++++ src/main/webapp/WEB-INF/web.xml (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) +@@ -0,0 +1,18 @@ ++ ++ ++ Topjava ++ ++ ++ userServlet ++ ru.javawebinar.topjava.web.UserServlet ++ 0 ++ ++ ++ userServlet ++ /users ++ ++ ++ +Index: src/main/webapp/index.html +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/index.html (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) ++++ src/main/webapp/index.html (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) +@@ -0,0 +1,14 @@ ++ ++ ++ ++ ++ Java Enterprise (Topjava) ++ ++ ++

Проект "Java Enterprise (Topjava)"

++
++ ++ ++ +Index: src/main/webapp/userList.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/userList.jsp (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) ++++ src/main/webapp/userList.jsp (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) +@@ -0,0 +1,10 @@ ++<%@ page contentType="text/html;charset=UTF-8" language="java" %> ++ ++ ++ User list ++ ++ ++

Home

++

User list

++ ++ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1464632045000) ++++ pom.xml (date 1464815793000) +@@ -4,7 +4,7 @@ + + ru.javawebinar + topjava +- jar ++ war + + 1.0-SNAPSHOT + diff --git a/patchs/1_4_add_servlet_api.patch b/patchs/1_4_add_servlet_api.patch new file mode 100644 index 000000000000..c24b59a6a66f --- /dev/null +++ b/patchs/1_4_add_servlet_api.patch @@ -0,0 +1,48 @@ +Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision 543a5fca19c11a10a560a964587b61fa5f5134b6) ++++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision 543a5fca19c11a10a560a964587b61fa5f5134b6) +@@ -0,0 +1,18 @@ ++package ru.javawebinar.topjava.web; ++ ++import javax.servlet.ServletException; ++import javax.servlet.http.HttpServlet; ++import javax.servlet.http.HttpServletRequest; ++import javax.servlet.http.HttpServletResponse; ++import java.io.IOException; ++ ++/** ++ * User: gkislin ++ * Date: 19.08.2014 ++ */ ++public class UserServlet extends HttpServlet { ++ ++ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ++ request.getRequestDispatcher("/userList.jsp").forward(request, response); ++ } ++} +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1456909639000) ++++ pom.xml (date 1456909915000) +@@ -34,6 +34,14 @@ + + + ++ ++ ++ ++ javax.servlet ++ servlet-api ++ 2.5 ++ provided ++ + + + diff --git a/patchs/1_5_forward_to_redirect.patch b/patchs/1_5_forward_to_redirect.patch new file mode 100644 index 000000000000..df841d096f83 --- /dev/null +++ b/patchs/1_5_forward_to_redirect.patch @@ -0,0 +1,32 @@ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1456909915000) ++++ pom.xml (revision ) +@@ -19,7 +19,7 @@ + + + topjava +- install ++ package + + + org.apache.maven.plugins +Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (date 1456909915000) ++++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision ) +@@ -13,6 +13,7 @@ + public class UserServlet extends HttpServlet { + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { +- request.getRequestDispatcher("/userList.jsp").forward(request, response); ++// request.getRequestDispatcher("/userList.jsp").forward(request, response); ++ response.sendRedirect("userList.jsp"); + } + } diff --git a/patchs/1_6_logging.patch b/patchs/1_6_logging.patch new file mode 100644 index 000000000000..734cd292b080 --- /dev/null +++ b/patchs/1_6_logging.patch @@ -0,0 +1,128 @@ +Index: src/main/resources/logback.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/logback.xml (revision ) ++++ src/main/resources/logback.xml (revision ) +@@ -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 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1464819221000) ++++ pom.xml (revision ) +@@ -15,6 +15,10 @@ + 1.8 + UTF-8 + UTF-8 ++ ++ ++ 1.1.7 ++ 1.7.21 + + + +@@ -34,6 +38,34 @@ + + + ++ ++ ++ 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 ++ + + + +Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (date 1464819221000) ++++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision ) +@@ -1,18 +1,26 @@ + 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/patchs/1_7_remote_jmx.patch b/patchs/1_7_remote_jmx.patch new file mode 100644 index 000000000000..7bd470faff3b --- /dev/null +++ b/patchs/1_7_remote_jmx.patch @@ -0,0 +1,12 @@ +Index: config/setenv.bat +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- config/setenv.bat (revision ) ++++ config/setenv.bat (revision ) +@@ -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/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..57da93fdd37a --- /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 { + private final LocalDateTime dateTime; + + private final String description; + + private 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..13db2ba30959 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java @@ -0,0 +1,24 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +/** + * GKislin + * 11.01.2015. + */ +public class UserMealWithExceed { + private final LocalDateTime dateTime; + + private final String description; + + private final int calories; + + private 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; + } +} 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..a74eecb448cd --- /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..9300a2b71fa5 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -0,0 +1,35 @@ +package ru.javawebinar.topjava.util; + +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.model.UserMealWithExceed; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.util.Arrays; +import java.util.List; + +/** + * 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) + ); + getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000); +// .toLocalDate(); +// .toLocalTime(); + } + + public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + // TODO return filtered list with correctly exceeded field + return null; + } +} From 5841ab7295b9705d954592b10d4f2dc9affc4114 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Wed, 15 Jun 2016 12:07:44 +0300 Subject: [PATCH 05/39] apply patchs 1.1-1.7 --- config/setenv.bat | 4 ++ pom.xml | 44 ++++++++++++- .../topjava/model/UserMealWithExceed.java | 10 +++ .../topjava/util/UserMealsUtil.java | 61 ++++++++++++++----- .../javawebinar/topjava/web/UserServlet.java | 27 ++++++++ src/main/resources/logback.xml | 33 ++++++++++ src/main/webapp/WEB-INF/web.xml | 18 ++++++ src/main/webapp/index.html | 14 +++++ src/main/webapp/userList.jsp | 10 +++ 9 files changed, 204 insertions(+), 17 deletions(-) create mode 100644 config/setenv.bat create mode 100644 src/main/java/ru/javawebinar/topjava/web/UserServlet.java create mode 100644 src/main/resources/logback.xml create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/index.html create mode 100644 src/main/webapp/userList.jsp 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..b7c2974eaea8 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.7 + 1.7.21 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/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java index 13db2ba30959..143d75c71239 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java @@ -21,4 +21,14 @@ public UserMealWithExceed(LocalDateTime dateTime, String description, int calori 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/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java index 9300a2b71fa5..2f0f531483d7 100644 --- a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -3,11 +3,12 @@ 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.Arrays; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; /** * GKislin @@ -16,20 +17,50 @@ 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) + 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) ); - getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000); -// .toLocalDate(); -// .toLocalTime(); + getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + List filteredMealsWithExceeded = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + filteredMealsWithExceeded.forEach(System.out::println); + + System.out.println(getFilteredWithExceededByCycle(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); + } + + public static List getFilteredWithExceeded(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 getFilteredWithExceededByCycle(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 List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { - // TODO return filtered list with correctly exceeded field - return null; + 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..b4f020f9cc32 --- /dev/null +++ b/src/main/webapp/index.html @@ -0,0 +1,14 @@ + + + + + Java Enterprise (Topjava) + + +

Проект "Java Enterprise (Topjava)"

+
+ + + diff --git a/src/main/webapp/userList.jsp b/src/main/webapp/userList.jsp new file mode 100644 index 000000000000..31084b82fd3f --- /dev/null +++ b/src/main/webapp/userList.jsp @@ -0,0 +1,10 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + User list + + +

Home

+

User list

+ + From e76766e7cb3515ecde62b1103445e19c5202a910 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Wed, 15 Jun 2016 12:19:53 +0300 Subject: [PATCH 06/39] until patch 2.1 (copy changes from github) --- patchs/1_1_HW0_stream.patch | 104 -------------- patchs/1_2_HW0_cycle.patch | 59 -------- patchs/1_3_switch_to_war.patch | 82 ----------- patchs/1_4_add_servlet_api.patch | 48 ------- patchs/1_5_forward_to_redirect.patch | 32 ----- patchs/1_6_logging.patch | 128 ------------------ patchs/1_7_remote_jmx.patch | 12 -- pom.xml | 7 +- .../topjava/model/UserMealWithExceed.java | 18 ++- .../ru/javawebinar/topjava/util/TimeUtil.java | 10 +- .../topjava/util/UserMealsUtil.java | 31 +++-- .../javawebinar/topjava/web/MealServlet.java | 25 ++++ src/main/webapp/WEB-INF/tld/functions.tld | 16 +++ src/main/webapp/WEB-INF/web.xml | 10 ++ src/main/webapp/index.html | 1 + src/main/webapp/mealList.jsp | 46 +++++++ 16 files changed, 148 insertions(+), 481 deletions(-) delete mode 100644 patchs/1_1_HW0_stream.patch delete mode 100644 patchs/1_2_HW0_cycle.patch delete mode 100644 patchs/1_3_switch_to_war.patch delete mode 100644 patchs/1_4_add_servlet_api.patch delete mode 100644 patchs/1_5_forward_to_redirect.patch delete mode 100644 patchs/1_6_logging.patch delete mode 100644 patchs/1_7_remote_jmx.patch create mode 100644 src/main/java/ru/javawebinar/topjava/web/MealServlet.java create mode 100644 src/main/webapp/WEB-INF/tld/functions.tld create mode 100644 src/main/webapp/mealList.jsp diff --git a/patchs/1_1_HW0_stream.patch b/patchs/1_1_HW0_stream.patch deleted file mode 100644 index f0374f5dab2b..000000000000 --- a/patchs/1_1_HW0_stream.patch +++ /dev/null @@ -1,104 +0,0 @@ -Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision dbb6f02aa01015bf5dd7e976a74f22bb5bf3d6f3) -+++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) -@@ -3,11 +3,14 @@ - 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.Arrays; - import java.util.List; -+import java.util.Map; -+import java.util.stream.Collectors; - - /** - * GKislin -@@ -16,20 +19,29 @@ - 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, 10, 0), "Завтрак", 500), -- new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,13,0), "Обед", 1000), -+ 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, 30, 20, 0), "Ужин", 500), -- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,10,0), "Завтрак", 1000), -+ 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, 13, 0), "Обед", 500), -- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,20,0), "Ужин", 510) -+ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510) - ); -- getFilteredMealsWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000); --// .toLocalDate(); --// .toLocalTime(); -+ List filteredMealsWithExceeded = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); -+ filteredMealsWithExceeded.forEach(System.out::println); - } - -- public static List getFilteredMealsWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { -- // TODO return filtered list with correctly exceeded field -- return null; -+ public static List getFilteredWithExceeded(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 -> -+ new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), -+ caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) -+ .collect(Collectors.toList()); - } - } -Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision dbb6f02aa01015bf5dd7e976a74f22bb5bf3d6f3) -+++ src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision ) -@@ -7,18 +7,28 @@ - * 11.01.2015. - */ - public class UserMealWithExceed { -- protected final LocalDateTime dateTime; -+ private final LocalDateTime dateTime; - -- protected final String description; -+ private final String description; - -- protected final int calories; -+ private final int calories; - -- protected final boolean exceed; -+ private 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/patchs/1_2_HW0_cycle.patch b/patchs/1_2_HW0_cycle.patch deleted file mode 100644 index 49f6b9c10c7e..000000000000 --- a/patchs/1_2_HW0_cycle.patch +++ /dev/null @@ -1,59 +0,0 @@ -Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (date 1464631839000) -+++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) -@@ -7,9 +7,7 @@ - import java.time.LocalDateTime; - import java.time.LocalTime; - import java.time.Month; --import java.util.Arrays; --import java.util.List; --import java.util.Map; -+import java.util.*; - import java.util.stream.Collectors; - - /** -@@ -28,6 +26,8 @@ - ); - List filteredMealsWithExceeded = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); - filteredMealsWithExceeded.forEach(System.out::println); -+ -+ System.out.println(getFilteredWithExceededByCycle(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); - } - - public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { -@@ -39,9 +39,26 @@ - - return mealList.stream() - .filter(um -> TimeUtil.isBetween(um.getDateTime().toLocalTime(), startTime, endTime)) -- .map(um -> -- new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), -- caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) -+ .map(um -> createWithExceed(um, caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) - .collect(Collectors.toList()); -+ } -+ -+ public static List getFilteredWithExceededByCycle(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/patchs/1_3_switch_to_war.patch b/patchs/1_3_switch_to_war.patch deleted file mode 100644 index cf803628690f..000000000000 --- a/patchs/1_3_switch_to_war.patch +++ /dev/null @@ -1,82 +0,0 @@ -Index: src/main/webapp/WEB-INF/web.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/webapp/WEB-INF/web.xml (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) -+++ src/main/webapp/WEB-INF/web.xml (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) -@@ -0,0 +1,18 @@ -+ -+ -+ Topjava -+ -+ -+ userServlet -+ ru.javawebinar.topjava.web.UserServlet -+ 0 -+ -+ -+ userServlet -+ /users -+ -+ -+ -Index: src/main/webapp/index.html -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/webapp/index.html (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) -+++ src/main/webapp/index.html (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) -@@ -0,0 +1,14 @@ -+ -+ -+ -+ -+ Java Enterprise (Topjava) -+ -+ -+

Проект "Java Enterprise (Topjava)"

-+
-+ -+ -+ -Index: src/main/webapp/userList.jsp -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/webapp/userList.jsp (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) -+++ src/main/webapp/userList.jsp (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) -@@ -0,0 +1,10 @@ -+<%@ page contentType="text/html;charset=UTF-8" language="java" %> -+ -+ -+ User list -+ -+ -+

Home

-+

User list

-+ -+ -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1464632045000) -+++ pom.xml (date 1464815793000) -@@ -4,7 +4,7 @@ - - ru.javawebinar - topjava -- jar -+ war - - 1.0-SNAPSHOT - diff --git a/patchs/1_4_add_servlet_api.patch b/patchs/1_4_add_servlet_api.patch deleted file mode 100644 index c24b59a6a66f..000000000000 --- a/patchs/1_4_add_servlet_api.patch +++ /dev/null @@ -1,48 +0,0 @@ -Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision 543a5fca19c11a10a560a964587b61fa5f5134b6) -+++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision 543a5fca19c11a10a560a964587b61fa5f5134b6) -@@ -0,0 +1,18 @@ -+package ru.javawebinar.topjava.web; -+ -+import javax.servlet.ServletException; -+import javax.servlet.http.HttpServlet; -+import javax.servlet.http.HttpServletRequest; -+import javax.servlet.http.HttpServletResponse; -+import java.io.IOException; -+ -+/** -+ * User: gkislin -+ * Date: 19.08.2014 -+ */ -+public class UserServlet extends HttpServlet { -+ -+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { -+ request.getRequestDispatcher("/userList.jsp").forward(request, response); -+ } -+} -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1456909639000) -+++ pom.xml (date 1456909915000) -@@ -34,6 +34,14 @@ -
- - -+ -+ -+ -+ javax.servlet -+ servlet-api -+ 2.5 -+ provided -+ - - - diff --git a/patchs/1_5_forward_to_redirect.patch b/patchs/1_5_forward_to_redirect.patch deleted file mode 100644 index df841d096f83..000000000000 --- a/patchs/1_5_forward_to_redirect.patch +++ /dev/null @@ -1,32 +0,0 @@ -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1456909915000) -+++ pom.xml (revision ) -@@ -19,7 +19,7 @@ - - - topjava -- install -+ package - - - org.apache.maven.plugins -Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (date 1456909915000) -+++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision ) -@@ -13,6 +13,7 @@ - public class UserServlet extends HttpServlet { - - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { -- request.getRequestDispatcher("/userList.jsp").forward(request, response); -+// request.getRequestDispatcher("/userList.jsp").forward(request, response); -+ response.sendRedirect("userList.jsp"); - } - } diff --git a/patchs/1_6_logging.patch b/patchs/1_6_logging.patch deleted file mode 100644 index 734cd292b080..000000000000 --- a/patchs/1_6_logging.patch +++ /dev/null @@ -1,128 +0,0 @@ -Index: src/main/resources/logback.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/resources/logback.xml (revision ) -+++ src/main/resources/logback.xml (revision ) -@@ -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 -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1464819221000) -+++ pom.xml (revision ) -@@ -15,6 +15,10 @@ - 1.8 - UTF-8 - UTF-8 -+ -+ -+ 1.1.7 -+ 1.7.21 - - - -@@ -34,6 +38,34 @@ - - - -+ -+ -+ 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 -+ - - - -Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (date 1464819221000) -+++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision ) -@@ -1,18 +1,26 @@ - 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/patchs/1_7_remote_jmx.patch b/patchs/1_7_remote_jmx.patch deleted file mode 100644 index 7bd470faff3b..000000000000 --- a/patchs/1_7_remote_jmx.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: config/setenv.bat -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- config/setenv.bat (revision ) -+++ config/setenv.bat (revision ) -@@ -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 b7c2974eaea8..25e27fd1eb7f 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,11 @@ runtime + + javax.servlet + jstl + 1.2 + javax.servlet @@ -81,4 +86,4 @@ - + \ No newline at end of file diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java index 143d75c71239..42198904fe8b 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java @@ -22,6 +22,22 @@ public UserMealWithExceed(LocalDateTime dateTime, String description, int calori this.exceed = exceed; } + public LocalDateTime getDateTime() { + return dateTime; + } + + public String getDescription() { + return description; + } + + public int getCalories() { + return calories; + } + + public boolean isExceed() { + return exceed; + } + @Override public String toString() { return "UserMealWithExceed{" + @@ -31,4 +47,4 @@ public String toString() { ", exceed=" + exceed + '}'; } -} +} \ 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 index a74eecb448cd..aa014b3a923a 100644 --- a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -1,13 +1,21 @@ package ru.javawebinar.topjava.util; +import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.format.DateTimeFormatter; /** * GKislin * 07.01.2015. */ public class TimeUtil { + public static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime endTime) { return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) <= 0; } -} + + public static String toString(LocalDateTime ldt) { + return ldt == null ? "" : ldt.format(DATE_TME_FORMATTER); + } +} \ No newline at end of file diff --git a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java index 2f0f531483d7..12adb051c953 100644 --- a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -15,20 +15,26 @@ * 31.05.2015. */ public class UserMealsUtil { + public static final List MEAL_LIST = 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) + ); + + public static final int DEFAULT_CALORIES_PER_DAY = 2000; + 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) - ); - getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); - List filteredMealsWithExceeded = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + List filteredMealsWithExceeded = getFilteredWithExceeded(MEAL_LIST, LocalTime.of(7, 0), LocalTime.of(12, 0), DEFAULT_CALORIES_PER_DAY); filteredMealsWithExceeded.forEach(System.out::println); - System.out.println(getFilteredWithExceededByCycle(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); + System.out.println(getFilteredWithExceededByCycle(MEAL_LIST, LocalTime.of(7, 0), LocalTime.of(12, 0), DEFAULT_CALORIES_PER_DAY)); + } + + public static List getWithExceeded(List mealList, int caloriesPerDay) { + return getFilteredWithExceeded(mealList, LocalTime.MIN, LocalTime.MAX, caloriesPerDay); } public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { @@ -44,8 +50,7 @@ public static List getFilteredWithExceeded(List me .collect(Collectors.toList()); } - public static List getFilteredWithExceededByCycle(List mealList, LocalTime - startTime, LocalTime endTime, int caloriesPerDay) { + public static List getFilteredWithExceededByCycle(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)); diff --git a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java new file mode 100644 index 000000000000..e3eaa0e1a2ce --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java @@ -0,0 +1,25 @@ +package ru.javawebinar.topjava.web; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.javawebinar.topjava.util.UserMealsUtil; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * User: gkislin + * Date: 19.08.2014 + */ +public class MealServlet extends HttpServlet { + private static final Logger LOG = LoggerFactory.getLogger(MealServlet.class); + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + LOG.info("getAll"); + request.setAttribute("mealList", UserMealsUtil.getWithExceeded(UserMealsUtil.MEAL_LIST, UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); + request.getRequestDispatcher("/mealList.jsp").forward(request, response); + } +} \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/tld/functions.tld b/src/main/webapp/WEB-INF/tld/functions.tld new file mode 100644 index 000000000000..122c4197cc32 --- /dev/null +++ b/src/main/webapp/WEB-INF/tld/functions.tld @@ -0,0 +1,16 @@ + + + + 1.0 + functions + http://topjava.javawebinar.ru/functions + + + formatDateTime + ru.javawebinar.topjava.util.TimeUtil + java.lang.String toString(java.time.LocalDateTime) + + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index d53249c1ac6d..9e6a31e58952 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -15,4 +15,14 @@ /users + + mealServlet + ru.javawebinar.topjava.web.MealServlet + 0 + + + mealServlet + /meals + + diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index b4f020f9cc32..b380bc03c9db 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -9,6 +9,7 @@

Проект "User List +
  • Meal List
  • diff --git a/src/main/webapp/mealList.jsp b/src/main/webapp/mealList.jsp new file mode 100644 index 000000000000..41d681a77ca3 --- /dev/null +++ b/src/main/webapp/mealList.jsp @@ -0,0 +1,46 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="fn" uri="http://topjava.javawebinar.ru/functions" %> + + + Meal list + + + +
    +

    Home

    +

    Meal list

    +
    + + + + + + + + + + + + + + + + +
    DateDescriptionCalories
    + <%--${meal.dateTime.toLocalDate()} ${meal.dateTime.toLocalTime()}--%> + <%--<%=TimeUtil.toString(meal.getDateTime())%>--%> + ${fn:formatDateTime(meal.dateTime)} + ${meal.description}${meal.calories}
    +
    + + \ No newline at end of file From 0a7449ff1e8daf8af59630913fef642ac8d64824 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Wed, 15 Jun 2016 12:21:04 +0300 Subject: [PATCH 07/39] apply patch 2.1 --- pom.xml | 2 +- .../java/ru/javawebinar/topjava/model/UserMealWithExceed.java | 2 +- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 25e27fd1eb7f..f79727654639 100644 --- a/pom.xml +++ b/pom.xml @@ -86,4 +86,4 @@ - \ No newline at end of file + diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java index 42198904fe8b..5e6fdc5984fc 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java @@ -47,4 +47,4 @@ public String toString() { ", exceed=" + exceed + '}'; } -} \ 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 index aa014b3a923a..75b1b4127af4 100644 --- a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -18,4 +18,4 @@ public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime end public static String toString(LocalDateTime ldt) { return ldt == null ? "" : ldt.format(DATE_TME_FORMATTER); } -} \ No newline at end of file +} From 9f9b82d16f7faac01b3b1d84d920f15c5b605d42 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Thu, 16 Jun 2016 07:32:41 +0300 Subject: [PATCH 08/39] add patchs to vcs --- patchs/to_lesson01/1_1_HW0_stream.patch | 104 +++++++ patchs/to_lesson01/1_2_HW0_cycle.patch | 59 ++++ patchs/to_lesson01/1_3_switch_to_war.patch | 82 ++++++ patchs/to_lesson01/1_4_add_servlet_api.patch | 48 +++ .../to_lesson01/1_5_forward_to_redirect.patch | 32 ++ patchs/to_lesson01/1_6_logging.patch | 128 ++++++++ patchs/to_lesson01/1_7_remote_jmx.patch | 12 + patchs/to_lesson02/2_1_HW1.patch | 273 ++++++++++++++++++ 8 files changed, 738 insertions(+) create mode 100644 patchs/to_lesson01/1_1_HW0_stream.patch create mode 100644 patchs/to_lesson01/1_2_HW0_cycle.patch create mode 100644 patchs/to_lesson01/1_3_switch_to_war.patch create mode 100644 patchs/to_lesson01/1_4_add_servlet_api.patch create mode 100644 patchs/to_lesson01/1_5_forward_to_redirect.patch create mode 100644 patchs/to_lesson01/1_6_logging.patch create mode 100644 patchs/to_lesson01/1_7_remote_jmx.patch create mode 100644 patchs/to_lesson02/2_1_HW1.patch diff --git a/patchs/to_lesson01/1_1_HW0_stream.patch b/patchs/to_lesson01/1_1_HW0_stream.patch new file mode 100644 index 000000000000..f0374f5dab2b --- /dev/null +++ b/patchs/to_lesson01/1_1_HW0_stream.patch @@ -0,0 +1,104 @@ +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision dbb6f02aa01015bf5dd7e976a74f22bb5bf3d6f3) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) +@@ -3,11 +3,14 @@ + 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.Arrays; + import java.util.List; ++import java.util.Map; ++import java.util.stream.Collectors; + + /** + * GKislin +@@ -16,20 +19,29 @@ + 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, 10, 0), "Завтрак", 500), +- new UserMeal(LocalDateTime.of(2015, Month.MAY, 30,13,0), "Обед", 1000), ++ 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, 30, 20, 0), "Ужин", 500), +- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,10,0), "Завтрак", 1000), ++ 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, 13, 0), "Обед", 500), +- new UserMeal(LocalDateTime.of(2015, Month.MAY, 31,20,0), "Ужин", 510) ++ new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510) + ); +- getFilteredMealsWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12,0), 2000); +-// .toLocalDate(); +-// .toLocalTime(); ++ List filteredMealsWithExceeded = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); ++ filteredMealsWithExceeded.forEach(System.out::println); + } + +- public static List getFilteredMealsWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { +- // TODO return filtered list with correctly exceeded field +- return null; ++ public static List getFilteredWithExceeded(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 -> ++ new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), ++ caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) ++ .collect(Collectors.toList()); + } + } +Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision dbb6f02aa01015bf5dd7e976a74f22bb5bf3d6f3) ++++ src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision ) +@@ -7,18 +7,28 @@ + * 11.01.2015. + */ + public class UserMealWithExceed { +- protected final LocalDateTime dateTime; ++ private final LocalDateTime dateTime; + +- protected final String description; ++ private final String description; + +- protected final int calories; ++ private final int calories; + +- protected final boolean exceed; ++ private 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/patchs/to_lesson01/1_2_HW0_cycle.patch b/patchs/to_lesson01/1_2_HW0_cycle.patch new file mode 100644 index 000000000000..49f6b9c10c7e --- /dev/null +++ b/patchs/to_lesson01/1_2_HW0_cycle.patch @@ -0,0 +1,59 @@ +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (date 1464631839000) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) +@@ -7,9 +7,7 @@ + import java.time.LocalDateTime; + import java.time.LocalTime; + import java.time.Month; +-import java.util.Arrays; +-import java.util.List; +-import java.util.Map; ++import java.util.*; + import java.util.stream.Collectors; + + /** +@@ -28,6 +26,8 @@ + ); + List filteredMealsWithExceeded = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + filteredMealsWithExceeded.forEach(System.out::println); ++ ++ System.out.println(getFilteredWithExceededByCycle(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); + } + + public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { +@@ -39,9 +39,26 @@ + + return mealList.stream() + .filter(um -> TimeUtil.isBetween(um.getDateTime().toLocalTime(), startTime, endTime)) +- .map(um -> +- new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), +- caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) ++ .map(um -> createWithExceed(um, caloriesSumByDate.get(um.getDateTime().toLocalDate()) > caloriesPerDay)) + .collect(Collectors.toList()); ++ } ++ ++ public static List getFilteredWithExceededByCycle(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/patchs/to_lesson01/1_3_switch_to_war.patch b/patchs/to_lesson01/1_3_switch_to_war.patch new file mode 100644 index 000000000000..cf803628690f --- /dev/null +++ b/patchs/to_lesson01/1_3_switch_to_war.patch @@ -0,0 +1,82 @@ +Index: src/main/webapp/WEB-INF/web.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/WEB-INF/web.xml (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) ++++ src/main/webapp/WEB-INF/web.xml (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) +@@ -0,0 +1,18 @@ ++ ++ ++ Topjava ++ ++ ++ userServlet ++ ru.javawebinar.topjava.web.UserServlet ++ 0 ++ ++ ++ userServlet ++ /users ++ ++ ++ +Index: src/main/webapp/index.html +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/index.html (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) ++++ src/main/webapp/index.html (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) +@@ -0,0 +1,14 @@ ++ ++ ++ ++ ++ Java Enterprise (Topjava) ++ ++ ++

    Проект "Java Enterprise (Topjava)"

    ++
    ++ ++ ++ +Index: src/main/webapp/userList.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/userList.jsp (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) ++++ src/main/webapp/userList.jsp (revision a0eaa0d54f3c47a9c7de73f872b42587918b5487) +@@ -0,0 +1,10 @@ ++<%@ page contentType="text/html;charset=UTF-8" language="java" %> ++ ++ ++ User list ++ ++ ++

    Home

    ++

    User list

    ++ ++ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1464632045000) ++++ pom.xml (date 1464815793000) +@@ -4,7 +4,7 @@ + + ru.javawebinar + topjava +- jar ++ war + + 1.0-SNAPSHOT + diff --git a/patchs/to_lesson01/1_4_add_servlet_api.patch b/patchs/to_lesson01/1_4_add_servlet_api.patch new file mode 100644 index 000000000000..c24b59a6a66f --- /dev/null +++ b/patchs/to_lesson01/1_4_add_servlet_api.patch @@ -0,0 +1,48 @@ +Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision 543a5fca19c11a10a560a964587b61fa5f5134b6) ++++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision 543a5fca19c11a10a560a964587b61fa5f5134b6) +@@ -0,0 +1,18 @@ ++package ru.javawebinar.topjava.web; ++ ++import javax.servlet.ServletException; ++import javax.servlet.http.HttpServlet; ++import javax.servlet.http.HttpServletRequest; ++import javax.servlet.http.HttpServletResponse; ++import java.io.IOException; ++ ++/** ++ * User: gkislin ++ * Date: 19.08.2014 ++ */ ++public class UserServlet extends HttpServlet { ++ ++ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ++ request.getRequestDispatcher("/userList.jsp").forward(request, response); ++ } ++} +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1456909639000) ++++ pom.xml (date 1456909915000) +@@ -34,6 +34,14 @@ + + + ++ ++ ++ ++ javax.servlet ++ servlet-api ++ 2.5 ++ provided ++ + + + diff --git a/patchs/to_lesson01/1_5_forward_to_redirect.patch b/patchs/to_lesson01/1_5_forward_to_redirect.patch new file mode 100644 index 000000000000..df841d096f83 --- /dev/null +++ b/patchs/to_lesson01/1_5_forward_to_redirect.patch @@ -0,0 +1,32 @@ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1456909915000) ++++ pom.xml (revision ) +@@ -19,7 +19,7 @@ + + + topjava +- install ++ package + + + org.apache.maven.plugins +Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (date 1456909915000) ++++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision ) +@@ -13,6 +13,7 @@ + public class UserServlet extends HttpServlet { + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { +- request.getRequestDispatcher("/userList.jsp").forward(request, response); ++// request.getRequestDispatcher("/userList.jsp").forward(request, response); ++ response.sendRedirect("userList.jsp"); + } + } diff --git a/patchs/to_lesson01/1_6_logging.patch b/patchs/to_lesson01/1_6_logging.patch new file mode 100644 index 000000000000..734cd292b080 --- /dev/null +++ b/patchs/to_lesson01/1_6_logging.patch @@ -0,0 +1,128 @@ +Index: src/main/resources/logback.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/logback.xml (revision ) ++++ src/main/resources/logback.xml (revision ) +@@ -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 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1464819221000) ++++ pom.xml (revision ) +@@ -15,6 +15,10 @@ + 1.8 + UTF-8 + UTF-8 ++ ++ ++ 1.1.7 ++ 1.7.21 + + + +@@ -34,6 +38,34 @@ + + + ++ ++ ++ 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 ++ + + + +Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (date 1464819221000) ++++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision ) +@@ -1,18 +1,26 @@ + 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/patchs/to_lesson01/1_7_remote_jmx.patch b/patchs/to_lesson01/1_7_remote_jmx.patch new file mode 100644 index 000000000000..7bd470faff3b --- /dev/null +++ b/patchs/to_lesson01/1_7_remote_jmx.patch @@ -0,0 +1,12 @@ +Index: config/setenv.bat +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- config/setenv.bat (revision ) ++++ config/setenv.bat (revision ) +@@ -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/patchs/to_lesson02/2_1_HW1.patch b/patchs/to_lesson02/2_1_HW1.patch new file mode 100644 index 000000000000..dcb53080c11a --- /dev/null +++ b/patchs/to_lesson02/2_1_HW1.patch @@ -0,0 +1,273 @@ +Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision 2c8ba27e36b2266486b66b4594b4572c7b5a24c1) ++++ src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -22,6 +22,22 @@ + this.exceed = exceed; + } + ++ public LocalDateTime getDateTime() { ++ return dateTime; ++ } ++ ++ public String getDescription() { ++ return description; ++ } ++ ++ public int getCalories() { ++ return calories; ++ } ++ ++ public boolean isExceed() { ++ return exceed; ++ } ++ + @Override + public String toString() { + return "UserMealWithExceed{" + +Index: src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision 2c8ba27e36b2266486b66b4594b4572c7b5a24c1) ++++ src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -1,13 +1,21 @@ + package ru.javawebinar.topjava.util; + ++import java.time.LocalDateTime; + import java.time.LocalTime; ++import java.time.format.DateTimeFormatter; + + /** + * GKislin + * 07.01.2015. + */ + public class TimeUtil { ++ public static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); ++ + public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime endTime) { + return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) <= 0; ++ } ++ ++ public static String toString(LocalDateTime ldt) { ++ return ldt == null ? "" : ldt.format(DATE_TME_FORMATTER); + } + } +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision 2c8ba27e36b2266486b66b4594b4572c7b5a24c1) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -15,19 +15,26 @@ + * 31.05.2015. + */ + public class UserMealsUtil { +- public static void main(String[] args) { +- List mealList = Arrays.asList( ++ public static final List MEAL_LIST = 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) +- ); ++ 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 = getFilteredWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); ++ ++ public static final int DEFAULT_CALORIES_PER_DAY = 2000; ++ ++ public static void main(String[] args) { ++ List filteredMealsWithExceeded = getFilteredWithExceeded(MEAL_LIST, LocalTime.of(7, 0), LocalTime.of(12, 0), DEFAULT_CALORIES_PER_DAY); + filteredMealsWithExceeded.forEach(System.out::println); + +- System.out.println(getFilteredWithExceededByCycle(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000)); ++ System.out.println(getFilteredWithExceededByCycle(MEAL_LIST, LocalTime.of(7, 0), LocalTime.of(12, 0), DEFAULT_CALORIES_PER_DAY)); ++ } ++ ++ public static List getWithExceeded(List mealList, int caloriesPerDay) { ++ return getFilteredWithExceeded(mealList, LocalTime.MIN, LocalTime.MAX, caloriesPerDay); + } + + public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/web/MealServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/MealServlet.java (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) ++++ src/main/java/ru/javawebinar/topjava/web/MealServlet.java (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -0,0 +1,25 @@ ++package ru.javawebinar.topjava.web; ++ ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import ru.javawebinar.topjava.util.UserMealsUtil; ++ ++import javax.servlet.ServletException; ++import javax.servlet.http.HttpServlet; ++import javax.servlet.http.HttpServletRequest; ++import javax.servlet.http.HttpServletResponse; ++import java.io.IOException; ++ ++/** ++ * User: gkislin ++ * Date: 19.08.2014 ++ */ ++public class MealServlet extends HttpServlet { ++ private static final Logger LOG = LoggerFactory.getLogger(MealServlet.class); ++ ++ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ++ LOG.info("getAll"); ++ request.setAttribute("mealList", UserMealsUtil.getWithExceeded(UserMealsUtil.MEAL_LIST, UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); ++ request.getRequestDispatcher("/mealList.jsp").forward(request, response); ++ } ++} +Index: src/main/webapp/WEB-INF/tld/functions.tld +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/WEB-INF/tld/functions.tld (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) ++++ src/main/webapp/WEB-INF/tld/functions.tld (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -0,0 +1,16 @@ ++ ++ ++ ++ 1.0 ++ functions ++ http://topjava.javawebinar.ru/functions ++ ++ ++ formatDateTime ++ ru.javawebinar.topjava.util.TimeUtil ++ java.lang.String toString(java.time.LocalDateTime) ++ ++ +Index: src/main/webapp/WEB-INF/web.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/WEB-INF/web.xml (revision 2c8ba27e36b2266486b66b4594b4572c7b5a24c1) ++++ src/main/webapp/WEB-INF/web.xml (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -15,4 +15,14 @@ + /users + + ++ ++ mealServlet ++ ru.javawebinar.topjava.web.MealServlet ++ 0 ++ ++ ++ mealServlet ++ /meals ++ ++ + +Index: src/main/webapp/index.html +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/index.html (revision 2c8ba27e36b2266486b66b4594b4572c7b5a24c1) ++++ src/main/webapp/index.html (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -9,6 +9,7 @@ +
    + + + +Index: src/main/webapp/mealList.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/mealList.jsp (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) ++++ src/main/webapp/mealList.jsp (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -0,0 +1,46 @@ ++<%@ page contentType="text/html;charset=UTF-8" language="java" %> ++<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> ++<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> ++<%@ taglib prefix="fn" uri="http://topjava.javawebinar.ru/functions" %> ++ ++ ++ Meal list ++ ++ ++ ++
    ++

    Home

    ++

    Meal list

    ++
    ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
    DateDescriptionCalories
    ++ <%--${meal.dateTime.toLocalDate()} ${meal.dateTime.toLocalTime()}--%> ++ <%--<%=TimeUtil.toString(meal.getDateTime())%>--%> ++ ${fn:formatDateTime(meal.dateTime)} ++ ${meal.description}${meal.calories}
    ++
    ++ ++ +\ No newline at end of file +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (revision 2c8ba27e36b2266486b66b4594b4572c7b5a24c1) ++++ pom.xml (revision 7dd935c232786b2c0ed22155f9556016d9ca168d) +@@ -67,6 +67,11 @@ + runtime +
    + ++ ++ javax.servlet ++ jstl ++ 1.2 ++ + + + javax.servlet From 37d918036a2518a8f22c510586f78a9a56d2a481 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Fri, 17 Jun 2016 13:09:11 +0300 Subject: [PATCH 09/39] apply patch 2.2 --- .../javawebinar/topjava/model/UserMeal.java | 28 ++++++++++ .../topjava/model/UserMealWithExceed.java | 14 ++++- .../InMemoryUserMealRepositoryImpl.java | 47 ++++++++++++++++ .../repository/UserMealRepository.java | 19 +++++++ .../topjava/util/UserMealsUtil.java | 6 +- .../javawebinar/topjava/web/MealServlet.java | 55 +++++++++++++++++-- src/main/webapp/mealEdit.jsp | 51 +++++++++++++++++ src/main/webapp/mealList.jsp | 5 ++ 8 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java create mode 100644 src/main/webapp/mealEdit.jsp diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java index 57da93fdd37a..8f4ab58d4bd4 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -8,17 +8,27 @@ */ public class UserMeal { private final LocalDateTime dateTime; + private Integer id; private final String description; private final int calories; public UserMeal(LocalDateTime dateTime, String description, int calories) { + this(null, dateTime, description, calories); + } + + public UserMeal(Integer id, LocalDateTime dateTime, String description, int calories) { + this.id = id; this.dateTime = dateTime; this.description = description; this.calories = calories; } + public void setId(int id) { + this.id = id; + } + public LocalDateTime getDateTime() { return dateTime; } @@ -30,4 +40,22 @@ public String getDescription() { public int getCalories() { return calories; } + + public Integer getId() { + return id; + } + + public boolean isNew() { + return id == null; + } + + @Override + public String toString() { + return "UserMeal{" + + "id=" + id + + ", dateTime=" + dateTime + + ", description='" + description + '\'' + + ", calories=" + calories + + '}'; + } } diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java index 5e6fdc5984fc..065c41bdfb66 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java @@ -7,6 +7,8 @@ * 11.01.2015. */ public class UserMealWithExceed { + private final Integer id; + private final LocalDateTime dateTime; private final String description; @@ -16,12 +18,21 @@ public class UserMealWithExceed { private final boolean exceed; public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) { + this(null, dateTime, description, calories, exceed); + } + + public UserMealWithExceed(Integer id, LocalDateTime dateTime, String description, int calories, boolean exceed) { + this.id = id; this.dateTime = dateTime; this.description = description; this.calories = calories; this.exceed = exceed; } + public Integer getId() { + return id; + } + public LocalDateTime getDateTime() { return dateTime; } @@ -41,7 +52,8 @@ public boolean isExceed() { @Override public String toString() { return "UserMealWithExceed{" + - "dateTime=" + dateTime + + "id=" + id + + ", dateTime=" + dateTime + ", description='" + description + '\'' + ", calories=" + calories + ", exceed=" + exceed + diff --git a/src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java new file mode 100644 index 000000000000..440f0d0a3151 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java @@ -0,0 +1,47 @@ +package ru.javawebinar.topjava.repository; + +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.util.UserMealsUtil; + +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * GKislin + * 15.09.2015. + */ +public class InMemoryUserMealRepositoryImpl implements UserMealRepository { + private Map repository = new ConcurrentHashMap<>(); + private AtomicInteger counter = new AtomicInteger(0); + + { + UserMealsUtil.MEAL_LIST.forEach(this::save); + } + + @Override + public UserMeal save(UserMeal userMeal) { + if (userMeal.isNew()) { + userMeal.setId(counter.incrementAndGet()); + } + repository.put(userMeal.getId(), userMeal); + return userMeal; + } + + @Override + public void delete(int id) { + repository.remove(id); + } + + @Override + public UserMeal get(int id) { + return repository.get(id); + } + + @Override + public Collection getAll() { + return repository.values(); + } +} + diff --git a/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java b/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java new file mode 100644 index 000000000000..8bedd15f581f --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java @@ -0,0 +1,19 @@ +package ru.javawebinar.topjava.repository; + +import ru.javawebinar.topjava.model.UserMeal; + +import java.util.Collection; + +/** + * GKislin + * 06.03.2015. + */ +public interface UserMealRepository { + UserMeal save(UserMeal userMeal); + + void delete(int id); + + UserMeal get(int id); + + Collection getAll(); +} diff --git a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java index 12adb051c953..587c7e04af69 100644 --- a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -33,11 +33,11 @@ public static void main(String[] args) { System.out.println(getFilteredWithExceededByCycle(MEAL_LIST, LocalTime.of(7, 0), LocalTime.of(12, 0), DEFAULT_CALORIES_PER_DAY)); } - public static List getWithExceeded(List mealList, int caloriesPerDay) { + public static List getWithExceeded(Collection mealList, int caloriesPerDay) { return getFilteredWithExceeded(mealList, LocalTime.MIN, LocalTime.MAX, caloriesPerDay); } - public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + public static List getFilteredWithExceeded(Collection mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { Map caloriesSumByDate = mealList.stream() .collect( Collectors.groupingBy(um -> um.getDateTime().toLocalDate(), @@ -66,6 +66,6 @@ public static List getFilteredWithExceededByCycle(List +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + Meal + + + +
    +

    Home

    +

    Edit meal

    +
    + +
    + +
    +
    DateTime:
    +
    +
    +
    +
    Description:
    +
    +
    +
    +
    Calories:
    +
    +
    + + +
    +
    + + diff --git a/src/main/webapp/mealList.jsp b/src/main/webapp/mealList.jsp index 41d681a77ca3..12d837677f38 100644 --- a/src/main/webapp/mealList.jsp +++ b/src/main/webapp/mealList.jsp @@ -19,6 +19,7 @@

    Home

    Meal list

    + Add Meal
    @@ -26,6 +27,8 @@ + + @@ -38,6 +41,8 @@ + +
    Date Description Calories
    ${meal.description} ${meal.calories}UpdateDelete
    From a68ab3d5dca047c4d69c02d39973bb04d0cfd647 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Fri, 17 Jun 2016 17:10:25 +0300 Subject: [PATCH 10/39] apply patch 2.3 --- .../ru/javawebinar/topjava/LoggedUser.java | 18 ++++ .../javawebinar/topjava/model/BaseEntity.java | 28 ++++++ .../topjava/model/NamedEntity.java | 31 ++++++ .../ru/javawebinar/topjava/model/Role.java | 10 ++ .../ru/javawebinar/topjava/model/User.java | 98 +++++++++++++++++++ .../topjava/repository/UserRepository.java | 24 +++++ .../topjava/service/UserMealService.java | 8 ++ .../topjava/service/UserMealServiceImpl.java | 13 +++ .../topjava/service/UserService.java | 26 +++++ .../topjava/service/UserServiceImpl.java | 41 ++++++++ .../topjava/util/exception/ExceptionUtil.java | 25 +++++ .../util/exception/NotFoundException.java | 11 +++ .../web/meal/UserMealRestController.java | 12 +++ .../web/user/AbstractUserController.java | 49 ++++++++++ .../topjava/web/user/AdminRestController.java | 36 +++++++ .../web/user/ProfileRestController.java | 23 +++++ 16 files changed, 453 insertions(+) create mode 100644 src/main/java/ru/javawebinar/topjava/LoggedUser.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/BaseEntity.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/NamedEntity.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/Role.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/User.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/UserRepository.java create mode 100644 src/main/java/ru/javawebinar/topjava/service/UserMealService.java create mode 100644 src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/service/UserService.java create mode 100644 src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java create mode 100644 src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java create mode 100644 src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java create mode 100644 src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java create mode 100644 src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java diff --git a/src/main/java/ru/javawebinar/topjava/LoggedUser.java b/src/main/java/ru/javawebinar/topjava/LoggedUser.java new file mode 100644 index 000000000000..73543d905840 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/LoggedUser.java @@ -0,0 +1,18 @@ +package ru.javawebinar.topjava; + +import ru.javawebinar.topjava.util.UserMealsUtil; + +/** + * GKislin + * 06.03.2015. + */ +public class LoggedUser { + + public static int id() { + return 1; + } + + public static int getCaloriesPerDay() { + return UserMealsUtil.DEFAULT_CALORIES_PER_DAY; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java new file mode 100644 index 000000000000..735198372b5a --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java @@ -0,0 +1,28 @@ +package ru.javawebinar.topjava.model; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public class BaseEntity { + protected Integer id; + + public BaseEntity() { + } + + protected BaseEntity(Integer id) { + this.id = id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public boolean isNew() { + return (this.id == null); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java b/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java new file mode 100644 index 000000000000..b4de0fc0d649 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java @@ -0,0 +1,31 @@ +package ru.javawebinar.topjava.model; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public class NamedEntity extends BaseEntity { + + protected String name; + + public NamedEntity() { + } + + protected NamedEntity(Integer id, String name) { + super(id); + this.name = name; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/model/Role.java b/src/main/java/ru/javawebinar/topjava/model/Role.java new file mode 100644 index 000000000000..27f38aae7a3d --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/Role.java @@ -0,0 +1,10 @@ +package ru.javawebinar.topjava.model; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public enum Role { + ROLE_USER, + ROLE_ADMIN +} diff --git a/src/main/java/ru/javawebinar/topjava/model/User.java b/src/main/java/ru/javawebinar/topjava/model/User.java new file mode 100644 index 000000000000..645b7fb9e20e --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/User.java @@ -0,0 +1,98 @@ +package ru.javawebinar.topjava.model; + +import ru.javawebinar.topjava.util.UserMealsUtil; + +import java.util.Date; +import java.util.EnumSet; +import java.util.Set; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public class User extends NamedEntity { + + protected String email; + + protected String password; + + protected boolean enabled = true; + + protected Date registered = new Date(); + + protected Set roles; + + protected int caloriesPerDay = UserMealsUtil.DEFAULT_CALORIES_PER_DAY; + + public User() { + } + + public User(Integer id, String name, String email, String password, Role role, Role... roles) { + this(id, name, email, password, UserMealsUtil.DEFAULT_CALORIES_PER_DAY, true, EnumSet.of(role, roles)); + } + + public User(Integer id, String name, String email, String password, int caloriesPerDay, boolean enabled, Set roles) { + super(id, name); + this.email = email; + this.password = password; + this.caloriesPerDay = caloriesPerDay; + this.enabled = enabled; + this.roles = roles; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPassword(String password) { + this.password = password; + } + + public Date getRegistered() { + return registered; + } + + public void setRegistered(Date registered) { + this.registered = registered; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public int getCaloriesPerDay() { + return caloriesPerDay; + } + + public void setCaloriesPerDay(int caloriesPerDay) { + this.caloriesPerDay = caloriesPerDay; + } + + public boolean isEnabled() { + return enabled; + } + + public Set getRoles() { + return roles; + } + + public String getPassword() { + return password; + } + + @Override + public String toString() { + return "User (" + + "id=" + id + + ", email=" + email + + ", name=" + name + + ", enabled=" + enabled + + ", roles=" + roles + + ", caloriesPerDay=" + caloriesPerDay + + ')'; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/UserRepository.java b/src/main/java/ru/javawebinar/topjava/repository/UserRepository.java new file mode 100644 index 000000000000..b73bb1a95e7c --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/UserRepository.java @@ -0,0 +1,24 @@ +package ru.javawebinar.topjava.repository; + +import ru.javawebinar.topjava.model.User; + +import java.util.List; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public interface UserRepository { + User save(User user); + + // false if not found + boolean delete(int id); + + // null if not found + User get(int id); + + // null if not found + User getByEmail(String email); + + List getAll(); +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserMealService.java b/src/main/java/ru/javawebinar/topjava/service/UserMealService.java new file mode 100644 index 000000000000..182f91376582 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/service/UserMealService.java @@ -0,0 +1,8 @@ +package ru.javawebinar.topjava.service; + +/** + * GKislin + * 15.06.2015. + */ +public interface UserMealService { +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java new file mode 100644 index 000000000000..9a95447cc45a --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java @@ -0,0 +1,13 @@ +package ru.javawebinar.topjava.service; + +import ru.javawebinar.topjava.repository.UserMealRepository; + +/** + * GKislin + * 06.03.2015. + */ +public class UserMealServiceImpl implements UserMealService { + + private UserMealRepository repository; + +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserService.java b/src/main/java/ru/javawebinar/topjava/service/UserService.java new file mode 100644 index 000000000000..acab3bf3081d --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/service/UserService.java @@ -0,0 +1,26 @@ +package ru.javawebinar.topjava.service; + + +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.util.exception.NotFoundException; + +import java.util.List; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public interface UserService { + + User save(User user); + + void delete(int id) throws NotFoundException; + + User get(int id) throws NotFoundException; + + User getByEmail(String email) throws NotFoundException; + + List getAll(); + + void update(User user); +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java new file mode 100644 index 000000000000..6748bf2e7c88 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java @@ -0,0 +1,41 @@ +package ru.javawebinar.topjava.service; + +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; +import ru.javawebinar.topjava.util.exception.ExceptionUtil; +import ru.javawebinar.topjava.util.exception.NotFoundException; + +import java.util.List; + +/** + * GKislin + * 06.03.2015. + */ +public class UserServiceImpl implements UserService { + + private UserRepository repository; + + public User save(User user) { + return repository.save(user); + } + + public void delete(int id) { + ExceptionUtil.checkNotFoundWithId(repository.delete(id), id); + } + + public User get(int id) throws NotFoundException { + return ExceptionUtil.checkNotFoundWithId(repository.get(id), id); + } + + public User getByEmail(String email) throws NotFoundException { + return ExceptionUtil.checkNotFound(repository.getByEmail(email), "email=" + email); + } + + public List getAll() { + return repository.getAll(); + } + + public void update(User user) { + repository.save(user); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java b/src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java new file mode 100644 index 000000000000..1099bd9530ee --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java @@ -0,0 +1,25 @@ +package ru.javawebinar.topjava.util.exception; + + +/** + * User: gkislin + * Date: 14.05.2014 + */ +public class ExceptionUtil { + public static void checkNotFoundWithId(boolean found, int id) { + checkNotFound(found, "id=" + id); + } + + public static T checkNotFoundWithId(T object, int id) { + return checkNotFound(object, "id=" + id); + } + + public static T checkNotFound(T object, String msg) { + checkNotFound(object != null, msg); + return object; + } + + public static void checkNotFound(boolean found, String msg) { + if (!found) throw new NotFoundException("Not found entity with " + msg); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java b/src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java new file mode 100644 index 000000000000..1106389dc853 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java @@ -0,0 +1,11 @@ +package ru.javawebinar.topjava.util.exception; + +/** + * User: gkislin + * Date: 19.08.2014 + */ +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java b/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java new file mode 100644 index 000000000000..89194b79f7b2 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java @@ -0,0 +1,12 @@ +package ru.javawebinar.topjava.web.meal; + +import ru.javawebinar.topjava.service.UserMealService; + +/** + * GKislin + * 06.03.2015. + */ +public class UserMealRestController { + private UserMealService service; + +} diff --git a/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java b/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java new file mode 100644 index 000000000000..5057f02dc492 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java @@ -0,0 +1,49 @@ +package ru.javawebinar.topjava.web.user; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.service.UserService; + +import java.util.List; + +/** + * User: gkislin + */ +public abstract class AbstractUserController { + protected final Logger LOG = LoggerFactory.getLogger(getClass()); + + private UserService service; + + public List getAll() { + LOG.info("getAll"); + return service.getAll(); + } + + public User get(int id) { + LOG.info("get " + id); + return service.get(id); + } + + public User create(User user) { + user.setId(null); + LOG.info("create " + user); + return service.save(user); + } + + public void delete(int id) { + LOG.info("delete " + id); + service.delete(id); + } + + public void update(User user, int id) { + user.setId(id); + LOG.info("update " + user); + service.update(user); + } + + public User getByMail(String email) { + LOG.info("getByEmail " + email); + return service.getByEmail(email); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java b/src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java new file mode 100644 index 000000000000..bf781e9fb50c --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java @@ -0,0 +1,36 @@ +package ru.javawebinar.topjava.web.user; + +import ru.javawebinar.topjava.model.User; + +import java.util.List; + +/** + * GKislin + * 06.03.2015. + */ +public class AdminRestController extends AbstractUserController { + + public List getAll() { + return super.getAll(); + } + + public User get(int id) { + return super.get(id); + } + + public User create(User user) { + return super.create(user); + } + + public void delete(int id) { + super.delete(id); + } + + public void update(User user, int id) { + super.update(user, id); + } + + public User getByMail(String email) { + return super.getByMail(email); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java b/src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java new file mode 100644 index 000000000000..82406441de55 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java @@ -0,0 +1,23 @@ +package ru.javawebinar.topjava.web.user; + +import ru.javawebinar.topjava.LoggedUser; +import ru.javawebinar.topjava.model.User; + +/** + * GKislin + * 06.03.2015. + */ +public class ProfileRestController extends AbstractUserController { + + public User get() { + return super.get(LoggedUser.id()); + } + + public void delete() { + super.delete(LoggedUser.id()); + } + + public void update(User user) { + super.update(user, LoggedUser.id()); + } +} \ No newline at end of file From 3dbf65f752e8956b1d78274ab0083ffdc08c7a8a Mon Sep 17 00:00:00 2001 From: andreichernov Date: Sat, 18 Jun 2016 13:40:11 +0300 Subject: [PATCH 11/39] apply patch 2.4 --- pom.xml | 14 ++++++ .../ru/javawebinar/topjava/SpringMain.java | 23 +++++++++ .../InMemoryUserMealRepositoryImpl.java | 3 +- .../mock/MockUserRepositoryImpl.java | 47 +++++++++++++++++++ .../javawebinar/topjava/web/MealServlet.java | 2 +- src/main/resources/spring/spring-app.xml | 8 ++++ 6 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/main/java/ru/javawebinar/topjava/SpringMain.java rename src/main/java/ru/javawebinar/topjava/repository/{ => mock}/InMemoryUserMealRepositoryImpl.java (87%) create mode 100644 src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java create mode 100644 src/main/resources/spring/spring-app.xml diff --git a/pom.xml b/pom.xml index f79727654639..9e17b4a5669a 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,8 @@ UTF-8 UTF-8 + 4.2.6.RELEASE + 1.1.7 1.7.21 @@ -67,6 +69,18 @@ runtime + + + org.springframework + spring-context + ${spring.version} + + + commons-logging + commons-logging + + + javax.servlet jstl diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/main/java/ru/javawebinar/topjava/SpringMain.java new file mode 100644 index 000000000000..4e82530bdaf8 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/SpringMain.java @@ -0,0 +1,23 @@ +package ru.javawebinar.topjava; + +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import ru.javawebinar.topjava.repository.UserRepository; + +import java.util.Arrays; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public class SpringMain { + public static void main(String[] args) { + ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); + System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); + +// UserRepository userRepository = (UserRepository) appCtx.getBean("mockUserRepository"); + UserRepository userRepository = appCtx.getBean(UserRepository.class); + userRepository.getAll(); + appCtx.close(); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java similarity index 87% rename from src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java rename to src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java index 440f0d0a3151..cceba647c7a6 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java @@ -1,6 +1,7 @@ -package ru.javawebinar.topjava.repository; +package ru.javawebinar.topjava.repository.mock; import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.repository.UserMealRepository; import ru.javawebinar.topjava.util.UserMealsUtil; import java.util.Collection; diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java new file mode 100644 index 000000000000..1f2a36888cb1 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java @@ -0,0 +1,47 @@ +package ru.javawebinar.topjava.repository.mock; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; + +import java.util.Collections; +import java.util.List; + +/** + * GKislin + * 15.06.2015. + */ +public class MockUserRepositoryImpl implements UserRepository { + private static final Logger LOG = LoggerFactory.getLogger(MockUserRepositoryImpl.class); + + @Override + public boolean delete(int id) { + LOG.info("delete " + id); + return true; + } + + @Override + public User save(User user) { + LOG.info("save " + user); + return user; + } + + @Override + public User get(int id) { + LOG.info("get " + id); + return null; + } + + @Override + public List getAll() { + LOG.info("getAll"); + return Collections.emptyList(); + } + + @Override + public User getByEmail(String email) { + LOG.info("getByEmail " + email); + return null; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java index b28a548bfb69..c04e1efaf83f 100644 --- a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java @@ -3,7 +3,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.javawebinar.topjava.model.UserMeal; -import ru.javawebinar.topjava.repository.InMemoryUserMealRepositoryImpl; +import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; import ru.javawebinar.topjava.repository.UserMealRepository; import ru.javawebinar.topjava.util.UserMealsUtil; diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml new file mode 100644 index 000000000000..642f22f66db6 --- /dev/null +++ b/src/main/resources/spring/spring-app.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file From 5a2bb9a1d59823305c27d18e6a96cbc1491e5679 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Sat, 18 Jun 2016 13:43:10 +0300 Subject: [PATCH 12/39] download patch 2.5 --- patchs/to_lesson02/2_2_HW1_optional.patch | 398 ++++++++++++ patchs/to_lesson02/2_3_app_layers.patch | 582 ++++++++++++++++++ .../to_lesson02/2_4_add_spring_context.patch | 167 +++++ .../2_5_add_dependency_injection.patch | 68 ++ 4 files changed, 1215 insertions(+) create mode 100644 patchs/to_lesson02/2_2_HW1_optional.patch create mode 100644 patchs/to_lesson02/2_3_app_layers.patch create mode 100644 patchs/to_lesson02/2_4_add_spring_context.patch create mode 100644 patchs/to_lesson02/2_5_add_dependency_injection.patch diff --git a/patchs/to_lesson02/2_2_HW1_optional.patch b/patchs/to_lesson02/2_2_HW1_optional.patch new file mode 100644 index 000000000000..ecf1525beb4f --- /dev/null +++ b/patchs/to_lesson02/2_2_HW1_optional.patch @@ -0,0 +1,398 @@ +Index: src/main/webapp/mealEdit.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/mealEdit.jsp (revision ) ++++ src/main/webapp/mealEdit.jsp (revision ) +@@ -0,0 +1,51 @@ ++<%@ page contentType="text/html;charset=UTF-8" language="java" %> ++<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> ++ ++ ++ ++ Meal ++ ++ ++ ++
    ++

    Home

    ++

    Edit meal

    ++
    ++ ++
    ++ ++
    ++
    DateTime:
    ++
    ++
    ++
    ++
    Description:
    ++
    ++
    ++
    ++
    Calories:
    ++
    ++
    ++ ++ ++
    ++
    ++ ++ +Index: src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java (revision ) +@@ -0,0 +1,47 @@ ++package ru.javawebinar.topjava.repository; ++ ++import ru.javawebinar.topjava.model.UserMeal; ++import ru.javawebinar.topjava.util.UserMealsUtil; ++ ++import java.util.Collection; ++import java.util.Map; ++import java.util.concurrent.ConcurrentHashMap; ++import java.util.concurrent.atomic.AtomicInteger; ++ ++/** ++ * GKislin ++ * 15.09.2015. ++ */ ++public class InMemoryUserMealRepositoryImpl implements UserMealRepository { ++ private Map repository = new ConcurrentHashMap<>(); ++ private AtomicInteger counter = new AtomicInteger(0); ++ ++ { ++ UserMealsUtil.MEAL_LIST.forEach(this::save); ++ } ++ ++ @Override ++ public UserMeal save(UserMeal userMeal) { ++ if (userMeal.isNew()) { ++ userMeal.setId(counter.incrementAndGet()); ++ } ++ repository.put(userMeal.getId(), userMeal); ++ return userMeal; ++ } ++ ++ @Override ++ public void delete(int id) { ++ repository.remove(id); ++ } ++ ++ @Override ++ public UserMeal get(int id) { ++ return repository.get(id); ++ } ++ ++ @Override ++ public Collection getAll() { ++ return repository.values(); ++ } ++} ++ +Index: src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java (revision ) +@@ -0,0 +1,19 @@ ++package ru.javawebinar.topjava.repository; ++ ++import ru.javawebinar.topjava.model.UserMeal; ++ ++import java.util.Collection; ++ ++/** ++ * GKislin ++ * 06.03.2015. ++ */ ++public interface UserMealRepository { ++ UserMeal save(UserMeal userMeal); ++ ++ void delete(int id); ++ ++ UserMeal get(int id); ++ ++ Collection getAll(); ++} +Index: src/main/java/ru/javawebinar/topjava/model/UserMeal.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMeal.java (date 1465161605000) ++++ src/main/java/ru/javawebinar/topjava/model/UserMeal.java (revision ) +@@ -7,18 +7,29 @@ + * 11.01.2015. + */ + public class UserMeal { +- protected final LocalDateTime dateTime; ++ private Integer id; + +- protected final String description; ++ private final LocalDateTime dateTime; + +- protected final int calories; ++ private final String description; + ++ private final int calories; ++ + public UserMeal(LocalDateTime dateTime, String description, int calories) { ++ this(null, dateTime, description, calories); ++ } ++ ++ public UserMeal(Integer id, LocalDateTime dateTime, String description, int calories) { ++ this.id = id; + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + } + ++ public void setId(int id) { ++ this.id = id; ++ } ++ + public LocalDateTime getDateTime() { + return dateTime; + } +@@ -29,5 +40,23 @@ + + public int getCalories() { + return calories; ++ } ++ ++ public Integer getId() { ++ return id; ++ } ++ ++ public boolean isNew() { ++ return id == null; ++ } ++ ++ @Override ++ public String toString() { ++ return "UserMeal{" + ++ "id=" + id + ++ ", dateTime=" + dateTime + ++ ", description='" + description + '\'' + ++ ", calories=" + calories + ++ '}'; + } + } +Index: src/main/java/ru/javawebinar/topjava/web/MealServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/MealServlet.java (date 1465161605000) ++++ src/main/java/ru/javawebinar/topjava/web/MealServlet.java (revision ) +@@ -2,13 +2,19 @@ + + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; ++import ru.javawebinar.topjava.model.UserMeal; ++import ru.javawebinar.topjava.repository.InMemoryUserMealRepositoryImpl; ++import ru.javawebinar.topjava.repository.UserMealRepository; + import ru.javawebinar.topjava.util.UserMealsUtil; + ++import javax.servlet.ServletConfig; + import javax.servlet.ServletException; + import javax.servlet.http.HttpServlet; + import javax.servlet.http.HttpServletRequest; + import javax.servlet.http.HttpServletResponse; + import java.io.IOException; ++import java.time.LocalDateTime; ++import java.util.Objects; + + /** + * User: gkislin +@@ -17,9 +23,50 @@ + public class MealServlet extends HttpServlet { + private static final Logger LOG = LoggerFactory.getLogger(MealServlet.class); + ++ private UserMealRepository repository; ++ ++ @Override ++ public void init(ServletConfig config) throws ServletException { ++ super.init(config); ++ repository = new InMemoryUserMealRepositoryImpl(); ++ } ++ ++ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ++ request.setCharacterEncoding("UTF-8"); ++ String id = request.getParameter("id"); ++ UserMeal userMeal = new UserMeal(id.isEmpty() ? null : Integer.valueOf(id), ++ LocalDateTime.parse(request.getParameter("dateTime")), ++ request.getParameter("description"), ++ Integer.valueOf(request.getParameter("calories"))); ++ LOG.info(userMeal.isNew() ? "Create {}" : "Update {}", userMeal); ++ repository.save(userMeal); ++ response.sendRedirect("meals"); ++ } ++ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ++ String action = request.getParameter("action"); ++ ++ if (action == null) { +- LOG.info("getAll"); ++ LOG.info("getAll"); +- request.setAttribute("mealList", UserMealsUtil.getWithExceeded(UserMealsUtil.MEAL_LIST, UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); ++ request.setAttribute("mealList", ++ UserMealsUtil.getWithExceeded(repository.getAll(), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); +- request.getRequestDispatcher("/mealList.jsp").forward(request, response); ++ request.getRequestDispatcher("/mealList.jsp").forward(request, response); ++ } else if (action.equals("delete")) { ++ int id = getId(request); ++ LOG.info("Delete {}", id); ++ repository.delete(id); ++ response.sendRedirect("meals"); ++ } else if (action.equals("create") || action.equals("update")) { ++ final UserMeal meal = action.equals("create") ? ++ new UserMeal(LocalDateTime.now().withNano(0).withSecond(0), "", 1000) : ++ repository.get(getId(request)); ++ request.setAttribute("meal", meal); ++ request.getRequestDispatcher("mealEdit.jsp").forward(request, response); ++ } ++ } ++ ++ private int getId(HttpServletRequest request) { ++ String paramId = Objects.requireNonNull(request.getParameter("id")); ++ return Integer.valueOf(paramId); + } + } +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (date 1465161605000) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) +@@ -33,11 +33,11 @@ + System.out.println(getFilteredWithExceededByCycle(MEAL_LIST, LocalTime.of(7, 0), LocalTime.of(12, 0), DEFAULT_CALORIES_PER_DAY)); + } + +- public static List getWithExceeded(List mealList, int caloriesPerDay) { ++ public static List getWithExceeded(Collection mealList, int caloriesPerDay) { + return getFilteredWithExceeded(mealList, LocalTime.MIN, LocalTime.MAX, caloriesPerDay); + } + +- public static List getFilteredWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { ++ public static List getFilteredWithExceeded(Collection mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + Map caloriesSumByDate = mealList.stream() + .collect( + Collectors.groupingBy(um -> um.getDateTime().toLocalDate(), +@@ -66,6 +66,6 @@ + } + + public static UserMealWithExceed createWithExceed(UserMeal um, boolean exceeded) { +- return new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), exceeded); ++ return new UserMealWithExceed(um.getId(), um.getDateTime(), um.getDescription(), um.getCalories(), exceeded); + } + } +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (date 1465161605000) ++++ src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (revision ) +@@ -7,6 +7,8 @@ + * 11.01.2015. + */ + public class UserMealWithExceed { ++ private final Integer id; ++ + private final LocalDateTime dateTime; + + private final String description; +@@ -16,12 +18,21 @@ + private final boolean exceed; + + public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) { ++ this(null, dateTime, description, calories, exceed); ++ } ++ ++ public UserMealWithExceed(Integer id, LocalDateTime dateTime, String description, int calories, boolean exceed) { ++ this.id = id; + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + this.exceed = exceed; + } + ++ public Integer getId() { ++ return id; ++ } ++ + public LocalDateTime getDateTime() { + return dateTime; + } +@@ -41,7 +52,8 @@ + @Override + public String toString() { + return "UserMealWithExceed{" + +- "dateTime=" + dateTime + ++ "id=" + id + ++ ", dateTime=" + dateTime + + ", description='" + description + '\'' + + ", calories=" + calories + + ", exceed=" + exceed + +Index: src/main/webapp/mealList.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/mealList.jsp (date 1465161605000) ++++ src/main/webapp/mealList.jsp (revision ) +@@ -19,6 +19,7 @@ +
    +

    Home

    +

    Meal list

    ++ Add Meal +
    + + +@@ -26,6 +27,8 @@ + + + ++ ++ + + + +@@ -37,6 +40,8 @@ + + + ++ ++ + + +
    DateDescriptionCalories
    ${meal.description}${meal.calories}UpdateDelete
    +\ No newline at end of file diff --git a/patchs/to_lesson02/2_3_app_layers.patch b/patchs/to_lesson02/2_3_app_layers.patch new file mode 100644 index 000000000000..fe6bc202d19b --- /dev/null +++ b/patchs/to_lesson02/2_3_app_layers.patch @@ -0,0 +1,582 @@ +Index: src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java (revision ) +@@ -0,0 +1,36 @@ ++package ru.javawebinar.topjava.web.user; ++ ++import ru.javawebinar.topjava.model.User; ++ ++import java.util.List; ++ ++/** ++ * GKislin ++ * 06.03.2015. ++ */ ++public class AdminRestController extends AbstractUserController { ++ ++ public List getAll() { ++ return super.getAll(); ++ } ++ ++ public User get(int id) { ++ return super.get(id); ++ } ++ ++ public User create(User user) { ++ return super.create(user); ++ } ++ ++ public void delete(int id) { ++ super.delete(id); ++ } ++ ++ public void update(User user, int id) { ++ super.update(user, id); ++ } ++ ++ public User getByMail(String email) { ++ return super.getByMail(email); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java (revision ) +@@ -0,0 +1,41 @@ ++package ru.javawebinar.topjava.service; ++ ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.repository.UserRepository; ++import ru.javawebinar.topjava.util.exception.ExceptionUtil; ++import ru.javawebinar.topjava.util.exception.NotFoundException; ++ ++import java.util.List; ++ ++/** ++ * GKislin ++ * 06.03.2015. ++ */ ++public class UserServiceImpl implements UserService { ++ ++ private UserRepository repository; ++ ++ public User save(User user) { ++ return repository.save(user); ++ } ++ ++ public void delete(int id) { ++ ExceptionUtil.checkNotFoundWithId(repository.delete(id), id); ++ } ++ ++ public User get(int id) throws NotFoundException { ++ return ExceptionUtil.checkNotFoundWithId(repository.get(id), id); ++ } ++ ++ public User getByEmail(String email) throws NotFoundException { ++ return ExceptionUtil.checkNotFound(repository.getByEmail(email), "email=" + email); ++ } ++ ++ public List getAll() { ++ return repository.getAll(); ++ } ++ ++ public void update(User user) { ++ repository.save(user); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java (revision ) +@@ -0,0 +1,13 @@ ++package ru.javawebinar.topjava.service; ++ ++import ru.javawebinar.topjava.repository.UserMealRepository; ++ ++/** ++ * GKislin ++ * 06.03.2015. ++ */ ++public class UserMealServiceImpl implements UserMealService { ++ ++ private UserMealRepository repository; ++ ++} +Index: src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java (revision ) +@@ -0,0 +1,12 @@ ++package ru.javawebinar.topjava.web.meal; ++ ++import ru.javawebinar.topjava.service.UserMealService; ++ ++/** ++ * GKislin ++ * 06.03.2015. ++ */ ++public class UserMealRestController { ++ private UserMealService service; ++ ++} +Index: src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java (revision ) +@@ -0,0 +1,25 @@ ++package ru.javawebinar.topjava.util.exception; ++ ++ ++/** ++ * User: gkislin ++ * Date: 14.05.2014 ++ */ ++public class ExceptionUtil { ++ public static void checkNotFoundWithId(boolean found, int id) { ++ checkNotFound(found, "id=" + id); ++ } ++ ++ public static T checkNotFoundWithId(T object, int id) { ++ return checkNotFound(object, "id=" + id); ++ } ++ ++ public static T checkNotFound(T object, String msg) { ++ checkNotFound(object != null, msg); ++ return object; ++ } ++ ++ public static void checkNotFound(boolean found, String msg) { ++ if (!found) throw new NotFoundException("Not found entity with " + msg); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/model/NamedEntity.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/NamedEntity.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/model/NamedEntity.java (revision ) +@@ -0,0 +1,31 @@ ++package ru.javawebinar.topjava.model; ++ ++/** ++ * User: gkislin ++ * Date: 22.08.2014 ++ */ ++public class NamedEntity extends BaseEntity { ++ ++ protected String name; ++ ++ public NamedEntity() { ++ } ++ ++ protected NamedEntity(Integer id, String name) { ++ super(id); ++ this.name = name; ++ } ++ ++ public void setName(String name) { ++ this.name = name; ++ } ++ ++ public String getName() { ++ return this.name; ++ } ++ ++ @Override ++ public String toString() { ++ return name; ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java (revision ) +@@ -0,0 +1,23 @@ ++package ru.javawebinar.topjava.web.user; ++ ++import ru.javawebinar.topjava.LoggedUser; ++import ru.javawebinar.topjava.model.User; ++ ++/** ++ * GKislin ++ * 06.03.2015. ++ */ ++public class ProfileRestController extends AbstractUserController { ++ ++ public User get() { ++ return super.get(LoggedUser.id()); ++ } ++ ++ public void delete() { ++ super.delete(LoggedUser.id()); ++ } ++ ++ public void update(User user) { ++ super.update(user, LoggedUser.id()); ++ } ++} +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/service/UserService.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserService.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/service/UserService.java (revision ) +@@ -0,0 +1,26 @@ ++package ru.javawebinar.topjava.service; ++ ++ ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.util.exception.NotFoundException; ++ ++import java.util.List; ++ ++/** ++ * User: gkislin ++ * Date: 22.08.2014 ++ */ ++public interface UserService { ++ ++ User save(User user); ++ ++ void delete(int id) throws NotFoundException; ++ ++ User get(int id) throws NotFoundException; ++ ++ User getByEmail(String email) throws NotFoundException; ++ ++ List getAll(); ++ ++ void update(User user); ++} +Index: src/main/java/ru/javawebinar/topjava/repository/UserRepository.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/UserRepository.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/repository/UserRepository.java (revision ) +@@ -0,0 +1,24 @@ ++package ru.javawebinar.topjava.repository; ++ ++import ru.javawebinar.topjava.model.User; ++ ++import java.util.List; ++ ++/** ++ * User: gkislin ++ * Date: 22.08.2014 ++ */ ++public interface UserRepository { ++ User save(User user); ++ ++ // false if not found ++ boolean delete(int id); ++ ++ // null if not found ++ User get(int id); ++ ++ // null if not found ++ User getByEmail(String email); ++ ++ List getAll(); ++} +Index: src/main/java/ru/javawebinar/topjava/model/BaseEntity.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/BaseEntity.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/model/BaseEntity.java (revision ) +@@ -0,0 +1,28 @@ ++package ru.javawebinar.topjava.model; ++ ++/** ++ * User: gkislin ++ * Date: 22.08.2014 ++ */ ++public class BaseEntity { ++ protected Integer id; ++ ++ public BaseEntity() { ++ } ++ ++ protected BaseEntity(Integer id) { ++ this.id = id; ++ } ++ ++ public void setId(Integer id) { ++ this.id = id; ++ } ++ ++ public Integer getId() { ++ return id; ++ } ++ ++ public boolean isNew() { ++ return (this.id == null); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java (revision ) +@@ -0,0 +1,49 @@ ++package ru.javawebinar.topjava.web.user; ++ ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.service.UserService; ++ ++import java.util.List; ++ ++/** ++ * User: gkislin ++ */ ++public abstract class AbstractUserController { ++ protected final Logger LOG = LoggerFactory.getLogger(getClass()); ++ ++ private UserService service; ++ ++ public List getAll() { ++ LOG.info("getAll"); ++ return service.getAll(); ++ } ++ ++ public User get(int id) { ++ LOG.info("get " + id); ++ return service.get(id); ++ } ++ ++ public User create(User user) { ++ user.setId(null); ++ LOG.info("create " + user); ++ return service.save(user); ++ } ++ ++ public void delete(int id) { ++ LOG.info("delete " + id); ++ service.delete(id); ++ } ++ ++ public void update(User user, int id) { ++ user.setId(id); ++ LOG.info("update " + user); ++ service.update(user); ++ } ++ ++ public User getByMail(String email) { ++ LOG.info("getByEmail " + email); ++ return service.getByEmail(email); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java (revision ) +@@ -0,0 +1,11 @@ ++package ru.javawebinar.topjava.util.exception; ++ ++/** ++ * User: gkislin ++ * Date: 19.08.2014 ++ */ ++public class NotFoundException extends RuntimeException { ++ public NotFoundException(String message) { ++ super(message); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/service/UserMealService.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserMealService.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/service/UserMealService.java (revision ) +@@ -0,0 +1,8 @@ ++package ru.javawebinar.topjava.service; ++ ++/** ++ * GKislin ++ * 15.06.2015. ++ */ ++public interface UserMealService { ++} +Index: src/main/java/ru/javawebinar/topjava/LoggedUser.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/LoggedUser.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/LoggedUser.java (revision ) +@@ -0,0 +1,18 @@ ++package ru.javawebinar.topjava; ++ ++import ru.javawebinar.topjava.util.UserMealsUtil; ++ ++/** ++ * GKislin ++ * 06.03.2015. ++ */ ++public class LoggedUser { ++ ++ public static int id() { ++ return 1; ++ } ++ ++ public static int getCaloriesPerDay() { ++ return UserMealsUtil.DEFAULT_CALORIES_PER_DAY; ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/model/Role.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/Role.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/model/Role.java (revision ) +@@ -0,0 +1,10 @@ ++package ru.javawebinar.topjava.model; ++ ++/** ++ * User: gkislin ++ * Date: 22.08.2014 ++ */ ++public enum Role { ++ ROLE_USER, ++ ROLE_ADMIN ++} +Index: src/main/java/ru/javawebinar/topjava/model/User.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/User.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/model/User.java (revision ) +@@ -0,0 +1,98 @@ ++package ru.javawebinar.topjava.model; ++ ++import ru.javawebinar.topjava.util.UserMealsUtil; ++ ++import java.util.Date; ++import java.util.EnumSet; ++import java.util.Set; ++ ++/** ++ * User: gkislin ++ * Date: 22.08.2014 ++ */ ++public class User extends NamedEntity { ++ ++ protected String email; ++ ++ protected String password; ++ ++ protected boolean enabled = true; ++ ++ protected Date registered = new Date(); ++ ++ protected Set roles; ++ ++ protected int caloriesPerDay = UserMealsUtil.DEFAULT_CALORIES_PER_DAY; ++ ++ public User() { ++ } ++ ++ public User(Integer id, String name, String email, String password, Role role, Role... roles) { ++ this(id, name, email, password, UserMealsUtil.DEFAULT_CALORIES_PER_DAY, true, EnumSet.of(role, roles)); ++ } ++ ++ public User(Integer id, String name, String email, String password, int caloriesPerDay, boolean enabled, Set roles) { ++ super(id, name); ++ this.email = email; ++ this.password = password; ++ this.caloriesPerDay = caloriesPerDay; ++ this.enabled = enabled; ++ this.roles = roles; ++ } ++ ++ public String getEmail() { ++ return email; ++ } ++ ++ public void setEmail(String email) { ++ this.email = email; ++ } ++ ++ public void setPassword(String password) { ++ this.password = password; ++ } ++ ++ public Date getRegistered() { ++ return registered; ++ } ++ ++ public void setRegistered(Date registered) { ++ this.registered = registered; ++ } ++ ++ public void setEnabled(boolean enabled) { ++ this.enabled = enabled; ++ } ++ ++ public int getCaloriesPerDay() { ++ return caloriesPerDay; ++ } ++ ++ public void setCaloriesPerDay(int caloriesPerDay) { ++ this.caloriesPerDay = caloriesPerDay; ++ } ++ ++ public boolean isEnabled() { ++ return enabled; ++ } ++ ++ public Set getRoles() { ++ return roles; ++ } ++ ++ public String getPassword() { ++ return password; ++ } ++ ++ @Override ++ public String toString() { ++ return "User (" + ++ "id=" + id + ++ ", email=" + email + ++ ", name=" + name + ++ ", enabled=" + enabled + ++ ", roles=" + roles + ++ ", caloriesPerDay=" + caloriesPerDay + ++ ')'; ++ } ++} diff --git a/patchs/to_lesson02/2_4_add_spring_context.patch b/patchs/to_lesson02/2_4_add_spring_context.patch new file mode 100644 index 000000000000..47b295408fb3 --- /dev/null +++ b/patchs/to_lesson02/2_4_add_spring_context.patch @@ -0,0 +1,167 @@ +Index: src/main/java/ru/javawebinar/topjava/SpringMain.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/SpringMain.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/SpringMain.java (revision ) +@@ -0,0 +1,23 @@ ++package ru.javawebinar.topjava; ++ ++import org.springframework.context.ConfigurableApplicationContext; ++import org.springframework.context.support.ClassPathXmlApplicationContext; ++import ru.javawebinar.topjava.repository.UserRepository; ++ ++import java.util.Arrays; ++ ++/** ++ * User: gkislin ++ * Date: 22.08.2014 ++ */ ++public class SpringMain { ++ public static void main(String[] args) { ++ ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); ++ System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); ++ ++// UserRepository userRepository = (UserRepository) appCtx.getBean("mockUserRepository"); ++ UserRepository userRepository = appCtx.getBean(UserRepository.class); ++ userRepository.getAll(); ++ appCtx.close(); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (revision ) +@@ -0,0 +1,47 @@ ++package ru.javawebinar.topjava.repository.mock; ++ ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.repository.UserRepository; ++ ++import java.util.Collections; ++import java.util.List; ++ ++/** ++ * GKislin ++ * 15.06.2015. ++ */ ++public class MockUserRepositoryImpl implements UserRepository { ++ private static final Logger LOG = LoggerFactory.getLogger(MockUserRepositoryImpl.class); ++ ++ @Override ++ public boolean delete(int id) { ++ LOG.info("delete " + id); ++ return true; ++ } ++ ++ @Override ++ public User save(User user) { ++ LOG.info("save " + user); ++ return user; ++ } ++ ++ @Override ++ public User get(int id) { ++ LOG.info("get " + id); ++ return null; ++ } ++ ++ @Override ++ public List getAll() { ++ LOG.info("getAll"); ++ return Collections.emptyList(); ++ } ++ ++ @Override ++ public User getByEmail(String email) { ++ LOG.info("getByEmail " + email); ++ return null; ++ } ++} +Index: src/main/resources/spring/spring-app.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/spring/spring-app.xml (revision ) ++++ src/main/resources/spring/spring-app.xml (revision ) +@@ -0,0 +1,8 @@ ++ ++ ++ ++ ++ +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/web/MealServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/MealServlet.java (date 1465331514000) ++++ src/main/java/ru/javawebinar/topjava/web/MealServlet.java (revision ) +@@ -3,7 +3,7 @@ + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import ru.javawebinar.topjava.model.UserMeal; +-import ru.javawebinar.topjava.repository.InMemoryUserMealRepositoryImpl; ++import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; + import ru.javawebinar.topjava.repository.UserMealRepository; + import ru.javawebinar.topjava.util.UserMealsUtil; + +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1465331514000) ++++ pom.xml (revision ) +@@ -16,6 +16,8 @@ + UTF-8 + UTF-8 + ++ 4.2.6.RELEASE ++ + + 1.1.7 + 1.7.21 +@@ -67,6 +69,18 @@ + runtime + + ++ ++ ++ org.springframework ++ spring-context ++ ${spring.version} ++ ++ ++ commons-logging ++ commons-logging ++ ++ ++ + + javax.servlet + jstl +Index: src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/InMemoryUserMealRepositoryImpl.java (date 1465331514000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java (revision ) +@@ -1,6 +1,7 @@ +-package ru.javawebinar.topjava.repository; ++package ru.javawebinar.topjava.repository.mock; + + import ru.javawebinar.topjava.model.UserMeal; ++import ru.javawebinar.topjava.repository.UserMealRepository; + import ru.javawebinar.topjava.util.UserMealsUtil; + + import java.util.Collection; diff --git a/patchs/to_lesson02/2_5_add_dependency_injection.patch b/patchs/to_lesson02/2_5_add_dependency_injection.patch new file mode 100644 index 000000000000..b655f05343c6 --- /dev/null +++ b/patchs/to_lesson02/2_5_add_dependency_injection.patch @@ -0,0 +1,68 @@ +Index: src/main/resources/spring/spring-app.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/spring/spring-app.xml (date 1465332050000) ++++ src/main/resources/spring/spring-app.xml (revision ) +@@ -1,8 +1,10 @@ + ++ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> + + + ++ ++ ++ + +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/SpringMain.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/SpringMain.java (date 1465332050000) ++++ src/main/java/ru/javawebinar/topjava/SpringMain.java (revision ) +@@ -2,7 +2,10 @@ + + import org.springframework.context.ConfigurableApplicationContext; + import org.springframework.context.support.ClassPathXmlApplicationContext; ++import ru.javawebinar.topjava.model.Role; ++import ru.javawebinar.topjava.model.User; + import ru.javawebinar.topjava.repository.UserRepository; ++import ru.javawebinar.topjava.service.UserService; + + import java.util.Arrays; + +@@ -18,6 +21,10 @@ + // UserRepository userRepository = (UserRepository) appCtx.getBean("mockUserRepository"); + UserRepository userRepository = appCtx.getBean(UserRepository.class); + userRepository.getAll(); ++ ++ UserService userService = appCtx.getBean(UserService.class); ++ System.out.println(userService.save(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); ++ + appCtx.close(); + } + } +Index: src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java (date 1465332050000) ++++ src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java (revision ) +@@ -15,6 +15,10 @@ + + private UserRepository repository; + ++ public void setRepository(UserRepository repository) { ++ this.repository = repository; ++ } ++ + public User save(User user) { + return repository.save(user); + } From 2cfe5d04ae13db57298acf893303b8ca70a1850a Mon Sep 17 00:00:00 2001 From: andreichernov Date: Sat, 18 Jun 2016 13:44:56 +0300 Subject: [PATCH 13/39] apply patch 2.5 --- src/main/java/ru/javawebinar/topjava/SpringMain.java | 7 +++++++ .../ru/javawebinar/topjava/service/UserServiceImpl.java | 4 ++++ src/main/resources/spring/spring-app.xml | 6 ++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/main/java/ru/javawebinar/topjava/SpringMain.java index 4e82530bdaf8..7d3d75ca9eb7 100644 --- a/src/main/java/ru/javawebinar/topjava/SpringMain.java +++ b/src/main/java/ru/javawebinar/topjava/SpringMain.java @@ -2,7 +2,10 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import ru.javawebinar.topjava.model.Role; +import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.repository.UserRepository; +import ru.javawebinar.topjava.service.UserService; import java.util.Arrays; @@ -18,6 +21,10 @@ public static void main(String[] args) { // UserRepository userRepository = (UserRepository) appCtx.getBean("mockUserRepository"); UserRepository userRepository = appCtx.getBean(UserRepository.class); userRepository.getAll(); + + UserService userService = appCtx.getBean(UserService.class); + System.out.println(userService.save(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); + appCtx.close(); } } diff --git a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java index 6748bf2e7c88..8fdd7f5d0bde 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java @@ -15,6 +15,10 @@ public class UserServiceImpl implements UserService { private UserRepository repository; + public void setRepository(UserRepository repository) { + this.repository = repository; + } + public User save(User user) { return repository.save(user); } diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml index 642f22f66db6..3d3a20c59587 100644 --- a/src/main/resources/spring/spring-app.xml +++ b/src/main/resources/spring/spring-app.xml @@ -1,8 +1,10 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> + + + \ No newline at end of file From 8ded86da2e4e8b386e507084551bff28ab5e4e8c Mon Sep 17 00:00:00 2001 From: andreichernov Date: Wed, 22 Jun 2016 11:45:46 +0300 Subject: [PATCH 14/39] apply patch 2.6 --- .../ru/javawebinar/topjava/SpringMain.java | 20 ++++++---------- .../mock/MockUserRepositoryImpl.java | 2 ++ .../topjava/service/UserServiceImpl.java | 8 +++---- .../web/user/AbstractUserController.java | 2 ++ .../topjava/web/user/AdminRestController.java | 2 ++ .../web/user/ProfileRestController.java | 2 ++ src/main/resources/spring/spring-app.xml | 23 +++++++++++++++---- 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/main/java/ru/javawebinar/topjava/SpringMain.java index 7d3d75ca9eb7..2e5698f620c4 100644 --- a/src/main/java/ru/javawebinar/topjava/SpringMain.java +++ b/src/main/java/ru/javawebinar/topjava/SpringMain.java @@ -4,8 +4,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import ru.javawebinar.topjava.model.Role; import ru.javawebinar.topjava.model.User; -import ru.javawebinar.topjava.repository.UserRepository; -import ru.javawebinar.topjava.service.UserService; +import ru.javawebinar.topjava.web.user.AdminRestController; import java.util.Arrays; @@ -15,16 +14,11 @@ */ public class SpringMain { public static void main(String[] args) { - ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); - System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); - -// UserRepository userRepository = (UserRepository) appCtx.getBean("mockUserRepository"); - UserRepository userRepository = appCtx.getBean(UserRepository.class); - userRepository.getAll(); - - UserService userService = appCtx.getBean(UserService.class); - System.out.println(userService.save(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); - - appCtx.close(); + // java 7 Automatic resource management + try (ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml")) { + System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); + AdminRestController adminUserController = appCtx.getBean(AdminRestController.class); + System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); + } } } diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java index 1f2a36888cb1..758c107e1ca7 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java @@ -1,5 +1,6 @@ package ru.javawebinar.topjava.repository.mock; +import org.springframework.stereotype.Repository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.javawebinar.topjava.model.User; @@ -12,6 +13,7 @@ * GKislin * 15.06.2015. */ +@Repository public class MockUserRepositoryImpl implements UserRepository { private static final Logger LOG = LoggerFactory.getLogger(MockUserRepositoryImpl.class); diff --git a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java index 8fdd7f5d0bde..9f36f2bc0b48 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java @@ -1,5 +1,7 @@ package ru.javawebinar.topjava.service; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.repository.UserRepository; import ru.javawebinar.topjava.util.exception.ExceptionUtil; @@ -11,14 +13,12 @@ * GKislin * 06.03.2015. */ +@Service public class UserServiceImpl implements UserService { + @Autowired private UserRepository repository; - public void setRepository(UserRepository repository) { - this.repository = repository; - } - public User save(User user) { return repository.save(user); } diff --git a/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java b/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java index 5057f02dc492..47ba49234a94 100644 --- a/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java +++ b/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java @@ -1,5 +1,6 @@ package ru.javawebinar.topjava.web.user; +import org.springframework.beans.factory.annotation.Autowired; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.javawebinar.topjava.model.User; @@ -13,6 +14,7 @@ public abstract class AbstractUserController { protected final Logger LOG = LoggerFactory.getLogger(getClass()); + @Autowired private UserService service; public List getAll() { diff --git a/src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java b/src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java index bf781e9fb50c..c38fd790e101 100644 --- a/src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java +++ b/src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java @@ -1,5 +1,6 @@ package ru.javawebinar.topjava.web.user; +import org.springframework.stereotype.Controller; import ru.javawebinar.topjava.model.User; import java.util.List; @@ -8,6 +9,7 @@ * GKislin * 06.03.2015. */ +@Controller public class AdminRestController extends AbstractUserController { public List getAll() { diff --git a/src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java b/src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java index 82406441de55..7325a01b1c1d 100644 --- a/src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java +++ b/src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java @@ -1,5 +1,6 @@ package ru.javawebinar.topjava.web.user; +import org.springframework.stereotype.Controller; import ru.javawebinar.topjava.LoggedUser; import ru.javawebinar.topjava.model.User; @@ -7,6 +8,7 @@ * GKislin * 06.03.2015. */ +@Controller public class ProfileRestController extends AbstractUserController { public User get() { diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml index 3d3a20c59587..328aaa11684d 100644 --- a/src/main/resources/spring/spring-app.xml +++ b/src/main/resources/spring/spring-app.xml @@ -1,10 +1,23 @@ + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - + + + + + + + + + - - - \ No newline at end of file From 716d814c235e35dadbc9cfe3e7a3df5106cbcd41 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Wed, 22 Jun 2016 14:40:43 +0300 Subject: [PATCH 15/39] apply patch 3.0 --- .../2_6_add_annotation_processing.patch | 197 ++++++++++++++++++ patchs/to_lesson03/3_0_correction.patch | 18 ++ src/main/webapp/mealEdit.jsp | 4 +- 3 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 patchs/to_lesson02/2_6_add_annotation_processing.patch create mode 100644 patchs/to_lesson03/3_0_correction.patch diff --git a/patchs/to_lesson02/2_6_add_annotation_processing.patch b/patchs/to_lesson02/2_6_add_annotation_processing.patch new file mode 100644 index 000000000000..acdf8f9f0db3 --- /dev/null +++ b/patchs/to_lesson02/2_6_add_annotation_processing.patch @@ -0,0 +1,197 @@ +Index: src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (date 1465332238000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (revision ) +@@ -1,5 +1,6 @@ + package ru.javawebinar.topjava.repository.mock; + ++import org.springframework.stereotype.Repository; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import ru.javawebinar.topjava.model.User; +@@ -12,6 +13,7 @@ + * GKislin + * 15.06.2015. + */ ++@Repository + public class MockUserRepositoryImpl implements UserRepository { + private static final Logger LOG = LoggerFactory.getLogger(MockUserRepositoryImpl.class); + +Index: src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java (date 1465332238000) ++++ src/main/java/ru/javawebinar/topjava/web/user/ProfileRestController.java (revision ) +@@ -1,5 +1,6 @@ + package ru.javawebinar.topjava.web.user; + ++import org.springframework.stereotype.Controller; + import ru.javawebinar.topjava.LoggedUser; + import ru.javawebinar.topjava.model.User; + +@@ -7,6 +8,7 @@ + * GKislin + * 06.03.2015. + */ ++@Controller + public class ProfileRestController extends AbstractUserController { + + public User get() { +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java (date 1465332238000) ++++ src/main/java/ru/javawebinar/topjava/web/user/AdminRestController.java (revision ) +@@ -1,5 +1,6 @@ + package ru.javawebinar.topjava.web.user; + ++import org.springframework.stereotype.Controller; + import ru.javawebinar.topjava.model.User; + + import java.util.List; +@@ -8,6 +9,7 @@ + * GKislin + * 06.03.2015. + */ ++@Controller + public class AdminRestController extends AbstractUserController { + + public List getAll() { +Index: src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java (date 1465332238000) ++++ src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java (revision ) +@@ -1,5 +1,6 @@ + package ru.javawebinar.topjava.web.user; + ++import org.springframework.beans.factory.annotation.Autowired; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import ru.javawebinar.topjava.model.User; +@@ -13,6 +14,7 @@ + public abstract class AbstractUserController { + protected final Logger LOG = LoggerFactory.getLogger(getClass()); + ++ @Autowired + private UserService service; + + public List getAll() { +Index: src/main/resources/spring/spring-app.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/spring/spring-app.xml (date 1465332238000) ++++ src/main/resources/spring/spring-app.xml (revision ) +@@ -1,10 +1,23 @@ + ++ xmlns:context="http://www.springframework.org/schema/context" ++ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ++ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/SpringMain.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/SpringMain.java (date 1465332238000) ++++ src/main/java/ru/javawebinar/topjava/SpringMain.java (revision ) +@@ -4,8 +4,7 @@ + import org.springframework.context.support.ClassPathXmlApplicationContext; + import ru.javawebinar.topjava.model.Role; + import ru.javawebinar.topjava.model.User; +-import ru.javawebinar.topjava.repository.UserRepository; +-import ru.javawebinar.topjava.service.UserService; ++import ru.javawebinar.topjava.web.user.AdminRestController; + + import java.util.Arrays; + +@@ -15,16 +14,11 @@ + */ + public class SpringMain { + public static void main(String[] args) { +- ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); ++ // java 7 Automatic resource management ++ try (ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml")) { +- System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); ++ System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); +- +-// UserRepository userRepository = (UserRepository) appCtx.getBean("mockUserRepository"); +- UserRepository userRepository = appCtx.getBean(UserRepository.class); +- userRepository.getAll(); +- +- UserService userService = appCtx.getBean(UserService.class); +- System.out.println(userService.save(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); +- +- appCtx.close(); ++ AdminRestController adminUserController = appCtx.getBean(AdminRestController.class); ++ System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); ++ } + } + } +Index: src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java (date 1465332238000) ++++ src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java (revision ) +@@ -1,5 +1,7 @@ + package ru.javawebinar.topjava.service; + ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.stereotype.Service; + import ru.javawebinar.topjava.model.User; + import ru.javawebinar.topjava.repository.UserRepository; + import ru.javawebinar.topjava.util.exception.ExceptionUtil; +@@ -11,13 +13,11 @@ + * GKislin + * 06.03.2015. + */ ++@Service + public class UserServiceImpl implements UserService { + ++ @Autowired + private UserRepository repository; +- +- public void setRepository(UserRepository repository) { +- this.repository = repository; +- } + + public User save(User user) { + return repository.save(user); diff --git a/patchs/to_lesson03/3_0_correction.patch b/patchs/to_lesson03/3_0_correction.patch new file mode 100644 index 000000000000..278b0ac75460 --- /dev/null +++ b/patchs/to_lesson03/3_0_correction.patch @@ -0,0 +1,18 @@ +Index: src/main/webapp/mealEdit.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/mealEdit.jsp (date 1465332464000) ++++ src/main/webapp/mealEdit.jsp (revision ) +@@ -25,8 +25,8 @@ + + +
    +-

    Home

    +-

    Edit meal

    ++

    Home

    ++

    ${param.action == 'create' ? 'Create meal' : 'Edit meal'}

    +
    + +
    diff --git a/src/main/webapp/mealEdit.jsp b/src/main/webapp/mealEdit.jsp index 08eee8b50f4f..c5b5b317e1c9 100644 --- a/src/main/webapp/mealEdit.jsp +++ b/src/main/webapp/mealEdit.jsp @@ -25,8 +25,8 @@
    -

    Home

    -

    Edit meal

    +

    Home

    +

    ${param.action == 'create' ? 'Create meal' : 'Edit meal'}


    From aa0a83b1276b3f5f6961e90f5c30de9e6ddeb9f8 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Wed, 22 Jun 2016 15:05:53 +0300 Subject: [PATCH 16/39] apply patch 3.01 --- .../repository/UserMealRepository.java | 16 +++-- .../mock/InMemoryUserMealRepositoryImpl.java | 64 +++++++++++++++---- .../mock/InMemoryUserRepositoryImpl.java | 64 +++++++++++++++++++ .../mock/MockUserRepositoryImpl.java | 49 -------------- .../ru/javawebinar/topjava/util/TimeUtil.java | 7 +- .../javawebinar/topjava/web/MealServlet.java | 11 ++-- 6 files changed, 135 insertions(+), 76 deletions(-) create mode 100644 src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java delete mode 100644 src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java diff --git a/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java b/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java index 8bedd15f581f..e7cc41241ac9 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java +++ b/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java @@ -2,6 +2,7 @@ import ru.javawebinar.topjava.model.UserMeal; +import java.time.LocalDateTime; import java.util.Collection; /** @@ -9,11 +10,18 @@ * 06.03.2015. */ public interface UserMealRepository { - UserMeal save(UserMeal userMeal); + // null if updated meal do not belong to userId + UserMeal save(UserMeal userMeal, int userId); - void delete(int id); + // false if meal do not belong to userId + boolean delete(int id, int userId); - UserMeal get(int id); + // null if meal do not belong to userId + UserMeal get(int id, int userId); - Collection getAll(); + // ORDERED dateTime + Collection getAll(int userId); + + // ORDERED dateTime + Collection getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId); } diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java index cceba647c7a6..ec576d1326d9 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java @@ -1,48 +1,84 @@ package ru.javawebinar.topjava.repository.mock; +import org.springframework.stereotype.Repository; import ru.javawebinar.topjava.model.UserMeal; import ru.javawebinar.topjava.repository.UserMealRepository; +import ru.javawebinar.topjava.util.TimeUtil; import ru.javawebinar.topjava.util.UserMealsUtil; -import java.util.Collection; -import java.util.Map; +import java.time.LocalDateTime; +import java.time.Month; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.ADMIN_ID; +import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.USER_ID; /** * GKislin * 15.09.2015. */ +@Repository public class InMemoryUserMealRepositoryImpl implements UserMealRepository { - private Map repository = new ConcurrentHashMap<>(); + + private static final Comparator USER_MEAL_COMPARATOR = Comparator.comparing(UserMeal::getDateTime).reversed(); + + // Map userId -> (mealId-> meal) + private Map> repository = new ConcurrentHashMap<>(); private AtomicInteger counter = new AtomicInteger(0); { - UserMealsUtil.MEAL_LIST.forEach(this::save); + UserMealsUtil.MEAL_LIST.forEach(um -> save(um, USER_ID)); + + save(new UserMeal(LocalDateTime.of(2015, Month.JUNE, 1, 14, 0), "Админ ланч", 510), ADMIN_ID); + save(new UserMeal(LocalDateTime.of(2015, Month.JUNE, 1, 21, 0), "Админ ужин", 1500), ADMIN_ID); } @Override - public UserMeal save(UserMeal userMeal) { + public UserMeal save(UserMeal userMeal, int userId) { + Objects.requireNonNull(userMeal); + + Integer mealId = userMeal.getId(); + if (userMeal.isNew()) { - userMeal.setId(counter.incrementAndGet()); + mealId = counter.incrementAndGet(); + userMeal.setId(mealId); + } else if (get(mealId, userId) == null) { + return null; } - repository.put(userMeal.getId(), userMeal); + Map userMeals = repository.computeIfAbsent(userId, ConcurrentHashMap::new); + userMeals.put(mealId, userMeal); return userMeal; } @Override - public void delete(int id) { - repository.remove(id); + public boolean delete(int id, int userId) { + Map userMeals = repository.get(userId); + return userMeals != null && userMeals.remove(id) != null; } @Override - public UserMeal get(int id) { - return repository.get(id); + public UserMeal get(int id, int userId) { + Map userMeals = repository.get(userId); + return userMeals == null ? null : userMeals.get(id); } @Override - public Collection getAll() { - return repository.values(); + public Collection getAll(int userId) { + Map userMeals = repository.get(userId); + return userMeals == null ? + Collections.emptyList() : + userMeals.values().stream().sorted(USER_MEAL_COMPARATOR).collect(Collectors.toList()); } -} + @Override + public Collection getBetween(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId) { + Objects.requireNonNull(startDateTime); + Objects.requireNonNull(endDateTime); + return getAll(userId).stream() + .filter(um -> TimeUtil.isBetween(um.getDateTime(), startDateTime, endDateTime)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java new file mode 100644 index 000000000000..1663d7ad7cc4 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java @@ -0,0 +1,64 @@ +package ru.javawebinar.topjava.repository.mock; + +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +/** + * GKislin + * 15.06.2015. + */ +@Repository +public class InMemoryUserRepositoryImpl implements UserRepository { + private Map repository = new ConcurrentHashMap<>(); + private AtomicInteger counter = new AtomicInteger(0); + + private static final Comparator USER_COMPARATOR = Comparator.comparing(User::getName); + + public static final int USER_ID = 1; + public static final int ADMIN_ID = 2; + + @Override + public User save(User user) { + Objects.requireNonNull(user); + if (user.isNew()) { + user.setId(counter.incrementAndGet()); + } + repository.put(user.getId(), user); + return user; + } + + @Override + public boolean delete(int id) { + return repository.remove(id) != null; + } + + @Override + public User get(int id) { + return repository.get(id); + } + + @Override + public List getAll() { + return repository.values().stream() + .sorted(USER_COMPARATOR) + .collect(Collectors.toList()); + } + + @Override + public User getByEmail(String email) { + Objects.requireNonNull(email); + return repository.values().stream() + .filter(u -> email.equals(u.getEmail())) + .findFirst() + .orElse(null); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java deleted file mode 100644 index 758c107e1ca7..000000000000 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.javawebinar.topjava.repository.mock; - -import org.springframework.stereotype.Repository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import ru.javawebinar.topjava.model.User; -import ru.javawebinar.topjava.repository.UserRepository; - -import java.util.Collections; -import java.util.List; - -/** - * GKislin - * 15.06.2015. - */ -@Repository -public class MockUserRepositoryImpl implements UserRepository { - private static final Logger LOG = LoggerFactory.getLogger(MockUserRepositoryImpl.class); - - @Override - public boolean delete(int id) { - LOG.info("delete " + id); - return true; - } - - @Override - public User save(User user) { - LOG.info("save " + user); - return user; - } - - @Override - public User get(int id) { - LOG.info("get " + id); - return null; - } - - @Override - public List getAll() { - LOG.info("getAll"); - return Collections.emptyList(); - } - - @Override - public User getByEmail(String email) { - LOG.info("getByEmail " + email); - return null; - } -} diff --git a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java index 75b1b4127af4..56d2deaf6752 100644 --- a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -1,7 +1,6 @@ package ru.javawebinar.topjava.util; import java.time.LocalDateTime; -import java.time.LocalTime; import java.time.format.DateTimeFormatter; /** @@ -9,10 +8,10 @@ * 07.01.2015. */ public class TimeUtil { - public static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + private static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); - public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime endTime) { - return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) <= 0; + public static > boolean isBetween(T value, T start, T end) { + return value.compareTo(start) >= 0 && value.compareTo(end) <= 0; } public static String toString(LocalDateTime ldt) { diff --git a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java index c04e1efaf83f..90c19f16fcec 100644 --- a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java @@ -1,10 +1,11 @@ package ru.javawebinar.topjava.web; +import ru.javawebinar.topjava.LoggedUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.javawebinar.topjava.model.UserMeal; -import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; import ru.javawebinar.topjava.repository.UserMealRepository; +import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; import ru.javawebinar.topjava.util.UserMealsUtil; import javax.servlet.ServletConfig; @@ -39,7 +40,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) request.getParameter("description"), Integer.valueOf(request.getParameter("calories"))); LOG.info(userMeal.isNew() ? "Create {}" : "Update {}", userMeal); - repository.save(userMeal); + repository.save(userMeal, LoggedUser.id()); response.sendRedirect("meals"); } @@ -49,17 +50,17 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t if (action == null) { LOG.info("getAll"); request.setAttribute("mealList", - UserMealsUtil.getWithExceeded(repository.getAll(), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); + UserMealsUtil.getWithExceeded(repository.getAll(LoggedUser.id()), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); request.getRequestDispatcher("/mealList.jsp").forward(request, response); } else if (action.equals("delete")) { int id = getId(request); LOG.info("Delete {}", id); - repository.delete(id); + repository.delete(id, LoggedUser.id()); response.sendRedirect("meals"); } else if (action.equals("create") || action.equals("update")) { final UserMeal meal = action.equals("create") ? new UserMeal(LocalDateTime.now().withNano(0).withSecond(0), "", 1000) : - repository.get(getId(request)); + repository.get(getId(request), LoggedUser.id()); request.setAttribute("meal", meal); request.getRequestDispatcher("mealEdit.jsp").forward(request, response); } From 4f3c9538de746836a610a4c5c45b9ef1ceb87c46 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Wed, 22 Jun 2016 15:07:36 +0300 Subject: [PATCH 17/39] add patch 3.02 --- patchs/to_lesson03/3_01_HW2_repository.patch | 349 ++++++++++++++++++ patchs/to_lesson03/3_02_HW2_meal_layers.patch | 335 +++++++++++++++++ 2 files changed, 684 insertions(+) create mode 100644 patchs/to_lesson03/3_01_HW2_repository.patch create mode 100644 patchs/to_lesson03/3_02_HW2_meal_layers.patch diff --git a/patchs/to_lesson03/3_01_HW2_repository.patch b/patchs/to_lesson03/3_01_HW2_repository.patch new file mode 100644 index 000000000000..15deb9b2cbbb --- /dev/null +++ b/patchs/to_lesson03/3_01_HW2_repository.patch @@ -0,0 +1,349 @@ +Index: src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java (date 1465940521000) +@@ -1,48 +1,84 @@ + package ru.javawebinar.topjava.repository.mock; + ++import org.springframework.stereotype.Repository; + import ru.javawebinar.topjava.model.UserMeal; + import ru.javawebinar.topjava.repository.UserMealRepository; ++import ru.javawebinar.topjava.util.TimeUtil; + import ru.javawebinar.topjava.util.UserMealsUtil; + +-import java.util.Collection; +-import java.util.Map; ++import java.time.LocalDateTime; ++import java.time.Month; ++import java.util.*; + import java.util.concurrent.ConcurrentHashMap; + import java.util.concurrent.atomic.AtomicInteger; ++import java.util.stream.Collectors; + ++import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.ADMIN_ID; ++import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.USER_ID; ++ + /** + * GKislin + * 15.09.2015. + */ ++@Repository + public class InMemoryUserMealRepositoryImpl implements UserMealRepository { +- private Map repository = new ConcurrentHashMap<>(); ++ ++ private static final Comparator USER_MEAL_COMPARATOR = Comparator.comparing(UserMeal::getDateTime).reversed(); ++ ++ // Map userId -> (mealId-> meal) ++ private Map> repository = new ConcurrentHashMap<>(); + private AtomicInteger counter = new AtomicInteger(0); + + { +- UserMealsUtil.MEAL_LIST.forEach(this::save); ++ UserMealsUtil.MEAL_LIST.forEach(um -> save(um, USER_ID)); ++ ++ save(new UserMeal(LocalDateTime.of(2015, Month.JUNE, 1, 14, 0), "Админ ланч", 510), ADMIN_ID); ++ save(new UserMeal(LocalDateTime.of(2015, Month.JUNE, 1, 21, 0), "Админ ужин", 1500), ADMIN_ID); + } + + @Override +- public UserMeal save(UserMeal userMeal) { ++ public UserMeal save(UserMeal userMeal, int userId) { ++ Objects.requireNonNull(userMeal); ++ ++ Integer mealId = userMeal.getId(); ++ + if (userMeal.isNew()) { +- userMeal.setId(counter.incrementAndGet()); ++ mealId = counter.incrementAndGet(); ++ userMeal.setId(mealId); ++ } else if (get(mealId, userId) == null) { ++ return null; + } +- repository.put(userMeal.getId(), userMeal); ++ Map userMeals = repository.computeIfAbsent(userId, ConcurrentHashMap::new); ++ userMeals.put(mealId, userMeal); + return userMeal; + } + + @Override +- public void delete(int id) { +- repository.remove(id); ++ public boolean delete(int id, int userId) { ++ Map userMeals = repository.get(userId); ++ return userMeals != null && userMeals.remove(id) != null; + } + + @Override +- public UserMeal get(int id) { +- return repository.get(id); ++ public UserMeal get(int id, int userId) { ++ Map userMeals = repository.get(userId); ++ return userMeals == null ? null : userMeals.get(id); + } + + @Override +- public Collection getAll() { +- return repository.values(); ++ public Collection getAll(int userId) { ++ Map userMeals = repository.get(userId); ++ return userMeals == null ? ++ Collections.emptyList() : ++ userMeals.values().stream().sorted(USER_MEAL_COMPARATOR).collect(Collectors.toList()); + } +-} + ++ @Override ++ public Collection getBetween(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId) { ++ Objects.requireNonNull(startDateTime); ++ Objects.requireNonNull(endDateTime); ++ return getAll(userId).stream() ++ .filter(um -> TimeUtil.isBetween(um.getDateTime(), startDateTime, endDateTime)) ++ .collect(Collectors.toList()); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (date 1465940521000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (date 1465940521000) +@@ -0,0 +1,64 @@ ++package ru.javawebinar.topjava.repository.mock; ++ ++import org.springframework.stereotype.Repository; ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.repository.UserRepository; ++ ++import java.util.Comparator; ++import java.util.List; ++import java.util.Map; ++import java.util.Objects; ++import java.util.concurrent.ConcurrentHashMap; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.stream.Collectors; ++ ++/** ++ * GKislin ++ * 15.06.2015. ++ */ ++@Repository ++public class InMemoryUserRepositoryImpl implements UserRepository { ++ private Map repository = new ConcurrentHashMap<>(); ++ private AtomicInteger counter = new AtomicInteger(0); ++ ++ private static final Comparator USER_COMPARATOR = Comparator.comparing(User::getName); ++ ++ public static final int USER_ID = 1; ++ public static final int ADMIN_ID = 2; ++ ++ @Override ++ public User save(User user) { ++ Objects.requireNonNull(user); ++ if (user.isNew()) { ++ user.setId(counter.incrementAndGet()); ++ } ++ repository.put(user.getId(), user); ++ return user; ++ } ++ ++ @Override ++ public boolean delete(int id) { ++ return repository.remove(id) != null; ++ } ++ ++ @Override ++ public User get(int id) { ++ return repository.get(id); ++ } ++ ++ @Override ++ public List getAll() { ++ return repository.values().stream() ++ .sorted(USER_COMPARATOR) ++ .collect(Collectors.toList()); ++ } ++ ++ @Override ++ public User getByEmail(String email) { ++ Objects.requireNonNull(email); ++ return repository.values().stream() ++ .filter(u -> email.equals(u.getEmail())) ++ .findFirst() ++ .orElse(null); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (date 1465849306000) +@@ -1,49 +0,0 @@ +-package ru.javawebinar.topjava.repository.mock; +- +-import org.springframework.stereotype.Repository; +-import org.slf4j.Logger; +-import org.slf4j.LoggerFactory; +-import ru.javawebinar.topjava.model.User; +-import ru.javawebinar.topjava.repository.UserRepository; +- +-import java.util.Collections; +-import java.util.List; +- +-/** +- * GKislin +- * 15.06.2015. +- */ +-@Repository +-public class MockUserRepositoryImpl implements UserRepository { +- private static final Logger LOG = LoggerFactory.getLogger(MockUserRepositoryImpl.class); +- +- @Override +- public boolean delete(int id) { +- LOG.info("delete " + id); +- return true; +- } +- +- @Override +- public User save(User user) { +- LOG.info("save " + user); +- return user; +- } +- +- @Override +- public User get(int id) { +- LOG.info("get " + id); +- return null; +- } +- +- @Override +- public List getAll() { +- LOG.info("getAll"); +- return Collections.emptyList(); +- } +- +- @Override +- public User getByEmail(String email) { +- LOG.info("getByEmail " + email); +- return null; +- } +-} +Index: src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java (date 1465940521000) +@@ -2,6 +2,7 @@ + + import ru.javawebinar.topjava.model.UserMeal; + ++import java.time.LocalDateTime; + import java.util.Collection; + + /** +@@ -9,11 +10,18 @@ + * 06.03.2015. + */ + public interface UserMealRepository { +- UserMeal save(UserMeal userMeal); ++ // null if updated meal do not belong to userId ++ UserMeal save(UserMeal userMeal, int userId); + +- void delete(int id); ++ // false if meal do not belong to userId ++ boolean delete(int id, int userId); + +- UserMeal get(int id); ++ // null if meal do not belong to userId ++ UserMeal get(int id, int userId); + +- Collection getAll(); ++ // ORDERED dateTime ++ Collection getAll(int userId); ++ ++ // ORDERED dateTime ++ Collection getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId); + } +Index: src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (date 1465940521000) +@@ -1,7 +1,6 @@ + package ru.javawebinar.topjava.util; + + import java.time.LocalDateTime; +-import java.time.LocalTime; + import java.time.format.DateTimeFormatter; + + /** +@@ -9,10 +8,10 @@ + * 07.01.2015. + */ + public class TimeUtil { +- public static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); ++ private static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + +- public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime endTime) { +- return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) <= 0; ++ public static > boolean isBetween(T value, T start, T end) { ++ return value.compareTo(start) >= 0 && value.compareTo(end) <= 0; + } + + public static String toString(LocalDateTime ldt) { +Index: src/main/java/ru/javawebinar/topjava/web/MealServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/MealServlet.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/web/MealServlet.java (date 1465940521000) +@@ -1,10 +1,11 @@ + package ru.javawebinar.topjava.web; + ++import ru.javawebinar.topjava.LoggedUser; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import ru.javawebinar.topjava.model.UserMeal; +-import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; + import ru.javawebinar.topjava.repository.UserMealRepository; ++import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; + import ru.javawebinar.topjava.util.UserMealsUtil; + + import javax.servlet.ServletConfig; +@@ -39,7 +40,7 @@ + request.getParameter("description"), + Integer.valueOf(request.getParameter("calories"))); + LOG.info(userMeal.isNew() ? "Create {}" : "Update {}", userMeal); +- repository.save(userMeal); ++ repository.save(userMeal, LoggedUser.id()); + response.sendRedirect("meals"); + } + +@@ -49,17 +50,17 @@ + if (action == null) { + LOG.info("getAll"); + request.setAttribute("mealList", +- UserMealsUtil.getWithExceeded(repository.getAll(), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); ++ UserMealsUtil.getWithExceeded(repository.getAll(LoggedUser.id()), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); + request.getRequestDispatcher("/mealList.jsp").forward(request, response); + } else if (action.equals("delete")) { + int id = getId(request); + LOG.info("Delete {}", id); +- repository.delete(id); ++ repository.delete(id, LoggedUser.id()); + response.sendRedirect("meals"); + } else if (action.equals("create") || action.equals("update")) { + final UserMeal meal = action.equals("create") ? + new UserMeal(LocalDateTime.now().withNano(0).withSecond(0), "", 1000) : +- repository.get(getId(request)); ++ repository.get(getId(request), LoggedUser.id()); + request.setAttribute("meal", meal); + request.getRequestDispatcher("mealEdit.jsp").forward(request, response); + } diff --git a/patchs/to_lesson03/3_02_HW2_meal_layers.patch b/patchs/to_lesson03/3_02_HW2_meal_layers.patch new file mode 100644 index 000000000000..2baa6d25770a --- /dev/null +++ b/patchs/to_lesson03/3_02_HW2_meal_layers.patch @@ -0,0 +1,335 @@ +Index: src/main/java/ru/javawebinar/topjava/model/UserMeal.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMeal.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/model/UserMeal.java (revision ) +@@ -6,8 +6,7 @@ + * GKislin + * 11.01.2015. + */ +-public class UserMeal { +- private Integer id; ++public class UserMeal extends BaseEntity { + + private final LocalDateTime dateTime; + +@@ -20,16 +19,12 @@ + } + + public UserMeal(Integer id, LocalDateTime dateTime, String description, int calories) { +- this.id = id; ++ super(id); + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + } + +- public void setId(int id) { +- this.id = id; +- } +- + public LocalDateTime getDateTime() { + return dateTime; + } +@@ -40,14 +35,6 @@ + + public int getCalories() { + return calories; +- } +- +- public Integer getId() { +- return id; +- } +- +- public boolean isNew() { +- return id == null; + } + + @Override +Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/to/UserMealWithExceed.java (revision ) +@@ -1,4 +1,4 @@ +-package ru.javawebinar.topjava.model; ++package ru.javawebinar.topjava.to; + + import java.time.LocalDateTime; + +Index: src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision ) +@@ -1,5 +1,6 @@ + package ru.javawebinar.topjava.util; + ++import java.time.LocalDate; + import java.time.LocalDateTime; + import java.time.format.DateTimeFormatter; + +@@ -9,6 +10,9 @@ + */ + public class TimeUtil { + private static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); ++ ++ public static final LocalDate MIN_DATE = LocalDate.of(1, 1, 1); ++ public static final LocalDate MAX_DATE = LocalDate.of(3000, 1, 1); + + public static > boolean isBetween(T value, T start, T end) { + return value.compareTo(start) >= 0 && value.compareTo(end) <= 0; +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) +@@ -1,7 +1,7 @@ + package ru.javawebinar.topjava.util; + + import ru.javawebinar.topjava.model.UserMeal; +-import ru.javawebinar.topjava.model.UserMealWithExceed; ++import ru.javawebinar.topjava.to.UserMealWithExceed; + + import java.time.LocalDate; + import java.time.LocalDateTime; +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java (revision ) +@@ -1,13 +1,51 @@ + package ru.javawebinar.topjava.service; + ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.stereotype.Service; ++import ru.javawebinar.topjava.model.UserMeal; + import ru.javawebinar.topjava.repository.UserMealRepository; ++import ru.javawebinar.topjava.util.exception.ExceptionUtil; + ++import java.time.LocalDateTime; ++import java.util.Collection; ++ + /** + * GKislin + * 06.03.2015. + */ ++@Service + public class UserMealServiceImpl implements UserMealService { + ++ @Autowired + private UserMealRepository repository; + ++ @Override ++ public UserMeal get(int id, int userId) { ++ return ExceptionUtil.checkNotFoundWithId(repository.get(id, userId), id); ++ } ++ ++ @Override ++ public void delete(int id, int userId) { ++ ExceptionUtil.checkNotFoundWithId(repository.delete(id, userId), id); ++ } ++ ++ @Override ++ public Collection getBetweenDateTimes(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId) { ++ return repository.getBetween(startDateTime, endDateTime, userId); ++ } ++ ++ @Override ++ public Collection getAll(int userId) { ++ return repository.getAll(userId); ++ } ++ ++ @Override ++ public UserMeal update(UserMeal meal, int userId) { ++ return ExceptionUtil.checkNotFoundWithId(repository.save(meal, userId), meal.getId()); ++ } ++ ++ @Override ++ public UserMeal save(UserMeal meal, int userId) { ++ return repository.save(meal, userId); ++ } + } +Index: src/main/java/ru/javawebinar/topjava/SpringMain.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/SpringMain.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/SpringMain.java (revision ) +@@ -4,9 +4,15 @@ + import org.springframework.context.support.ClassPathXmlApplicationContext; + import ru.javawebinar.topjava.model.Role; + import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.to.UserMealWithExceed; ++import ru.javawebinar.topjava.web.meal.UserMealRestController; + import ru.javawebinar.topjava.web.user.AdminRestController; + ++import java.time.LocalDate; ++import java.time.LocalTime; ++import java.time.Month; + import java.util.Arrays; ++import java.util.List; + + /** + * User: gkislin +@@ -19,6 +25,14 @@ + System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); + AdminRestController adminUserController = appCtx.getBean(AdminRestController.class); + System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); ++ System.out.println(); ++ ++ UserMealRestController mealController = appCtx.getBean(UserMealRestController.class); ++ List filteredMealsWithExceeded = ++ mealController.getBetween( ++ LocalDate.of(2015, Month.MAY, 30), LocalTime.of(7, 0), ++ LocalDate.of(2015, Month.MAY, 31), LocalTime.of(11, 0)); ++ filteredMealsWithExceeded.forEach(System.out::println); + } + } + } +Index: src/main/java/ru/javawebinar/topjava/service/UserMealService.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserMealService.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/service/UserMealService.java (revision ) +@@ -1,8 +1,31 @@ + package ru.javawebinar.topjava.service; + ++import ru.javawebinar.topjava.model.UserMeal; ++import ru.javawebinar.topjava.util.exception.NotFoundException; ++ ++import java.time.LocalDate; ++import java.time.LocalDateTime; ++import java.time.LocalTime; ++import java.util.Collection; ++ + /** + * GKislin + * 15.06.2015. + */ + public interface UserMealService { ++ UserMeal get(int id, int userId) throws NotFoundException; ++ ++ void delete(int id, int userId) throws NotFoundException; ++ ++ default Collection getBetweenDates(LocalDate startDate, LocalDate endDate, int userId) { ++ return getBetweenDateTimes(LocalDateTime.of(startDate, LocalTime.MIN), LocalDateTime.of(endDate, LocalTime.MAX), userId); ++ } ++ ++ Collection getBetweenDateTimes(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId); ++ ++ Collection getAll(int userId); ++ ++ UserMeal update(UserMeal meal, int userId) throws NotFoundException; ++ ++ UserMeal save(UserMeal meal, int userId); + } +Index: src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java (revision ) +@@ -1,12 +1,71 @@ + package ru.javawebinar.topjava.web.meal; + ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.stereotype.Controller; ++import ru.javawebinar.topjava.LoggedUser; ++import ru.javawebinar.topjava.model.UserMeal; + import ru.javawebinar.topjava.service.UserMealService; ++import ru.javawebinar.topjava.to.UserMealWithExceed; ++import ru.javawebinar.topjava.util.TimeUtil; ++import ru.javawebinar.topjava.util.UserMealsUtil; + ++import java.time.LocalDate; ++import java.time.LocalTime; ++import java.util.List; ++ + /** + * GKislin + * 06.03.2015. + */ ++@Controller + public class UserMealRestController { ++ private static final Logger LOG = LoggerFactory.getLogger(UserMealRestController.class); ++ ++ @Autowired + private UserMealService service; + ++ public UserMeal get(int id) { ++ int userId = LoggedUser.id(); ++ LOG.info("get meal {} for User {}", id, userId); ++ return service.get(id, userId); ++ } ++ ++ public void delete(int id) { ++ int userId = LoggedUser.id(); ++ LOG.info("delete meal {} for User {}", id, userId); ++ service.delete(id, userId); ++ } ++ ++ public List getAll() { ++ int userId = LoggedUser.id(); ++ LOG.info("getAll for User {}", userId); ++ return UserMealsUtil.getWithExceeded(service.getAll(userId), LoggedUser.getCaloriesPerDay()); ++ } ++ ++ public void update(UserMeal meal, int id) { ++ meal.setId(id); ++ int userId = LoggedUser.id(); ++ LOG.info("update {} for User {}", meal, userId); ++ service.update(meal, userId); ++ } ++ ++ public UserMeal create(UserMeal meal) { ++ meal.setId(null); ++ int userId = LoggedUser.id(); ++ LOG.info("create {} for User {}", meal, userId); ++ return service.save(meal, userId); ++ } ++ ++ public List getBetween(LocalDate startDate, LocalTime startTime, LocalDate endDate, LocalTime endTime) { ++ int userId = LoggedUser.id(); ++ LOG.info("getBetween dates {} - {} for time {} - {} for User {}", startDate, endDate, startTime, endTime, userId); ++ ++ return UserMealsUtil.getFilteredWithExceeded( ++ service.getBetweenDates( ++ startDate != null ? startDate : TimeUtil.MIN_DATE, endDate != null ? endDate : TimeUtil.MAX_DATE, userId), ++ startTime != null ? startTime : LocalTime.MIN, endTime != null ? endTime : LocalTime.MAX, LoggedUser.getCaloriesPerDay() ++ ); ++ } +-} ++} +\ No newline at end of file +Index: src/main/webapp/mealList.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/mealList.jsp (date 1465849318000) ++++ src/main/webapp/mealList.jsp (revision ) +@@ -32,7 +32,7 @@ + + + +- ++ + + + <%--${meal.dateTime.toLocalDate()} ${meal.dateTime.toLocalTime()}--%> +\ No newline at end of file From 9e8fa61dec3c662d988ef1560d5705ce5be83172 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Fri, 24 Jun 2016 11:15:39 +0300 Subject: [PATCH 18/39] add patch 3.02 --- patchs/to_lesson03/3_01_HW2_repository.patch | 349 ++++++++++++++++++ patchs/to_lesson03/3_02_HW2_meal_layers.patch | 335 +++++++++++++++++ 2 files changed, 684 insertions(+) create mode 100644 patchs/to_lesson03/3_01_HW2_repository.patch create mode 100644 patchs/to_lesson03/3_02_HW2_meal_layers.patch diff --git a/patchs/to_lesson03/3_01_HW2_repository.patch b/patchs/to_lesson03/3_01_HW2_repository.patch new file mode 100644 index 000000000000..15deb9b2cbbb --- /dev/null +++ b/patchs/to_lesson03/3_01_HW2_repository.patch @@ -0,0 +1,349 @@ +Index: src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java (date 1465940521000) +@@ -1,48 +1,84 @@ + package ru.javawebinar.topjava.repository.mock; + ++import org.springframework.stereotype.Repository; + import ru.javawebinar.topjava.model.UserMeal; + import ru.javawebinar.topjava.repository.UserMealRepository; ++import ru.javawebinar.topjava.util.TimeUtil; + import ru.javawebinar.topjava.util.UserMealsUtil; + +-import java.util.Collection; +-import java.util.Map; ++import java.time.LocalDateTime; ++import java.time.Month; ++import java.util.*; + import java.util.concurrent.ConcurrentHashMap; + import java.util.concurrent.atomic.AtomicInteger; ++import java.util.stream.Collectors; + ++import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.ADMIN_ID; ++import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.USER_ID; ++ + /** + * GKislin + * 15.09.2015. + */ ++@Repository + public class InMemoryUserMealRepositoryImpl implements UserMealRepository { +- private Map repository = new ConcurrentHashMap<>(); ++ ++ private static final Comparator USER_MEAL_COMPARATOR = Comparator.comparing(UserMeal::getDateTime).reversed(); ++ ++ // Map userId -> (mealId-> meal) ++ private Map> repository = new ConcurrentHashMap<>(); + private AtomicInteger counter = new AtomicInteger(0); + + { +- UserMealsUtil.MEAL_LIST.forEach(this::save); ++ UserMealsUtil.MEAL_LIST.forEach(um -> save(um, USER_ID)); ++ ++ save(new UserMeal(LocalDateTime.of(2015, Month.JUNE, 1, 14, 0), "Админ ланч", 510), ADMIN_ID); ++ save(new UserMeal(LocalDateTime.of(2015, Month.JUNE, 1, 21, 0), "Админ ужин", 1500), ADMIN_ID); + } + + @Override +- public UserMeal save(UserMeal userMeal) { ++ public UserMeal save(UserMeal userMeal, int userId) { ++ Objects.requireNonNull(userMeal); ++ ++ Integer mealId = userMeal.getId(); ++ + if (userMeal.isNew()) { +- userMeal.setId(counter.incrementAndGet()); ++ mealId = counter.incrementAndGet(); ++ userMeal.setId(mealId); ++ } else if (get(mealId, userId) == null) { ++ return null; + } +- repository.put(userMeal.getId(), userMeal); ++ Map userMeals = repository.computeIfAbsent(userId, ConcurrentHashMap::new); ++ userMeals.put(mealId, userMeal); + return userMeal; + } + + @Override +- public void delete(int id) { +- repository.remove(id); ++ public boolean delete(int id, int userId) { ++ Map userMeals = repository.get(userId); ++ return userMeals != null && userMeals.remove(id) != null; + } + + @Override +- public UserMeal get(int id) { +- return repository.get(id); ++ public UserMeal get(int id, int userId) { ++ Map userMeals = repository.get(userId); ++ return userMeals == null ? null : userMeals.get(id); + } + + @Override +- public Collection getAll() { +- return repository.values(); ++ public Collection getAll(int userId) { ++ Map userMeals = repository.get(userId); ++ return userMeals == null ? ++ Collections.emptyList() : ++ userMeals.values().stream().sorted(USER_MEAL_COMPARATOR).collect(Collectors.toList()); + } +-} + ++ @Override ++ public Collection getBetween(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId) { ++ Objects.requireNonNull(startDateTime); ++ Objects.requireNonNull(endDateTime); ++ return getAll(userId).stream() ++ .filter(um -> TimeUtil.isBetween(um.getDateTime(), startDateTime, endDateTime)) ++ .collect(Collectors.toList()); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (date 1465940521000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (date 1465940521000) +@@ -0,0 +1,64 @@ ++package ru.javawebinar.topjava.repository.mock; ++ ++import org.springframework.stereotype.Repository; ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.repository.UserRepository; ++ ++import java.util.Comparator; ++import java.util.List; ++import java.util.Map; ++import java.util.Objects; ++import java.util.concurrent.ConcurrentHashMap; ++import java.util.concurrent.atomic.AtomicInteger; ++import java.util.stream.Collectors; ++ ++/** ++ * GKislin ++ * 15.06.2015. ++ */ ++@Repository ++public class InMemoryUserRepositoryImpl implements UserRepository { ++ private Map repository = new ConcurrentHashMap<>(); ++ private AtomicInteger counter = new AtomicInteger(0); ++ ++ private static final Comparator USER_COMPARATOR = Comparator.comparing(User::getName); ++ ++ public static final int USER_ID = 1; ++ public static final int ADMIN_ID = 2; ++ ++ @Override ++ public User save(User user) { ++ Objects.requireNonNull(user); ++ if (user.isNew()) { ++ user.setId(counter.incrementAndGet()); ++ } ++ repository.put(user.getId(), user); ++ return user; ++ } ++ ++ @Override ++ public boolean delete(int id) { ++ return repository.remove(id) != null; ++ } ++ ++ @Override ++ public User get(int id) { ++ return repository.get(id); ++ } ++ ++ @Override ++ public List getAll() { ++ return repository.values().stream() ++ .sorted(USER_COMPARATOR) ++ .collect(Collectors.toList()); ++ } ++ ++ @Override ++ public User getByEmail(String email) { ++ Objects.requireNonNull(email); ++ return repository.values().stream() ++ .filter(u -> email.equals(u.getEmail())) ++ .findFirst() ++ .orElse(null); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (date 1465849306000) +@@ -1,49 +0,0 @@ +-package ru.javawebinar.topjava.repository.mock; +- +-import org.springframework.stereotype.Repository; +-import org.slf4j.Logger; +-import org.slf4j.LoggerFactory; +-import ru.javawebinar.topjava.model.User; +-import ru.javawebinar.topjava.repository.UserRepository; +- +-import java.util.Collections; +-import java.util.List; +- +-/** +- * GKislin +- * 15.06.2015. +- */ +-@Repository +-public class MockUserRepositoryImpl implements UserRepository { +- private static final Logger LOG = LoggerFactory.getLogger(MockUserRepositoryImpl.class); +- +- @Override +- public boolean delete(int id) { +- LOG.info("delete " + id); +- return true; +- } +- +- @Override +- public User save(User user) { +- LOG.info("save " + user); +- return user; +- } +- +- @Override +- public User get(int id) { +- LOG.info("get " + id); +- return null; +- } +- +- @Override +- public List getAll() { +- LOG.info("getAll"); +- return Collections.emptyList(); +- } +- +- @Override +- public User getByEmail(String email) { +- LOG.info("getByEmail " + email); +- return null; +- } +-} +Index: src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java (date 1465940521000) +@@ -2,6 +2,7 @@ + + import ru.javawebinar.topjava.model.UserMeal; + ++import java.time.LocalDateTime; + import java.util.Collection; + + /** +@@ -9,11 +10,18 @@ + * 06.03.2015. + */ + public interface UserMealRepository { +- UserMeal save(UserMeal userMeal); ++ // null if updated meal do not belong to userId ++ UserMeal save(UserMeal userMeal, int userId); + +- void delete(int id); ++ // false if meal do not belong to userId ++ boolean delete(int id, int userId); + +- UserMeal get(int id); ++ // null if meal do not belong to userId ++ UserMeal get(int id, int userId); + +- Collection getAll(); ++ // ORDERED dateTime ++ Collection getAll(int userId); ++ ++ // ORDERED dateTime ++ Collection getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId); + } +Index: src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (date 1465940521000) +@@ -1,7 +1,6 @@ + package ru.javawebinar.topjava.util; + + import java.time.LocalDateTime; +-import java.time.LocalTime; + import java.time.format.DateTimeFormatter; + + /** +@@ -9,10 +8,10 @@ + * 07.01.2015. + */ + public class TimeUtil { +- public static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); ++ private static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + +- public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime endTime) { +- return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) <= 0; ++ public static > boolean isBetween(T value, T start, T end) { ++ return value.compareTo(start) >= 0 && value.compareTo(end) <= 0; + } + + public static String toString(LocalDateTime ldt) { +Index: src/main/java/ru/javawebinar/topjava/web/MealServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/MealServlet.java (date 1465849306000) ++++ src/main/java/ru/javawebinar/topjava/web/MealServlet.java (date 1465940521000) +@@ -1,10 +1,11 @@ + package ru.javawebinar.topjava.web; + ++import ru.javawebinar.topjava.LoggedUser; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import ru.javawebinar.topjava.model.UserMeal; +-import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; + import ru.javawebinar.topjava.repository.UserMealRepository; ++import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; + import ru.javawebinar.topjava.util.UserMealsUtil; + + import javax.servlet.ServletConfig; +@@ -39,7 +40,7 @@ + request.getParameter("description"), + Integer.valueOf(request.getParameter("calories"))); + LOG.info(userMeal.isNew() ? "Create {}" : "Update {}", userMeal); +- repository.save(userMeal); ++ repository.save(userMeal, LoggedUser.id()); + response.sendRedirect("meals"); + } + +@@ -49,17 +50,17 @@ + if (action == null) { + LOG.info("getAll"); + request.setAttribute("mealList", +- UserMealsUtil.getWithExceeded(repository.getAll(), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); ++ UserMealsUtil.getWithExceeded(repository.getAll(LoggedUser.id()), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); + request.getRequestDispatcher("/mealList.jsp").forward(request, response); + } else if (action.equals("delete")) { + int id = getId(request); + LOG.info("Delete {}", id); +- repository.delete(id); ++ repository.delete(id, LoggedUser.id()); + response.sendRedirect("meals"); + } else if (action.equals("create") || action.equals("update")) { + final UserMeal meal = action.equals("create") ? + new UserMeal(LocalDateTime.now().withNano(0).withSecond(0), "", 1000) : +- repository.get(getId(request)); ++ repository.get(getId(request), LoggedUser.id()); + request.setAttribute("meal", meal); + request.getRequestDispatcher("mealEdit.jsp").forward(request, response); + } diff --git a/patchs/to_lesson03/3_02_HW2_meal_layers.patch b/patchs/to_lesson03/3_02_HW2_meal_layers.patch new file mode 100644 index 000000000000..2baa6d25770a --- /dev/null +++ b/patchs/to_lesson03/3_02_HW2_meal_layers.patch @@ -0,0 +1,335 @@ +Index: src/main/java/ru/javawebinar/topjava/model/UserMeal.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMeal.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/model/UserMeal.java (revision ) +@@ -6,8 +6,7 @@ + * GKislin + * 11.01.2015. + */ +-public class UserMeal { +- private Integer id; ++public class UserMeal extends BaseEntity { + + private final LocalDateTime dateTime; + +@@ -20,16 +19,12 @@ + } + + public UserMeal(Integer id, LocalDateTime dateTime, String description, int calories) { +- this.id = id; ++ super(id); + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + } + +- public void setId(int id) { +- this.id = id; +- } +- + public LocalDateTime getDateTime() { + return dateTime; + } +@@ -40,14 +35,6 @@ + + public int getCalories() { + return calories; +- } +- +- public Integer getId() { +- return id; +- } +- +- public boolean isNew() { +- return id == null; + } + + @Override +Index: src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/to/UserMealWithExceed.java (revision ) +@@ -1,4 +1,4 @@ +-package ru.javawebinar.topjava.model; ++package ru.javawebinar.topjava.to; + + import java.time.LocalDateTime; + +Index: src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision ) +@@ -1,5 +1,6 @@ + package ru.javawebinar.topjava.util; + ++import java.time.LocalDate; + import java.time.LocalDateTime; + import java.time.format.DateTimeFormatter; + +@@ -9,6 +10,9 @@ + */ + public class TimeUtil { + private static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); ++ ++ public static final LocalDate MIN_DATE = LocalDate.of(1, 1, 1); ++ public static final LocalDate MAX_DATE = LocalDate.of(3000, 1, 1); + + public static > boolean isBetween(T value, T start, T end) { + return value.compareTo(start) >= 0 && value.compareTo(end) <= 0; +Index: src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java (revision ) +@@ -1,7 +1,7 @@ + package ru.javawebinar.topjava.util; + + import ru.javawebinar.topjava.model.UserMeal; +-import ru.javawebinar.topjava.model.UserMealWithExceed; ++import ru.javawebinar.topjava.to.UserMealWithExceed; + + import java.time.LocalDate; + import java.time.LocalDateTime; +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java (revision ) +@@ -1,13 +1,51 @@ + package ru.javawebinar.topjava.service; + ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.stereotype.Service; ++import ru.javawebinar.topjava.model.UserMeal; + import ru.javawebinar.topjava.repository.UserMealRepository; ++import ru.javawebinar.topjava.util.exception.ExceptionUtil; + ++import java.time.LocalDateTime; ++import java.util.Collection; ++ + /** + * GKislin + * 06.03.2015. + */ ++@Service + public class UserMealServiceImpl implements UserMealService { + ++ @Autowired + private UserMealRepository repository; + ++ @Override ++ public UserMeal get(int id, int userId) { ++ return ExceptionUtil.checkNotFoundWithId(repository.get(id, userId), id); ++ } ++ ++ @Override ++ public void delete(int id, int userId) { ++ ExceptionUtil.checkNotFoundWithId(repository.delete(id, userId), id); ++ } ++ ++ @Override ++ public Collection getBetweenDateTimes(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId) { ++ return repository.getBetween(startDateTime, endDateTime, userId); ++ } ++ ++ @Override ++ public Collection getAll(int userId) { ++ return repository.getAll(userId); ++ } ++ ++ @Override ++ public UserMeal update(UserMeal meal, int userId) { ++ return ExceptionUtil.checkNotFoundWithId(repository.save(meal, userId), meal.getId()); ++ } ++ ++ @Override ++ public UserMeal save(UserMeal meal, int userId) { ++ return repository.save(meal, userId); ++ } + } +Index: src/main/java/ru/javawebinar/topjava/SpringMain.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/SpringMain.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/SpringMain.java (revision ) +@@ -4,9 +4,15 @@ + import org.springframework.context.support.ClassPathXmlApplicationContext; + import ru.javawebinar.topjava.model.Role; + import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.to.UserMealWithExceed; ++import ru.javawebinar.topjava.web.meal.UserMealRestController; + import ru.javawebinar.topjava.web.user.AdminRestController; + ++import java.time.LocalDate; ++import java.time.LocalTime; ++import java.time.Month; + import java.util.Arrays; ++import java.util.List; + + /** + * User: gkislin +@@ -19,6 +25,14 @@ + System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); + AdminRestController adminUserController = appCtx.getBean(AdminRestController.class); + System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); ++ System.out.println(); ++ ++ UserMealRestController mealController = appCtx.getBean(UserMealRestController.class); ++ List filteredMealsWithExceeded = ++ mealController.getBetween( ++ LocalDate.of(2015, Month.MAY, 30), LocalTime.of(7, 0), ++ LocalDate.of(2015, Month.MAY, 31), LocalTime.of(11, 0)); ++ filteredMealsWithExceeded.forEach(System.out::println); + } + } + } +Index: src/main/java/ru/javawebinar/topjava/service/UserMealService.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/service/UserMealService.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/service/UserMealService.java (revision ) +@@ -1,8 +1,31 @@ + package ru.javawebinar.topjava.service; + ++import ru.javawebinar.topjava.model.UserMeal; ++import ru.javawebinar.topjava.util.exception.NotFoundException; ++ ++import java.time.LocalDate; ++import java.time.LocalDateTime; ++import java.time.LocalTime; ++import java.util.Collection; ++ + /** + * GKislin + * 15.06.2015. + */ + public interface UserMealService { ++ UserMeal get(int id, int userId) throws NotFoundException; ++ ++ void delete(int id, int userId) throws NotFoundException; ++ ++ default Collection getBetweenDates(LocalDate startDate, LocalDate endDate, int userId) { ++ return getBetweenDateTimes(LocalDateTime.of(startDate, LocalTime.MIN), LocalDateTime.of(endDate, LocalTime.MAX), userId); ++ } ++ ++ Collection getBetweenDateTimes(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId); ++ ++ Collection getAll(int userId); ++ ++ UserMeal update(UserMeal meal, int userId) throws NotFoundException; ++ ++ UserMeal save(UserMeal meal, int userId); + } +Index: src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java (date 1465849318000) ++++ src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java (revision ) +@@ -1,12 +1,71 @@ + package ru.javawebinar.topjava.web.meal; + ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.stereotype.Controller; ++import ru.javawebinar.topjava.LoggedUser; ++import ru.javawebinar.topjava.model.UserMeal; + import ru.javawebinar.topjava.service.UserMealService; ++import ru.javawebinar.topjava.to.UserMealWithExceed; ++import ru.javawebinar.topjava.util.TimeUtil; ++import ru.javawebinar.topjava.util.UserMealsUtil; + ++import java.time.LocalDate; ++import java.time.LocalTime; ++import java.util.List; ++ + /** + * GKislin + * 06.03.2015. + */ ++@Controller + public class UserMealRestController { ++ private static final Logger LOG = LoggerFactory.getLogger(UserMealRestController.class); ++ ++ @Autowired + private UserMealService service; + ++ public UserMeal get(int id) { ++ int userId = LoggedUser.id(); ++ LOG.info("get meal {} for User {}", id, userId); ++ return service.get(id, userId); ++ } ++ ++ public void delete(int id) { ++ int userId = LoggedUser.id(); ++ LOG.info("delete meal {} for User {}", id, userId); ++ service.delete(id, userId); ++ } ++ ++ public List getAll() { ++ int userId = LoggedUser.id(); ++ LOG.info("getAll for User {}", userId); ++ return UserMealsUtil.getWithExceeded(service.getAll(userId), LoggedUser.getCaloriesPerDay()); ++ } ++ ++ public void update(UserMeal meal, int id) { ++ meal.setId(id); ++ int userId = LoggedUser.id(); ++ LOG.info("update {} for User {}", meal, userId); ++ service.update(meal, userId); ++ } ++ ++ public UserMeal create(UserMeal meal) { ++ meal.setId(null); ++ int userId = LoggedUser.id(); ++ LOG.info("create {} for User {}", meal, userId); ++ return service.save(meal, userId); ++ } ++ ++ public List getBetween(LocalDate startDate, LocalTime startTime, LocalDate endDate, LocalTime endTime) { ++ int userId = LoggedUser.id(); ++ LOG.info("getBetween dates {} - {} for time {} - {} for User {}", startDate, endDate, startTime, endTime, userId); ++ ++ return UserMealsUtil.getFilteredWithExceeded( ++ service.getBetweenDates( ++ startDate != null ? startDate : TimeUtil.MIN_DATE, endDate != null ? endDate : TimeUtil.MAX_DATE, userId), ++ startTime != null ? startTime : LocalTime.MIN, endTime != null ? endTime : LocalTime.MAX, LoggedUser.getCaloriesPerDay() ++ ); ++ } +-} ++} +\ No newline at end of file +Index: src/main/webapp/mealList.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/mealList.jsp (date 1465849318000) ++++ src/main/webapp/mealList.jsp (revision ) +@@ -32,7 +32,7 @@ + + + +- ++ + + + <%--${meal.dateTime.toLocalDate()} ${meal.dateTime.toLocalTime()}--%> +\ No newline at end of file From 1af44781079072bbe5ed8618d424a7d0a7df4127 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Fri, 24 Jun 2016 12:21:53 +0300 Subject: [PATCH 19/39] apply patch 3.02 --- .../repository/mock/InMemoryUserMealRepositoryImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java index ec576d1326d9..7efb0bdad304 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java @@ -6,6 +6,8 @@ import ru.javawebinar.topjava.util.TimeUtil; import ru.javawebinar.topjava.util.UserMealsUtil; +import java.util.Collection; +import java.util.Map; import java.time.LocalDateTime; import java.time.Month; import java.util.*; @@ -22,7 +24,6 @@ */ @Repository public class InMemoryUserMealRepositoryImpl implements UserMealRepository { - private static final Comparator USER_MEAL_COMPARATOR = Comparator.comparing(UserMeal::getDateTime).reversed(); // Map userId -> (mealId-> meal) @@ -74,7 +75,8 @@ public Collection getAll(int userId) { } @Override - public Collection getBetween(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId) { + public Collection getBetween(LocalDateTime startDateTime, LocalDateTime + endDateTime, int userId) { Objects.requireNonNull(startDateTime); Objects.requireNonNull(endDateTime); return getAll(userId).stream() From 7d4fc3fdc6f36c12358dbe2821ad3ce4979a58f5 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Fri, 24 Jun 2016 12:25:37 +0300 Subject: [PATCH 20/39] add patch 3.03 --- .../3_03_HW2_optional_MealServlet.patch | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 patchs/to_lesson03/3_03_HW2_optional_MealServlet.patch diff --git a/patchs/to_lesson03/3_03_HW2_optional_MealServlet.patch b/patchs/to_lesson03/3_03_HW2_optional_MealServlet.patch new file mode 100644 index 000000000000..58d5b809e9dc --- /dev/null +++ b/patchs/to_lesson03/3_03_HW2_optional_MealServlet.patch @@ -0,0 +1,90 @@ +Index: src/main/java/ru/javawebinar/topjava/web/MealServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/MealServlet.java (date 1465849675000) ++++ src/main/java/ru/javawebinar/topjava/web/MealServlet.java (revision ) +@@ -1,12 +1,11 @@ + package ru.javawebinar.topjava.web; + +-import ru.javawebinar.topjava.LoggedUser; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; ++import org.springframework.context.ConfigurableApplicationContext; ++import org.springframework.context.support.ClassPathXmlApplicationContext; + import ru.javawebinar.topjava.model.UserMeal; +-import ru.javawebinar.topjava.repository.UserMealRepository; +-import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; +-import ru.javawebinar.topjava.util.UserMealsUtil; ++import ru.javawebinar.topjava.web.meal.UserMealRestController; + + import javax.servlet.ServletConfig; + import javax.servlet.ServletException; +@@ -24,23 +23,37 @@ + public class MealServlet extends HttpServlet { + private static final Logger LOG = LoggerFactory.getLogger(MealServlet.class); + +- private UserMealRepository repository; ++ private ConfigurableApplicationContext springContext; ++ private UserMealRestController mealController; + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); +- repository = new InMemoryUserMealRepositoryImpl(); ++ springContext = new ClassPathXmlApplicationContext("spring/spring-app.xml"); ++ mealController = springContext.getBean(UserMealRestController.class); + } + ++ @Override ++ public void destroy() { ++ springContext.close(); ++ super.destroy(); ++ } ++ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + request.setCharacterEncoding("UTF-8"); +- String id = request.getParameter("id"); +- UserMeal userMeal = new UserMeal(id.isEmpty() ? null : Integer.valueOf(id), ++ ++ final UserMeal userMeal = new UserMeal( + LocalDateTime.parse(request.getParameter("dateTime")), + request.getParameter("description"), + Integer.valueOf(request.getParameter("calories"))); +- LOG.info(userMeal.isNew() ? "Create {}" : "Update {}", userMeal); +- repository.save(userMeal, LoggedUser.id()); ++ ++ if (request.getParameter("id").isEmpty()) { ++ LOG.info("Create {}", userMeal); ++ mealController.create(userMeal); ++ } else { ++ LOG.info("Update {}", userMeal); ++ mealController.update(userMeal, getId(request)); ++ } + response.sendRedirect("meals"); + } + +@@ -49,18 +62,17 @@ + + if (action == null) { + LOG.info("getAll"); +- request.setAttribute("mealList", +- UserMealsUtil.getWithExceeded(repository.getAll(LoggedUser.id()), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); +- request.getRequestDispatcher("/mealList.jsp").forward(request, response); ++ request.setAttribute("mealList", mealController.getAll()); ++ request.getRequestDispatcher("mealList.jsp").forward(request, response); + } else if (action.equals("delete")) { + int id = getId(request); + LOG.info("Delete {}", id); +- repository.delete(id, LoggedUser.id()); ++ mealController.delete(id); + response.sendRedirect("meals"); + } else if (action.equals("create") || action.equals("update")) { + final UserMeal meal = action.equals("create") ? + new UserMeal(LocalDateTime.now().withNano(0).withSecond(0), "", 1000) : +- repository.get(getId(request), LoggedUser.id()); ++ mealController.get(getId(request)); // update + request.setAttribute("meal", meal); + request.getRequestDispatcher("mealEdit.jsp").forward(request, response); + } From c908eb4f9317abf9056bbd00daab6ee214c63176 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Sat, 25 Jun 2016 11:59:29 +0300 Subject: [PATCH 21/39] apply patch 3.03 --- .../javawebinar/topjava/web/MealServlet.java | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java index 90c19f16fcec..47852082c5fc 100644 --- a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java @@ -1,12 +1,11 @@ package ru.javawebinar.topjava.web; -import ru.javawebinar.topjava.LoggedUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; import ru.javawebinar.topjava.model.UserMeal; -import ru.javawebinar.topjava.repository.UserMealRepository; -import ru.javawebinar.topjava.repository.mock.InMemoryUserMealRepositoryImpl; -import ru.javawebinar.topjava.util.UserMealsUtil; +import ru.javawebinar.topjava.web.meal.UserMealRestController; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -24,23 +23,37 @@ public class MealServlet extends HttpServlet { private static final Logger LOG = LoggerFactory.getLogger(MealServlet.class); - private UserMealRepository repository; + private ConfigurableApplicationContext springContext; + private UserMealRestController mealController; @Override public void init(ServletConfig config) throws ServletException { super.init(config); - repository = new InMemoryUserMealRepositoryImpl(); + springContext = new ClassPathXmlApplicationContext("spring/spring-app.xml"); + mealController = springContext.getBean(UserMealRestController.class); + } + + @Override + public void destroy() { + springContext.close(); + super.destroy(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); - String id = request.getParameter("id"); - UserMeal userMeal = new UserMeal(id.isEmpty() ? null : Integer.valueOf(id), + + final UserMeal userMeal = new UserMeal( LocalDateTime.parse(request.getParameter("dateTime")), request.getParameter("description"), Integer.valueOf(request.getParameter("calories"))); - LOG.info(userMeal.isNew() ? "Create {}" : "Update {}", userMeal); - repository.save(userMeal, LoggedUser.id()); + + if (request.getParameter("id").isEmpty()) { + LOG.info("Create {}", userMeal); + mealController.create(userMeal); + } else { + LOG.info("Update {}", userMeal); + mealController.update(userMeal, getId(request)); + } response.sendRedirect("meals"); } @@ -49,18 +62,17 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t if (action == null) { LOG.info("getAll"); - request.setAttribute("mealList", - UserMealsUtil.getWithExceeded(repository.getAll(LoggedUser.id()), UserMealsUtil.DEFAULT_CALORIES_PER_DAY)); - request.getRequestDispatcher("/mealList.jsp").forward(request, response); + request.setAttribute("mealList", mealController.getAll()); + request.getRequestDispatcher("mealList.jsp").forward(request, response); } else if (action.equals("delete")) { int id = getId(request); LOG.info("Delete {}", id); - repository.delete(id, LoggedUser.id()); + mealController.delete(id); response.sendRedirect("meals"); } else if (action.equals("create") || action.equals("update")) { final UserMeal meal = action.equals("create") ? new UserMeal(LocalDateTime.now().withNano(0).withSecond(0), "", 1000) : - repository.get(getId(request), LoggedUser.id()); + mealController.get(getId(request)); // update request.setAttribute("meal", meal); request.getRequestDispatcher("mealEdit.jsp").forward(request, response); } From ba2ce39568d863ff5583fb1887e1f0c3c74534e3 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Sat, 25 Jun 2016 12:00:32 +0300 Subject: [PATCH 22/39] add patch 3.04 --- .../3_04_HW2_optional_filter.patch | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 patchs/to_lesson03/3_04_HW2_optional_filter.patch diff --git a/patchs/to_lesson03/3_04_HW2_optional_filter.patch b/patchs/to_lesson03/3_04_HW2_optional_filter.patch new file mode 100644 index 000000000000..d6b29083bd7a --- /dev/null +++ b/patchs/to_lesson03/3_04_HW2_optional_filter.patch @@ -0,0 +1,231 @@ +Index: src/main/webapp/css/style.css +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/css/style.css (revision ) ++++ src/main/webapp/css/style.css (revision ) +@@ -0,0 +1,24 @@ ++dl { ++ background: none repeat scroll 0 0 #FAFAFA; ++ margin: 8px 0; ++ padding: 0; ++} ++ ++dt { ++ display: inline-block; ++ width: 170px; ++} ++ ++dd { ++ display: inline-block; ++ margin-left: 8px; ++ vertical-align: top; ++} ++ ++.normal { ++ color: green; ++} ++ ++.exceeded { ++ color: red; ++} +Index: src/main/webapp/mealEdit.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/mealEdit.jsp (date 1465850101000) ++++ src/main/webapp/mealEdit.jsp (revision ) +@@ -4,24 +4,7 @@ + + + Meal +- ++ + + +
    +Index: src/main/java/ru/javawebinar/topjava/web/MealServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/MealServlet.java (date 1465850101000) ++++ src/main/java/ru/javawebinar/topjava/web/MealServlet.java (revision ) +@@ -5,6 +5,7 @@ + import org.springframework.context.ConfigurableApplicationContext; + import org.springframework.context.support.ClassPathXmlApplicationContext; + import ru.javawebinar.topjava.model.UserMeal; ++import ru.javawebinar.topjava.util.TimeUtil; + import ru.javawebinar.topjava.web.meal.UserMealRestController; + + import javax.servlet.ServletConfig; +@@ -13,7 +14,9 @@ + import javax.servlet.http.HttpServletRequest; + import javax.servlet.http.HttpServletResponse; + import java.io.IOException; ++import java.time.LocalDate; + import java.time.LocalDateTime; ++import java.time.LocalTime; + import java.util.Objects; + + /** +@@ -41,21 +44,31 @@ + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + request.setCharacterEncoding("UTF-8"); +- ++ String action = request.getParameter("action"); ++ if (action == null) { +- final UserMeal userMeal = new UserMeal( +- LocalDateTime.parse(request.getParameter("dateTime")), +- request.getParameter("description"), +- Integer.valueOf(request.getParameter("calories"))); ++ final UserMeal userMeal = new UserMeal( ++ LocalDateTime.parse(request.getParameter("dateTime")), ++ request.getParameter("description"), ++ Integer.valueOf(request.getParameter("calories"))); + +- if (request.getParameter("id").isEmpty()) { +- LOG.info("Create {}", userMeal); +- mealController.create(userMeal); +- } else { +- LOG.info("Update {}", userMeal); +- mealController.update(userMeal, getId(request)); +- } +- response.sendRedirect("meals"); ++ if (request.getParameter("id").isEmpty()) { ++ LOG.info("Create {}", userMeal); ++ mealController.create(userMeal); ++ } else { ++ LOG.info("Update {}", userMeal); ++ mealController.update(userMeal, getId(request)); ++ } ++ response.sendRedirect("meals"); ++ ++ } else if (action.equals("filter")) { ++ LocalDate startDate = TimeUtil.parseLocalDate(resetParam("startDate", request)); ++ LocalDate endDate = TimeUtil.parseLocalDate(resetParam("endDate", request)); ++ LocalTime startTime = TimeUtil.parseLocalTime(resetParam("startTime", request)); ++ LocalTime endTime = TimeUtil.parseLocalTime(resetParam("endTime", request)); ++ request.setAttribute("mealList", mealController.getBetween(startDate, startTime, endDate, endTime)); ++ request.getRequestDispatcher("/mealList.jsp").forward(request, response); +- } ++ } ++ } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String action = request.getParameter("action"); +@@ -76,6 +89,12 @@ + request.setAttribute("meal", meal); + request.getRequestDispatcher("mealEdit.jsp").forward(request, response); + } ++ } ++ ++ private String resetParam(String param, HttpServletRequest request) { ++ String value = request.getParameter(param); ++ request.setAttribute(param, value); ++ return value; + } + + private int getId(HttpServletRequest request) { +Index: src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (date 1465850101000) ++++ src/main/java/ru/javawebinar/topjava/util/TimeUtil.java (revision ) +@@ -1,7 +1,10 @@ + package ru.javawebinar.topjava.util; + ++import org.springframework.util.StringUtils; ++ + import java.time.LocalDate; + import java.time.LocalDateTime; ++import java.time.LocalTime; + import java.time.format.DateTimeFormatter; + + /** +@@ -20,5 +23,13 @@ + + public static String toString(LocalDateTime ldt) { + return ldt == null ? "" : ldt.format(DATE_TME_FORMATTER); ++ } ++ ++ public static LocalDate parseLocalDate(String str) { ++ return StringUtils.isEmpty(str) ? null : LocalDate.parse(str); ++ } ++ ++ public static LocalTime parseLocalTime(String str) { ++ return StringUtils.isEmpty(str) ? null : LocalTime.parse(str); + } + } +Index: src/main/webapp/mealList.jsp +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/mealList.jsp (date 1465850101000) ++++ src/main/webapp/mealList.jsp (revision ) +@@ -5,20 +5,32 @@ + + + Meal list +- ++ + + +
    +

    Home

    +

    Meal list

    ++ ++
    ++
    From Date:
    ++
    ++
    ++
    ++
    To Date:
    ++
    ++
    ++
    ++
    From Time:
    ++
    ++
    ++
    ++
    To Time:
    ++
    ++
    ++ ++ ++
    + Add Meal +
    + +\ No newline at end of file From 9ef99c7fafcf3d2ea16b00bb97c695625db7b2a6 Mon Sep 17 00:00:00 2001 From: andreichernov Date: Sat, 25 Jun 2016 12:11:08 +0300 Subject: [PATCH 23/39] apply patch 3.05 --- .../ru/javawebinar/topjava/LoggedUser.java | 7 +++- .../ru/javawebinar/topjava/util/TimeUtil.java | 12 ++++++ .../javawebinar/topjava/web/MealServlet.java | 41 ++++++++++++++----- .../javawebinar/topjava/web/UserServlet.java | 10 +++-- src/main/webapp/css/style.css | 24 +++++++++++ src/main/webapp/index.html | 12 ++++-- src/main/webapp/mealEdit.jsp | 19 +-------- src/main/webapp/mealList.jsp | 30 ++++++++++---- 8 files changed, 109 insertions(+), 46 deletions(-) create mode 100644 src/main/webapp/css/style.css diff --git a/src/main/java/ru/javawebinar/topjava/LoggedUser.java b/src/main/java/ru/javawebinar/topjava/LoggedUser.java index 73543d905840..e1e2ac0f58c8 100644 --- a/src/main/java/ru/javawebinar/topjava/LoggedUser.java +++ b/src/main/java/ru/javawebinar/topjava/LoggedUser.java @@ -7,9 +7,14 @@ * 06.03.2015. */ public class LoggedUser { + public static int id = 1; public static int id() { - return 1; + return id; + } + + public static void setId(int id) { + LoggedUser.id = id; } public static int getCaloriesPerDay() { diff --git a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java index 56d2deaf6752..4e08f304fb0c 100644 --- a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -1,6 +1,10 @@ package ru.javawebinar.topjava.util; +import org.springframework.util.StringUtils; + +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.format.DateTimeFormatter; /** @@ -17,4 +21,12 @@ public static > boolean isBetween(T value, T sta public static String toString(LocalDateTime ldt) { return ldt == null ? "" : ldt.format(DATE_TME_FORMATTER); } + + public static LocalDate parseLocalDate(String str) { + return StringUtils.isEmpty(str) ? null : LocalDate.parse(str); + } + + public static LocalTime parseLocalTime(String str) { + return StringUtils.isEmpty(str) ? null : LocalTime.parse(str); + } } diff --git a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java index 47852082c5fc..49a1530c2e8b 100644 --- a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java @@ -5,6 +5,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.util.TimeUtil; import ru.javawebinar.topjava.web.meal.UserMealRestController; import javax.servlet.ServletConfig; @@ -13,7 +14,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.Objects; /** @@ -41,20 +44,30 @@ public void destroy() { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); + String action = request.getParameter("action"); + if (action == null) { + final UserMeal userMeal = new UserMeal( + LocalDateTime.parse(request.getParameter("dateTime")), + request.getParameter("description"), + Integer.valueOf(request.getParameter("calories"))); - final UserMeal userMeal = new UserMeal( - LocalDateTime.parse(request.getParameter("dateTime")), - request.getParameter("description"), - Integer.valueOf(request.getParameter("calories"))); + if (request.getParameter("id").isEmpty()) { + LOG.info("Create {}", userMeal); + mealController.create(userMeal); + } else { + LOG.info("Update {}", userMeal); + mealController.update(userMeal, getId(request)); + } + response.sendRedirect("meals"); - if (request.getParameter("id").isEmpty()) { - LOG.info("Create {}", userMeal); - mealController.create(userMeal); - } else { - LOG.info("Update {}", userMeal); - mealController.update(userMeal, getId(request)); + } else if (action.equals("filter")) { + LocalDate startDate = TimeUtil.parseLocalDate(resetParam("startDate", request)); + LocalDate endDate = TimeUtil.parseLocalDate(resetParam("endDate", request)); + LocalTime startTime = TimeUtil.parseLocalTime(resetParam("startTime", request)); + LocalTime endTime = TimeUtil.parseLocalTime(resetParam("endTime", request)); + request.setAttribute("mealList", mealController.getBetween(startDate, startTime, endDate, endTime)); + request.getRequestDispatcher("/mealList.jsp").forward(request, response); } - response.sendRedirect("meals"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -78,6 +91,12 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t } } + private String resetParam(String param, HttpServletRequest request) { + String value = request.getParameter(param); + request.setAttribute(param, value); + return value; + } + private int getId(HttpServletRequest request) { String paramId = Objects.requireNonNull(request.getParameter("id")); return Integer.valueOf(paramId); diff --git a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java index 9f2490f822e3..ba9635c5e922 100644 --- a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java @@ -1,7 +1,7 @@ package ru.javawebinar.topjava.web; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import ru.javawebinar.topjava.LoggedUser; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -18,10 +18,14 @@ public class UserServlet extends HttpServlet { private static final Logger LOG = getLogger(UserServlet.class); + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + int userId = Integer.valueOf(request.getParameter("userId")); + LoggedUser.setId(userId); + response.sendRedirect("meals"); + } + 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/webapp/css/style.css b/src/main/webapp/css/style.css new file mode 100644 index 000000000000..0c9fc667371c --- /dev/null +++ b/src/main/webapp/css/style.css @@ -0,0 +1,24 @@ +dl { + background: none repeat scroll 0 0 #FAFAFA; + margin: 8px 0; + padding: 0; +} + +dt { + display: inline-block; + width: 170px; +} + +dd { + display: inline-block; + margin-left: 8px; + vertical-align: top; +} + +.normal { + color: green; +} + +.exceeded { + color: red; +} diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index b380bc03c9db..b3f17eb0bf40 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -7,9 +7,13 @@

    Проект "Java Enterprise (Topjava)"


    - +
    + Meal list of + + + diff --git a/src/main/webapp/mealEdit.jsp b/src/main/webapp/mealEdit.jsp index c5b5b317e1c9..3a5b3bc07647 100644 --- a/src/main/webapp/mealEdit.jsp +++ b/src/main/webapp/mealEdit.jsp @@ -4,24 +4,7 @@ Meal - +
    diff --git a/src/main/webapp/mealList.jsp b/src/main/webapp/mealList.jsp index 12d837677f38..28eb52276c63 100644 --- a/src/main/webapp/mealList.jsp +++ b/src/main/webapp/mealList.jsp @@ -5,20 +5,32 @@ Meal list - +

    Home

    Meal list

    +
    +
    +
    From Date:
    +
    +
    +
    +
    To Date:
    +
    +
    +
    +
    From Time:
    +
    +
    +
    +
    To Time:
    +
    +
    + + +
    Add Meal
    From 1e3e557b4e4f5dc4e841eb70010a0856e2823a31 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Thu, 30 Jun 2016 13:51:36 +0300 Subject: [PATCH 24/39] apply patch 3.02 --- .../ru/javawebinar/topjava/SpringMain.java | 14 +++++ .../javawebinar/topjava/model/UserMeal.java | 16 +---- .../topjava/service/UserMealService.java | 23 +++++++ .../topjava/service/UserMealServiceImpl.java | 38 ++++++++++++ .../{model => to}/UserMealWithExceed.java | 2 +- .../ru/javawebinar/topjava/util/TimeUtil.java | 4 ++ .../topjava/util/UserMealsUtil.java | 2 +- .../web/meal/UserMealRestController.java | 61 ++++++++++++++++++- src/main/webapp/mealList.jsp | 2 +- 9 files changed, 144 insertions(+), 18 deletions(-) rename src/main/java/ru/javawebinar/topjava/{model => to}/UserMealWithExceed.java (93%) diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/main/java/ru/javawebinar/topjava/SpringMain.java index 2e5698f620c4..ead5744b7d1e 100644 --- a/src/main/java/ru/javawebinar/topjava/SpringMain.java +++ b/src/main/java/ru/javawebinar/topjava/SpringMain.java @@ -4,9 +4,15 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import ru.javawebinar.topjava.model.Role; import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.to.UserMealWithExceed; +import ru.javawebinar.topjava.web.meal.UserMealRestController; import ru.javawebinar.topjava.web.user.AdminRestController; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.Month; import java.util.Arrays; +import java.util.List; /** * User: gkislin @@ -19,6 +25,14 @@ public static void main(String[] args) { System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); AdminRestController adminUserController = appCtx.getBean(AdminRestController.class); System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); + System.out.println(); + + UserMealRestController mealController = appCtx.getBean(UserMealRestController.class); + List filteredMealsWithExceeded = + mealController.getBetween( + LocalDate.of(2015, Month.MAY, 30), LocalTime.of(7, 0), + LocalDate.of(2015, Month.MAY, 31), LocalTime.of(11, 0)); + filteredMealsWithExceeded.forEach(System.out::println); } } } diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java index 8f4ab58d4bd4..f63f195f13d0 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -6,7 +6,7 @@ * GKislin * 11.01.2015. */ -public class UserMeal { +public class UserMeal extends BaseEntity { private final LocalDateTime dateTime; private Integer id; @@ -19,16 +19,12 @@ public UserMeal(LocalDateTime dateTime, String description, int calories) { } public UserMeal(Integer id, LocalDateTime dateTime, String description, int calories) { - this.id = id; + super(id); this.dateTime = dateTime; this.description = description; this.calories = calories; } - public void setId(int id) { - this.id = id; - } - public LocalDateTime getDateTime() { return dateTime; } @@ -41,14 +37,6 @@ public int getCalories() { return calories; } - public Integer getId() { - return id; - } - - public boolean isNew() { - return id == null; - } - @Override public String toString() { return "UserMeal{" + diff --git a/src/main/java/ru/javawebinar/topjava/service/UserMealService.java b/src/main/java/ru/javawebinar/topjava/service/UserMealService.java index 182f91376582..810220a803dd 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserMealService.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserMealService.java @@ -1,8 +1,31 @@ package ru.javawebinar.topjava.service; +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.util.exception.NotFoundException; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Collection; + /** * GKislin * 15.06.2015. */ public interface UserMealService { + UserMeal get(int id, int userId) throws NotFoundException; + + void delete(int id, int userId) throws NotFoundException; + + default Collection getBetweenDates(LocalDate startDate, LocalDate endDate, int userId) { + return getBetweenDateTimes(LocalDateTime.of(startDate, LocalTime.MIN), LocalDateTime.of(endDate, LocalTime.MAX), userId); + } + + Collection getBetweenDateTimes(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId); + + Collection getAll(int userId); + + UserMeal update(UserMeal meal, int userId) throws NotFoundException; + + UserMeal save(UserMeal meal, int userId); } diff --git a/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java index 9a95447cc45a..a5db71cf1ce3 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java @@ -1,13 +1,51 @@ package ru.javawebinar.topjava.service; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.javawebinar.topjava.model.UserMeal; import ru.javawebinar.topjava.repository.UserMealRepository; +import ru.javawebinar.topjava.util.exception.ExceptionUtil; + +import java.time.LocalDateTime; +import java.util.Collection; /** * GKislin * 06.03.2015. */ +@Service public class UserMealServiceImpl implements UserMealService { + @Autowired private UserMealRepository repository; + @Override + public UserMeal get(int id, int userId) { + return ExceptionUtil.checkNotFoundWithId(repository.get(id, userId), id); + } + + @Override + public void delete(int id, int userId) { + ExceptionUtil.checkNotFoundWithId(repository.delete(id, userId), id); + } + + @Override + public Collection getBetweenDateTimes(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId) { + return repository.getBetween(startDateTime, endDateTime, userId); + } + + @Override + public Collection getAll(int userId) { + return repository.getAll(userId); + } + + @Override + public UserMeal update(UserMeal meal, int userId) { + return ExceptionUtil.checkNotFoundWithId(repository.save(meal, userId), meal.getId()); + } + + @Override + public UserMeal save(UserMeal meal, int userId) { + return repository.save(meal, userId); + } } diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/to/UserMealWithExceed.java similarity index 93% rename from src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java rename to src/main/java/ru/javawebinar/topjava/to/UserMealWithExceed.java index 065c41bdfb66..6472063f7e9c 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +++ b/src/main/java/ru/javawebinar/topjava/to/UserMealWithExceed.java @@ -1,4 +1,4 @@ -package ru.javawebinar.topjava.model; +package ru.javawebinar.topjava.to; import java.time.LocalDateTime; diff --git a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java index 56d2deaf6752..b35f7cc03003 100644 --- a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -1,5 +1,6 @@ package ru.javawebinar.topjava.util; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -10,6 +11,9 @@ public class TimeUtil { private static final DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + public static final LocalDate MIN_DATE = LocalDate.of(1, 1, 1); + public static final LocalDate MAX_DATE = LocalDate.of(3000, 1, 1); + public static > boolean isBetween(T value, T start, T end) { return value.compareTo(start) >= 0 && value.compareTo(end) <= 0; } diff --git a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java index 587c7e04af69..cb796745215c 100644 --- a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -1,7 +1,7 @@ package ru.javawebinar.topjava.util; import ru.javawebinar.topjava.model.UserMeal; -import ru.javawebinar.topjava.model.UserMealWithExceed; +import ru.javawebinar.topjava.to.UserMealWithExceed; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java b/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java index 89194b79f7b2..1a9b74cab364 100644 --- a/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java +++ b/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java @@ -1,12 +1,71 @@ package ru.javawebinar.topjava.web.meal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import ru.javawebinar.topjava.LoggedUser; +import ru.javawebinar.topjava.model.UserMeal; import ru.javawebinar.topjava.service.UserMealService; +import ru.javawebinar.topjava.to.UserMealWithExceed; +import ru.javawebinar.topjava.util.TimeUtil; +import ru.javawebinar.topjava.util.UserMealsUtil; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.List; /** * GKislin * 06.03.2015. */ +@Controller public class UserMealRestController { + private static final Logger LOG = LoggerFactory.getLogger(UserMealRestController.class); + + @Autowired private UserMealService service; -} + public UserMeal get(int id) { + int userId = LoggedUser.id(); + LOG.info("get meal {} for User {}", id, userId); + return service.get(id, userId); + } + + public void delete(int id) { + int userId = LoggedUser.id(); + LOG.info("delete meal {} for User {}", id, userId); + service.delete(id, userId); + } + + public List getAll() { + int userId = LoggedUser.id(); + LOG.info("getAll for User {}", userId); + return UserMealsUtil.getWithExceeded(service.getAll(userId), LoggedUser.getCaloriesPerDay()); + } + + public void update(UserMeal meal, int id) { + meal.setId(id); + int userId = LoggedUser.id(); + LOG.info("update {} for User {}", meal, userId); + service.update(meal, userId); + } + + public UserMeal create(UserMeal meal) { + meal.setId(null); + int userId = LoggedUser.id(); + LOG.info("create {} for User {}", meal, userId); + return service.save(meal, userId); + } + + public List getBetween(LocalDate startDate, LocalTime startTime, LocalDate endDate, LocalTime endTime) { + int userId = LoggedUser.id(); + LOG.info("getBetween dates {} - {} for time {} - {} for User {}", startDate, endDate, startTime, endTime, userId); + + return UserMealsUtil.getFilteredWithExceeded( + service.getBetweenDates( + startDate != null ? startDate : TimeUtil.MIN_DATE, endDate != null ? endDate : TimeUtil.MAX_DATE, userId), + startTime != null ? startTime : LocalTime.MIN, endTime != null ? endTime : LocalTime.MAX, LoggedUser.getCaloriesPerDay() + ); + } +} \ No newline at end of file diff --git a/src/main/webapp/mealList.jsp b/src/main/webapp/mealList.jsp index 12d837677f38..98485552b322 100644 --- a/src/main/webapp/mealList.jsp +++ b/src/main/webapp/mealList.jsp @@ -32,7 +32,7 @@ - +
    <%--${meal.dateTime.toLocalDate()} ${meal.dateTime.toLocalTime()}--%> From 0bf5bb7ff6a150eb9e4efd4aa0e8fc088e78ecb9 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Thu, 30 Jun 2016 13:56:02 +0300 Subject: [PATCH 25/39] apply patch 3.03-3.05 --- .../java/ru/javawebinar/topjava/util/TimeUtil.java | 11 +++++++++++ .../ru/javawebinar/topjava/web/MealServlet.java | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java index b35f7cc03003..14bc39924f6e 100644 --- a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -1,7 +1,10 @@ package ru.javawebinar.topjava.util; +import org.springframework.util.StringUtils; + import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.format.DateTimeFormatter; /** @@ -21,4 +24,12 @@ public static > boolean isBetween(T value, T sta public static String toString(LocalDateTime ldt) { return ldt == null ? "" : ldt.format(DATE_TME_FORMATTER); } + + public static LocalDate parseLocalDate(String str) { + return StringUtils.isEmpty(str) ? null : LocalDate.parse(str); + } + + public static LocalTime parseLocalTime(String str) { + return StringUtils.isEmpty(str) ? null : LocalTime.parse(str); + } } diff --git a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java index 49a1530c2e8b..52c3d3b51614 100644 --- a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java @@ -36,12 +36,26 @@ public void init(ServletConfig config) throws ServletException { mealController = springContext.getBean(UserMealRestController.class); } + final UserMeal userMeal = new UserMeal( @Override public void destroy() { springContext.close(); super.destroy(); } + @Override + public void destroy() { + springContext.close(); + super.destroy(); + } + + if (request.getParameter("id").isEmpty()) { + LOG.info("Create {}", userMeal); + mealController.create(userMeal); + } else { + LOG.info("Update {}", userMeal); + mealController.update(userMeal, getId(request)); + } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String action = request.getParameter("action"); From 26194be5d2239b249da1f1e7e33627097e590644 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Thu, 30 Jun 2016 14:00:28 +0300 Subject: [PATCH 26/39] apply patch 3.03-3.05 --- .../ru/javawebinar/topjava/web/MealServlet.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java index 52c3d3b51614..49a1530c2e8b 100644 --- a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java @@ -36,26 +36,12 @@ public void init(ServletConfig config) throws ServletException { mealController = springContext.getBean(UserMealRestController.class); } - final UserMeal userMeal = new UserMeal( @Override public void destroy() { springContext.close(); super.destroy(); } - @Override - public void destroy() { - springContext.close(); - super.destroy(); - } - - if (request.getParameter("id").isEmpty()) { - LOG.info("Create {}", userMeal); - mealController.create(userMeal); - } else { - LOG.info("Update {}", userMeal); - mealController.update(userMeal, getId(request)); - } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String action = request.getParameter("action"); From b801c42a8164974fff0a94e5c60cb99d64ed1e64 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Sat, 9 Jul 2016 12:58:23 +0300 Subject: [PATCH 27/39] add patch 3.06 --- patchs/to_lesson03/3_06_bean_life_cycle.patch | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 patchs/to_lesson03/3_06_bean_life_cycle.patch diff --git a/patchs/to_lesson03/3_06_bean_life_cycle.patch b/patchs/to_lesson03/3_06_bean_life_cycle.patch new file mode 100644 index 000000000000..2d2d799f8201 --- /dev/null +++ b/patchs/to_lesson03/3_06_bean_life_cycle.patch @@ -0,0 +1,47 @@ +Index: src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (date 1465940660000) ++++ src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (revision ) +@@ -1,9 +1,13 @@ + package ru.javawebinar.topjava.repository.mock; + ++import org.slf4j.Logger; ++import org.slf4j.LoggerFactory; + import org.springframework.stereotype.Repository; + import ru.javawebinar.topjava.model.User; + import ru.javawebinar.topjava.repository.UserRepository; + ++import javax.annotation.PostConstruct; ++import javax.annotation.PreDestroy; + import java.util.Comparator; + import java.util.List; + import java.util.Map; +@@ -18,6 +22,8 @@ + */ + @Repository + public class InMemoryUserRepositoryImpl implements UserRepository { ++ private static final Logger LOG = LoggerFactory.getLogger(InMemoryUserRepositoryImpl.class); ++ + private Map repository = new ConcurrentHashMap<>(); + private AtomicInteger counter = new AtomicInteger(0); + +@@ -34,6 +40,16 @@ + } + repository.put(user.getId(), user); + return user; ++ } ++ ++ @PostConstruct ++ public void postConstruct() { ++ LOG.info("+++ PostConstruct"); ++ } ++ ++ @PreDestroy ++ public void preDestroy() { ++ LOG.info("+++ PreDestroy"); + } + + @Override From 9935b7a172a8db8f9e1519236928d3effca05c90 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Sat, 9 Jul 2016 12:59:54 +0300 Subject: [PATCH 28/39] apply patch 3.06 --- .../3_05_HW2_optional_select_user.patch | 81 +++++++++++++++++++ .../mock/InMemoryUserRepositoryImpl.java | 16 ++++ 2 files changed, 97 insertions(+) create mode 100644 patchs/to_lesson03/3_05_HW2_optional_select_user.patch diff --git a/patchs/to_lesson03/3_05_HW2_optional_select_user.patch b/patchs/to_lesson03/3_05_HW2_optional_select_user.patch new file mode 100644 index 000000000000..35694e33bd88 --- /dev/null +++ b/patchs/to_lesson03/3_05_HW2_optional_select_user.patch @@ -0,0 +1,81 @@ +Index: src/main/java/ru/javawebinar/topjava/LoggedUser.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/LoggedUser.java (date 1465850476000) ++++ src/main/java/ru/javawebinar/topjava/LoggedUser.java (revision ) +@@ -7,9 +7,14 @@ + * 06.03.2015. + */ + public class LoggedUser { ++ public static int id = 1; + + public static int id() { +- return 1; ++ return id; ++ } ++ ++ public static void setId(int id) { ++ LoggedUser.id = id; + } + + public static int getCaloriesPerDay() { +Index: src/main/webapp/index.html +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/webapp/index.html (date 1465850476000) ++++ src/main/webapp/index.html (revision ) +@@ -7,9 +7,13 @@ + +

    Проект "Java Enterprise (Topjava)"

    +
    +- ++
    ++ Meal list of ++ ++ ++
    + + +Index: src/main/java/ru/javawebinar/topjava/web/UserServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/web/UserServlet.java (date 1465850476000) ++++ src/main/java/ru/javawebinar/topjava/web/UserServlet.java (revision ) +@@ -1,7 +1,7 @@ + package ru.javawebinar.topjava.web; + + import org.slf4j.Logger; +-import org.slf4j.LoggerFactory; ++import ru.javawebinar.topjava.LoggedUser; + + import javax.servlet.ServletException; + import javax.servlet.http.HttpServlet; +@@ -18,10 +18,14 @@ + public class UserServlet extends HttpServlet { + private static final Logger LOG = getLogger(UserServlet.class); + ++ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ++ int userId = Integer.valueOf(request.getParameter("userId")); ++ LoggedUser.setId(userId); ++ response.sendRedirect("meals"); ++ } ++ + 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/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java index 1663d7ad7cc4..10667af83d27 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java @@ -1,9 +1,13 @@ package ru.javawebinar.topjava.repository.mock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Repository; import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.repository.UserRepository; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; import java.util.Comparator; import java.util.List; import java.util.Map; @@ -18,6 +22,8 @@ */ @Repository public class InMemoryUserRepositoryImpl implements UserRepository { + private static final Logger LOG = LoggerFactory.getLogger(InMemoryUserRepositoryImpl.class); + private Map repository = new ConcurrentHashMap<>(); private AtomicInteger counter = new AtomicInteger(0); @@ -36,6 +42,16 @@ public User save(User user) { return user; } + @PostConstruct + public void postConstruct() { + LOG.info("+++ PostConstruct"); + } + + @PreDestroy + public void preDestroy() { + LOG.info("+++ PreDestroy"); + } + @Override public boolean delete(int id) { return repository.remove(id) != null; From e3b5bcb1256e88c0dc072dbb384759ddef7dd3d1 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Sat, 9 Jul 2016 19:01:42 +0300 Subject: [PATCH 29/39] add patch 3.07 --- patchs/to_lesson03/3_07_add_junit.patch | 171 ++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 patchs/to_lesson03/3_07_add_junit.patch diff --git a/patchs/to_lesson03/3_07_add_junit.patch b/patchs/to_lesson03/3_07_add_junit.patch new file mode 100644 index 000000000000..64cb2f39b256 --- /dev/null +++ b/patchs/to_lesson03/3_07_add_junit.patch @@ -0,0 +1,171 @@ +Index: src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java (date 1465996980000) ++++ src/test/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java (revision ) +@@ -13,8 +13,8 @@ + import java.util.concurrent.atomic.AtomicInteger; + import java.util.stream.Collectors; + +-import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.ADMIN_ID; +-import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.USER_ID; ++import static ru.javawebinar.topjava.UserTestData.ADMIN_ID; ++import static ru.javawebinar.topjava.UserTestData.USER_ID; + + /** + * GKislin +Index: src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (date 1465996980000) ++++ src/test/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (revision ) +@@ -29,9 +29,6 @@ + + private static final Comparator USER_COMPARATOR = Comparator.comparing(User::getName); + +- public static final int USER_ID = 1; +- public static final int ADMIN_ID = 2; +- + @Override + public User save(User user) { + Objects.requireNonNull(user); +Index: src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java (revision ) ++++ src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java (revision ) +@@ -0,0 +1,55 @@ ++package ru.javawebinar.topjava.web; ++ ++import org.junit.*; ++import org.springframework.context.ConfigurableApplicationContext; ++import org.springframework.context.support.ClassPathXmlApplicationContext; ++import ru.javawebinar.topjava.UserTestData; ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.repository.UserRepository; ++import ru.javawebinar.topjava.util.exception.NotFoundException; ++import ru.javawebinar.topjava.web.user.AdminRestController; ++ ++import java.util.Arrays; ++import java.util.Collection; ++ ++import static ru.javawebinar.topjava.UserTestData.ADMIN; ++import static ru.javawebinar.topjava.UserTestData.USER; ++ ++public class InMemoryAdminRestControllerTest { ++ private static ConfigurableApplicationContext appCtx; ++ private static AdminRestController controller; ++ ++ @BeforeClass ++ public static void beforeClass() { ++ appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); ++ System.out.println("\n" + Arrays.toString(appCtx.getBeanDefinitionNames()) + "\n"); ++ controller = appCtx.getBean(AdminRestController.class); ++ } ++ ++ @AfterClass ++ public static void afterClass() { ++ appCtx.close(); ++ } ++ ++ @Before ++ public void setUp() throws Exception { ++ // Re-initialize ++ UserRepository repository = appCtx.getBean(UserRepository.class); ++ repository.getAll().forEach(u -> repository.delete(u.getId())); ++ repository.save(USER); ++ repository.save(ADMIN); ++ } ++ ++ @Test ++ public void testDelete() throws Exception { ++ controller.delete(UserTestData.USER_ID); ++ Collection users = controller.getAll(); ++ Assert.assertEquals(users.size(), 1); ++ Assert.assertEquals(users.iterator().next(), ADMIN); ++ } ++ ++ @Test(expected = NotFoundException.class) ++ public void testDeleteNotFound() throws Exception { ++ controller.delete(10); ++ } ++} +\ No newline at end of file +Index: src/test/java/ru/javawebinar/topjava/UserTestData.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javawebinar/topjava/UserTestData.java (revision ) ++++ src/test/java/ru/javawebinar/topjava/UserTestData.java (revision ) +@@ -0,0 +1,16 @@ ++package ru.javawebinar.topjava; ++ ++import ru.javawebinar.topjava.model.Role; ++import ru.javawebinar.topjava.model.User; ++ ++/** ++ * GKislin ++ * 24.09.2015. ++ */ ++public class UserTestData { ++ public static final int USER_ID = 1; ++ public static final int ADMIN_ID = 2; ++ ++ public static final User USER = new User(USER_ID, "User", "user@yandex.ru", "password", Role.ROLE_USER); ++ public static final User ADMIN = new User(ADMIN_ID, "Admin", "admin@gmail.com", "admin", Role.ROLE_ADMIN); ++} +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1465996980000) ++++ pom.xml (revision ) +@@ -21,6 +21,9 @@ + + 1.1.7 + 1.7.21 ++ ++ ++ 4.12 + + + +@@ -80,6 +83,14 @@ + commons-logging + + ++ ++ ++ ++ ++ junit ++ junit ++ ${junit.version} ++ test + + + javax.servlet +Index: src/main/java/ru/javawebinar/topjava/SpringMain.java +=================================================================== +--- src/main/java/ru/javawebinar/topjava/SpringMain.java (date 1465996980000) ++++ src/test/java/ru/javawebinar/topjava/SpringMain.java (revision ) +@@ -2,8 +2,6 @@ + + import org.springframework.context.ConfigurableApplicationContext; + import org.springframework.context.support.ClassPathXmlApplicationContext; +-import ru.javawebinar.topjava.model.Role; +-import ru.javawebinar.topjava.model.User; + import ru.javawebinar.topjava.to.UserMealWithExceed; + import ru.javawebinar.topjava.web.meal.UserMealRestController; + import ru.javawebinar.topjava.web.user.AdminRestController; +@@ -24,7 +22,7 @@ + try (ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml")) { + System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); + AdminRestController adminUserController = appCtx.getBean(AdminRestController.class); +- System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); ++ System.out.println(adminUserController.create(UserTestData.USER)); + System.out.println(); + + UserMealRestController mealController = appCtx.getBean(UserMealRestController.class); From 2db8ad1438f9a55f09cd9861012f2bb932a8a163 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Sat, 9 Jul 2016 19:04:17 +0300 Subject: [PATCH 30/39] apply patch 3.07 --- pom.xml | 11 ++++ .../ru/javawebinar/topjava/SpringMain.java | 4 +- .../ru/javawebinar/topjava/UserTestData.java | 16 ++++++ .../mock/InMemoryUserMealRepositoryImpl.java | 4 +- .../mock/InMemoryUserRepositoryImpl.java | 3 - .../web/InMemoryAdminRestControllerTest.java | 55 +++++++++++++++++++ 6 files changed, 85 insertions(+), 8 deletions(-) rename src/{main => test}/java/ru/javawebinar/topjava/SpringMain.java (85%) create mode 100644 src/test/java/ru/javawebinar/topjava/UserTestData.java rename src/{main => test}/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java (91%) rename src/{main => test}/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java (92%) create mode 100644 src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java diff --git a/pom.xml b/pom.xml index 9e17b4a5669a..d4bb43e8b66d 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,9 @@ 1.1.7 1.7.21 + + + 4.12 @@ -81,6 +84,14 @@ + + + + junit + junit + ${junit.version} + test + javax.servlet jstl diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/test/java/ru/javawebinar/topjava/SpringMain.java similarity index 85% rename from src/main/java/ru/javawebinar/topjava/SpringMain.java rename to src/test/java/ru/javawebinar/topjava/SpringMain.java index ead5744b7d1e..97d10049a1c7 100644 --- a/src/main/java/ru/javawebinar/topjava/SpringMain.java +++ b/src/test/java/ru/javawebinar/topjava/SpringMain.java @@ -2,8 +2,6 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; -import ru.javawebinar.topjava.model.Role; -import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.to.UserMealWithExceed; import ru.javawebinar.topjava.web.meal.UserMealRestController; import ru.javawebinar.topjava.web.user.AdminRestController; @@ -24,7 +22,7 @@ public static void main(String[] args) { try (ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml")) { System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); AdminRestController adminUserController = appCtx.getBean(AdminRestController.class); - System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); + System.out.println(adminUserController.create(UserTestData.USER)); System.out.println(); UserMealRestController mealController = appCtx.getBean(UserMealRestController.class); diff --git a/src/test/java/ru/javawebinar/topjava/UserTestData.java b/src/test/java/ru/javawebinar/topjava/UserTestData.java new file mode 100644 index 000000000000..bb8a9fb19788 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/UserTestData.java @@ -0,0 +1,16 @@ +package ru.javawebinar.topjava; + +import ru.javawebinar.topjava.model.Role; +import ru.javawebinar.topjava.model.User; + +/** + * GKislin + * 24.09.2015. + */ +public class UserTestData { + public static final int USER_ID = 1; + public static final int ADMIN_ID = 2; + + public static final User USER = new User(USER_ID, "User", "user@yandex.ru", "password", Role.ROLE_USER); + public static final User ADMIN = new User(ADMIN_ID, "Admin", "admin@gmail.com", "admin", Role.ROLE_ADMIN); +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java b/src/test/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java similarity index 91% rename from src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java rename to src/test/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java index 7efb0bdad304..f181bc40a6cc 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java +++ b/src/test/java/ru/javawebinar/topjava/repository/mock/InMemoryUserMealRepositoryImpl.java @@ -15,8 +15,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; -import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.ADMIN_ID; -import static ru.javawebinar.topjava.repository.mock.InMemoryUserRepositoryImpl.USER_ID; +import static ru.javawebinar.topjava.UserTestData.ADMIN_ID; +import static ru.javawebinar.topjava.UserTestData.USER_ID; /** * GKislin diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java b/src/test/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java similarity index 92% rename from src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java rename to src/test/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java index 10667af83d27..8bdae5d96824 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java +++ b/src/test/java/ru/javawebinar/topjava/repository/mock/InMemoryUserRepositoryImpl.java @@ -29,9 +29,6 @@ public class InMemoryUserRepositoryImpl implements UserRepository { private static final Comparator USER_COMPARATOR = Comparator.comparing(User::getName); - public static final int USER_ID = 1; - public static final int ADMIN_ID = 2; - @Override public User save(User user) { Objects.requireNonNull(user); diff --git a/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java b/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java new file mode 100644 index 000000000000..becff75a3425 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java @@ -0,0 +1,55 @@ +package ru.javawebinar.topjava.web; + +import org.junit.*; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import ru.javawebinar.topjava.UserTestData; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; +import ru.javawebinar.topjava.util.exception.NotFoundException; +import ru.javawebinar.topjava.web.user.AdminRestController; + +import java.util.Arrays; +import java.util.Collection; + +import static ru.javawebinar.topjava.UserTestData.ADMIN; +import static ru.javawebinar.topjava.UserTestData.USER; + +public class InMemoryAdminRestControllerTest { + private static ConfigurableApplicationContext appCtx; + private static AdminRestController controller; + + @BeforeClass + public static void beforeClass() { + appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); + System.out.println("\n" + Arrays.toString(appCtx.getBeanDefinitionNames()) + "\n"); + controller = appCtx.getBean(AdminRestController.class); + } + + @AfterClass + public static void afterClass() { + appCtx.close(); + } + + @Before + public void setUp() throws Exception { + // Re-initialize + UserRepository repository = appCtx.getBean(UserRepository.class); + repository.getAll().forEach(u -> repository.delete(u.getId())); + repository.save(USER); + repository.save(ADMIN); + } + + @Test + public void testDelete() throws Exception { + controller.delete(UserTestData.USER_ID); + Collection users = controller.getAll(); + Assert.assertEquals(users.size(), 1); + Assert.assertEquals(users.iterator().next(), ADMIN); + } + + @Test(expected = NotFoundException.class) + public void testDeleteNotFound() throws Exception { + controller.delete(10); + } +} \ No newline at end of file From 9fb5a0941672bd5dffc8fba1edcd1f61b5b9a6b6 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Sat, 9 Jul 2016 19:29:25 +0300 Subject: [PATCH 31/39] add patch 3.08 --- patchs/to_lesson03/3_08_add_spring_test.patch | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 patchs/to_lesson03/3_08_add_spring_test.patch diff --git a/patchs/to_lesson03/3_08_add_spring_test.patch b/patchs/to_lesson03/3_08_add_spring_test.patch new file mode 100644 index 000000000000..04f5a20acd31 --- /dev/null +++ b/patchs/to_lesson03/3_08_add_spring_test.patch @@ -0,0 +1,83 @@ +Index: src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerSpringTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerSpringTest.java (revision ) ++++ src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerSpringTest.java (revision ) +@@ -0,0 +1,54 @@ ++package ru.javawebinar.topjava.web; ++ ++import org.junit.Assert; ++import org.junit.Before; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.test.context.ContextConfiguration; ++import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; ++import ru.javawebinar.topjava.UserTestData; ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.repository.UserRepository; ++import ru.javawebinar.topjava.util.exception.NotFoundException; ++import ru.javawebinar.topjava.web.user.AdminRestController; ++ ++import java.util.Collection; ++ ++import static ru.javawebinar.topjava.UserTestData.ADMIN; ++import static ru.javawebinar.topjava.UserTestData.USER; ++ ++/** ++ * GKislin ++ * 13.03.2015. ++ */ ++@ContextConfiguration("classpath:spring/spring-app.xml") ++@RunWith(SpringJUnit4ClassRunner.class) ++public class InMemoryAdminRestControllerSpringTest { ++ ++ @Autowired ++ private AdminRestController controller; ++ ++ @Autowired ++ private UserRepository repository; ++ ++ @Before ++ public void setUp() throws Exception { ++ repository.getAll().forEach(u -> repository.delete(u.getId())); ++ repository.save(USER); ++ repository.save(ADMIN); ++ } ++ ++ @Test ++ public void testDelete() throws Exception { ++ controller.delete(UserTestData.USER_ID); ++ Collection users = controller.getAll(); ++ Assert.assertEquals(users.size(), 1); ++ Assert.assertEquals(users.iterator().next(), ADMIN); ++ } ++ ++ @Test(expected = NotFoundException.class) ++ public void testDeleteNotFound() throws Exception { ++ controller.delete(10); ++ } ++} +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1465997509000) ++++ pom.xml (revision ) +@@ -104,6 +104,13 @@ + 2.5 + provided + ++ ++ org.springframework ++ spring-test ++ ${spring.version} ++ test ++ ++ + + + From 021b2547931ab010d90d2f6ee233902e65bb5146 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Sat, 9 Jul 2016 19:33:35 +0300 Subject: [PATCH 32/39] apply patch 3.08 --- pom.xml | 7 +++ ...InMemoryAdminRestControllerSpringTest.java | 54 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerSpringTest.java diff --git a/pom.xml b/pom.xml index d4bb43e8b66d..0585bb36384a 100644 --- a/pom.xml +++ b/pom.xml @@ -104,6 +104,13 @@ 2.5 provided + + org.springframework + spring-test + ${spring.version} + test + + diff --git a/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerSpringTest.java b/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerSpringTest.java new file mode 100644 index 000000000000..9396810afe48 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerSpringTest.java @@ -0,0 +1,54 @@ +package ru.javawebinar.topjava.web; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import ru.javawebinar.topjava.UserTestData; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; +import ru.javawebinar.topjava.util.exception.NotFoundException; +import ru.javawebinar.topjava.web.user.AdminRestController; + +import java.util.Collection; + +import static ru.javawebinar.topjava.UserTestData.ADMIN; +import static ru.javawebinar.topjava.UserTestData.USER; + +/** + * GKislin + * 13.03.2015. + */ +@ContextConfiguration("classpath:spring/spring-app.xml") +@RunWith(SpringJUnit4ClassRunner.class) +public class InMemoryAdminRestControllerSpringTest { + + @Autowired + private AdminRestController controller; + + @Autowired + private UserRepository repository; + + @Before + public void setUp() throws Exception { + repository.getAll().forEach(u -> repository.delete(u.getId())); + repository.save(USER); + repository.save(ADMIN); + } + + @Test + public void testDelete() throws Exception { + controller.delete(UserTestData.USER_ID); + Collection users = controller.getAll(); + Assert.assertEquals(users.size(), 1); + Assert.assertEquals(users.iterator().next(), ADMIN); + } + + @Test(expected = NotFoundException.class) + public void testDeleteNotFound() throws Exception { + controller.delete(10); + } +} From 96ef328a6052c6167e59eae987ec79ac4ddbf796 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Mon, 11 Jul 2016 11:10:22 +0300 Subject: [PATCH 33/39] apply patch 3.08 --- .../topjava/web/InMemoryAdminRestControllerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java b/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java index becff75a3425..043542ec585a 100644 --- a/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java +++ b/src/test/java/ru/javawebinar/topjava/web/InMemoryAdminRestControllerTest.java @@ -50,6 +50,6 @@ public void testDelete() throws Exception { @Test(expected = NotFoundException.class) public void testDeleteNotFound() throws Exception { - controller.delete(10); + controller.delete(0); } } \ No newline at end of file From 1931a77264c13debce113aa71de3e3cb4058f3a8 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Mon, 11 Jul 2016 11:11:43 +0300 Subject: [PATCH 34/39] add patch 3.09 --- patchs/to_lesson03/3_09_add_postgresql.patch | 45 ++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 patchs/to_lesson03/3_09_add_postgresql.patch diff --git a/patchs/to_lesson03/3_09_add_postgresql.patch b/patchs/to_lesson03/3_09_add_postgresql.patch new file mode 100644 index 000000000000..0a6c919f7eb1 --- /dev/null +++ b/patchs/to_lesson03/3_09_add_postgresql.patch @@ -0,0 +1,45 @@ +Index: src/main/resources/db/postgres.properties +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>NATIVE_TO_ASCII_UTF-8 +=================================================================== +--- src/main/resources/db/postgres.properties (revision ) ++++ src/main/resources/db/postgres.properties (revision ) +@@ -0,0 +1,7 @@ ++#database.url=jdbc:postgresql://ec2-54-217-202-110.eu-west-1.compute.amazonaws.com:5432/dehm6lvm8bink0?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory ++#database.username=wegxlfzjjgxaxy ++#database.password=SSQyKKE_e93kiUCR-ehzMcKCxZ ++ ++database.url=jdbc:postgresql://localhost:5432/topjava ++database.username=user ++database.password=password +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1465997620000) ++++ pom.xml (revision ) +@@ -22,6 +22,8 @@ + 1.1.7 + 1.7.21 + ++ ++ 9.4.1208 + + 4.12 + +@@ -83,6 +85,13 @@ + commons-logging + + ++ ++ ++ ++ ++ org.postgresql ++ postgresql ++ ${postgresql.version} + + + From 8482950264cbba20173bee4aa52d7ff58aa4689f Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Mon, 11 Jul 2016 11:23:46 +0300 Subject: [PATCH 35/39] apply patch 3.09 --- pom.xml | 9 +++++++++ src/main/resources/db/postgres.properties | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 src/main/resources/db/postgres.properties diff --git a/pom.xml b/pom.xml index 0585bb36384a..a1a7a863fa69 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,8 @@ 1.1.7 1.7.21 + + 9.4.1208 4.12 @@ -85,6 +87,13 @@ + + + org.postgresql + postgresql + ${postgresql.version} + + junit diff --git a/src/main/resources/db/postgres.properties b/src/main/resources/db/postgres.properties new file mode 100644 index 000000000000..44dd64eb26b8 --- /dev/null +++ b/src/main/resources/db/postgres.properties @@ -0,0 +1,7 @@ +#database.url=jdbc:postgresql://ec2-54-217-202-110.eu-west-1.compute.amazonaws.com:5432/dehm6lvm8bink0?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory +#database.username=wegxlfzjjgxaxy +#database.password=SSQyKKE_e93kiUCR-ehzMcKCxZ + +database.url=jdbc:postgresql://localhost:5432/topjava +database.username=user +database.password=password From d6c1913e8f267bfce51a0bd819358b6dde6096e3 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Mon, 11 Jul 2016 13:43:45 +0300 Subject: [PATCH 36/39] add patchs 3.10, 3.11 --- .../3_10_populate_and_init_db.patch | 54 +++++++ .../3_11_impl_JdbcUserRepository.patch | 145 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 patchs/to_lesson03/3_10_populate_and_init_db.patch create mode 100644 patchs/to_lesson03/3_11_impl_JdbcUserRepository.patch diff --git a/patchs/to_lesson03/3_10_populate_and_init_db.patch b/patchs/to_lesson03/3_10_populate_and_init_db.patch new file mode 100644 index 000000000000..0239545d20c9 --- /dev/null +++ b/patchs/to_lesson03/3_10_populate_and_init_db.patch @@ -0,0 +1,54 @@ +Index: src/main/resources/db/populateDB.sql +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/db/populateDB.sql (revision ) ++++ src/main/resources/db/populateDB.sql (revision ) +@@ -0,0 +1,13 @@ ++DELETE FROM user_roles; ++DELETE FROM users; ++ALTER SEQUENCE global_seq RESTART WITH 100000; ++ ++INSERT INTO users (name, email, password) ++VALUES ('User', 'user@yandex.ru', 'password'); ++ ++INSERT INTO users (name, email, password) ++VALUES ('Admin', 'admin@gmail.com', 'admin'); ++ ++INSERT INTO user_roles (role, user_id) VALUES ++ ('ROLE_USER', 100000), ++ ('ROLE_ADMIN', 100001); +Index: src/main/resources/db/initDB.sql +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/db/initDB.sql (revision ) ++++ src/main/resources/db/initDB.sql (revision ) +@@ -0,0 +1,25 @@ ++DROP TABLE IF EXISTS user_roles; ++DROP TABLE IF EXISTS users; ++DROP SEQUENCE IF EXISTS global_seq; ++ ++CREATE SEQUENCE global_seq START 100000; ++ ++CREATE TABLE users ++( ++ id INTEGER PRIMARY KEY DEFAULT nextval('global_seq'), ++ name VARCHAR NOT NULL, ++ email VARCHAR NOT NULL, ++ password VARCHAR NOT NULL, ++ registered TIMESTAMP DEFAULT now(), ++ enabled BOOL DEFAULT TRUE, ++ calories_per_day INTEGER DEFAULT 2000 NOT NULL ++); ++CREATE UNIQUE INDEX users_unique_email_idx ON users (email); ++ ++CREATE TABLE user_roles ++( ++ user_id INTEGER NOT NULL, ++ role VARCHAR, ++ CONSTRAINT user_roles_idx UNIQUE (user_id, role), ++ FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ++); diff --git a/patchs/to_lesson03/3_11_impl_JdbcUserRepository.patch b/patchs/to_lesson03/3_11_impl_JdbcUserRepository.patch new file mode 100644 index 000000000000..f751a1d87416 --- /dev/null +++ b/patchs/to_lesson03/3_11_impl_JdbcUserRepository.patch @@ -0,0 +1,145 @@ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1465998544000) ++++ pom.xml (revision ) +@@ -119,6 +119,11 @@ + ${spring.version} + test + ++ ++ org.springframework ++ spring-jdbc ++ ${spring.version} ++ + + + +Index: src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java (revision ) +@@ -0,0 +1,84 @@ ++package ru.javawebinar.topjava.repository.jdbc; ++ ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.dao.support.DataAccessUtils; ++import org.springframework.jdbc.core.BeanPropertyRowMapper; ++import org.springframework.jdbc.core.JdbcTemplate; ++import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; ++import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; ++import org.springframework.jdbc.core.simple.SimpleJdbcInsert; ++import org.springframework.stereotype.Repository; ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.repository.UserRepository; ++ ++import javax.sql.DataSource; ++import java.util.List; ++ ++/** ++ * User: gkislin ++ * Date: 26.08.2014 ++ */ ++ ++@Repository ++public class JdbcUserRepositoryImpl implements UserRepository { ++ ++ private static final BeanPropertyRowMapper ROW_MAPPER = BeanPropertyRowMapper.newInstance(User.class); ++ ++ @Autowired ++ private JdbcTemplate jdbcTemplate; ++ ++ @Autowired ++ private NamedParameterJdbcTemplate namedParameterJdbcTemplate; ++ ++ private SimpleJdbcInsert insertUser; ++ ++ @Autowired ++ public JdbcUserRepositoryImpl(DataSource dataSource) { ++ this.insertUser = new SimpleJdbcInsert(dataSource) ++ .withTableName("USERS") ++ .usingGeneratedKeyColumns("id"); ++ } ++ ++ @Override ++ public User save(User user) { ++ MapSqlParameterSource map = new MapSqlParameterSource() ++ .addValue("id", user.getId()) ++ .addValue("name", user.getName()) ++ .addValue("email", user.getEmail()) ++ .addValue("password", user.getPassword()) ++ .addValue("registered", user.getRegistered()) ++ .addValue("enabled", user.isEnabled()) ++ .addValue("caloriesPerDay", user.getCaloriesPerDay()); ++ ++ if (user.isNew()) { ++ Number newKey = insertUser.executeAndReturnKey(map); ++ user.setId(newKey.intValue()); ++ } else { ++ namedParameterJdbcTemplate.update( ++ "UPDATE users SET name=:name, email=:email, password=:password, " + ++ "registered=:registered, enabled=:enabled, calories_per_day=:caloriesPerDay WHERE id=:id", map); ++ } ++ return user; ++ } ++ ++ @Override ++ public boolean delete(int id) { ++ return jdbcTemplate.update("DELETE FROM users WHERE id=?", id) != 0; ++ } ++ ++ @Override ++ public User get(int id) { ++ List users = jdbcTemplate.query("SELECT * FROM users WHERE id=?", ROW_MAPPER, id); ++ return DataAccessUtils.singleResult(users); ++ } ++ ++ @Override ++ public User getByEmail(String email) { ++ return jdbcTemplate.queryForObject("SELECT * FROM users WHERE email=?", ROW_MAPPER, email); ++ } ++ ++ @Override ++ public List getAll() { ++ return jdbcTemplate.query("SELECT * FROM users ORDER BY name, email", ROW_MAPPER); ++ } ++} +Index: src/main/resources/spring/spring-db.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/spring/spring-db.xml (revision ) ++++ src/main/resources/spring/spring-db.xml (revision ) +@@ -0,0 +1,25 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\ No newline at end of file From b419992ed3c2c75ffe704d47d10bba7b043a72ef Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Mon, 11 Jul 2016 13:44:40 +0300 Subject: [PATCH 37/39] apply patch 3.10 --- src/main/resources/db/initDB.sql | 25 +++++++++++++++++++++++++ src/main/resources/db/populateDB.sql | 13 +++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/main/resources/db/initDB.sql create mode 100644 src/main/resources/db/populateDB.sql diff --git a/src/main/resources/db/initDB.sql b/src/main/resources/db/initDB.sql new file mode 100644 index 000000000000..a0631c79567b --- /dev/null +++ b/src/main/resources/db/initDB.sql @@ -0,0 +1,25 @@ +DROP TABLE IF EXISTS user_roles; +DROP TABLE IF EXISTS users; +DROP SEQUENCE IF EXISTS global_seq; + +CREATE SEQUENCE global_seq START 100000; + +CREATE TABLE users +( + id INTEGER PRIMARY KEY DEFAULT nextval('global_seq'), + name VARCHAR NOT NULL, + email VARCHAR NOT NULL, + password VARCHAR NOT NULL, + registered TIMESTAMP DEFAULT now(), + enabled BOOL DEFAULT TRUE, + calories_per_day INTEGER DEFAULT 2000 NOT NULL +); +CREATE UNIQUE INDEX users_unique_email_idx ON users (email); + +CREATE TABLE user_roles +( + user_id INTEGER NOT NULL, + role VARCHAR, + CONSTRAINT user_roles_idx UNIQUE (user_id, role), + FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE +); diff --git a/src/main/resources/db/populateDB.sql b/src/main/resources/db/populateDB.sql new file mode 100644 index 000000000000..199e2ace615d --- /dev/null +++ b/src/main/resources/db/populateDB.sql @@ -0,0 +1,13 @@ +DELETE FROM user_roles; +DELETE FROM users; +ALTER SEQUENCE global_seq RESTART WITH 100000; + +INSERT INTO users (name, email, password) +VALUES ('User', 'user@yandex.ru', 'password'); + +INSERT INTO users (name, email, password) +VALUES ('Admin', 'admin@gmail.com', 'admin'); + +INSERT INTO user_roles (role, user_id) VALUES + ('ROLE_USER', 100000), + ('ROLE_ADMIN', 100001); From a4bd3c949fed20e0f132d01e97bc0cb8b70ccb25 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Mon, 11 Jul 2016 21:26:55 +0300 Subject: [PATCH 38/39] apply patch 3.11 + add patch 3.12 --- .../to_lesson03/3_12_test_UserService.patch | 435 ++++++++++++++++++ pom.xml | 5 + .../jdbc/JdbcUserRepositoryImpl.java | 84 ++++ src/main/resources/spring/spring-db.xml | 25 + 4 files changed, 549 insertions(+) create mode 100644 patchs/to_lesson03/3_12_test_UserService.patch create mode 100644 src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java create mode 100644 src/main/resources/spring/spring-db.xml diff --git a/patchs/to_lesson03/3_12_test_UserService.patch b/patchs/to_lesson03/3_12_test_UserService.patch new file mode 100644 index 000000000000..e35a481c1f80 --- /dev/null +++ b/patchs/to_lesson03/3_12_test_UserService.patch @@ -0,0 +1,435 @@ +Index: src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java (revision ) ++++ src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java (revision ) +@@ -0,0 +1,34 @@ ++package ru.javawebinar.topjava.matcher; ++ ++import org.junit.Assert; ++ ++import java.util.Collection; ++import java.util.function.Function; ++import java.util.stream.Collectors; ++ ++/** ++ * GKislin ++ * 06.01.2015. ++ * ++ * @param : entity ++ * @param : testEntity, converter result for compare ++ */ ++public class ModelMatcher { ++ protected Function entityConverter; ++ ++ public ModelMatcher(Function entityConverter) { ++ this.entityConverter = entityConverter; ++ } ++ ++ public void assertEquals(T expected, T actual) { ++ Assert.assertEquals(entityConverter.apply(expected), entityConverter.apply(actual)); ++ } ++ ++ public void assertCollectionEquals(Collection expected, Collection actual) { ++ Assert.assertEquals(map(expected, entityConverter), map(actual, entityConverter)); ++ } ++ ++ public static Collection map(Collection collection, Function converter) { ++ return collection.stream().map(converter).collect(Collectors.toList()); ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/model/BaseEntity.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/BaseEntity.java (date 1465998878000) ++++ src/main/java/ru/javawebinar/topjava/model/BaseEntity.java (revision ) +@@ -5,6 +5,8 @@ + * Date: 22.08.2014 + */ + public class BaseEntity { ++ public static final int START_SEQ = 100000; ++ + protected Integer id; + + public BaseEntity() { +@@ -25,4 +27,25 @@ + public boolean isNew() { + return (this.id == null); + } ++ ++ @Override ++ public boolean equals(Object o) { ++ if (this == o) { ++ return true; ++ } ++ if (o == null || getClass() != o.getClass()) { ++ return false; ++ } ++ BaseEntity that = (BaseEntity) o; ++ if (id == null || that.id == null) { ++ return false; ++ } ++ return id.equals(that.id); ++ } ++ ++ @Override ++ public int hashCode() { ++ return (id == null) ? 0 : id; ++ } ++ + } +Index: src/main/resources/spring/spring-app.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/spring/spring-app.xml (date 1465998878000) ++++ src/main/resources/spring/spring-app.xml (revision ) +@@ -14,7 +14,7 @@ + + + +- ++ + + + +\ No newline at end of file +Index: src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java (revision ) ++++ src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java (revision ) +@@ -0,0 +1,95 @@ ++package ru.javawebinar.topjava.service; ++ ++import org.junit.Before; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.dao.DataAccessException; ++import org.springframework.test.context.ContextConfiguration; ++import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; ++import ru.javawebinar.topjava.UserTestData.*; ++import ru.javawebinar.topjava.model.Role; ++import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.util.DbPopulator; ++import ru.javawebinar.topjava.util.exception.NotFoundException; ++ ++import java.util.Arrays; ++import java.util.Collection; ++import java.util.Collections; ++ ++import static ru.javawebinar.topjava.UserTestData.*; ++ ++@ContextConfiguration({ ++ "classpath:spring/spring-app.xml", ++ "classpath:spring/spring-db.xml" ++}) ++@RunWith(SpringJUnit4ClassRunner.class) ++public class UserServiceTest { ++ ++ @Autowired ++ protected UserService service; ++ ++ @Autowired ++ private DbPopulator dbPopulator; ++ ++ @Before ++ public void setUp() throws Exception { ++ dbPopulator.execute(); ++ } ++ ++ @Test ++ public void testSave() throws Exception { ++ TestUser tu = new TestUser(null, "New", "new@gmail.com", "newPass", 1555, false, Collections.singleton(Role.ROLE_USER)); ++ User created = service.save(tu.asUser()); ++ tu.setId(created.getId()); ++ MATCHER.assertCollectionEquals(Arrays.asList(ADMIN, tu, USER), service.getAll()); ++ } ++ ++ @Test(expected = DataAccessException.class) ++ public void testDuplicateMailSave() throws Exception { ++ service.save(new TestUser("Duplicate", "user@yandex.ru", "newPass", Role.ROLE_USER).asUser()); ++ } ++ ++ @Test ++ public void testDelete() throws Exception { ++ service.delete(USER_ID); ++ MATCHER.assertCollectionEquals(Collections.singletonList(ADMIN), service.getAll()); ++ } ++ ++ @Test(expected = NotFoundException.class) ++ public void testNotFoundDelete() throws Exception { ++ service.delete(1); ++ } ++ ++ @Test ++ public void testGet() throws Exception { ++ User user = service.get(USER_ID); ++ MATCHER.assertEquals(USER, user); ++ } ++ ++ @Test(expected = NotFoundException.class) ++ public void testGetNotFound() throws Exception { ++ service.get(1); ++ } ++ ++ @Test ++ public void testGetByEmail() throws Exception { ++ User user = service.getByEmail("user@yandex.ru"); ++ MATCHER.assertEquals(USER, user); ++ } ++ ++ @Test ++ public void testGetAll() throws Exception { ++ Collection all = service.getAll(); ++ MATCHER.assertCollectionEquals(Arrays.asList(ADMIN, USER), all); ++ } ++ ++ @Test ++ public void testUpdate() throws Exception { ++ TestUser updated = new TestUser(USER); ++ updated.setName("UpdatedName"); ++ updated.setCaloriesPerDay(330); ++ service.update(updated.asUser()); ++ MATCHER.assertEquals(updated, service.get(USER_ID)); ++ } ++} +\ No newline at end of file +Index: src/test/java/ru/javawebinar/topjava/UserTestData.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javawebinar/topjava/UserTestData.java (date 1465998878000) ++++ src/test/java/ru/javawebinar/topjava/UserTestData.java (revision ) +@@ -1,16 +1,75 @@ + package ru.javawebinar.topjava; + ++import ru.javawebinar.topjava.matcher.ModelMatcher; + import ru.javawebinar.topjava.model.Role; + import ru.javawebinar.topjava.model.User; ++import ru.javawebinar.topjava.util.UserMealsUtil; + ++import java.util.EnumSet; ++import java.util.Objects; ++import java.util.Set; ++ ++import static ru.javawebinar.topjava.model.BaseEntity.START_SEQ; ++ + /** + * GKislin + * 24.09.2015. + */ + public class UserTestData { +- public static final int USER_ID = 1; +- public static final int ADMIN_ID = 2; ++ public static final int USER_ID = START_SEQ; ++ public static final int ADMIN_ID = START_SEQ + 1; + + public static final User USER = new User(USER_ID, "User", "user@yandex.ru", "password", Role.ROLE_USER); + public static final User ADMIN = new User(ADMIN_ID, "Admin", "admin@gmail.com", "admin", Role.ROLE_ADMIN); ++ ++ public static final ModelMatcher MATCHER = new ModelMatcher<>(u -> ((u instanceof TestUser) ? (TestUser) u : new TestUser(u))); ++ ++ public static class TestUser extends User { ++ ++ public TestUser(User u) { ++ this(u.getId(), u.getName(), u.getEmail(), u.getPassword(), u.getCaloriesPerDay(), u.isEnabled(), u.getRoles()); ++ } ++ ++ public TestUser(String name, String email, String password, Role role, Role... roles) { ++ this(null, name, email, password, UserMealsUtil.DEFAULT_CALORIES_PER_DAY, true, EnumSet.of(role, roles)); ++ } ++ ++ public TestUser(Integer id, String name, String email, String password, int caloriesPerDay, boolean enabled, Set roles) { ++ super(id, name, email, password, caloriesPerDay, enabled, roles); ++ } ++ ++ public User asUser() { ++ return new User(this); ++ } ++ ++ @Override ++ public String toString() { ++ return "User (" + ++ "id=" + id + ++ ", email=" + email + ++ ", name=" + name + ++ ", enabled=" + enabled + ++ ", password=" + password + ++ ", authorities=" + roles + ++ ')'; ++ } ++ ++ @Override ++ public boolean equals(Object o) { ++ if (this == o) { ++ return true; ++ } ++ if (o == null || getClass() != o.getClass()) { ++ return false; ++ } ++ ++ TestUser that = (TestUser) o; ++ return Objects.equals(this.password, that.password) ++ && Objects.equals(this.id, that.id) ++ && Objects.equals(this.name, that.name) ++ && Objects.equals(this.email, that.email) ++ && Objects.equals(this.caloriesPerDay, that.caloriesPerDay) ++ && Objects.equals(this.enabled, that.enabled); ++ } ++ } + } +Index: src/test/java/ru/javawebinar/topjava/MealTestData.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javawebinar/topjava/MealTestData.java (revision ) ++++ src/test/java/ru/javawebinar/topjava/MealTestData.java (revision ) +@@ -0,0 +1,14 @@ ++package ru.javawebinar.topjava; ++ ++import ru.javawebinar.topjava.matcher.ModelMatcher; ++import ru.javawebinar.topjava.model.UserMeal; ++ ++/** ++ * GKislin ++ * 13.03.2015. ++ */ ++public class MealTestData { ++ ++ public static final ModelMatcher MATCHER = new ModelMatcher<>(UserMeal::toString); ++ ++} +Index: src/main/java/ru/javawebinar/topjava/util/DbPopulator.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/util/DbPopulator.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/util/DbPopulator.java (revision ) +@@ -0,0 +1,28 @@ ++package ru.javawebinar.topjava.util; ++ ++import org.springframework.beans.factory.annotation.Autowired; ++import org.springframework.core.io.DefaultResourceLoader; ++import org.springframework.core.io.ResourceLoader; ++import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; ++import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; ++ ++import javax.sql.DataSource; ++ ++/** ++ * User: gkislin ++ * Date: 26.08.2014 ++ */ ++public class DbPopulator extends ResourceDatabasePopulator { ++ private static final ResourceLoader RESOURCE_LOADER = new DefaultResourceLoader(); ++ ++ @Autowired ++ private DataSource dataSource; ++ ++ public DbPopulator(String scriptLocation) { ++ super(RESOURCE_LOADER.getResource(scriptLocation)); ++ } ++ ++ public void execute() { ++ DatabasePopulatorUtils.execute(this, dataSource); ++ } ++} +Index: src/main/resources/spring/spring-db.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/spring/spring-db.xml (date 1465998878000) ++++ src/main/resources/spring/spring-db.xml (revision ) +@@ -6,6 +6,10 @@ + + + ++ ++ ++ ++ + + +\ No newline at end of file +Index: src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java (revision ) ++++ src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java (revision ) +@@ -0,0 +1,42 @@ ++package ru.javawebinar.topjava.repository.jdbc; ++ ++import org.springframework.stereotype.Repository; ++import ru.javawebinar.topjava.model.UserMeal; ++import ru.javawebinar.topjava.repository.UserMealRepository; ++ ++import java.time.LocalDateTime; ++import java.util.List; ++ ++/** ++ * User: gkislin ++ * Date: 26.08.2014 ++ */ ++ ++@Repository ++public class JdbcUserMealRepositoryImpl implements UserMealRepository { ++ ++ @Override ++ public UserMeal save(UserMeal UserMeal, int userId) { ++ return null; ++ } ++ ++ @Override ++ public boolean delete(int id, int userId) { ++ return false; ++ } ++ ++ @Override ++ public UserMeal get(int id, int userId) { ++ return null; ++ } ++ ++ @Override ++ public List getAll(int userId) { ++ return null; ++ } ++ ++ @Override ++ public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { ++ return null; ++ } ++} +Index: src/main/java/ru/javawebinar/topjava/model/User.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javawebinar/topjava/model/User.java (date 1465998878000) ++++ src/main/java/ru/javawebinar/topjava/model/User.java (revision ) +@@ -27,6 +27,10 @@ + public User() { + } + ++ public User(User u) { ++ this(u.getId(), u.getName(), u.getEmail(), u.getPassword(), u.getCaloriesPerDay(), u.isEnabled(), u.getRoles()); ++ } ++ + public User(Integer id, String name, String email, String password, Role role, Role... roles) { + this(id, name, email, password, UserMealsUtil.DEFAULT_CALORIES_PER_DAY, true, EnumSet.of(role, roles)); + } diff --git a/pom.xml b/pom.xml index a1a7a863fa69..9d5fb076404b 100644 --- a/pom.xml +++ b/pom.xml @@ -119,6 +119,11 @@ ${spring.version} test + + org.springframework + spring-jdbc + ${spring.version} + diff --git a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java new file mode 100644 index 000000000000..5646bad071ed --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java @@ -0,0 +1,84 @@ +package ru.javawebinar.topjava.repository.jdbc; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.support.DataAccessUtils; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; + +import javax.sql.DataSource; +import java.util.List; + +/** + * User: gkislin + * Date: 26.08.2014 + */ + +@Repository +public class JdbcUserRepositoryImpl implements UserRepository { + + private static final BeanPropertyRowMapper ROW_MAPPER = BeanPropertyRowMapper.newInstance(User.class); + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + private SimpleJdbcInsert insertUser; + + @Autowired + public JdbcUserRepositoryImpl(DataSource dataSource) { + this.insertUser = new SimpleJdbcInsert(dataSource) + .withTableName("USERS") + .usingGeneratedKeyColumns("id"); + } + + @Override + public User save(User user) { + MapSqlParameterSource map = new MapSqlParameterSource() + .addValue("id", user.getId()) + .addValue("name", user.getName()) + .addValue("email", user.getEmail()) + .addValue("password", user.getPassword()) + .addValue("registered", user.getRegistered()) + .addValue("enabled", user.isEnabled()) + .addValue("caloriesPerDay", user.getCaloriesPerDay()); + + if (user.isNew()) { + Number newKey = insertUser.executeAndReturnKey(map); + user.setId(newKey.intValue()); + } else { + namedParameterJdbcTemplate.update( + "UPDATE users SET name=:name, email=:email, password=:password, " + + "registered=:registered, enabled=:enabled, calories_per_day=:caloriesPerDay WHERE id=:id", map); + } + return user; + } + + @Override + public boolean delete(int id) { + return jdbcTemplate.update("DELETE FROM users WHERE id=?", id) != 0; + } + + @Override + public User get(int id) { + List users = jdbcTemplate.query("SELECT * FROM users WHERE id=?", ROW_MAPPER, id); + return DataAccessUtils.singleResult(users); + } + + @Override + public User getByEmail(String email) { + return jdbcTemplate.queryForObject("SELECT * FROM users WHERE email=?", ROW_MAPPER, email); + } + + @Override + public List getAll() { + return jdbcTemplate.query("SELECT * FROM users ORDER BY name, email", ROW_MAPPER); + } +} diff --git a/src/main/resources/spring/spring-db.xml b/src/main/resources/spring/spring-db.xml new file mode 100644 index 000000000000..a1f6b09a7464 --- /dev/null +++ b/src/main/resources/spring/spring-db.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From cd24564d1478ba21d1449a710970ea7b5f760703 Mon Sep 17 00:00:00 2001 From: Andrei Chernov Date: Mon, 11 Jul 2016 21:49:16 +0300 Subject: [PATCH 39/39] apply patch 3.12 --- .../javawebinar/topjava/model/BaseEntity.java | 23 +++++ .../ru/javawebinar/topjava/model/User.java | 4 + .../jdbc/JdbcUserMealRepositoryImpl.java | 42 ++++++++ .../javawebinar/topjava/util/DbPopulator.java | 28 ++++++ src/main/resources/spring/spring-app.xml | 2 +- src/main/resources/spring/spring-db.xml | 4 + .../ru/javawebinar/topjava/MealTestData.java | 14 +++ .../ru/javawebinar/topjava/UserTestData.java | 63 +++++++++++- .../topjava/matcher/ModelMatcher.java | 34 +++++++ .../topjava/service/UserServiceTest.java | 95 +++++++++++++++++++ 10 files changed, 306 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/DbPopulator.java create mode 100644 src/test/java/ru/javawebinar/topjava/MealTestData.java create mode 100644 src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java create mode 100644 src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java diff --git a/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java index 735198372b5a..ba930b2c4394 100644 --- a/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java +++ b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java @@ -5,6 +5,8 @@ * Date: 22.08.2014 */ public class BaseEntity { + public static final int START_SEQ = 100000; + protected Integer id; public BaseEntity() { @@ -25,4 +27,25 @@ public Integer getId() { public boolean isNew() { return (this.id == null); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BaseEntity that = (BaseEntity) o; + if (id == null || that.id == null) { + return false; + } + return id.equals(that.id); + } + + @Override + public int hashCode() { + return (id == null) ? 0 : id; + } + } diff --git a/src/main/java/ru/javawebinar/topjava/model/User.java b/src/main/java/ru/javawebinar/topjava/model/User.java index 645b7fb9e20e..980a9f0d494b 100644 --- a/src/main/java/ru/javawebinar/topjava/model/User.java +++ b/src/main/java/ru/javawebinar/topjava/model/User.java @@ -27,6 +27,10 @@ public class User extends NamedEntity { public User() { } + public User(User u) { + this(u.getId(), u.getName(), u.getEmail(), u.getPassword(), u.getCaloriesPerDay(), u.isEnabled(), u.getRoles()); + } + public User(Integer id, String name, String email, String password, Role role, Role... roles) { this(id, name, email, password, UserMealsUtil.DEFAULT_CALORIES_PER_DAY, true, EnumSet.of(role, roles)); } diff --git a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java new file mode 100644 index 000000000000..77c0ba8f639d --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java @@ -0,0 +1,42 @@ +package ru.javawebinar.topjava.repository.jdbc; + +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.repository.UserMealRepository; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * User: gkislin + * Date: 26.08.2014 + */ + +@Repository +public class JdbcUserMealRepositoryImpl implements UserMealRepository { + + @Override + public UserMeal save(UserMeal UserMeal, int userId) { + return null; + } + + @Override + public boolean delete(int id, int userId) { + return false; + } + + @Override + public UserMeal get(int id, int userId) { + return null; + } + + @Override + public List getAll(int userId) { + return null; + } + + @Override + public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { + return null; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java b/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java new file mode 100644 index 000000000000..8d4a6cc3c719 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java @@ -0,0 +1,28 @@ +package ru.javawebinar.topjava.util; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.ResourceLoader; +import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; + +import javax.sql.DataSource; + +/** + * User: gkislin + * Date: 26.08.2014 + */ +public class DbPopulator extends ResourceDatabasePopulator { + private static final ResourceLoader RESOURCE_LOADER = new DefaultResourceLoader(); + + @Autowired + private DataSource dataSource; + + public DbPopulator(String scriptLocation) { + super(RESOURCE_LOADER.getResource(scriptLocation)); + } + + public void execute() { + DatabasePopulatorUtils.execute(this, dataSource); + } +} diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml index 328aaa11684d..3688d3a84cd8 100644 --- a/src/main/resources/spring/spring-app.xml +++ b/src/main/resources/spring/spring-app.xml @@ -14,7 +14,7 @@ - + diff --git a/src/main/resources/spring/spring-db.xml b/src/main/resources/spring/spring-db.xml index a1f6b09a7464..051f225300cd 100644 --- a/src/main/resources/spring/spring-db.xml +++ b/src/main/resources/spring/spring-db.xml @@ -6,6 +6,10 @@ + + + + diff --git a/src/test/java/ru/javawebinar/topjava/MealTestData.java b/src/test/java/ru/javawebinar/topjava/MealTestData.java new file mode 100644 index 000000000000..ac44047caa52 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/MealTestData.java @@ -0,0 +1,14 @@ +package ru.javawebinar.topjava; + +import ru.javawebinar.topjava.matcher.ModelMatcher; +import ru.javawebinar.topjava.model.UserMeal; + +/** + * GKislin + * 13.03.2015. + */ +public class MealTestData { + + public static final ModelMatcher MATCHER = new ModelMatcher<>(UserMeal::toString); + +} diff --git a/src/test/java/ru/javawebinar/topjava/UserTestData.java b/src/test/java/ru/javawebinar/topjava/UserTestData.java index bb8a9fb19788..c6855207f44e 100644 --- a/src/test/java/ru/javawebinar/topjava/UserTestData.java +++ b/src/test/java/ru/javawebinar/topjava/UserTestData.java @@ -1,16 +1,75 @@ package ru.javawebinar.topjava; +import ru.javawebinar.topjava.matcher.ModelMatcher; import ru.javawebinar.topjava.model.Role; import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.util.UserMealsUtil; + +import java.util.EnumSet; +import java.util.Objects; +import java.util.Set; + +import static ru.javawebinar.topjava.model.BaseEntity.START_SEQ; /** * GKislin * 24.09.2015. */ public class UserTestData { - public static final int USER_ID = 1; - public static final int ADMIN_ID = 2; + public static final int USER_ID = START_SEQ; + public static final int ADMIN_ID = START_SEQ + 1; public static final User USER = new User(USER_ID, "User", "user@yandex.ru", "password", Role.ROLE_USER); public static final User ADMIN = new User(ADMIN_ID, "Admin", "admin@gmail.com", "admin", Role.ROLE_ADMIN); + + public static final ModelMatcher MATCHER = new ModelMatcher<>(u -> ((u instanceof TestUser) ? (TestUser) u : new TestUser(u))); + + public static class TestUser extends User { + + public TestUser(User u) { + this(u.getId(), u.getName(), u.getEmail(), u.getPassword(), u.getCaloriesPerDay(), u.isEnabled(), u.getRoles()); + } + + public TestUser(String name, String email, String password, Role role, Role... roles) { + this(null, name, email, password, UserMealsUtil.DEFAULT_CALORIES_PER_DAY, true, EnumSet.of(role, roles)); + } + + public TestUser(Integer id, String name, String email, String password, int caloriesPerDay, boolean enabled, Set roles) { + super(id, name, email, password, caloriesPerDay, enabled, roles); + } + + public User asUser() { + return new User(this); + } + + @Override + public String toString() { + return "User (" + + "id=" + id + + ", email=" + email + + ", name=" + name + + ", enabled=" + enabled + + ", password=" + password + + ", authorities=" + roles + + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + TestUser that = (TestUser) o; + return Objects.equals(this.password, that.password) + && Objects.equals(this.id, that.id) + && Objects.equals(this.name, that.name) + && Objects.equals(this.email, that.email) + && Objects.equals(this.caloriesPerDay, that.caloriesPerDay) + && Objects.equals(this.enabled, that.enabled); + } + } } diff --git a/src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java b/src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java new file mode 100644 index 000000000000..f2b18b2e34bd --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java @@ -0,0 +1,34 @@ +package ru.javawebinar.topjava.matcher; + +import org.junit.Assert; + +import java.util.Collection; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * GKislin + * 06.01.2015. + * + * @param : entity + * @param : testEntity, converter result for compare + */ +public class ModelMatcher { + protected Function entityConverter; + + public ModelMatcher(Function entityConverter) { + this.entityConverter = entityConverter; + } + + public void assertEquals(T expected, T actual) { + Assert.assertEquals(entityConverter.apply(expected), entityConverter.apply(actual)); + } + + public void assertCollectionEquals(Collection expected, Collection actual) { + Assert.assertEquals(map(expected, entityConverter), map(actual, entityConverter)); + } + + public static Collection map(Collection collection, Function converter) { + return collection.stream().map(converter).collect(Collectors.toList()); + } +} diff --git a/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java new file mode 100644 index 000000000000..c9c6eb8fd0f0 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java @@ -0,0 +1,95 @@ +package ru.javawebinar.topjava.service; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import ru.javawebinar.topjava.UserTestData.*; +import ru.javawebinar.topjava.model.Role; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.util.DbPopulator; +import ru.javawebinar.topjava.util.exception.NotFoundException; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import static ru.javawebinar.topjava.UserTestData.*; + +@ContextConfiguration({ + "classpath:spring/spring-app.xml", + "classpath:spring/spring-db.xml" +}) +@RunWith(SpringJUnit4ClassRunner.class) +public class UserServiceTest { + + @Autowired + protected UserService service; + + @Autowired + private DbPopulator dbPopulator; + + @Before + public void setUp() throws Exception { + dbPopulator.execute(); + } + + @Test + public void testSave() throws Exception { + TestUser tu = new TestUser(null, "New", "new@gmail.com", "newPass", 1555, false, Collections.singleton(Role.ROLE_USER)); + User created = service.save(tu.asUser()); + tu.setId(created.getId()); + MATCHER.assertCollectionEquals(Arrays.asList(ADMIN, tu, USER), service.getAll()); + } + + @Test(expected = DataAccessException.class) + public void testDuplicateMailSave() throws Exception { + service.save(new TestUser("Duplicate", "user@yandex.ru", "newPass", Role.ROLE_USER).asUser()); + } + + @Test + public void testDelete() throws Exception { + service.delete(USER_ID); + MATCHER.assertCollectionEquals(Collections.singletonList(ADMIN), service.getAll()); + } + + @Test(expected = NotFoundException.class) + public void testNotFoundDelete() throws Exception { + service.delete(1); + } + + @Test + public void testGet() throws Exception { + User user = service.get(USER_ID); + MATCHER.assertEquals(USER, user); + } + + @Test(expected = NotFoundException.class) + public void testGetNotFound() throws Exception { + service.get(1); + } + + @Test + public void testGetByEmail() throws Exception { + User user = service.getByEmail("user@yandex.ru"); + MATCHER.assertEquals(USER, user); + } + + @Test + public void testGetAll() throws Exception { + Collection all = service.getAll(); + MATCHER.assertCollectionEquals(Arrays.asList(ADMIN, USER), all); + } + + @Test + public void testUpdate() throws Exception { + TestUser updated = new TestUser(USER); + updated.setName("UpdatedName"); + updated.setCaloriesPerDay(330); + service.update(updated.asUser()); + MATCHER.assertEquals(updated, service.get(USER_ID)); + } +} \ No newline at end of file