From d030a1f6a53380b46ba83f294e792379b500a6d1 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 18 Dec 2017 19:07:41 +0300 Subject: [PATCH 001/220] Update lessons --- README.md | 146 ++++++++++++++++++------------ intro.md | 38 -------- lesson/lesson1.md | 103 +++++++++++++++++++++ lesson10.md => lesson/lesson10.md | 0 lesson11.md => lesson/lesson11.md | 0 lesson12.md => lesson/lesson12.md | 19 +++- lesson13.md => lesson/lesson13.md | 0 lesson14.md => lesson/lesson14.md | 0 lesson15.md => lesson/lesson15.md | 0 lesson16.md => lesson/lesson16.md | 0 lesson17.md => lesson/lesson17.md | 0 lesson2.md => lesson/lesson2.md | 4 + lesson3.md => lesson/lesson3.md | 3 + lesson4.md => lesson/lesson4.md | 0 lesson5.md => lesson/lesson5.md | 4 +- lesson6.md => lesson/lesson6.md | 0 lesson7.md => lesson/lesson7.md | 0 lesson8.md => lesson/lesson8.md | 0 lesson9.md => lesson/lesson9.md | 0 lesson1.md | 60 ------------ 20 files changed, 220 insertions(+), 157 deletions(-) delete mode 100644 intro.md create mode 100644 lesson/lesson1.md rename lesson10.md => lesson/lesson10.md (100%) rename lesson11.md => lesson/lesson11.md (100%) rename lesson12.md => lesson/lesson12.md (63%) rename lesson13.md => lesson/lesson13.md (100%) rename lesson14.md => lesson/lesson14.md (100%) rename lesson15.md => lesson/lesson15.md (100%) rename lesson16.md => lesson/lesson16.md (100%) rename lesson17.md => lesson/lesson17.md (100%) rename lesson2.md => lesson/lesson2.md (92%) rename lesson3.md => lesson/lesson3.md (87%) rename lesson4.md => lesson/lesson4.md (100%) rename lesson5.md => lesson/lesson5.md (62%) rename lesson6.md => lesson/lesson6.md (100%) rename lesson7.md => lesson/lesson7.md (100%) rename lesson8.md => lesson/lesson8.md (100%) rename lesson9.md => lesson/lesson9.md (100%) delete mode 100644 lesson1.md diff --git a/README.md b/README.md index 86806493..e288257e 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,120 @@ -# Курс JavaSE + Web - -## Вступительное заниятие - - [Необходимое ПО](intro.md#Необходимое-ПО) - - [Рекомендуемые книги](intro.md#Рекомендуемые-книги) - - [Ресуры в сети](intro.md#Ресуры-в-сети) - - [Вступительное задание](intro.md#Вступительное-задание) - -## Темы курса -### Занятие 1 - - [Разработка ПО](lesson1.md#Разработка-ПО) - - [Обзор языка Java](lesson1.md#Обзор-языка-java) - - [Системы управления версиями. Git](lesson1.md#Системы-управления-версиями-git) - - [Настройка окружения](lesson1.md#Настройка-окружения) - - [Насторойка проекта. Ветка HW1. Debug](lesson1.md#Насторойка-проекта-Ветка-hw1-debug) +# Курс BaseJava (обновленный и переработанный) + +## Разработка Web приложения "База данных резюме" + - используем: Java 8, IntelliJ IDEA, + GitHib/Git, Сервлеты, JSP, JSTL, Tomcat, JUnit, PostgreSQL, GSON, JAXB + - хранение резюме + - в памяти на основе массива, отсортированного массива, списка и ассоциированного массива (Map) + - в файловой системе (File API и Java 7 NIO File API) + - в стандартной и кастомной сериализации Java + - в формате JSON (Google Gson) + - в формате XML (JAXB) + - в реляционной базе PostgreSQL + - деплой веб приложения + - в контейнер сервлетов Tomcat + - в облачный сервис Heroku + +Приложение будет разрабатываться начиная со первого занятия, основываясь на базовых темах курса: +**объектная модель, коллекции, система ввода-вывода, работа с файлами, сериализация, работа с XML, JSON, SQL, персистентность в базу данных (PostgreSQL), сервлеты, HTML/JSP/JSTL, веб-контейнер Tomcat, модульные тесты JUnit, java.util.Logging, система контроля версий Git.** + +> Любое знание стоит воспринимать как подобие семантического дерева: убедитесь в том, что понимаете фундаментальные принципы, то есть ствол и крупные ветки, прежде чем лезть в мелкие листья-детали. Иначе последним не на чем будет держаться. + +[*— Илон Маск](https://ru.wikipedia.org/wiki/Маск,_Илон) + +# Изучайте [первое открытое занятие](lesson/lesson1.md). +### Внизу урока есть первое домашнее задание, по которому можно оценить свой уровень готовности к проекту. + +## Программа +### [Регистрация](http://javaops.ru/reg/basejava) +### Открытое занятие 1 + - [Презентация проекта](lesson/lesson1.md#-Вебинар-ПРЕЗЕНТАЦИЯ-обучения) + - [Разработка ПО](lesson/lesson1.md#-1-Разработка-ПО) + - [Обзор языка Java](lesson/lesson1.md#-3-Обзор-языка-java) + - [Системы управления версиями. Git](lesson/lesson1.md#-4-Системы-управления-версиями-git) + - [ПЕРВОЕ ДОМАШНЕЕ ЗАДАНИЕ](lesson/lesson1.md#Домашнее-задание-hw1) ### Занятие 2 - - [Принципы ООП](lesson2.md#Принципы-ООП) - - [Структура памяти: куча, стек, регистры, константы](lesson2.md#Структура-памяти-куча-стек-регистры-константы) - - [Типы данных. Пакеты](lesson2.md#Типы-данных-Пакеты) + - [Принципы ООП](lesson/lesson2.md#Принципы-ООП) + - [Структура памяти: куча, стек, регистры, константы](lesson/lesson2.md#Структура-памяти-куча-стек-регистры-константы) + - [Типы данных. Пакеты](lesson/lesson2.md#Типы-данных-Пакеты) ### Занятие 3 - - [Объектная модель в Java](lesson3.md#Объектная-модель-в-java) - - [Сложность алгоритмов](lesson3.md#Сложность-алгоритмов) - + - [Объектная модель в Java](lesson/lesson3.md#Объектная-модель-в-java) + - [Сложность алгоритмов](lesson/lesson3.md#Сложность-алгоритмов) + - [Паттерн проектирования Шаблонный метод](https://github.com/JavaOPs/JavaSE-Web/blob/master/lesson/lesson3.md#Паттерн-проектирования-Шаблонный-метод) + ### Занятие 4 - - [Работа со строками](lesson4.md#Работа-со-строками) - - [Исключения](lesson4.md#Исключения) - - [Reflection. Аннотации. Модульное тестирование](lesson4.md#reflection-Аннотации-Модульное-тестирование) + - [Работа со строками](lesson/lesson4.md#Работа-со-строками) + - [Исключения](lesson/lesson4.md#Исключения) + - [Reflection. Аннотации. Модульное тестирование](lesson/lesson4.md#reflection-Аннотации-Модульное-тестирование) ### Занятие 5 - - [Контейнеры/коллекции](lesson5.md#Контейнерыколлекции) + - [Контейнеры/коллекции](lesson/lesson5.md#Контейнерыколлекции) ### Занятие 6 - - [Iterator / Iterable. Вложенные, внутренние, локальные и анонимные классы](lesson6.md#iterator--iterable-Вложенные-внутренние-локальные-и-анонимные-классы) - - [Новое в Java 8](lesson6.md#Новое-в-java-8) + - [Iterator / Iterable. Вложенные, внутренние, локальные и анонимные классы](lesson/lesson6.md#iterator--iterable-Вложенные-внутренние-локальные-и-анонимные-классы) + - [Новое в Java 8](lesson/lesson6.md#Новое-в-java-8) ### Занятие 7 - - [Параметризация. Стирание типов](lesson7.md#Параметризация-Стирание-типов) - - [Логирование](lesson7.md#Логирование) - - [Синглетон, Enum](lesson7.md#Синглетон-enum) + - [Параметризация. Стирание типов](lesson/lesson7.md#Параметризация-Стирание-типов) + - [Логирование](lesson/lesson7.md#Логирование) + - [Синглетон, Enum](lesson/lesson7.md#Синглетон-enum) ### Занятие 8 - - [Работа с датами и временем](lesson8.md#Работа-с-датами-и-временем) - - [Работа с файлами и ресурсами](lesson8.md#Работа-с-файлами-и-ресурсами) + - [Работа с датами и временем](lesson/lesson8.md#Работа-с-датами-и-временем) + - [Работа с файлами и ресурсами](lesson/lesson8.md#Работа-с-файлами-и-ресурсами) ### Занятие 9 - - [Ввод/вывод](lesson9.md#Вводвывод) - - [Сериализация](lesson9.md#Сериализация) - - [NIO](lesson9.md#nio) - - [Основы Java 8 Stream API](lesson9.md#Основы-java-8-stream-api) + - [Ввод/вывод](lesson/lesson9.md#Вводвывод) + - [Сериализация](lesson/lesson9.md#Сериализация) + - [NIO](lesson/lesson9.md#nio) + - [Основы Java 8 Stream API](lesson/lesson9.md#Основы-java-8-stream-api) ### Занятие 10 - - [Формат XML. Работа с XML в Java](lesson10.md#Формат-xml-Работа-с-xml-в-java) - - [JSON](lesson10.md#json) - - [DataInputStream / DataOutputStream](lesson10.md#datainputstream--dataoutputstream) + - [Формат XML. Работа с XML в Java](lesson/lesson10.md#Формат-xml-Работа-с-xml-в-java) + - [JSON](lesson/lesson10.md#json) + - [DataInputStream / DataOutputStream](lesson/lesson10.md#datainputstream--dataoutputstream) ### Занятие 11 - - [Многопоточность. Параллельное выполнение.](lesson11.md#Многопоточность-Параллельное-выполнение) - - [Потоки. Синхронизация](lesson11.md#Потоки-Синхронизация) - - [Ленивая инициализация, JMM](lesson11.md#Ленивая-инициализация-jmm) + - [Многопоточность. Параллельное выполнение.](lesson/lesson11.md#Многопоточность-Параллельное-выполнение) + - [Потоки. Синхронизация](lesson/lesson11.md#Потоки-Синхронизация) + - [Ленивая инициализация, JMM](lesson/lesson11.md#Ленивая-инициализация-jmm) ### Занятие 12 - - [java.util.concurrent](lesson12.md#javautilconcurrent) + - [java.util.concurrent](lesson/lesson12.md#javautilconcurrent) ### Занятие 13 - - [Базы данных. Реляционные СУБД. PostgreSQL](lesson13.md#Базы-данных-Реляционные-СУБД-postgresql) - - [Конфигурирование данных в Java проекте](lesson13.md#Конфигурирование-данных-в-java-проекте) - - [Подключение DB в проект](lesson13.md#Подключение-db-в-проект) + - [Базы данных. Реляционные СУБД. PostgreSQL](lesson/lesson13.md#Базы-данных-Реляционные-СУБД-postgresql) + - [Конфигурирование данных в Java проекте](lesson/lesson13.md#Конфигурирование-данных-в-java-проекте) + - [Подключение DB в проект](lesson/lesson13.md#Подключение-db-в-проект) ### Занятие 14 - - [JOIN](lesson14.md#join) - - [Транзакции](lesson14.md#Транзакции) - - [Установка/запуск Tomcat](lesson14.md#Установказапуск-tomcat) + - [JOIN](lesson/lesson14.md#join) + - [Транзакции](lesson/lesson14.md#Транзакции) + - [Установка/запуск Tomcat](lesson/lesson14.md#Установказапуск-tomcat) ### Занятие 15 - - [HTML, Tomcat](lesson15.md#html-tomcat) - - [Сервлеты](lesson15.md#Сервлеты) + - [HTML, Tomcat](lesson/lesson15.md#html-tomcat) + - [Сервлеты](lesson/lesson15.md#Сервлеты) ### Занятие 16 - - [JSP](lesson16.md#jsp) - - [JSTL](lesson16.md#jstl) + - [JSP](lesson/lesson16.md#jsp) + - [JSTL](lesson/lesson16.md#jstl) ### Занятие 17 - - [Деплой в Heroku](lesson17.md#Деплой-в-heroku) - - [Classloader](lesson17.md#classloader) - - [Обзор Java Enterprise](lesson17.md#Обзор-java-enterprise) - + - [Деплой в Heroku](lesson/lesson17.md#Деплой-в-heroku) + - [Classloader](lesson/lesson17.md#classloader) + - [Обзор Java Enterprise](lesson/lesson17.md#Обзор-java-enterprise) + +## Рекомендуемые книги +- YAKOV FAIN: Программирование на Java для начинающих +- Книги по Java: от новичка до профессионала +- Джошуа Блох: Java. Эффективное программирование, 2-е издание +- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования +- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL. + +## Ресуры в сети +- [Руководство по Java Core](http://proselyte.net/tutorials/java-core/) +- [Java. Базовый курс](https://stepik.org/course/Java-Базовый-курс-187) +- intuit: Программирование на Java +- Основы программирования на Java: учебное пособие diff --git a/intro.md b/intro.md deleted file mode 100644 index c929bead..00000000 --- a/intro.md +++ /dev/null @@ -1,38 +0,0 @@ - -# Вступительное занятие - -## Необходимое ПО -- JDK8 -- Git -- Аккаунт GitHub -- IntelliJ IDEA - -> Выбирать Ultimate, 30 days trial (нам понадобится Git, JavaScript, Tomcat, JSP). Учебный ключ выдается на первом занятии. - -## Рекомендуемые книги -- YAKOV FAIN: Программирование на Java для начинающих -- Книги по Java: от новичка до профессионала -- Джошуа Блох: Java. Эффективное программирование, 2-е издание -- Гамма, Хелм, Джонсон: Приемы объектно-ориентированного проектирования. Паттерны проектирования -- Редмонд Э.: Семь баз данных за семь недель. Введение в современные базы данных и идеологию NoSQL. - -## Ресуры в сети -- intuit: Программирование на Java -- Основы программирования на Java: учебное пособие - -## Вступительное задание -- Установите ПО: Git, Java 8, IntelliJ IDEA -- Создайте локальную копию нашего проекта: `git clone https://github.com/JavaWebinar/JavaSE-Web.git` -> в результате у вас должен появится каталог `JavaSE-Web` - -- В IntelliJ IDEA создайте новый проект, выбрав каталог `JavaSE-Web` - -![image](https://cloud.githubusercontent.com/assets/18701152/14917746/38c4a20a-0e29-11e6-8985-c57911da57c4.png) - -![image](https://cloud.githubusercontent.com/assets/18701152/14917800/71887238-0e29-11e6-9830-e557901892b4.png) - -![image](https://cloud.githubusercontent.com/assets/18701152/14917769/5025e29c-0e29-11e6-9c7b-70b82966ccbe.png) - -- Реализуйте класс `ArrayStorage`: хранение резюме на основе массива (методы `clear, get, save, delete, getAll, size`). -- Протестируйте вашу реализацию, запустив `MainTestArrayStorage.main()`: в IDEA слева на полях зеленая стрелка. -- Протестируйте вашу реализацию интерактивно с помощью `MainArray.main()`. diff --git a/lesson/lesson1.md b/lesson/lesson1.md new file mode 100644 index 00000000..afeca7ff --- /dev/null +++ b/lesson/lesson1.md @@ -0,0 +1,103 @@ +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар ПРЕЗЕНТАЦИЯ обучения](https://drive.google.com/file/d/0B_4NpoQW1xfpNzdqT2hOcUJ6TGs) +- [Так будет выглядеть мое резюме в разрабатываемом на этом проекте приложении](https://javawebinar.github.io/) + +## Для участия необходимо: +- Установить JDK8 (выбрать Accept License Agreement) +- Установить систему управления версиями Git (опции по умолчанию) +- Создать аккаунт на GitHub +- Установить IntelliJ IDEA +> Выбирать Ultimate, 30 days trial (нам понадобится SQL, Tomcat, JSP). Ключ на 6 месяцев выдается на первом занятии. + +# Первое открытое занятие +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) +- [Книга: Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) +- [Размеры проектов в количестве строк кода](https://medium.freecodecamp.com/the-biggest-codebases-in-history-a128bb3eea73) +- [Соглашения по именованию](http://www.intuit.ru/studies/courses/16/16/lecture/27113?page=4) +- [Методологии разработки ПО](https://dou.ua/forums/topic/14015/) + - **Доступ из России через прокси (например [friGate CDN](https://chrome.google.com/webstore/detail/frigate-cdn-smooth-access/mbacbcfdfaapbcnlnbmciiaakomhkbkb))** +- [Ещё раз про семь основных методологий разработки](https://habrahabr.ru/company/edison/blog/269789/) + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. [Обзор инструментов и технологий](https://drive.google.com/file/d/0B_4NpoQW1xfpTXJYU2xZbjN2d2M) +- [Bash — шпаргалка для начинающих](https://tproger.ru/translations/bash-cheatsheet) +- [Типичный тест SQL на собеседованиях](https://habrahabr.ru/post/181033/) +- **Обновление!!**[Что и почему используют Java-разработчики: опрос RebelLabs](https://jug.ru/2017/12/rebellabs-report/) + - [Java Tools and Technologies Landscape Report 2016](https://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/) + - [Java Tools and Technologies Landscape for 2014](http://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-for-2014) +- Дополнительно: + - [Автоматизированные сборки в Java](http://www.quizful.net/post/automated-builds-java) + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/open?id=0B_4NpoQW1xfpTU5SSElhUjlGNnc) +- [Java](http://ru.wikipedia.org/wiki/Java), [JVM](http://ru.wikipedia.org/wiki/Виртуальная_машина_Java), [JIT-компиляция](http://ru.wikipedia.org/wiki/JIT) +- [Что такое Java? История создания](http://www.intuit.ru/studies/courses/16/16/lecture/27105) +- [Programming languages TIOBE Index](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) + +![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) + +- [Java Microbenchmark JMH](https://github.com/JavaOPs/masterjava#Занятие-2) используем на курсе Masterjava +- [Oracle Java8 Home](http://docs.oracle.com/javase/8/docs/index.html) +- [ME](http://ru.wikipedia.org/wiki/Java_Platform,_Micro_Edition), [SE](http://en.wikipedia.org/wiki/Java_Platform,_Standard_Edition) (русский), [EE](http://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition) ([русский](http://ru.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition)) +- Дополнительно: + - [Java version and vendor data analyzed](https://plumbr.eu/blog/java/java-version-and-vendor-data-analyzed-2016-edition) + - [Most Popular Java EE Servers](https://dzone.com/articles/most-popular-java-ee-servers-2016-edition) + - [Понимаем основы Java garbage collection](https://ggenikus.github.io/blog/2014/05/04/gc) + +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s) +### Настройка проекта +- Создать на GitHub репозиторий `basejava` +- git занести в переменная окружения PATH, перезапустить cmd +- Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git` +- Перейти в каталог проекта: `cd basejava` +- Настроить git в локальном проекте на свой проект в GitHub: + - `git remote -v` + - `git remote set-url origin https://github.com/[твой_GITHUB_аккаунт]/[твой_репозиторий].git` - настройка pull + - `git remote set-url --push origin https://github.com/[твой_GITHUB_аккаунт]/[твой_репозиторий].git` - настройка push + - `git push -u origin master` + +### Система управления версиями. VCS/DVSC + +![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) + +- Ресурсы: + - Интерактивная Git обучалка + - Еще одна интерактивная обучалка, по русски + - Книга Git + - Working with remote repositories + - Видео по обучению Git + - Git Overview + - Видеокурс по Git + - [Основы Git за 20 минут](https://www.youtube.com/watch?v=TMeZGvtQnT8) +- [Популярность разный VSC](http://www.netinstructions.com/the-case-for-git/) +- Книга по Git + +## Домашнее задание HW1 +- Создайте в IntelliJ IDEA новый проект, выбрав каталог `basejava`, **в котором находится локальная копия моего проекта (необходимо выполнить все действия выше по настройке проекта)**: + +![newproject](https://user-images.githubusercontent.com/13649199/27245917-c66f0b5a-52f6-11e7-98dc-f88d0198b5c4.png) + +![next](https://user-images.githubusercontent.com/13649199/27245921-c88b4570-52f6-11e7-83a3-e52627468be7.png) + +![finish](https://user-images.githubusercontent.com/13649199/27245924-cab3618e-52f6-11e7-9655-4293149b4126.png) + +- Реализуйте класс `ArrayStorage` (вставте код в пустые методы класса): работа с `Resume` на основе массива (методы `clear, get, save, delete, getAll, size`) + - Не используйте в решении коллекции, реализацию на их основе мы добавим позднее + - Не меняйте синтаксис методов `ArrayStorage` и не меняйте класс `Resume`. Нужет только код внутри готовых методов `ArrayStorage` + - [Массивы](http://study-java.ru/uroki-java/massivy-v-java/) + - [Java массивы](http://info.javarush.ru/javarush_articles/2015/12/10/Java-%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D1%8B.html) +- Протестируйте вашу реализацию, запустив `MainTestArrayStorage.main()`: в IDEA слева на полях зеленая стрелка. +- Протестируйте вашу реализацию интерактивно с помощью `MainArray.main()`. +- Дополнительные материалы по IntelliJ IDEA + - Idea Wiki (поставить кодировку UTF-8, поменять фонт по умолчанию на DejaVu) + - Отладчик IntelliJ IDEA + - Эффективная работа с кодом в IntelliJ IDEA + +### Optional +- Модифицировать класс `ArrayStorage`: хранить все резюме в начале storage (без дырок null), чтобы не перебирать каждый раз все 10000 элементов. +``` +Хранеие резюме в storage (от 0 до size-1 элементов null нет): + +r1, r2, r3,..., rn, null, null,..., null +<---- size -----> +<---- storage.length (10000)----------> +``` +- Посмотреть на класс `Arrays`. Там есть полезные вещи, которые могут упростить код `ArrayStorage`. +- Протестируйте реализацию, запустив MainArray.main(): в IDEA слева на полях зеленая стрелка. diff --git a/lesson10.md b/lesson/lesson10.md similarity index 100% rename from lesson10.md rename to lesson/lesson10.md diff --git a/lesson11.md b/lesson/lesson11.md similarity index 100% rename from lesson11.md rename to lesson/lesson11.md diff --git a/lesson12.md b/lesson/lesson12.md similarity index 63% rename from lesson12.md rename to lesson/lesson12.md index c3a99007..47156cdd 100644 --- a/lesson12.md +++ b/lesson/lesson12.md @@ -9,10 +9,27 @@ - Справочник по синхронизаторам java.util.concurrent.* - Использование ThreadLocal переменных +> Замечания по видео: + + ThreadLocal DATE_FORMAT = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + }; + }; + +можно написать через лямбду: + + ThreadLocal.withInitial(() -> new SimpleDateFormat("dd.MM.yyyy HH:mm:ss")); + +А лучше использовать потокобезопасный `DateTimeFormatter` Java 8 Time API: + + DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"); + ## Разбор домашнего задания 10го урока ## Домашнее задание: - Установить PostgreSQL - Посомтреть на реляционные базы данных и SQL: - Введение в базы данных - - Основы SQL \ No newline at end of file + - Основы SQL diff --git a/lesson13.md b/lesson/lesson13.md similarity index 100% rename from lesson13.md rename to lesson/lesson13.md diff --git a/lesson14.md b/lesson/lesson14.md similarity index 100% rename from lesson14.md rename to lesson/lesson14.md diff --git a/lesson15.md b/lesson/lesson15.md similarity index 100% rename from lesson15.md rename to lesson/lesson15.md diff --git a/lesson16.md b/lesson/lesson16.md similarity index 100% rename from lesson16.md rename to lesson/lesson16.md diff --git a/lesson17.md b/lesson/lesson17.md similarity index 100% rename from lesson17.md rename to lesson/lesson17.md diff --git a/lesson2.md b/lesson/lesson2.md similarity index 92% rename from lesson2.md rename to lesson/lesson2.md index e5f33609..1e9066ff 100644 --- a/lesson2.md +++ b/lesson/lesson2.md @@ -5,6 +5,7 @@ - Методология процедурно-ориентированного и объектно-ориентированного программирования - Объекты (cостояние, поведение, уникальность) - Классы. Инкапсуляция. Наследование. Полиморфизм. +- Основы Объектно-Ориентированного Программирования (ООП) - Типы отношений между классами Наследование, агрегация, композиция, ассоциация. - Достоинства/Недостатки ООП. Библиотеки vs фреймворки. - Дополнительно: @@ -30,6 +31,9 @@ - Модификаторы доступа. Область Видимости. ## Домашнее задание + +> Правка к видео: ArrayStorage.delete() - вместо `storage[i] = null` нужно `storage[size-1] = null` + - Прочитать Соглашения по именованию. - Реализовать `ArrayStorage.update` - Сделать проверки: в `update/delete/get` - резюме есть в storage, в `save`- нет в storage: `System.out.println("Resume ...")`. diff --git a/lesson3.md b/lesson/lesson3.md similarity index 87% rename from lesson3.md rename to lesson/lesson3.md index e86bcc05..36b8407f 100644 --- a/lesson3.md +++ b/lesson/lesson3.md @@ -8,12 +8,15 @@ - Object. Контракт equals/hashCode - Интерфейсы - Полиморфизм, abstract +- [Java Core. Вопросы к собеседованию](http://info.javarush.ru/translation/2014/02/12/Java-Core-Вопросы-к-собеседованию-ч-1.html) ## Сложность алгоритмов - Алгоритмы и структуры данных для начинающих: сложность алгоритмов - Time complexity - Временная сложность алгоритма - Вычислительная сложность + +## Паттерн проектирования Шаблонный метод - Шаблонный метод ## Домашнее задание diff --git a/lesson4.md b/lesson/lesson4.md similarity index 100% rename from lesson4.md rename to lesson/lesson4.md diff --git a/lesson5.md b/lesson/lesson5.md similarity index 62% rename from lesson5.md rename to lesson/lesson5.md index fdc77b03..169a361c 100644 --- a/lesson5.md +++ b/lesson/lesson5.md @@ -8,6 +8,8 @@ - Структуры данных в картинках - Инициализация полей в Java - Java собеседование по коллекциям +- [Часто задаваемые на собеседованиях вопросы по классам коллекциям в Java](http://info.javarush.ru/translation/2013/10/08/Часто-задаваемые-на-собеседованиях-вопросы-по-классам-коллекциям-в-Java-Часть-2-.html#1) +- [Собеседование по Java — коллекции](http://javastudy.ru/interview/collections/) ## Домашнее задание -Выделить общий класс `AbstractStorage` и реализовать подклассы `ListStorage` и `MapStorage`. Выбор реализации List и Map за вами. \ No newline at end of file +Выделить общий класс `AbstractStorage` и реализовать подклассы `ListStorage` и `MapStorage`. Выбор реализации List и Map за вами. diff --git a/lesson6.md b/lesson/lesson6.md similarity index 100% rename from lesson6.md rename to lesson/lesson6.md diff --git a/lesson7.md b/lesson/lesson7.md similarity index 100% rename from lesson7.md rename to lesson/lesson7.md diff --git a/lesson8.md b/lesson/lesson8.md similarity index 100% rename from lesson8.md rename to lesson/lesson8.md diff --git a/lesson9.md b/lesson/lesson9.md similarity index 100% rename from lesson9.md rename to lesson/lesson9.md diff --git a/lesson1.md b/lesson1.md deleted file mode 100644 index 0b1fc5c0..00000000 --- a/lesson1.md +++ /dev/null @@ -1,60 +0,0 @@ - -# Первое занятие - -## Разработка ПО. -- Книга: Мифический человеко-месяц -- Методологии разработки ПО -- Ещё раз про семь основных методологий разработки - -## Обзор инструментов и технологий. -- Обзор популярности инструментов и технологий Java за 2014г. -- Дополнительно: - - Автоматизированные сборки в Java - -## Обзор языка Java -- Java, JVM, JIT-компиляция - -![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) - -- Programming languages TIOBE Index -- ME, SE (русский), EE (русский) -- Oracle Java8 Home -- Дополнительно: - - Java version and vendor data analyzed - - Most Popular Java EE Servers - - Что такое Java? История создания - - Понимаем основы Java garbage collection - -## Системы управления версиями. Git. -- Система управления версиями. -- VCS/DVSC. - -![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) - -- Популярность разный VSC -- Книга по Git - -## Настройка окружения -- Idea Wiki (поставить кодировку UTF-8, поменять фонт по умолчанию на DejaVu) -- git занести в переменная окружения PATH, перезапустить cmd -- Создайте локальную копию нашего проекта: `git clone https://github.com/School-IT-Programm/resume-storage.git` -- Перейти в каталог проекта: `cd resume-storage` -- `git remote -v` -- `git remote set-url origin https://github.com/School-IT-Programm/resume-storage.git` - настройка pull -- `git remote set-url --push origin https://github.com/[YouGitHub/YourRepo].git` - настройка push -- `git push -u origin master` - -## Насторойка проекта. Ветка HW1. Debug -- Отладчик IntelliJ IDEA -- Эффективная работа с кодом в IntelliJ IDEA - -## Домашнее задание -- Модифицировать класс `ArrayStorage`: хранить все резюме в начале storage (без дырок null), чтобы не перебирать каждый раз все 10000 элементов. -``` -Хранеие резюме в storage (от 0 до size-1 элементов null нет): - -r1, r2, r3,..., rn, null, null,..., null -<---- size -----> -<---- storage.length ---------------> -``` -- Посмотреть на класс `Arrays`. Там есть полезные вещи, которые могут упростить код `ArrayStorage`. From 4ad719534b7022a5512080ba602d7b8c52fc9f41 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 11 Jan 2018 13:38:14 +0300 Subject: [PATCH 002/220] Update lesson1.md --- lesson/lesson1.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index afeca7ff..00366758 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -1,14 +1,16 @@ +# Первое занятие + ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар ПРЕЗЕНТАЦИЯ обучения](https://drive.google.com/file/d/0B_4NpoQW1xfpNzdqT2hOcUJ6TGs) -- [Так будет выглядеть мое резюме в разрабатываемом на этом проекте приложении](https://javawebinar.github.io/) +#### [Итоговый пример приложения, разрабатываемого в рамках данного курса (на примере резюме Григория Кислина)](https://javawebinar.github.io/) -## Для участия необходимо: -- Установить JDK8 (выбрать Accept License Agreement) -- Установить систему управления версиями Git (опции по умолчанию) -- Создать аккаунт на GitHub -- Установить IntelliJ IDEA -> Выбирать Ultimate, 30 days trial (нам понадобится SQL, Tomcat, JSP). Ключ на 6 месяцев выдается на первом занятии. +### Подготовка рабочего окружения +- Установите [JDK8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) (выбрать Accept License Agreement) +- Установите систему управления версиями [Git](http://git-scm.com/downloads) (опции по умолчанию) +- Создайте аккаунт на [GitHub](https://github.com/) +- Для удобной навигации по файлам на GitHub установите расширение для браузера - [Octotree](https://habrahabr.ru/post/223527/) +- Установите [IntelliJ IDEA Ultimate](http://www.jetbrains.com/idea/download/index.html) +> Данная среда разработки является платным продуктом, рассчитанным на 30 дней пробного бесплатного использования. Для выполнения заданий в этой IDE каждый участник курса получит ключ на 6 месяцев -# Первое открытое занятие ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) - [Книга: Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) - [Размеры проектов в количестве строк кода](https://medium.freecodecamp.com/the-biggest-codebases-in-history-a128bb3eea73) @@ -42,10 +44,10 @@ - [Понимаем основы Java garbage collection](https://ggenikus.github.io/blog/2014/05/04/gc) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s) -### Настройка проекта -- Создать на GitHub репозиторий `basejava` -- git занести в переменная окружения PATH, перезапустить cmd -- Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git` +### *Настройка проекта* +- Создайте на GitHub репозиторий с названием `basejava` +- [Занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите cmd +- Создайте локальную копию ЭТОГО проекта: `git clone https://github.com/JavaOps/basejava.git` - Перейти в каталог проекта: `cd basejava` - Настроить git в локальном проекте на свой проект в GitHub: - `git remote -v` From 1f2aaea9db8f2537b3634c68190817b9409a37cc Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 11 Jan 2018 13:38:48 +0300 Subject: [PATCH 003/220] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 00366758..5770d550 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -44,7 +44,7 @@ - [Понимаем основы Java garbage collection](https://ggenikus.github.io/blog/2014/05/04/gc) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s) -### *Настройка проекта* +### Настройка проекта - Создайте на GitHub репозиторий с названием `basejava` - [Занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите cmd - Создайте локальную копию ЭТОГО проекта: `git clone https://github.com/JavaOps/basejava.git` From ef606000ecdf28abe6c86e8ea2c89a168e5af92d Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 12 Apr 2018 21:19:54 +0300 Subject: [PATCH 004/220] Update lesson01 --- lesson/lesson1.md | 112 ++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 58 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 5770d550..19217751 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -1,6 +1,6 @@ # Первое занятие -## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар ПРЕЗЕНТАЦИЯ обучения](https://drive.google.com/file/d/0B_4NpoQW1xfpNzdqT2hOcUJ6TGs) +## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) [Вебинар-презентация обучения на проекте BaseJava](https://drive.google.com/file/d/0B_4NpoQW1xfpNzdqT2hOcUJ6TGs) #### [Итоговый пример приложения, разрабатываемого в рамках данного курса (на примере резюме Григория Кислина)](https://javawebinar.github.io/) ### Подготовка рабочего окружения @@ -12,94 +12,90 @@ > Данная среда разработки является платным продуктом, рассчитанным на 30 дней пробного бесплатного использования. Для выполнения заданий в этой IDE каждый участник курса получит ключ на 6 месяцев ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) -- [Книга: Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) -- [Размеры проектов в количестве строк кода](https://medium.freecodecamp.com/the-biggest-codebases-in-history-a128bb3eea73) -- [Соглашения по именованию](http://www.intuit.ru/studies/courses/16/16/lecture/27113?page=4) +- [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) (wiki) +- [Размеры проектов в количестве строк кода [eng]](https://medium.freecodecamp.com/the-biggest-codebases-in-history-a128bb3eea73) +- [Соглашения по оформлению кода [eng]](https://google.github.io/styleguide/javaguide.html) - [Методологии разработки ПО](https://dou.ua/forums/topic/14015/) - - **Доступ из России через прокси (например [friGate CDN](https://chrome.google.com/webstore/detail/frigate-cdn-smooth-access/mbacbcfdfaapbcnlnbmciiaakomhkbkb))** - [Ещё раз про семь основных методологий разработки](https://habrahabr.ru/company/edison/blog/269789/) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 2. [Обзор инструментов и технологий](https://drive.google.com/file/d/0B_4NpoQW1xfpTXJYU2xZbjN2d2M) - [Bash — шпаргалка для начинающих](https://tproger.ru/translations/bash-cheatsheet) +- [Интерактивный курс по SQL](http://www.sql-ex.ru/) - [Типичный тест SQL на собеседованиях](https://habrahabr.ru/post/181033/) - **Обновление!!**[Что и почему используют Java-разработчики: опрос RebelLabs](https://jug.ru/2017/12/rebellabs-report/) - [Java Tools and Technologies Landscape Report 2016](https://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/) - [Java Tools and Technologies Landscape for 2014](http://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-for-2014) -- Дополнительно: - - [Автоматизированные сборки в Java](http://www.quizful.net/post/automated-builds-java) +- **Дополнительно:** + - [Автоматизированная сборка проекта в Java](http://spring-projects.ru/guides/maven/) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 3. [Обзор языка Java](https://drive.google.com/open?id=0B_4NpoQW1xfpTU5SSElhUjlGNnc) -- [Java](http://ru.wikipedia.org/wiki/Java), [JVM](http://ru.wikipedia.org/wiki/Виртуальная_машина_Java), [JIT-компиляция](http://ru.wikipedia.org/wiki/JIT) +- [Java](http://ru.wikipedia.org/wiki/Java), [JVM](http://ru.wikipedia.org/wiki/Виртуальная_машина_Java), [JIT-компиляция](http://ru.wikipedia.org/wiki/JIT) (wiki) - [Что такое Java? История создания](http://www.intuit.ru/studies/courses/16/16/lecture/27105) - [Programming languages TIOBE Index](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html) ![jvm](https://cloud.githubusercontent.com/assets/18701152/15219296/e6c67e86-186b-11e6-986f-651a87deec6c.png) -- [Java Microbenchmark JMH](https://github.com/JavaOPs/masterjava#Занятие-2) используем на курсе Masterjava +- [ME](http://ru.wikipedia.org/wiki/Java_Platform,_Micro_Edition), [SE](https://ru.wikipedia.org/wiki/Java_Platform,_Standard_Edition), [EE](http://ru.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition) (wiki) +- [Java Microbenchmark JMH](http://openjdk.java.net/projects/code-tools/jmh/) (используем на курсе [MasterJava](https://github.com/JavaWebinar/masterjava#Занятие-2)) - [Oracle Java8 Home](http://docs.oracle.com/javase/8/docs/index.html) -- [ME](http://ru.wikipedia.org/wiki/Java_Platform,_Micro_Edition), [SE](http://en.wikipedia.org/wiki/Java_Platform,_Standard_Edition) (русский), [EE](http://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition) ([русский](http://ru.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition)) -- Дополнительно: - - [Java version and vendor data analyzed](https://plumbr.eu/blog/java/java-version-and-vendor-data-analyzed-2016-edition) - - [Most Popular Java EE Servers](https://dzone.com/articles/most-popular-java-ee-servers-2016-edition) +- **Дополнительно:** + - [Java version and vendor data analyzed 2017](https://plumbr.io/blog/java/java-version-and-vendor-data-analyzed-2017-edition) + - [Most popular Java application servers: 2017 edition](https://plumbr.io/blog/java/most-popular-java-application-servers-2017-edition) - [Понимаем основы Java garbage collection](https://ggenikus.github.io/blog/2014/05/04/gc) ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 4. [Системы управления версиями. Git](https://drive.google.com/file/d/0B9Ye2auQ_NsFSUNrdVc0bDZuX2s) + +![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) + + - [Система управления версиями](https://ru.wikipedia.org/wiki/Система_управления_версиями) (wiki) + - [Сравнение разных VCS](https://biz30.timedoctor.com/ru/cистема-контроля-версий/) + - [Git обучалка](https://githowto.com/ru) + - [Интерактивная Git обучалка (в настройках выберите русский язык)](http://learngitbranching.js.org) + - [Официальная книга про Git](https://git-scm.com/book/ru/v2) + - [Working with remote repositories](https://illustrated-git.readthedocs.org/en/latest/#working-with-remote-repositories) + - [Базовый курс по обучению Git](https://www.youtube.com/playlist?list=PLIU76b8Cjem5B3sufBJ_KFTpKkMEvaTQR) (youtube) + - [Git. Быстрый старт](https://www.youtube.com/watch?v=4-NX17Ip-xQ&list=PLmRNNqEA7JoM77hOJkPrLOfJQGizCLR3P) (youtube) + ### Настройка проекта - Создайте на GitHub репозиторий с названием `basejava` -- [Занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите cmd -- Создайте локальную копию ЭТОГО проекта: `git clone https://github.com/JavaOps/basejava.git` -- Перейти в каталог проекта: `cd basejava` -- Настроить git в локальном проекте на свой проект в GitHub: +- Откройте консоль (терминал) у себя на компьютере +- [Занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите консоль +- Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git` +- Перейдите в каталог проекта: `cd basejava` +- Настройте git в локальном проекте на свой проект в GitHub: - `git remote -v` - - `git remote set-url origin https://github.com/[твой_GITHUB_аккаунт]/[твой_репозиторий].git` - настройка pull - - `git remote set-url --push origin https://github.com/[твой_GITHUB_аккаунт]/[твой_репозиторий].git` - настройка push + - `git remote set-url origin url_на_твой_basejava-репозиторий.git` - настройка pull + - `git remote set-url --push origin url_на_твой_basejava-репозиторий.git` - настройка push - `git push -u origin master` -### Система управления версиями. VCS/DVSC - -![image](https://cloud.githubusercontent.com/assets/18701152/15219746/9295a2fe-186d-11e6-876b-c61cc9be71e4.png) - -- Ресурсы: - - Интерактивная Git обучалка - - Еще одна интерактивная обучалка, по русски - - Книга Git - - Working with remote repositories - - Видео по обучению Git - - Git Overview - - Видеокурс по Git - - [Основы Git за 20 минут](https://www.youtube.com/watch?v=TMeZGvtQnT8) -- [Популярность разный VSC](http://www.netinstructions.com/the-case-for-git/) -- Книга по Git - ## Домашнее задание HW1 -- Создайте в IntelliJ IDEA новый проект, выбрав каталог `basejava`, **в котором находится локальная копия моего проекта (необходимо выполнить все действия выше по настройке проекта)**: +- Создайте в IntelliJ IDEA новый проект, выбрав каталог `basejava`, который вы клонировали ранее к себе на компьютер: -![newproject](https://user-images.githubusercontent.com/13649199/27245917-c66f0b5a-52f6-11e7-98dc-f88d0198b5c4.png) +![newproject](https://user-images.githubusercontent.com/29703461/38273513-d1f7ce52-3794-11e8-829c-305212c25be7.png) -![next](https://user-images.githubusercontent.com/13649199/27245921-c88b4570-52f6-11e7-83a3-e52627468be7.png) +![next](https://user-images.githubusercontent.com/29703461/38273546-e712a6fe-3794-11e8-9850-29287b46a8a0.png) -![finish](https://user-images.githubusercontent.com/13649199/27245924-cab3618e-52f6-11e7-9655-4293149b4126.png) +![next1](https://user-images.githubusercontent.com/29703461/38273584-00e07dc2-3795-11e8-9006-3109f949cf33.png) -- Реализуйте класс `ArrayStorage` (вставте код в пустые методы класса): работа с `Resume` на основе массива (методы `clear, get, save, delete, getAll, size`) - - Не используйте в решении коллекции, реализацию на их основе мы добавим позднее - - Не меняйте синтаксис методов `ArrayStorage` и не меняйте класс `Resume`. Нужет только код внутри готовых методов `ArrayStorage` - - [Массивы](http://study-java.ru/uroki-java/massivy-v-java/) - - [Java массивы](http://info.javarush.ru/javarush_articles/2015/12/10/Java-%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2%D1%8B.html) -- Протестируйте вашу реализацию, запустив `MainTestArrayStorage.main()`: в IDEA слева на полях зеленая стрелка. -- Протестируйте вашу реализацию интерактивно с помощью `MainArray.main()`. -- Дополнительные материалы по IntelliJ IDEA - - Idea Wiki (поставить кодировку UTF-8, поменять фонт по умолчанию на DejaVu) - - Отладчик IntelliJ IDEA - - Эффективная работа с кодом в IntelliJ IDEA +![finish](https://user-images.githubusercontent.com/29703461/38275669-3e621614-379b-11e8-8b3a-8e0a3ad4c65c.png) -### Optional -- Модифицировать класс `ArrayStorage`: хранить все резюме в начале storage (без дырок null), чтобы не перебирать каждый раз все 10000 элементов. +- Реализуйте класс `ArrayStorage`, организовав хранение резюме на основе массива с методами `save, get, delete, size, clear, getAll` +- При этом храните все резюме в начале `storage` (без дырок в виде `null`), чтобы не перебирать каждый раз все 10000 элементов ``` -Хранеие резюме в storage (от 0 до size-1 элементов null нет): - +Схема хранения резюме в storage (от 0 до size - 1 элементов null нет): r1, r2, r3,..., rn, null, null,..., null -<---- size -----> -<---- storage.length (10000)----------> +<----- size -----> +<------- storage.length (10000) -------> ``` -- Посмотреть на класс `Arrays`. Там есть полезные вещи, которые могут упростить код `ArrayStorage`. -- Протестируйте реализацию, запустив MainArray.main(): в IDEA слева на полях зеленая стрелка. +- Посмотрите на класс `java.util.Arrays`. В нем есть полезные методы, которые помогут вам написать более простой и понятный код +- Протестируйте вашу реализацию с помощью классов `MainArray.main()` и `MainTestArrayStorage.main()` +- Изучите дополнительные материалы по IntelliJ IDEA: + - [Idea Wiki](https://github.com/JavaOPs/topjava/wiki/IDEA) ([поставьте кодировку UTF-8](https://github.com/JavaOPs/topjava/wiki/IDEA#Поставить-кодировку-utf-8), [поменяйте шрифт по умолчанию на DejaVu](https://github.com/JavaOPs/topjava/wiki/IDEA#Поменять-фонт-по-умолчанию-dejavu)) + - [Руководство пользователя IntelliJ IDEA. Отладчик](http://info.javarush.ru/idea_help/2014/01/22/Руководство-пользователя-IntelliJ-IDEA-Отладчик-.html) + - [Эффективная работа с кодом в IntelliJ IDEA](https://www.youtube.com/watch?v=tpv5n2jWHlw) (youtube) + - [Эффективная работа в IDEA](https://www.youtube.com/watch?v=_rj7dx6c5R8) (youtube) + +### Вопросы по HW1 + > Не могу запустить программу, да и рядом с классами появился какой-то значок + ![badsrc](https://user-images.githubusercontent.com/29703461/38277015-9cd9155e-379f-11e8-9cd4-a9182a005e9a.png) + - Проблема в том, что IDEA неправильно "воспринимает" папку `src`. Для ее решения необходимо нажать `ПКМ на папке src -> выбрать Mark Directory as -> Sources Root` From f3a80ed285e05d3c18cdee3db1ed68f26539baaf Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 18 Apr 2018 10:19:00 +0300 Subject: [PATCH 005/220] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 19217751..68908046 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -59,7 +59,7 @@ ### Настройка проекта - Создайте на GitHub репозиторий с названием `basejava` - Откройте консоль (терминал) у себя на компьютере -- [Занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите консоль +- Наберите и запустите: `git` (По умолчанию при установке git заносится в PATH. Если он не находится, [занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите консоль) - Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git` - Перейдите в каталог проекта: `cd basejava` - Настройте git в локальном проекте на свой проект в GitHub: From 543828e2a7361a37e4b19f273c78fcecaa052267 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 18 Apr 2018 10:19:55 +0300 Subject: [PATCH 006/220] Update lesson1.md --- lesson/lesson1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 68908046..abfe6d66 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -59,7 +59,7 @@ ### Настройка проекта - Создайте на GitHub репозиторий с названием `basejava` - Откройте консоль (терминал) у себя на компьютере -- Наберите и запустите: `git` (По умолчанию при установке git заносится в PATH. Если он не находится, [занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите консоль) +- Наберите и запустите: `git` (по умолчанию при установке git заносится в PATH. Если он не находится, [занесите](https://www.java.com/ru/download/help/path.xml) git в переменную окружения PATH и перезапустите консоль) - Создайте локальную копию проекта: `git clone https://github.com/JavaOps/basejava.git` - Перейдите в каталог проекта: `cd basejava` - Настройте git в локальном проекте на свой проект в GitHub: From 758dfa3242b590ca41fc7e34b2b2443a5e7010aa Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 18 Apr 2018 10:31:56 +0300 Subject: [PATCH 007/220] Update lesson1.md --- lesson/lesson1.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index abfe6d66..38d358f0 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -8,8 +8,7 @@ - Установите систему управления версиями [Git](http://git-scm.com/downloads) (опции по умолчанию) - Создайте аккаунт на [GitHub](https://github.com/) - Для удобной навигации по файлам на GitHub установите расширение для браузера - [Octotree](https://habrahabr.ru/post/223527/) -- Установите [IntelliJ IDEA Ultimate](http://www.jetbrains.com/idea/download/index.html) -> Данная среда разработки является платным продуктом, рассчитанным на 30 дней пробного бесплатного использования. Для выполнения заданий в этой IDE каждый участник курса получит ключ на 6 месяцев +- Установите [IntelliJ IDEA Ultimate](http://www.jetbrains.com/idea/download/index.html) (30 дней пробного бесплатного использования. Каждый участник проектов получает единоразовый личный купон на бесплатную версию Ultimate на 6 месяцев). **Пока нет базы данных и веб, можно работать с версией community**. ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) - [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) (wiki) From cff24d3ca9a28182652fbea86e305ce1e5501c62 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 18 Apr 2018 10:42:23 +0300 Subject: [PATCH 008/220] Update lesson1.md --- lesson/lesson1.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 38d358f0..019aef70 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -6,9 +6,8 @@ ### Подготовка рабочего окружения - Установите [JDK8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) (выбрать Accept License Agreement) - Установите систему управления версиями [Git](http://git-scm.com/downloads) (опции по умолчанию) -- Создайте аккаунт на [GitHub](https://github.com/) -- Для удобной навигации по файлам на GitHub установите расширение для браузера - [Octotree](https://habrahabr.ru/post/223527/) -- Установите [IntelliJ IDEA Ultimate](http://www.jetbrains.com/idea/download/index.html) (30 дней пробного бесплатного использования. Каждый участник проектов получает единоразовый личный купон на бесплатную версию Ultimate на 6 месяцев). **Пока нет базы данных и веб, можно работать с версией community**. +- Создайте аккаунт на [GitHub](https://github.com/). Для удобной навигации по файлам на GitHub можно установить расширение для браузера [Octotree](https://habrahabr.ru/post/223527/) +- Установите [IntelliJ IDEA](http://www.jetbrains.com/idea/download/index.html). **Пока нет базы данных и веб, можно работать с версией Community**. На версию Ultimate дается 30 дней пробного бесплатного использования (trial). На проектах каждый участник проектов получает единоразовый личный купон на бесплатную версию Ultimate на 6 месяцев. ## ![video](https://cloud.githubusercontent.com/assets/13649199/13672715/06dbc6ce-e6e7-11e5-81a9-04fbddb9e488.png) 1. [Разработка ПО](https://drive.google.com/open?id=0B_4NpoQW1xfpVjZUTEpvVUN1TTA) - [Мифический человеко-месяц](https://ru.wikipedia.org/wiki/Мифический_человеко-месяц) (wiki) From 08e39be6594619541dbb2104221d3b96362793cf Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Wed, 18 Apr 2018 10:57:34 +0300 Subject: [PATCH 009/220] Update lesson1.md --- lesson/lesson1.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 019aef70..93b78857 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -97,3 +97,8 @@ r1, r2, r3,..., rn, null, null,..., null > Не могу запустить программу, да и рядом с классами появился какой-то значок ![badsrc](https://user-images.githubusercontent.com/29703461/38277015-9cd9155e-379f-11e8-9cd4-a9182a005e9a.png) - Проблема в том, что IDEA неправильно "воспринимает" папку `src`. Для ее решения необходимо нажать `ПКМ на папке src -> выбрать Mark Directory as -> Sources Root` + + > Что такое `null`? + +[Что такое null в Java?](http://qaru.site/questions/1960/what-is-null-in-java) (оригинал: [What is null in Java? +](https://stackoverflow.com/questions/2707322/what-is-null-in-java)) From a0b0beaa7d2f5de4c0c87e7c2211c5e8b1d7c04f Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 13 May 2018 15:15:13 +0300 Subject: [PATCH 010/220] HW1 --- src/ArrayStorage.java | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java index 7aff0388..b389ca5c 100644 --- a/src/ArrayStorage.java +++ b/src/ArrayStorage.java @@ -1,3 +1,5 @@ +import com.sun.deploy.util.ArrayUtil; + /** * Array based storage for Resumes */ @@ -5,26 +7,55 @@ public class ArrayStorage { Resume[] storage = new Resume[10000]; void clear() { + storage = new Resume[10000]; } void save(Resume r) { + for (int i = 0; i < storage.length; i++){ + if (storage[i] == null) { + storage[i] = r; + break; + } + } } Resume get(String uuid) { + for (Resume i:storage) { + if ((i != null) && (i.toString().equals(uuid))) return i; + } return null; } void delete(String uuid) { + for (int i = 0; i < storage.length; i++) { + if (storage[i].toString().equals(uuid)) { + storage[i] = null; + break; + } + } } /** * @return array, contains only Resumes in storage (without null) */ Resume[] getAll() { - return new Resume[0]; + Resume[] all = new Resume[0]; + for (int i = 0; i < storage.length; i++) { + if (storage[i] != null) { + Resume[] tmp = new Resume[all.length + 1]; + System.arraycopy(all, 0, tmp, 0, all.length); + System.arraycopy(storage, i, tmp, all.length, 1); + all = tmp; + } + } + return all; } int size() { - return 0; + int size = 0; + for (Resume i:storage) { + if (i != null) size++; + } + return size; } } From 120f86ff300ac53fbeeedfe35bc381d6d6d848c6 Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 13 May 2018 19:07:54 +0300 Subject: [PATCH 011/220] HW1 - error correction after review --- src/ArrayStorage.java | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java index b389ca5c..525aec66 100644 --- a/src/ArrayStorage.java +++ b/src/ArrayStorage.java @@ -5,31 +5,35 @@ */ public class ArrayStorage { Resume[] storage = new Resume[10000]; + int size = 0; void clear() { storage = new Resume[10000]; + size = 0; } void save(Resume r) { - for (int i = 0; i < storage.length; i++){ - if (storage[i] == null) { - storage[i] = r; - break; - } - } + storage[size] = r; + size++; } Resume get(String uuid) { - for (Resume i:storage) { - if ((i != null) && (i.toString().equals(uuid))) return i; + for (int i = 0; i < size; i++) { + if (storage[i].uuid.equals(uuid)) { + return storage[i]; + } } return null; } void delete(String uuid) { - for (int i = 0; i < storage.length; i++) { - if (storage[i].toString().equals(uuid)) { - storage[i] = null; + for (int i = 0; i < size; i++) { + if (storage[i].uuid.equals(uuid)){ + Resume[] tmp = new Resume[10000]; + System.arraycopy(storage, 0, tmp, 0, i); + System.arraycopy(storage, i + 1, tmp, i, size - i); + storage = tmp; + size--; break; } } @@ -39,23 +43,12 @@ void delete(String uuid) { * @return array, contains only Resumes in storage (without null) */ Resume[] getAll() { - Resume[] all = new Resume[0]; - for (int i = 0; i < storage.length; i++) { - if (storage[i] != null) { - Resume[] tmp = new Resume[all.length + 1]; - System.arraycopy(all, 0, tmp, 0, all.length); - System.arraycopy(storage, i, tmp, all.length, 1); - all = tmp; - } - } + Resume[] all = new Resume[size]; + System.arraycopy(storage, 0, all, 0, size); return all; } int size() { - int size = 0; - for (Resume i:storage) { - if (i != null) size++; - } return size; } } From 2eedaa5ddf6c97ce6870cd0f2e955915b9908625 Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 13 May 2018 21:29:12 +0300 Subject: [PATCH 012/220] HW1 - error correction after review v2 --- src/ArrayStorage.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java index 525aec66..5b272ee7 100644 --- a/src/ArrayStorage.java +++ b/src/ArrayStorage.java @@ -13,8 +13,10 @@ void clear() { } void save(Resume r) { - storage[size] = r; - size++; + if (size < storage.length){ + storage[size] = r; + size++; + } } Resume get(String uuid) { @@ -29,9 +31,8 @@ Resume get(String uuid) { void delete(String uuid) { for (int i = 0; i < size; i++) { if (storage[i].uuid.equals(uuid)){ - Resume[] tmp = new Resume[10000]; - System.arraycopy(storage, 0, tmp, 0, i); - System.arraycopy(storage, i + 1, tmp, i, size - i); + Resume[] tmp = storage; + System.arraycopy(storage, i + 1, tmp, i, storage.length - i - 1); storage = tmp; size--; break; From 3f53ae923d871644d35c0c575c320592afb74eed Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 14 May 2018 09:39:20 +0300 Subject: [PATCH 013/220] HW1 - error correction after review v3 (14.05.2018) --- src/ArrayStorage.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/ArrayStorage.java b/src/ArrayStorage.java index 5b272ee7..677d85ea 100644 --- a/src/ArrayStorage.java +++ b/src/ArrayStorage.java @@ -1,5 +1,3 @@ -import com.sun.deploy.util.ArrayUtil; - /** * Array based storage for Resumes */ @@ -31,9 +29,7 @@ Resume get(String uuid) { void delete(String uuid) { for (int i = 0; i < size; i++) { if (storage[i].uuid.equals(uuid)){ - Resume[] tmp = storage; - System.arraycopy(storage, i + 1, tmp, i, storage.length - i - 1); - storage = tmp; + System.arraycopy(storage, i + 1, storage, i, storage.length - i - 1); size--; break; } From 76dac2e15bfdaf0b20302c5f22c9ed8cadf056a4 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 24 May 2018 23:07:45 +0300 Subject: [PATCH 014/220] Add packages, and getters & setters for Resume --- lesson/lesson1.md | 2 +- lesson/lesson2.md | 8 +++---- lesson/lesson3.md | 4 ++-- lesson/lesson6.md | 4 ++-- lesson/lesson7.md | 2 +- src/MainArray.java | 7 ++++-- src/MainTestArrayStorage.java | 15 +++++++----- src/Resume.java | 13 ---------- src/ru/javaops/webapp/model/Resume.java | 23 ++++++++++++++++++ .../javaops/webapp/storage}/ArrayStorage.java | 24 +++++++++++-------- 10 files changed, 61 insertions(+), 41 deletions(-) delete mode 100644 src/Resume.java create mode 100644 src/ru/javaops/webapp/model/Resume.java rename src/{ => ru/javaops/webapp/storage}/ArrayStorage.java (64%) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 93b78857..59fecf5b 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -77,7 +77,7 @@ ![finish](https://user-images.githubusercontent.com/29703461/38275669-3e621614-379b-11e8-8b3a-8e0a3ad4c65c.png) -- Реализуйте класс `ArrayStorage`, организовав хранение резюме на основе массива с методами `save, get, delete, size, clear, getAll` +- Реализуйте класс `ru.javaops.webapp.storage.ArrayStorage`, организовав хранение резюме на основе массива с методами `save, get, delete, size, clear, getAll` - При этом храните все резюме в начале `storage` (без дырок в виде `null`), чтобы не перебирать каждый раз все 10000 элементов ``` Схема хранения резюме в storage (от 0 до size - 1 элементов null нет): diff --git a/lesson/lesson2.md b/lesson/lesson2.md index 1e9066ff..a6888a56 100644 --- a/lesson/lesson2.md +++ b/lesson/lesson2.md @@ -32,10 +32,10 @@ ## Домашнее задание -> Правка к видео: ArrayStorage.delete() - вместо `storage[i] = null` нужно `storage[size-1] = null` +> Правка к видео: ru.javaops.webapp.storage.ArrayStorage.delete() - вместо `storage[i] = null` нужно `storage[size-1] = null` - Прочитать Соглашения по именованию. -- Реализовать `ArrayStorage.update` -- Сделать проверки: в `update/delete/get` - резюме есть в storage, в `save`- нет в storage: `System.out.println("Resume ...")`. +- Реализовать `ru.javaops.webapp.storage.ArrayStorage.update` +- Сделать проверки: в `update/delete/get` - резюме есть в storage, в `save`- нет в storage: `System.out.println("ru.javaops.webapp.model.Resume ...")`. - Сделать в save проверку на переполнениеe: `System.out.println("...")`. -- Избавится от дублирования в коде `ArrayStorage` +- Избавится от дублирования в коде `ru.javaops.webapp.storage.ArrayStorage` diff --git a/lesson/lesson3.md b/lesson/lesson3.md index 36b8407f..af719e49 100644 --- a/lesson/lesson3.md +++ b/lesson/lesson3.md @@ -20,5 +20,5 @@ - Шаблонный метод ## Домашнее задание -- Закончить реализацию `AbstractArrayStorage`, `ArrayStorage`, `SortedArrayStorage` (`SortedArrayStorage` хранит элементы отсортированными, сортировать весь массив не надо). -- Сделать проверку `ArrayStorage.update` +- Закончить реализацию `AbstractArrayStorage`, `ru.javaops.webapp.storage.ArrayStorage`, `SortedArrayStorage` (`SortedArrayStorage` хранит элементы отсортированными, сортировать весь массив не надо). +- Сделать проверку `ru.javaops.webapp.storage.ArrayStorage.update` diff --git a/lesson/lesson6.md b/lesson/lesson6.md index 3295fbb7..a995d525 100644 --- a/lesson/lesson6.md +++ b/lesson/lesson6.md @@ -15,6 +15,6 @@ ## Домашнее задание - Сделать рефакторинг тестов: `saveOverflow` должно быть только для Array реализаций. -- Рефакторинг: в конструктор Resume добавить второй параметр `fullName` -- Сделать рефакторинг всех реализаций `Storage`: заменить метод `Resume[] getAll()` на `List getAllSorted()` +- Рефакторинг: в конструктор ru.javaops.webapp.model.Resume добавить второй параметр `fullName` +- Сделать рефакторинг всех реализаций `Storage`: заменить метод `ru.javaops.webapp.model.Resume[] getAll()` на `List getAllSorted()` - Реализовать до конца `MapUuidStorage`. Подумать что еще может быть search key в реализации на основе Map. diff --git a/lesson/lesson7.md b/lesson/lesson7.md index 30494c95..cf77911e 100644 --- a/lesson/lesson7.md +++ b/lesson/lesson7.md @@ -23,7 +23,7 @@ Доменный объект Cделать объектную модель резюме (диаграмма и классы). Образец резюме (делаем упрощенно) - - Делать только классы, включаемые в Resume. Resume - главный класс. В него все включается (композиция - строгий вид агрегации). + - Делать только классы, включаемые в ru.javaops.webapp.model.Resume. ru.javaops.webapp.model.Resume - главный класс. В него все включается (композиция - строгий вид агрегации). - Схожие по структуре и функциональности сущности делаем одним классом. - Модель упрощаем для хранения только необходимой информации для вывода/ редактирования резюме. - В модели резюме должны быть представлены контакты и следующие разделы: diff --git a/src/MainArray.java b/src/MainArray.java index 20f1f141..75edda5d 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -1,9 +1,12 @@ +import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.storage.ArrayStorage; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** - * Test for com.urise.webapp.storage.ArrayStorage + * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainArray { private final static ArrayStorage ARRAY_STORAGE = new ArrayStorage(); @@ -31,7 +34,7 @@ public static void main(String[] args) throws IOException { break; case "save": r = new Resume(); - r.uuid = uuid; + r.setUuid(uuid); ARRAY_STORAGE.save(r); printAll(); break; diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index 17ba8c03..2f61f4ee 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -1,28 +1,31 @@ +import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.storage.ArrayStorage; + /** - * Test for com.urise.webapp.storage.ArrayStorage + * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainTestArrayStorage { static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) { Resume r1 = new Resume(); - r1.uuid = "uuid1"; + r1.setUuid("uuid1"); Resume r2 = new Resume(); - r2.uuid = "uuid2"; + r2.setUuid("uuid2"); Resume r3 = new Resume(); - r3.uuid = "uuid3"; + r3.setUuid("uuid3"); ARRAY_STORAGE.save(r1); ARRAY_STORAGE.save(r2); ARRAY_STORAGE.save(r3); - System.out.println("Get r1: " + ARRAY_STORAGE.get(r1.uuid)); + System.out.println("Get r1: " + ARRAY_STORAGE.get(r1.getUuid())); System.out.println("Size: " + ARRAY_STORAGE.size()); System.out.println("Get dummy: " + ARRAY_STORAGE.get("dummy")); printAll(); - ARRAY_STORAGE.delete(r1.uuid); + ARRAY_STORAGE.delete(r1.getUuid()); printAll(); ARRAY_STORAGE.clear(); printAll(); diff --git a/src/Resume.java b/src/Resume.java deleted file mode 100644 index 937c6a75..00000000 --- a/src/Resume.java +++ /dev/null @@ -1,13 +0,0 @@ -/** - * com.urise.webapp.model.Resume class - */ -public class Resume { - - // Unique identifier - String uuid; - - @Override - public String toString() { - return uuid; - } -} diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java new file mode 100644 index 00000000..92e1bca5 --- /dev/null +++ b/src/ru/javaops/webapp/model/Resume.java @@ -0,0 +1,23 @@ +package ru.javaops.webapp.model; + +/** + * com.urise.webapp.model.ru.javaops.webapp.model.Resume class + */ +public class Resume { + + // Unique identifier + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String toString() { + return uuid; + } +} diff --git a/src/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java similarity index 64% rename from src/ArrayStorage.java rename to src/ru/javaops/webapp/storage/ArrayStorage.java index 677d85ea..d28316fa 100644 --- a/src/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -1,34 +1,38 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + /** * Array based storage for Resumes */ public class ArrayStorage { - Resume[] storage = new Resume[10000]; - int size = 0; + private Resume[] storage = new Resume[10000]; + private int size = 0; - void clear() { + public void clear() { storage = new Resume[10000]; size = 0; } - void save(Resume r) { + public void save(Resume r) { if (size < storage.length){ storage[size] = r; size++; } } - Resume get(String uuid) { + public Resume get(String uuid) { for (int i = 0; i < size; i++) { - if (storage[i].uuid.equals(uuid)) { + if (storage[i].getUuid().equals(uuid)) { return storage[i]; } } return null; } - void delete(String uuid) { + public void delete(String uuid) { for (int i = 0; i < size; i++) { - if (storage[i].uuid.equals(uuid)){ + if (storage[i].getUuid().equals(uuid)){ System.arraycopy(storage, i + 1, storage, i, storage.length - i - 1); size--; break; @@ -39,13 +43,13 @@ void delete(String uuid) { /** * @return array, contains only Resumes in storage (without null) */ - Resume[] getAll() { + public Resume[] getAll() { Resume[] all = new Resume[size]; System.arraycopy(storage, 0, all, 0, size); return all; } - int size() { + public int size() { return size; } } From 2e7555e3ab641218241736866950ab632d099f5c Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 25 May 2018 13:29:28 +0300 Subject: [PATCH 015/220] HW2 ArrayStorage.update, DRY --- .../javaops/webapp/storage/ArrayStorage.java | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index d28316fa..a2fea92e 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -14,29 +14,51 @@ public void clear() { size = 0; } + private int search(String uuid) { + for (int i = 0; i < size; i++) { + if (storage[i].getUuid().equals(uuid)) { + return i; + } + } + return -1; + } + + public void update(Resume r) { + int index = search(r.getUuid()); + if (index >= 0){ + storage[index] = r; + } else { + System.out.println("Error: resume with uuid: " + r.getUuid() + " not found!"); + } + } + public void save(Resume r) { - if (size < storage.length){ - storage[size] = r; - size++; + if (size < storage.length) { + if (search(r.getUuid()) < 0) { + storage[size] = r; + size++; + } else { + System.out.println("Error: resume with uuid: " + r.getUuid() + " already exist!"); + } } } public Resume get(String uuid) { - for (int i = 0; i < size; i++) { - if (storage[i].getUuid().equals(uuid)) { - return storage[i]; - } + int index = search(uuid); + if (index >= 0) { + return storage[index]; } + System.out.println("Error: resume with uuid: " + uuid + " not found!"); return null; } public void delete(String uuid) { - for (int i = 0; i < size; i++) { - if (storage[i].getUuid().equals(uuid)){ - System.arraycopy(storage, i + 1, storage, i, storage.length - i - 1); - size--; - break; - } + int index = search(uuid); + if (index >= 0) { + System.arraycopy(storage, index + 1, storage, index, storage.length - index - 1); + size--; + } else { + System.out.println("Error: resume with uuid: " + uuid + " not found!"); } } From 94f0e363f1f01f7e5d0003fdc3da6cd3d1c826be Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 25 May 2018 15:27:16 +0300 Subject: [PATCH 016/220] HW2 Use Class Arrays methods, test ArrayStorage.update method --- src/MainTestArrayStorage.java | 5 ++++ .../javaops/webapp/storage/ArrayStorage.java | 29 ++++++++++--------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index 2f61f4ee..9405d5b9 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -24,6 +24,11 @@ public static void main(String[] args) { System.out.println("Get dummy: " + ARRAY_STORAGE.get("dummy")); + //Test update method + printAll(); + r3.setUuid("uuid4"); + ARRAY_STORAGE.update(r3); + printAll(); ARRAY_STORAGE.delete(r1.getUuid()); printAll(); diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index a2fea92e..0c2b9ea1 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -2,6 +2,8 @@ import ru.javaops.webapp.model.Resume; +import java.util.Arrays; + /** * Array based storage for Resumes */ @@ -10,11 +12,11 @@ public class ArrayStorage { private int size = 0; public void clear() { - storage = new Resume[10000]; + Arrays.fill(storage, null); size = 0; } - private int search(String uuid) { + private int getUuidIndex(String uuid) { for (int i = 0; i < size; i++) { if (storage[i].getUuid().equals(uuid)) { return i; @@ -24,7 +26,7 @@ private int search(String uuid) { } public void update(Resume r) { - int index = search(r.getUuid()); + int index = getUuidIndex(r.getUuid()); if (index >= 0){ storage[index] = r; } else { @@ -32,19 +34,21 @@ public void update(Resume r) { } } - public void save(Resume r) { + public void save(Resume resume) { if (size < storage.length) { - if (search(r.getUuid()) < 0) { - storage[size] = r; + if (getUuidIndex(resume.getUuid()) < 0) { + storage[size] = resume; size++; } else { - System.out.println("Error: resume with uuid: " + r.getUuid() + " already exist!"); + System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); } + } else { + System.out.println("Resume storage is full!"); } } public Resume get(String uuid) { - int index = search(uuid); + int index = getUuidIndex(uuid); if (index >= 0) { return storage[index]; } @@ -53,9 +57,10 @@ public Resume get(String uuid) { } public void delete(String uuid) { - int index = search(uuid); + int index = getUuidIndex(uuid); if (index >= 0) { - System.arraycopy(storage, index + 1, storage, index, storage.length - index - 1); + storage[index] = storage[size - 1]; + storage[size - 1] = null; size--; } else { System.out.println("Error: resume with uuid: " + uuid + " not found!"); @@ -66,9 +71,7 @@ public void delete(String uuid) { * @return array, contains only Resumes in storage (without null) */ public Resume[] getAll() { - Resume[] all = new Resume[size]; - System.arraycopy(storage, 0, all, 0, size); - return all; + return Arrays.copyOf(storage, size); } public int size() { From ac34d3c16499db5b2927134790bc0152e2a32bfe Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 25 May 2018 15:29:32 +0300 Subject: [PATCH 017/220] HW2 Use Class Arrays methods, test ArrayStorage.update method --- src/ru/javaops/webapp/storage/ArrayStorage.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 0c2b9ea1..93d8eaec 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -25,12 +25,12 @@ private int getUuidIndex(String uuid) { return -1; } - public void update(Resume r) { - int index = getUuidIndex(r.getUuid()); + public void update(Resume resume) { + int index = getUuidIndex(resume.getUuid()); if (index >= 0){ - storage[index] = r; + storage[index] = resume; } else { - System.out.println("Error: resume with uuid: " + r.getUuid() + " not found!"); + System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); } } From 0ee0eb06fefaa81462bc16855a365a3d00d229fd Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 25 May 2018 15:33:16 +0300 Subject: [PATCH 018/220] HW2 Use Class Arrays methods, test ArrayStorage.update method --- src/ru/javaops/webapp/storage/ArrayStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 93d8eaec..a8e38236 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -43,7 +43,7 @@ public void save(Resume resume) { System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); } } else { - System.out.println("Resume storage is full!"); + System.out.println("Error: resume storage is full!"); } } From 14025707de8ece31c866a25089b0f2fb4384a723 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 25 May 2018 15:52:12 +0300 Subject: [PATCH 019/220] HW2 Test storage overflow --- src/MainTestArrayStorage.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index 9405d5b9..a226b334 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -36,6 +36,13 @@ public static void main(String[] args) { printAll(); System.out.println("Size: " + ARRAY_STORAGE.size()); + + //Test storage overflow + for (int i = 0; i < 10001; i++){ + Resume resume = new Resume(); + resume.setUuid("uuid" + i); + ARRAY_STORAGE.save(resume); + } } static void printAll() { From 42acd32b0159934c46f28f8d36b622d34ea00c2c Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 25 May 2018 16:58:10 +0300 Subject: [PATCH 020/220] HW2 1) ArrayStorage.clear fill only not null array elements, 2) Rename method getUuidIndex to getIndexResume, 3) ArrayStorage.delete - code simplification. --- src/ru/javaops/webapp/storage/ArrayStorage.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index a8e38236..c8dba6bf 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -12,11 +12,11 @@ public class ArrayStorage { private int size = 0; public void clear() { - Arrays.fill(storage, null); + Arrays.fill(storage, 0, size - 1, null); size = 0; } - private int getUuidIndex(String uuid) { + private int getIndexResume(String uuid) { for (int i = 0; i < size; i++) { if (storage[i].getUuid().equals(uuid)) { return i; @@ -26,7 +26,7 @@ private int getUuidIndex(String uuid) { } public void update(Resume resume) { - int index = getUuidIndex(resume.getUuid()); + int index = getIndexResume(resume.getUuid()); if (index >= 0){ storage[index] = resume; } else { @@ -36,7 +36,7 @@ public void update(Resume resume) { public void save(Resume resume) { if (size < storage.length) { - if (getUuidIndex(resume.getUuid()) < 0) { + if (getIndexResume(resume.getUuid()) < 0) { storage[size] = resume; size++; } else { @@ -48,7 +48,7 @@ public void save(Resume resume) { } public Resume get(String uuid) { - int index = getUuidIndex(uuid); + int index = getIndexResume(uuid); if (index >= 0) { return storage[index]; } @@ -57,11 +57,12 @@ public Resume get(String uuid) { } public void delete(String uuid) { - int index = getUuidIndex(uuid); + int index = getIndexResume(uuid); if (index >= 0) { - storage[index] = storage[size - 1]; - storage[size - 1] = null; size--; + storage[index] = storage[size]; + storage[size] = null; + } else { System.out.println("Error: resume with uuid: " + uuid + " not found!"); } From 55eb3c1fd342f9bb83067a6441f58997657ca286 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 25 May 2018 17:13:17 +0300 Subject: [PATCH 021/220] HW2 ArrayStorage.clear fix --- src/ru/javaops/webapp/storage/ArrayStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index c8dba6bf..6635a98f 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -12,7 +12,7 @@ public class ArrayStorage { private int size = 0; public void clear() { - Arrays.fill(storage, 0, size - 1, null); + Arrays.fill(storage, 0, size, null); size = 0; } From 31eccd7b5a5f805fd0131d487f59d4376e6c31e2 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 28 May 2018 13:29:40 +0300 Subject: [PATCH 022/220] HW2 cleanup --- .../javaops/webapp/storage/ArrayStorage.java | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 6635a98f..1f5c954b 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -16,7 +16,7 @@ public void clear() { size = 0; } - private int getIndexResume(String uuid) { + private int getIndex(String uuid) { for (int i = 0; i < size; i++) { if (storage[i].getUuid().equals(uuid)) { return i; @@ -25,46 +25,43 @@ private int getIndexResume(String uuid) { return -1; } - public void update(Resume resume) { - int index = getIndexResume(resume.getUuid()); - if (index >= 0){ - storage[index] = resume; - } else { - System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); + public Resume get(String uuid) { + int index = getIndex(uuid); + if (index == -1) { + System.out.println("Error: resume with uuid: " + uuid + " not found!"); + return null; } + return storage[index]; } - public void save(Resume resume) { - if (size < storage.length) { - if (getIndexResume(resume.getUuid()) < 0) { - storage[size] = resume; - size++; - } else { - System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); - } + public void update(Resume resume) { + int index = getIndex(resume.getUuid()); + if (index == -1){ + System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); } else { - System.out.println("Error: resume storage is full!"); + storage[index] = resume; } } - public Resume get(String uuid) { - int index = getIndexResume(uuid); - if (index >= 0) { - return storage[index]; + public void save(Resume resume) { + if (getIndex(resume.getUuid()) != -1) { + System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); + } else if (size >= storage.length) { + System.out.println("Error: resume storage is full!"); + } else { + storage[size] = resume; + size++; } - System.out.println("Error: resume with uuid: " + uuid + " not found!"); - return null; } public void delete(String uuid) { - int index = getIndexResume(uuid); - if (index >= 0) { + int index = getIndex(uuid); + if (index == -1) { + System.out.println("Error: resume with uuid: " + uuid + " not found!"); + } else { size--; storage[index] = storage[size]; storage[size] = null; - - } else { - System.out.println("Error: resume with uuid: " + uuid + " not found!"); } } From e9cda82f38473524627221b4b931e3554a5ac4ab Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 28 May 2018 22:50:35 +0300 Subject: [PATCH 023/220] lesson 3, add class Resume equals, hashCode add STORAGE_LIMIT constant add interface Storage and implementation --- src/MainArray.java | 3 +- src/MainTestArrayStorage.java | 3 +- src/ru/javaops/webapp/model/Resume.java | 15 ++++++++++ .../javaops/webapp/storage/ArrayStorage.java | 8 ++++-- src/ru/javaops/webapp/storage/Storage.java | 28 +++++++++++++++++++ 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/Storage.java diff --git a/src/MainArray.java b/src/MainArray.java index 75edda5d..986dd77d 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -1,5 +1,6 @@ import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.storage.ArrayStorage; +import ru.javaops.webapp.storage.Storage; import java.io.BufferedReader; import java.io.IOException; @@ -9,7 +10,7 @@ * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainArray { - private final static ArrayStorage ARRAY_STORAGE = new ArrayStorage(); + private final static Storage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index a226b334..b1f05313 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -1,11 +1,12 @@ import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.storage.ArrayStorage; +import ru.javaops.webapp.storage.Storage; /** * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainTestArrayStorage { - static final ArrayStorage ARRAY_STORAGE = new ArrayStorage(); + private static final Storage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) { Resume r1 = new Resume(); diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 92e1bca5..2539ce01 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -8,6 +8,21 @@ public class Resume { // Unique identifier private String uuid; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Resume resume = (Resume) o; + + return uuid.equals(resume.uuid); + } + + @Override + public int hashCode() { + return uuid.hashCode(); + } + public String getUuid() { return uuid; } diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 1f5c954b..7295c389 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -7,8 +7,10 @@ /** * Array based storage for Resumes */ -public class ArrayStorage { - private Resume[] storage = new Resume[10000]; +public class ArrayStorage implements Storage { + private static final int STORAGE_LIMIT = 10000; + + private Resume[] storage = new Resume[STORAGE_LIMIT]; private int size = 0; public void clear() { @@ -69,7 +71,7 @@ public void delete(String uuid) { * @return array, contains only Resumes in storage (without null) */ public Resume[] getAll() { - return Arrays.copyOf(storage, size); + return Arrays.copyOfRange(storage, 0, size); } public int size() { diff --git a/src/ru/javaops/webapp/storage/Storage.java b/src/ru/javaops/webapp/storage/Storage.java new file mode 100644 index 00000000..f752e5ef --- /dev/null +++ b/src/ru/javaops/webapp/storage/Storage.java @@ -0,0 +1,28 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.util.Arrays; + +/** + * Array based storage for Resumes + */ +public interface Storage { + + void clear(); + + Resume get(String uuid); + + void update(Resume resume); + + void save(Resume resume); + + void delete(String uuid); + + /** + * @return array, contains only Resumes in storage (without null) + */ + Resume[] getAll(); + + int size(); +} From 87b05e57538c41275134cf6e57b5e1a0b7a1bdf4 Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 28 May 2018 23:07:35 +0300 Subject: [PATCH 024/220] Replace storage.length to STORAGE_LIMIT --- src/MainTestArrayStorage.java | 6 +++--- src/ru/javaops/webapp/storage/ArrayStorage.java | 2 +- src/ru/javaops/webapp/storage/Storage.java | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index b1f05313..01874b1b 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -9,11 +9,11 @@ public class MainTestArrayStorage { private static final Storage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) { - Resume r1 = new Resume(); + final Resume r1 = new Resume(); r1.setUuid("uuid1"); - Resume r2 = new Resume(); + final Resume r2 = new Resume(); r2.setUuid("uuid2"); - Resume r3 = new Resume(); + final Resume r3 = new Resume(); r3.setUuid("uuid3"); ARRAY_STORAGE.save(r1); diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 7295c389..cb5db9fa 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -48,7 +48,7 @@ public void update(Resume resume) { public void save(Resume resume) { if (getIndex(resume.getUuid()) != -1) { System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); - } else if (size >= storage.length) { + } else if (size >= STORAGE_LIMIT) { System.out.println("Error: resume storage is full!"); } else { storage[size] = resume; diff --git a/src/ru/javaops/webapp/storage/Storage.java b/src/ru/javaops/webapp/storage/Storage.java index f752e5ef..0a7d47a0 100644 --- a/src/ru/javaops/webapp/storage/Storage.java +++ b/src/ru/javaops/webapp/storage/Storage.java @@ -2,8 +2,6 @@ import ru.javaops.webapp.model.Resume; -import java.util.Arrays; - /** * Array based storage for Resumes */ From b88372da80c5aa9a7e4c034812689adbf1d8afa8 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 29 May 2018 19:20:21 +0300 Subject: [PATCH 025/220] make storage final, printAll private --- src/MainArray.java | 2 +- src/MainTestArrayStorage.java | 2 +- src/ru/javaops/webapp/storage/ArrayStorage.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index 986dd77d..02db9d6c 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -59,7 +59,7 @@ public static void main(String[] args) throws IOException { } } - static void printAll() { + private static void printAll() { Resume[] all = ARRAY_STORAGE.getAll(); System.out.println("----------------------------"); if (all.length == 0) { diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index 01874b1b..b6090aee 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -46,7 +46,7 @@ public static void main(String[] args) { } } - static void printAll() { + private static void printAll() { System.out.println("\nGet All"); for (Resume r : ARRAY_STORAGE.getAll()) { System.out.println(r); diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index cb5db9fa..d459df83 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -10,7 +10,7 @@ public class ArrayStorage implements Storage { private static final int STORAGE_LIMIT = 10000; - private Resume[] storage = new Resume[STORAGE_LIMIT]; + private final Resume[] storage = new Resume[STORAGE_LIMIT]; private int size = 0; public void clear() { From 2c4690a75992adb239dcc4062357f2bab25bfd0b Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 2 Jun 2018 16:35:55 +0300 Subject: [PATCH 026/220] rename interface Storage to IStorage --- .../javaops/webapp/storage/ArrayStorage.java | 2 +- src/ru/javaops/webapp/storage/Storage.java | 26 ------------------- 2 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 src/ru/javaops/webapp/storage/Storage.java diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index d459df83..8ff786c1 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -7,7 +7,7 @@ /** * Array based storage for Resumes */ -public class ArrayStorage implements Storage { +public class ArrayStorage implements IStorage { private static final int STORAGE_LIMIT = 10000; private final Resume[] storage = new Resume[STORAGE_LIMIT]; diff --git a/src/ru/javaops/webapp/storage/Storage.java b/src/ru/javaops/webapp/storage/Storage.java deleted file mode 100644 index 0a7d47a0..00000000 --- a/src/ru/javaops/webapp/storage/Storage.java +++ /dev/null @@ -1,26 +0,0 @@ -package ru.javaops.webapp.storage; - -import ru.javaops.webapp.model.Resume; - -/** - * Array based storage for Resumes - */ -public interface Storage { - - void clear(); - - Resume get(String uuid); - - void update(Resume resume); - - void save(Resume resume); - - void delete(String uuid); - - /** - * @return array, contains only Resumes in storage (without null) - */ - Resume[] getAll(); - - int size(); -} From df146b2d2fb983a8c7ae4fb7dd6d359c029da071 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 2 Jun 2018 16:37:12 +0300 Subject: [PATCH 027/220] rename interface Storage to IStorage --- src/ru/javaops/webapp/storage/IStorage.java | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/ru/javaops/webapp/storage/IStorage.java diff --git a/src/ru/javaops/webapp/storage/IStorage.java b/src/ru/javaops/webapp/storage/IStorage.java new file mode 100644 index 00000000..1219b5c4 --- /dev/null +++ b/src/ru/javaops/webapp/storage/IStorage.java @@ -0,0 +1,26 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +/** + * Array based storage for Resumes + */ +public interface IStorage { + + void clear(); + + Resume get(String uuid); + + void update(Resume resume); + + void save(Resume resume); + + void delete(String uuid); + + /** + * @return array, contains only Resumes in storage (without null) + */ + Resume[] getAll(); + + int size(); +} From 152d885621426a1bffa9fd5e0206c054bae7d443 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 2 Jun 2018 17:13:16 +0300 Subject: [PATCH 028/220] Add AbstractArrayStorage and SortedArrayStorage --- src/MainArray.java | 4 ++-- src/MainTestArrayStorage.java | 4 ++-- .../webapp/storage/AbstractArrayStorage.java | 18 ++++++++++++++++++ .../javaops/webapp/storage/ArrayStorage.java | 10 +--------- .../webapp/storage/SortedArrayStorage.java | 8 ++++++++ 5 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/AbstractArrayStorage.java create mode 100644 src/ru/javaops/webapp/storage/SortedArrayStorage.java diff --git a/src/MainArray.java b/src/MainArray.java index 02db9d6c..b90321f7 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -1,6 +1,6 @@ import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.storage.ArrayStorage; -import ru.javaops.webapp.storage.Storage; +import ru.javaops.webapp.storage.IStorage; import java.io.BufferedReader; import java.io.IOException; @@ -10,7 +10,7 @@ * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainArray { - private final static Storage ARRAY_STORAGE = new ArrayStorage(); + private final static IStorage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index b6090aee..ab3cc2a1 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -1,12 +1,12 @@ import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.storage.ArrayStorage; -import ru.javaops.webapp.storage.Storage; +import ru.javaops.webapp.storage.IStorage; /** * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainTestArrayStorage { - private static final Storage ARRAY_STORAGE = new ArrayStorage(); + private static final IStorage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) { final Resume r1 = new Resume(); diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java new file mode 100644 index 00000000..b9438390 --- /dev/null +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -0,0 +1,18 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +/** + * Array based storage for Resumes + */ +public abstract class AbstractArrayStorage implements IStorage { + protected static final int STORAGE_LIMIT = 100000; + + protected final Resume[] storage = new Resume[STORAGE_LIMIT]; + protected int size = 0; + + public int size() { + return size; + } + +} diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 8ff786c1..6000d5cb 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -7,12 +7,7 @@ /** * Array based storage for Resumes */ -public class ArrayStorage implements IStorage { - private static final int STORAGE_LIMIT = 10000; - - private final Resume[] storage = new Resume[STORAGE_LIMIT]; - private int size = 0; - +public class ArrayStorage extends AbstractArrayStorage { public void clear() { Arrays.fill(storage, 0, size, null); size = 0; @@ -74,7 +69,4 @@ public Resume[] getAll() { return Arrays.copyOfRange(storage, 0, size); } - public int size() { - return size; - } } diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java new file mode 100644 index 00000000..c3d54c90 --- /dev/null +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -0,0 +1,8 @@ +package ru.javaops.webapp.storage; + +/** + * Array based storage for Resumes + */ +public class SortedArrayStorage { + +} From 90419a71e7d8772e33f6b737def43d9fbafbc7f2 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 2 Jun 2018 20:11:55 +0300 Subject: [PATCH 029/220] Add implements Comparable to Resume class --- src/ru/javaops/webapp/model/Resume.java | 7 +++- .../webapp/storage/AbstractArrayStorage.java | 11 ++++++ .../javaops/webapp/storage/ArrayStorage.java | 11 +----- .../webapp/storage/SortedArrayStorage.java | 37 ++++++++++++++++++- 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 2539ce01..ae80eb4c 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -3,7 +3,7 @@ /** * com.urise.webapp.model.ru.javaops.webapp.model.Resume class */ -public class Resume { +public class Resume implements Comparable{ // Unique identifier private String uuid; @@ -35,4 +35,9 @@ public void setUuid(String uuid) { public String toString() { return uuid; } + + @Override + public int compareTo(Resume o) { + return uuid.compareTo(o.uuid); + } } diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index b9438390..7b9ed908 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -15,4 +15,15 @@ public int size() { return size; } + public Resume get(String uuid) { + int index = getIndex(uuid); + if (index == -1) { + System.out.println("Error: resume with uuid: " + uuid + " not found!"); + return null; + } + return storage[index]; + } + + protected abstract int getIndex(String uuid); + } diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 6000d5cb..1f344c76 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -13,7 +13,7 @@ public void clear() { size = 0; } - private int getIndex(String uuid) { + protected int getIndex(String uuid) { for (int i = 0; i < size; i++) { if (storage[i].getUuid().equals(uuid)) { return i; @@ -22,15 +22,6 @@ private int getIndex(String uuid) { return -1; } - public Resume get(String uuid) { - int index = getIndex(uuid); - if (index == -1) { - System.out.println("Error: resume with uuid: " + uuid + " not found!"); - return null; - } - return storage[index]; - } - public void update(Resume resume) { int index = getIndex(resume.getUuid()); if (index == -1){ diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index c3d54c90..65d487f0 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -1,8 +1,43 @@ package ru.javaops.webapp.storage; +import ru.javaops.webapp.model.Resume; + +import java.util.Arrays; + /** * Array based storage for Resumes */ -public class SortedArrayStorage { +public class SortedArrayStorage extends AbstractArrayStorage{ + + @Override + public void clear() { + + } + + @Override + protected int getIndex(String uuid) { + Resume searchResume = new Resume(); + searchResume.setUuid(uuid); + return Arrays.binarySearch(storage, 0, size, searchResume); + } + + @Override + public void update(Resume resume) { + + } + + @Override + public void save(Resume resume) { + + } + + @Override + public void delete(String uuid) { + + } + @Override + public Resume[] getAll() { + return new Resume[0]; + } } From 609b3bfd1a3e7cb39e449e9568fcfa5b2f422bfc Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 7 Jun 2018 00:20:08 +0300 Subject: [PATCH 030/220] Implemented SortedArrayStorage save and delete methods, need cosmetic --- src/MainArray.java | 3 +- .../webapp/storage/AbstractArrayStorage.java | 11 +++++++ .../javaops/webapp/storage/ArrayStorage.java | 11 ------- .../webapp/storage/SortedArrayStorage.java | 29 +++++++++++-------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index b90321f7..b7fd93f9 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -1,6 +1,7 @@ import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.storage.ArrayStorage; import ru.javaops.webapp.storage.IStorage; +import ru.javaops.webapp.storage.SortedArrayStorage; import java.io.BufferedReader; import java.io.IOException; @@ -10,7 +11,7 @@ * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainArray { - private final static IStorage ARRAY_STORAGE = new ArrayStorage(); + private final static IStorage ARRAY_STORAGE = new SortedArrayStorage();//ArrayStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 7b9ed908..e70d8e29 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -2,6 +2,8 @@ import ru.javaops.webapp.model.Resume; +import java.util.Arrays; + /** * Array based storage for Resumes */ @@ -24,6 +26,15 @@ public Resume get(String uuid) { return storage[index]; } + public void clear() { + Arrays.fill(storage, 0, size, null); + size = 0; + } + + public Resume[] getAll() { + return Arrays.copyOfRange(storage, 0, size); + } + protected abstract int getIndex(String uuid); } diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 1f344c76..8f8ac294 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -8,10 +8,6 @@ * Array based storage for Resumes */ public class ArrayStorage extends AbstractArrayStorage { - public void clear() { - Arrays.fill(storage, 0, size, null); - size = 0; - } protected int getIndex(String uuid) { for (int i = 0; i < size; i++) { @@ -53,11 +49,4 @@ public void delete(String uuid) { } } - /** - * @return array, contains only Resumes in storage (without null) - */ - public Resume[] getAll() { - return Arrays.copyOfRange(storage, 0, size); - } - } diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index 65d487f0..db755118 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -9,11 +9,6 @@ */ public class SortedArrayStorage extends AbstractArrayStorage{ - @Override - public void clear() { - - } - @Override protected int getIndex(String uuid) { Resume searchResume = new Resume(); @@ -23,21 +18,31 @@ protected int getIndex(String uuid) { @Override public void update(Resume resume) { - + int index = getIndex(resume.getUuid()); + if (index == -1){ + System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); + } else { + storage[index] = resume; + } } @Override public void save(Resume resume) { - + int insertIndex = ~Arrays.binarySearch(storage, 0, size, resume); + System.arraycopy(storage, insertIndex, storage, insertIndex + 1, size - insertIndex); + storage[insertIndex] = resume; + size++; } @Override public void delete(String uuid) { - + int index = getIndex(uuid); + if (index == -1) { + System.out.println("Error: resume with uuid: " + uuid + " not found!"); + } else { + size--; + System.arraycopy(storage, index + 1, storage, index, size - index); + } } - @Override - public Resume[] getAll() { - return new Resume[0]; - } } From 62996867ec2831cd748a839c4e33e457a5e29267 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 7 Jun 2018 10:43:08 +0300 Subject: [PATCH 031/220] SorterdArrayStorage implemented update --- src/MainArray.java | 1 - src/MainTestArrayStorage.java | 13 +++++++------ .../javaops/webapp/storage/ArrayStorage.java | 2 -- .../webapp/storage/SortedArrayStorage.java | 18 +++++++++++++----- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index b7fd93f9..6cae2007 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -1,5 +1,4 @@ import ru.javaops.webapp.model.Resume; -import ru.javaops.webapp.storage.ArrayStorage; import ru.javaops.webapp.storage.IStorage; import ru.javaops.webapp.storage.SortedArrayStorage; diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index ab3cc2a1..e37896f6 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -1,20 +1,21 @@ import ru.javaops.webapp.model.Resume; -import ru.javaops.webapp.storage.ArrayStorage; import ru.javaops.webapp.storage.IStorage; +import ru.javaops.webapp.storage.SortedArrayStorage; /** * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainTestArrayStorage { - private static final IStorage ARRAY_STORAGE = new ArrayStorage(); + private static final IStorage ARRAY_STORAGE = new SortedArrayStorage();//ArrayStorage(); public static void main(String[] args) { final Resume r1 = new Resume(); - r1.setUuid("uuid1"); + r1.setUuid("uuid3"); final Resume r2 = new Resume(); - r2.setUuid("uuid2"); + r2.setUuid("uuid1"); final Resume r3 = new Resume(); - r3.setUuid("uuid3"); + r3.setUuid("uuid2"); + ARRAY_STORAGE.save(r1); ARRAY_STORAGE.save(r2); @@ -39,7 +40,7 @@ public static void main(String[] args) { System.out.println("Size: " + ARRAY_STORAGE.size()); //Test storage overflow - for (int i = 0; i < 10001; i++){ + for (int i = 0; i < 100001; i++){ Resume resume = new Resume(); resume.setUuid("uuid" + i); ARRAY_STORAGE.save(resume); diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 8f8ac294..eca5cead 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -2,8 +2,6 @@ import ru.javaops.webapp.model.Resume; -import java.util.Arrays; - /** * Array based storage for Resumes */ diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index db755118..43e35f13 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -22,16 +22,24 @@ public void update(Resume resume) { if (index == -1){ System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); } else { - storage[index] = resume; + delete(resume.getUuid()); + save(resume); } } @Override public void save(Resume resume) { - int insertIndex = ~Arrays.binarySearch(storage, 0, size, resume); - System.arraycopy(storage, insertIndex, storage, insertIndex + 1, size - insertIndex); - storage[insertIndex] = resume; - size++; + int index = getIndex(resume.getUuid()); + if (index >= 0){ + System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); + } else if (size >= STORAGE_LIMIT) { + System.out.println("Error: resume storage is full!"); + } else { + index = ~index; + System.arraycopy(storage, index, storage, index + 1, size - index); + storage[index] = resume; + size++; + } } @Override From e8aa362ada25873cd3420956d81bd3cae7227be9 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 7 Jun 2018 14:57:23 +0300 Subject: [PATCH 032/220] SorterdArrayStorage delete and update fix --- src/ru/javaops/webapp/storage/SortedArrayStorage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index 43e35f13..4d7e248b 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -19,7 +19,7 @@ protected int getIndex(String uuid) { @Override public void update(Resume resume) { int index = getIndex(resume.getUuid()); - if (index == -1){ + if (index < 0){ System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); } else { delete(resume.getUuid()); @@ -45,7 +45,7 @@ public void save(Resume resume) { @Override public void delete(String uuid) { int index = getIndex(uuid); - if (index == -1) { + if (index < 0) { System.out.println("Error: resume with uuid: " + uuid + " not found!"); } else { size--; From a0b11e61875a209a9c3cf43661defc0b5d488c0a Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 9 Jun 2018 19:22:25 +0300 Subject: [PATCH 033/220] Add abstract method putResumeToStorage --- src/MainTestArrayStorage.java | 4 ++- .../webapp/storage/AbstractArrayStorage.java | 13 ++++++++ .../javaops/webapp/storage/ArrayStorage.java | 12 ++----- .../webapp/storage/SortedArrayStorage.java | 32 ++++++++++++------- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index e37896f6..5a3d9dd3 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -1,4 +1,5 @@ import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.storage.ArrayStorage; import ru.javaops.webapp.storage.IStorage; import ru.javaops.webapp.storage.SortedArrayStorage; @@ -6,7 +7,8 @@ * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainTestArrayStorage { - private static final IStorage ARRAY_STORAGE = new SortedArrayStorage();//ArrayStorage(); + private static final IStorage ARRAY_STORAGE = new SortedArrayStorage(); + //private static final IStorage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) { final Resume r1 = new Resume(); diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index e70d8e29..3c9a263d 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -35,6 +35,19 @@ public Resume[] getAll() { return Arrays.copyOfRange(storage, 0, size); } + public void save(Resume resume) { + if (getIndex(resume.getUuid()) >= 0) { + System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); + } else if (size >= STORAGE_LIMIT) { + System.out.println("Error: resume storage is full!"); + } else { + putResumeToStorage(resume); + size++; + } + } + protected abstract int getIndex(String uuid); + protected abstract void putResumeToStorage(Resume resume); + } diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index eca5cead..5dec91a7 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -25,15 +25,9 @@ public void update(Resume resume) { } } - public void save(Resume resume) { - if (getIndex(resume.getUuid()) != -1) { - System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); - } else if (size >= STORAGE_LIMIT) { - System.out.println("Error: resume storage is full!"); - } else { - storage[size] = resume; - size++; - } + @Override + protected void putResumeToStorage(Resume resume) { + storage[size] = resume; } public void delete(String uuid) { diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index 4d7e248b..9e5d65d3 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -27,19 +27,27 @@ public void update(Resume resume) { } } +// @Override +// public void save(Resume resume) { +// int index = getIndex(resume.getUuid()); +// if (index >= 0){ +// System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); +// } else if (size >= STORAGE_LIMIT) { +// System.out.println("Error: resume storage is full!"); +// } else { +// index = ~index; +// System.arraycopy(storage, index, storage, index + 1, size - index); +// storage[index] = resume; +// size++; +// } +// } + + @Override - public void save(Resume resume) { - int index = getIndex(resume.getUuid()); - if (index >= 0){ - System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); - } else if (size >= STORAGE_LIMIT) { - System.out.println("Error: resume storage is full!"); - } else { - index = ~index; - System.arraycopy(storage, index, storage, index + 1, size - index); - storage[index] = resume; - size++; - } + protected void putResumeToStorage(Resume resume) { + int index = ~getIndex(resume.getUuid()); + System.arraycopy(storage, index, storage, index + 1, size - index); + storage[index] = resume; } @Override From 5c1b95b88557f93160fee5f735479b8b85f70a74 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 9 Jun 2018 19:32:45 +0300 Subject: [PATCH 034/220] Add abstract method removeResumeFromStorage --- .../webapp/storage/AbstractArrayStorage.java | 12 +++++++++ .../javaops/webapp/storage/ArrayStorage.java | 14 +++------- .../webapp/storage/SortedArrayStorage.java | 26 ++----------------- 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 3c9a263d..e4cd433d 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -46,8 +46,20 @@ public void save(Resume resume) { } } + public void delete(String uuid) { + int index = getIndex(uuid); + if (index == -1) { + System.out.println("Error: resume with uuid: " + uuid + " not found!"); + } else { + size--; + removeResumeFromStorage(index); + } + } + protected abstract int getIndex(String uuid); protected abstract void putResumeToStorage(Resume resume); + protected abstract void removeResumeFromStorage(int index); + } diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 5dec91a7..c81fd28a 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -30,15 +30,9 @@ protected void putResumeToStorage(Resume resume) { storage[size] = resume; } - public void delete(String uuid) { - int index = getIndex(uuid); - if (index == -1) { - System.out.println("Error: resume with uuid: " + uuid + " not found!"); - } else { - size--; - storage[index] = storage[size]; - storage[size] = null; - } + @Override + protected void removeResumeFromStorage(int index) { + storage[index] = storage[size]; + storage[size] = null; } - } diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index 9e5d65d3..ba8189ff 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -27,22 +27,6 @@ public void update(Resume resume) { } } -// @Override -// public void save(Resume resume) { -// int index = getIndex(resume.getUuid()); -// if (index >= 0){ -// System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); -// } else if (size >= STORAGE_LIMIT) { -// System.out.println("Error: resume storage is full!"); -// } else { -// index = ~index; -// System.arraycopy(storage, index, storage, index + 1, size - index); -// storage[index] = resume; -// size++; -// } -// } - - @Override protected void putResumeToStorage(Resume resume) { int index = ~getIndex(resume.getUuid()); @@ -51,14 +35,8 @@ protected void putResumeToStorage(Resume resume) { } @Override - public void delete(String uuid) { - int index = getIndex(uuid); - if (index < 0) { - System.out.println("Error: resume with uuid: " + uuid + " not found!"); - } else { - size--; - System.arraycopy(storage, index + 1, storage, index, size - index); - } + protected void removeResumeFromStorage(int index) { + System.arraycopy(storage, index + 1, storage, index, size - index); } } From b8d36ea4a950e5e55f968289138d99787cac45d6 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 9 Jun 2018 19:49:03 +0300 Subject: [PATCH 035/220] Add abstract method removeResumeFromStorage --- src/ru/javaops/webapp/storage/AbstractArrayStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index e4cd433d..f57ec433 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -48,7 +48,7 @@ public void save(Resume resume) { public void delete(String uuid) { int index = getIndex(uuid); - if (index == -1) { + if (index < 0) { System.out.println("Error: resume with uuid: " + uuid + " not found!"); } else { size--; From fc276bbc01137822ac8a344b70a64c4b10237b5f Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 9 Jun 2018 20:00:26 +0300 Subject: [PATCH 036/220] Add abstract method updateResumeInStorage --- .../javaops/webapp/storage/AbstractArrayStorage.java | 11 +++++++++++ src/ru/javaops/webapp/storage/ArrayStorage.java | 9 +++------ src/ru/javaops/webapp/storage/SortedArrayStorage.java | 11 +++-------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index f57ec433..88c2ba7e 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -35,6 +35,15 @@ public Resume[] getAll() { return Arrays.copyOfRange(storage, 0, size); } + public void update(Resume resume) { + int index = getIndex(resume.getUuid()); + if (index < 0){ + System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); + } else { + updateResumeInStorage(resume); + } + } + public void save(Resume resume) { if (getIndex(resume.getUuid()) >= 0) { System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); @@ -58,6 +67,8 @@ public void delete(String uuid) { protected abstract int getIndex(String uuid); + protected abstract void updateResumeInStorage(Resume resume); + protected abstract void putResumeToStorage(Resume resume); protected abstract void removeResumeFromStorage(int index); diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index c81fd28a..a6b325aa 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -16,13 +16,10 @@ protected int getIndex(String uuid) { return -1; } - public void update(Resume resume) { + @Override + protected void updateResumeInStorage(Resume resume) { int index = getIndex(resume.getUuid()); - if (index == -1){ - System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); - } else { - storage[index] = resume; - } + storage[index] = resume; } @Override diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index ba8189ff..fd97c17b 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -17,14 +17,9 @@ protected int getIndex(String uuid) { } @Override - public void update(Resume resume) { - int index = getIndex(resume.getUuid()); - if (index < 0){ - System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); - } else { - delete(resume.getUuid()); - save(resume); - } + protected void updateResumeInStorage(Resume resume) { + delete(resume.getUuid()); + save(resume); } @Override From fb8327f7ce178dfa65c792b70493e723a86fe80a Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 11 Jun 2018 17:48:36 +0300 Subject: [PATCH 037/220] Add abstract method updateResumeInStorage --- src/ru/javaops/webapp/storage/AbstractArrayStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 88c2ba7e..500792d3 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -19,7 +19,7 @@ public int size() { public Resume get(String uuid) { int index = getIndex(uuid); - if (index == -1) { + if (index < 0) { System.out.println("Error: resume with uuid: " + uuid + " not found!"); return null; } From 8cbb8fc57a2697a7384d0596bc2bee6980191478 Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 11 Jun 2018 21:06:26 +0300 Subject: [PATCH 038/220] Add parameter index to method putResume --- .../webapp/storage/AbstractArrayStorage.java | 17 +++++++++-------- src/ru/javaops/webapp/storage/ArrayStorage.java | 11 ++--------- .../webapp/storage/SortedArrayStorage.java | 12 +++--------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 500792d3..96377903 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -40,17 +40,19 @@ public void update(Resume resume) { if (index < 0){ System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); } else { - updateResumeInStorage(resume); + delete(resume.getUuid()); + save(resume); } } public void save(Resume resume) { - if (getIndex(resume.getUuid()) >= 0) { + int index = getIndex(resume.getUuid()); + if (index >= 0) { System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); } else if (size >= STORAGE_LIMIT) { System.out.println("Error: resume storage is full!"); } else { - putResumeToStorage(resume); + putResume(index, resume); size++; } } @@ -61,16 +63,15 @@ public void delete(String uuid) { System.out.println("Error: resume with uuid: " + uuid + " not found!"); } else { size--; - removeResumeFromStorage(index); + removeResume(index); + storage[size] = null; } } protected abstract int getIndex(String uuid); - protected abstract void updateResumeInStorage(Resume resume); - - protected abstract void putResumeToStorage(Resume resume); + protected abstract void putResume(int index, Resume resume); - protected abstract void removeResumeFromStorage(int index); + protected abstract void removeResume(int index); } diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index a6b325aa..92898283 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -17,19 +17,12 @@ protected int getIndex(String uuid) { } @Override - protected void updateResumeInStorage(Resume resume) { - int index = getIndex(resume.getUuid()); - storage[index] = resume; - } - - @Override - protected void putResumeToStorage(Resume resume) { + protected void putResume(int index, Resume resume) { storage[size] = resume; } @Override - protected void removeResumeFromStorage(int index) { + protected void removeResume(int index) { storage[index] = storage[size]; - storage[size] = null; } } diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index fd97c17b..4d1d42e5 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -17,20 +17,14 @@ protected int getIndex(String uuid) { } @Override - protected void updateResumeInStorage(Resume resume) { - delete(resume.getUuid()); - save(resume); - } - - @Override - protected void putResumeToStorage(Resume resume) { - int index = ~getIndex(resume.getUuid()); + protected void putResume(int index, Resume resume) { + index = ~index; System.arraycopy(storage, index, storage, index + 1, size - index); storage[index] = resume; } @Override - protected void removeResumeFromStorage(int index) { + protected void removeResume(int index) { System.arraycopy(storage, index + 1, storage, index, size - index); } From 98de9825ba7c957d7cbfa2478558184de718a7b2 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 12 Jun 2018 00:02:46 +0300 Subject: [PATCH 039/220] class Resume - method set replace to constructor --- src/MainArray.java | 7 ++++--- src/MainTestArrayStorage.java | 13 ++++--------- src/ru/javaops/webapp/model/Resume.java | 8 ++++---- .../webapp/storage/AbstractArrayStorage.java | 3 +-- .../javaops/webapp/storage/SortedArrayStorage.java | 3 +-- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index 6cae2007..036b046f 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -1,4 +1,5 @@ import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.storage.ArrayStorage; import ru.javaops.webapp.storage.IStorage; import ru.javaops.webapp.storage.SortedArrayStorage; @@ -10,7 +11,8 @@ * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainArray { - private final static IStorage ARRAY_STORAGE = new SortedArrayStorage();//ArrayStorage(); + //private final static IStorage ARRAY_STORAGE = new ArrayStorage(); + private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); @@ -34,8 +36,7 @@ public static void main(String[] args) throws IOException { System.out.println(ARRAY_STORAGE.size()); break; case "save": - r = new Resume(); - r.setUuid(uuid); + r = new Resume(uuid); ARRAY_STORAGE.save(r); printAll(); break; diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index 5a3d9dd3..c678c277 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -11,12 +11,9 @@ public class MainTestArrayStorage { //private static final IStorage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) { - final Resume r1 = new Resume(); - r1.setUuid("uuid3"); - final Resume r2 = new Resume(); - r2.setUuid("uuid1"); - final Resume r3 = new Resume(); - r3.setUuid("uuid2"); + final Resume r1 = new Resume("uuid3"); + final Resume r2 = new Resume("uuid1"); + final Resume r3 = new Resume("uuid2"); ARRAY_STORAGE.save(r1); @@ -30,7 +27,6 @@ public static void main(String[] args) { //Test update method printAll(); - r3.setUuid("uuid4"); ARRAY_STORAGE.update(r3); printAll(); @@ -43,8 +39,7 @@ public static void main(String[] args) { //Test storage overflow for (int i = 0; i < 100001; i++){ - Resume resume = new Resume(); - resume.setUuid("uuid" + i); + Resume resume = new Resume("uuid" + i); ARRAY_STORAGE.save(resume); } } diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index ae80eb4c..761237c7 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -8,6 +8,10 @@ public class Resume implements Comparable{ // Unique identifier private String uuid; + public Resume(String uuid){ + this.uuid = uuid; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -27,10 +31,6 @@ public String getUuid() { return uuid; } - public void setUuid(String uuid) { - this.uuid = uuid; - } - @Override public String toString() { return uuid; diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 96377903..f8254b27 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -40,8 +40,7 @@ public void update(Resume resume) { if (index < 0){ System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); } else { - delete(resume.getUuid()); - save(resume); + storage[index] = resume; } } diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index 4d1d42e5..692b0cda 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -11,8 +11,7 @@ public class SortedArrayStorage extends AbstractArrayStorage{ @Override protected int getIndex(String uuid) { - Resume searchResume = new Resume(); - searchResume.setUuid(uuid); + Resume searchResume = new Resume(uuid); return Arrays.binarySearch(storage, 0, size, searchResume); } From 4350a007cd8ee6602287cbc79bf57086ca3fefef Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 12 Jun 2018 00:04:51 +0300 Subject: [PATCH 040/220] class Resume uuid is final --- src/ru/javaops/webapp/model/Resume.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 761237c7..91c128c6 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -6,7 +6,7 @@ public class Resume implements Comparable{ // Unique identifier - private String uuid; + private final String uuid; public Resume(String uuid){ this.uuid = uuid; From 1f27182d30cd870be211acc07aa640edfd4b40d8 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 11 Jul 2018 15:37:24 +0300 Subject: [PATCH 041/220] Add exceptions --- .../exception/ExistStorageException.java | 7 +++++++ .../exception/NotExistStorageException.java | 7 +++++++ .../webapp/exception/StorageException.java | 18 ++++++++++++++++++ src/ru/javaops/webapp/model/Resume.java | 6 ++++++ .../webapp/storage/AbstractArrayStorage.java | 12 +++++++----- 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 src/ru/javaops/webapp/exception/ExistStorageException.java create mode 100644 src/ru/javaops/webapp/exception/NotExistStorageException.java create mode 100644 src/ru/javaops/webapp/exception/StorageException.java diff --git a/src/ru/javaops/webapp/exception/ExistStorageException.java b/src/ru/javaops/webapp/exception/ExistStorageException.java new file mode 100644 index 00000000..cbbb4c03 --- /dev/null +++ b/src/ru/javaops/webapp/exception/ExistStorageException.java @@ -0,0 +1,7 @@ +package ru.javaops.webapp.exception; + +public class ExistStorageException extends StorageException { + public ExistStorageException(String uuid) { + super("Error: resume with uuid: " + uuid + " already exist!", uuid); + } +} diff --git a/src/ru/javaops/webapp/exception/NotExistStorageException.java b/src/ru/javaops/webapp/exception/NotExistStorageException.java new file mode 100644 index 00000000..5c3cae41 --- /dev/null +++ b/src/ru/javaops/webapp/exception/NotExistStorageException.java @@ -0,0 +1,7 @@ +package ru.javaops.webapp.exception; + +public class NotExistStorageException extends StorageException { + public NotExistStorageException(String uuid) { + super("Error: resume with uuid: " + uuid + " not found!", uuid); + } +} diff --git a/src/ru/javaops/webapp/exception/StorageException.java b/src/ru/javaops/webapp/exception/StorageException.java new file mode 100644 index 00000000..971852d5 --- /dev/null +++ b/src/ru/javaops/webapp/exception/StorageException.java @@ -0,0 +1,18 @@ +package ru.javaops.webapp.exception; + +public class StorageException extends RuntimeException { + private final String uuid; + + public StorageException(String uuid){ + this.uuid = uuid; + } + + public StorageException(String message, String uuid) { + super(message); + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } +} diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 91c128c6..bb4879aa 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,5 +1,7 @@ package ru.javaops.webapp.model; +import java.util.UUID; + /** * com.urise.webapp.model.ru.javaops.webapp.model.Resume class */ @@ -8,6 +10,10 @@ public class Resume implements Comparable{ // Unique identifier private final String uuid; + public Resume(){ + this(UUID.randomUUID().toString()); + } + public Resume(String uuid){ this.uuid = uuid; } diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index f8254b27..c565dbe8 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -1,5 +1,8 @@ package ru.javaops.webapp.storage; +import ru.javaops.webapp.exception.ExistStorageException; +import ru.javaops.webapp.exception.NotExistStorageException; +import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; import java.util.Arrays; @@ -20,8 +23,7 @@ public int size() { public Resume get(String uuid) { int index = getIndex(uuid); if (index < 0) { - System.out.println("Error: resume with uuid: " + uuid + " not found!"); - return null; + throw new NotExistStorageException(uuid); } return storage[index]; } @@ -38,7 +40,7 @@ public Resume[] getAll() { public void update(Resume resume) { int index = getIndex(resume.getUuid()); if (index < 0){ - System.out.println("Error: resume with uuid: " + resume.getUuid() + " not found!"); + throw new NotExistStorageException(resume.getUuid()); } else { storage[index] = resume; } @@ -47,9 +49,9 @@ public void update(Resume resume) { public void save(Resume resume) { int index = getIndex(resume.getUuid()); if (index >= 0) { - System.out.println("Error: resume with uuid: " + resume.getUuid() + " already exist!"); + throw new ExistStorageException(resume.getUuid()); } else if (size >= STORAGE_LIMIT) { - System.out.println("Error: resume storage is full!"); + throw new StorageException("Error: resume storage is full!", resume.getUuid()); } else { putResume(index, resume); size++; From 8047a56530eb9cc708451ed149af5585a62c8874 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 16 Jul 2018 16:59:41 +0300 Subject: [PATCH 042/220] MainReflection --- src/MainReflection.java | 21 +++++++ .../storage/AbstractArrayStorageTest.java | 61 +++++++++++++++++++ .../webapp/storage/ArrayStorageTest.java | 7 +++ .../storage/SortedArrayStorageTest.java | 7 +++ 4 files changed, 96 insertions(+) create mode 100644 src/MainReflection.java create mode 100644 test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java create mode 100644 test/ru/javaops/webapp/storage/ArrayStorageTest.java create mode 100644 test/ru/javaops/webapp/storage/SortedArrayStorageTest.java diff --git a/src/MainReflection.java b/src/MainReflection.java new file mode 100644 index 00000000..dfd59d2c --- /dev/null +++ b/src/MainReflection.java @@ -0,0 +1,21 @@ +import ru.javaops.webapp.model.Resume; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class MainReflection { + public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + Resume r = new Resume(); + Field field = r.getClass().getDeclaredFields()[0]; + field.setAccessible(true); + System.out.println(field.getName()); + System.out.println(field.get(r)); + field.set(r, "new_uuid"); + System.out.println(r); + + Class resumeClass = Resume.class; + Method method = resumeClass.getDeclaredMethod("toString", null); + System.out.println(method.invoke(r, null)); + } +} diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java new file mode 100644 index 00000000..8a1714d9 --- /dev/null +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -0,0 +1,61 @@ +package ru.javaops.webapp.storage; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import ru.javaops.webapp.exception.NotExistStorageException; +import ru.javaops.webapp.model.Resume; + +import java.util.UUID; + +import static org.junit.Assert.*; + +public abstract class AbstractArrayStorageTest { + private IStorage storage; + + private static final String UUID_1 = "uuid1"; + private static final String UUID_2 = "uuid2"; + private static final String UUID_3 = "uuid3"; + + @Before + public void setUp() throws Exception{ + storage.clear(); + storage.save(new Resume(UUID_1)); + storage.save(new Resume(UUID_2)); + storage.save(new Resume(UUID_3)); + } + + @Test + public void size() { + Assert.assertEquals(3, storage.size()); + } + + @Test + public void get() { + } + + @Test + public void clear() { + } + + @Test + public void getAll() { + } + + @Test + public void update() { + } + + @Test + public void save() { + } + + @Test + public void delete() { + } + + @Test(expected = NotExistStorageException.class) + public void getNotExist() throws Exception { + storage.get("dummy"); + } +} \ No newline at end of file diff --git a/test/ru/javaops/webapp/storage/ArrayStorageTest.java b/test/ru/javaops/webapp/storage/ArrayStorageTest.java new file mode 100644 index 00000000..895fa509 --- /dev/null +++ b/test/ru/javaops/webapp/storage/ArrayStorageTest.java @@ -0,0 +1,7 @@ +package ru.javaops.webapp.storage; + +import static org.junit.Assert.*; + +public class ArrayStorageTest extends AbstractArrayStorageTest { + +} \ No newline at end of file diff --git a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java new file mode 100644 index 00000000..70234e9a --- /dev/null +++ b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java @@ -0,0 +1,7 @@ +package ru.javaops.webapp.storage; + +import static org.junit.Assert.*; + +public class SortedArrayStorageTest extends AbstractArrayStorageTest { + +} \ No newline at end of file From 94a893c16c0f943165d4845d463d5b765db4780c Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 16 Jul 2018 17:14:30 +0300 Subject: [PATCH 043/220] MainReflection, add try-catch --- src/MainReflection.java | 11 +++++++++-- .../webapp/storage/AbstractArrayStorageTest.java | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/MainReflection.java b/src/MainReflection.java index dfd59d2c..fc61ed39 100644 --- a/src/MainReflection.java +++ b/src/MainReflection.java @@ -15,7 +15,14 @@ public static void main(String[] args) throws IllegalAccessException, NoSuchMeth System.out.println(r); Class resumeClass = Resume.class; - Method method = resumeClass.getDeclaredMethod("toString", null); - System.out.println(method.invoke(r, null)); + try { + Method method = resumeClass.getDeclaredMethod("toString", null); + System.out.println(method.invoke(r, null)); + }catch (NoSuchMethodException e1){ + System.out.println(e1.getMessage()); + }catch (InvocationTargetException e2){ + System.out.println(e2.getMessage()); + } + } } diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 8a1714d9..d4549c75 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -32,6 +32,7 @@ public void size() { @Test public void get() { + } @Test From 3a1b18e1879f0bb36cf7231dcd2e94f38f2c332a Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 10:46:20 +0300 Subject: [PATCH 044/220] AbstractArrayStorageTests --- .../storage/AbstractArrayStorageTest.java | 20 ++++++++++++++++--- .../webapp/storage/ArrayStorageTest.java | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index d4549c75..8cdd9f0c 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.*; public abstract class AbstractArrayStorageTest { - private IStorage storage; + private IStorage storage = new ArrayStorage(); private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; @@ -32,27 +32,41 @@ public void size() { @Test public void get() { - + Assert.assertEquals("uuid1", storage.get(UUID_1).toString()); + Assert.assertEquals("uuid2", storage.get(UUID_2).toString()); + Assert.assertEquals("uuid3", storage.get(UUID_3).toString()); } @Test public void clear() { + storage.clear(); + Assert.assertEquals(0, storage.size()); } @Test public void getAll() { + Resume[] all = storage.getAll(); + Assert.assertArrayEquals(all, storage.getAll()); } @Test public void update() { + Resume resume = storage.get("uuid3"); + storage.update(resume); + Assert.assertEquals(resume, storage.get(resume.getUuid())); } @Test public void save() { + final String UUID_4 = "uuid4"; + storage.save(new Resume(UUID_4)); + Assert.assertEquals("uuid4", storage.get("uuid4").toString()); } - @Test + @Test(expected = NotExistStorageException.class) public void delete() { + storage.delete("uuid4"); + storage.get("uuid4"); } @Test(expected = NotExistStorageException.class) diff --git a/test/ru/javaops/webapp/storage/ArrayStorageTest.java b/test/ru/javaops/webapp/storage/ArrayStorageTest.java index 895fa509..f67db0d8 100644 --- a/test/ru/javaops/webapp/storage/ArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/ArrayStorageTest.java @@ -3,5 +3,5 @@ import static org.junit.Assert.*; public class ArrayStorageTest extends AbstractArrayStorageTest { - + //private IStorage storage = new ArrayStorage(); } \ No newline at end of file From 568e4b8671856c0aa69cc58d4d12dc66be14cc71 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 11:52:32 +0300 Subject: [PATCH 045/220] Add ArrayStorageTest and SortedArrayStorageTest --- .../ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 6 +++++- test/ru/javaops/webapp/storage/ArrayStorageTest.java | 6 +++++- test/ru/javaops/webapp/storage/SortedArrayStorageTest.java | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 8cdd9f0c..34329b6c 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -11,7 +11,11 @@ import static org.junit.Assert.*; public abstract class AbstractArrayStorageTest { - private IStorage storage = new ArrayStorage(); + private IStorage storage; + + public AbstractArrayStorageTest(IStorage storage){ + this.storage = storage; + } private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; diff --git a/test/ru/javaops/webapp/storage/ArrayStorageTest.java b/test/ru/javaops/webapp/storage/ArrayStorageTest.java index f67db0d8..ce15be49 100644 --- a/test/ru/javaops/webapp/storage/ArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/ArrayStorageTest.java @@ -3,5 +3,9 @@ import static org.junit.Assert.*; public class ArrayStorageTest extends AbstractArrayStorageTest { - //private IStorage storage = new ArrayStorage(); + private final static IStorage ARRAY_STORAGE = new ArrayStorage(); + + public ArrayStorageTest() { + super(ARRAY_STORAGE); + } } \ No newline at end of file diff --git a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java index 70234e9a..8036411d 100644 --- a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java @@ -3,5 +3,9 @@ import static org.junit.Assert.*; public class SortedArrayStorageTest extends AbstractArrayStorageTest { + private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); + public SortedArrayStorageTest() { + super(ARRAY_STORAGE); + } } \ No newline at end of file From 4254d547b0dd2ad5426aab7cf966c7dec2d2d409 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 12:06:39 +0300 Subject: [PATCH 046/220] Add Test storageOverflow --- .../webapp/storage/AbstractArrayStorageTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 34329b6c..732b4f58 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -77,4 +77,16 @@ public void delete() { public void getNotExist() throws Exception { storage.get("dummy"); } + + @Test + public void storageOverflow() throws Exception { + try{ + for (int i = 0; i < 100001; i++){ + storage.save(new Resume()); + } + fail("Exception not thrown"); + }catch(Exception e){ + assertEquals("Error: resume storage is full!", e.getMessage()); + } + } } \ No newline at end of file From bb751809562748404bbc422ce8f8507db2159f79 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 12:49:13 +0300 Subject: [PATCH 047/220] Some fix in Tests --- .../javaops/webapp/storage/AbstractArrayStorageTest.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 732b4f58..62944fd5 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -62,15 +62,14 @@ public void update() { @Test public void save() { - final String UUID_4 = "uuid4"; - storage.save(new Resume(UUID_4)); - Assert.assertEquals("uuid4", storage.get("uuid4").toString()); + storage.save(new Resume("uuid9")); + Assert.assertEquals("uuid9", storage.get("uuid9").toString()); } @Test(expected = NotExistStorageException.class) public void delete() { - storage.delete("uuid4"); - storage.get("uuid4"); + storage.delete("uuid3"); + storage.get("uuid3"); } @Test(expected = NotExistStorageException.class) From dc9a16285b4d8e63273ebc065b1ea9f3a50ecd49 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 12:58:22 +0300 Subject: [PATCH 048/220] Some fix in Tests --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 62944fd5..e8614fa1 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -67,7 +67,7 @@ public void save() { } @Test(expected = NotExistStorageException.class) - public void delete() { + public void delete() throws Exception { storage.delete("uuid3"); storage.get("uuid3"); } From d7f635cc70fcbfc6df6a4349c222fbbfae0d8701 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 13:18:21 +0300 Subject: [PATCH 049/220] MainReflection collapse catch --- src/MainReflection.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/MainReflection.java b/src/MainReflection.java index fc61ed39..18729a4e 100644 --- a/src/MainReflection.java +++ b/src/MainReflection.java @@ -18,10 +18,8 @@ public static void main(String[] args) throws IllegalAccessException, NoSuchMeth try { Method method = resumeClass.getDeclaredMethod("toString", null); System.out.println(method.invoke(r, null)); - }catch (NoSuchMethodException e1){ + }catch (NoSuchMethodException | InvocationTargetException e1){ System.out.println(e1.getMessage()); - }catch (InvocationTargetException e2){ - System.out.println(e2.getMessage()); } } From 96356d0f72cdc26ae55d06a3f117f6285c2f33a1 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 13:25:14 +0300 Subject: [PATCH 050/220] MainReflection collapse catch --- src/MainReflection.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MainReflection.java b/src/MainReflection.java index 18729a4e..68658ef6 100644 --- a/src/MainReflection.java +++ b/src/MainReflection.java @@ -16,10 +16,10 @@ public static void main(String[] args) throws IllegalAccessException, NoSuchMeth Class resumeClass = Resume.class; try { - Method method = resumeClass.getDeclaredMethod("toString", null); - System.out.println(method.invoke(r, null)); - }catch (NoSuchMethodException | InvocationTargetException e1){ - System.out.println(e1.getMessage()); + Method method = resumeClass.getDeclaredMethod("toString", (Class[]) null); + System.out.println(method.invoke(r, (Object[]) null)); + }catch (NoSuchMethodException | InvocationTargetException e){ + System.out.println(e.getMessage()); } } From 74b9f54ac1f97a3f846e48f9c25dadba5a29620c Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 13:29:18 +0300 Subject: [PATCH 051/220] MainReflection collapse catch --- src/MainReflection.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MainReflection.java b/src/MainReflection.java index 68658ef6..8f7691e3 100644 --- a/src/MainReflection.java +++ b/src/MainReflection.java @@ -5,7 +5,8 @@ import java.lang.reflect.Method; public class MainReflection { - public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + @SuppressWarnings("unchecked") + public static void main(String[] args) throws IllegalAccessException { Resume r = new Resume(); Field field = r.getClass().getDeclaredFields()[0]; field.setAccessible(true); From 0c8b9633347370acd1534ae179f7cd8d6d6520c7 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 13:32:03 +0300 Subject: [PATCH 052/220] Remove redundant Exceptions from AbstractArrayStorageTest --- .../webapp/storage/AbstractArrayStorageTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index e8614fa1..b9db151a 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -22,7 +22,7 @@ public AbstractArrayStorageTest(IStorage storage){ private static final String UUID_3 = "uuid3"; @Before - public void setUp() throws Exception{ + public void setUp() { storage.clear(); storage.save(new Resume(UUID_1)); storage.save(new Resume(UUID_2)); @@ -67,24 +67,24 @@ public void save() { } @Test(expected = NotExistStorageException.class) - public void delete() throws Exception { + public void delete() { storage.delete("uuid3"); storage.get("uuid3"); } @Test(expected = NotExistStorageException.class) - public void getNotExist() throws Exception { + public void getNotExist() { storage.get("dummy"); } @Test - public void storageOverflow() throws Exception { + public void storageOverflow() { try{ for (int i = 0; i < 100001; i++){ storage.save(new Resume()); } fail("Exception not thrown"); - }catch(Exception e){ + } catch(Exception e) { assertEquals("Error: resume storage is full!", e.getMessage()); } } From 6aa2c31162c44c3b91d370410ca199dd2744e532 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 13:35:27 +0300 Subject: [PATCH 053/220] Delete unused imports in Tests --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 2 -- test/ru/javaops/webapp/storage/ArrayStorageTest.java | 2 -- test/ru/javaops/webapp/storage/SortedArrayStorageTest.java | 2 -- 3 files changed, 6 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index b9db151a..0c877813 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -6,8 +6,6 @@ import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; -import java.util.UUID; - import static org.junit.Assert.*; public abstract class AbstractArrayStorageTest { diff --git a/test/ru/javaops/webapp/storage/ArrayStorageTest.java b/test/ru/javaops/webapp/storage/ArrayStorageTest.java index ce15be49..5f1c23a9 100644 --- a/test/ru/javaops/webapp/storage/ArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/ArrayStorageTest.java @@ -1,7 +1,5 @@ package ru.javaops.webapp.storage; -import static org.junit.Assert.*; - public class ArrayStorageTest extends AbstractArrayStorageTest { private final static IStorage ARRAY_STORAGE = new ArrayStorage(); diff --git a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java index 8036411d..24be36f4 100644 --- a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java @@ -1,7 +1,5 @@ package ru.javaops.webapp.storage; -import static org.junit.Assert.*; - public class SortedArrayStorageTest extends AbstractArrayStorageTest { private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); From 13b7fa22c043bbd28952959a1691c1fd1ea12c54 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 16:02:41 +0300 Subject: [PATCH 054/220] Error correction --- .../storage/AbstractArrayStorageTest.java | 22 +++++++++++-------- .../webapp/storage/ArrayStorageTest.java | 4 +--- .../storage/SortedArrayStorageTest.java | 4 +--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 0c877813..894ce0ad 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -6,7 +6,10 @@ import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; +import java.util.Arrays; + import static org.junit.Assert.*; +import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; public abstract class AbstractArrayStorageTest { private IStorage storage; @@ -18,13 +21,16 @@ public AbstractArrayStorageTest(IStorage storage){ private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; + private static final Resume resume1 = new Resume(UUID_1); + private static final Resume resume2 = new Resume(UUID_2); + private static final Resume resume3 = new Resume(UUID_3); @Before public void setUp() { storage.clear(); - storage.save(new Resume(UUID_1)); - storage.save(new Resume(UUID_2)); - storage.save(new Resume(UUID_3)); + storage.save(resume1); + storage.save(resume2); + storage.save(resume3); } @Test @@ -34,9 +40,7 @@ public void size() { @Test public void get() { - Assert.assertEquals("uuid1", storage.get(UUID_1).toString()); - Assert.assertEquals("uuid2", storage.get(UUID_2).toString()); - Assert.assertEquals("uuid3", storage.get(UUID_3).toString()); + Assert.assertEquals(resume1, storage.get(UUID_1)); } @Test @@ -47,13 +51,13 @@ public void clear() { @Test public void getAll() { - Resume[] all = storage.getAll(); + Resume[] all = new Resume[]{resume1, resume2, resume3}; Assert.assertArrayEquals(all, storage.getAll()); } @Test public void update() { - Resume resume = storage.get("uuid3"); + Resume resume = storage.get(UUID_3); storage.update(resume); Assert.assertEquals(resume, storage.get(resume.getUuid())); } @@ -78,7 +82,7 @@ public void getNotExist() { @Test public void storageOverflow() { try{ - for (int i = 0; i < 100001; i++){ + for (int i = storage.size(); i < STORAGE_LIMIT + 1; i++){ storage.save(new Resume()); } fail("Exception not thrown"); diff --git a/test/ru/javaops/webapp/storage/ArrayStorageTest.java b/test/ru/javaops/webapp/storage/ArrayStorageTest.java index 5f1c23a9..bc6dcbaa 100644 --- a/test/ru/javaops/webapp/storage/ArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/ArrayStorageTest.java @@ -1,9 +1,7 @@ package ru.javaops.webapp.storage; public class ArrayStorageTest extends AbstractArrayStorageTest { - private final static IStorage ARRAY_STORAGE = new ArrayStorage(); - public ArrayStorageTest() { - super(ARRAY_STORAGE); + super(new ArrayStorage()); } } \ No newline at end of file diff --git a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java index 24be36f4..f170edf6 100644 --- a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java @@ -1,9 +1,7 @@ package ru.javaops.webapp.storage; public class SortedArrayStorageTest extends AbstractArrayStorageTest { - private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); - public SortedArrayStorageTest() { - super(ARRAY_STORAGE); + super(new SortedArrayStorage()); } } \ No newline at end of file From 2d67f95ef985be20ef6e4efa2deab98c20bab170 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 16:51:59 +0300 Subject: [PATCH 055/220] Group methods, add throw StorageException to AbstractArrayStorage delete method --- .../webapp/storage/AbstractArrayStorage.java | 2 +- .../storage/AbstractArrayStorageTest.java | 38 +++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index c565dbe8..3c448a90 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -61,7 +61,7 @@ public void save(Resume resume) { public void delete(String uuid) { int index = getIndex(uuid); if (index < 0) { - System.out.println("Error: resume with uuid: " + uuid + " not found!"); + throw new NotExistStorageException(uuid); } else { size--; removeResume(index); diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 894ce0ad..988d92c1 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -3,7 +3,9 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; +import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; import java.util.Arrays; @@ -43,18 +45,17 @@ public void get() { Assert.assertEquals(resume1, storage.get(UUID_1)); } - @Test - public void clear() { - storage.clear(); - Assert.assertEquals(0, storage.size()); - } - @Test public void getAll() { Resume[] all = new Resume[]{resume1, resume2, resume3}; Assert.assertArrayEquals(all, storage.getAll()); } + @Test(expected = NotExistStorageException.class) + public void getNotExist() { + storage.get("dummy"); + } + @Test public void update() { Resume resume = storage.get(UUID_3); @@ -68,6 +69,11 @@ public void save() { Assert.assertEquals("uuid9", storage.get("uuid9").toString()); } + @Test(expected = ExistStorageException.class) + public void saveStorageException() { + storage.save(resume1); + } + @Test(expected = NotExistStorageException.class) public void delete() { storage.delete("uuid3"); @@ -75,19 +81,21 @@ public void delete() { } @Test(expected = NotExistStorageException.class) - public void getNotExist() { - storage.get("dummy"); + public void deleteStorageException() { + storage.delete(new Resume().getUuid()); } @Test + public void clear() { + storage.clear(); + Assert.assertEquals(0, storage.size()); + } + + @Test(expected = StorageException.class) public void storageOverflow() { - try{ - for (int i = storage.size(); i < STORAGE_LIMIT + 1; i++){ - storage.save(new Resume()); - } - fail("Exception not thrown"); - } catch(Exception e) { - assertEquals("Error: resume storage is full!", e.getMessage()); + for (int i = storage.size(); i < STORAGE_LIMIT + 1; i++) { + storage.save(new Resume()); } + fail("Exception not thrown"); } } \ No newline at end of file From 9fdd09d6b81da5c83655e56f818d33d2ad144e80 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 16:58:39 +0300 Subject: [PATCH 056/220] Group methods, add throw StorageException to AbstractArrayStorage delete method --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 988d92c1..fd6d4f4d 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -76,8 +76,8 @@ public void saveStorageException() { @Test(expected = NotExistStorageException.class) public void delete() { - storage.delete("uuid3"); - storage.get("uuid3"); + storage.delete(UUID_3); + storage.get(UUID_3); } @Test(expected = NotExistStorageException.class) From 5b4aafc4547f2f74407d2978ab05c75362577f21 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 17:26:24 +0300 Subject: [PATCH 057/220] class AbstractArrayStorageTest, private final IStorage storage --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index fd6d4f4d..093bfe64 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -14,7 +14,7 @@ import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; public abstract class AbstractArrayStorageTest { - private IStorage storage; + private final IStorage storage; public AbstractArrayStorageTest(IStorage storage){ this.storage = storage; From f9d98f03c3a7f02048e8df3fe1478490536e1a6b Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 17 Jul 2018 17:27:52 +0300 Subject: [PATCH 058/220] AbstractArrayStorageTest delete unused imports --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 093bfe64..cf6abfc6 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -8,8 +8,6 @@ import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import java.util.Arrays; - import static org.junit.Assert.*; import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; From 6ba7a39d609bae0da144dae72971448f5a87f0ce Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 17 Jul 2018 23:23:33 +0300 Subject: [PATCH 059/220] HW4, Work on bugs 2 --- .../storage/AbstractArrayStorageTest.java | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index cf6abfc6..85adeb8a 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -5,7 +5,6 @@ import org.junit.Test; import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; -import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; import static org.junit.Assert.*; @@ -14,10 +13,6 @@ public abstract class AbstractArrayStorageTest { private final IStorage storage; - public AbstractArrayStorageTest(IStorage storage){ - this.storage = storage; - } - private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; @@ -25,6 +20,10 @@ public AbstractArrayStorageTest(IStorage storage){ private static final Resume resume2 = new Resume(UUID_2); private static final Resume resume3 = new Resume(UUID_3); + public AbstractArrayStorageTest(IStorage storage){ + this.storage = storage; + } + @Before public void setUp() { storage.clear(); @@ -43,35 +42,48 @@ public void get() { Assert.assertEquals(resume1, storage.get(UUID_1)); } - @Test - public void getAll() { - Resume[] all = new Resume[]{resume1, resume2, resume3}; - Assert.assertArrayEquals(all, storage.getAll()); - } - @Test(expected = NotExistStorageException.class) public void getNotExist() { storage.get("dummy"); } + @Test + public void getAll() { + Resume[] resumes = new Resume[]{resume1, resume2, resume3}; + Assert.assertArrayEquals(resumes, storage.getAll()); + } + @Test public void update() { Resume resume = storage.get(UUID_3); storage.update(resume); - Assert.assertEquals(resume, storage.get(resume.getUuid())); + Assert.assertEquals(resume, storage.get(UUID_3)); } @Test public void save() { - storage.save(new Resume("uuid9")); - Assert.assertEquals("uuid9", storage.get("uuid9").toString()); + Resume resume = new Resume(); + storage.save(resume); + Assert.assertEquals(resume, storage.get(resume.getUuid())); } @Test(expected = ExistStorageException.class) - public void saveStorageException() { + public void saveExistStorageException() { storage.save(resume1); } + @Test + public void storageOverflow() { + try { + for (int i = storage.size(); i <= STORAGE_LIMIT; i++) { + storage.save(new Resume()); + } + fail("Exception not thrown"); + } catch (Exception e) { + Assert.assertEquals("Error: resume storage is full!", e.getMessage()); + } + } + @Test(expected = NotExistStorageException.class) public void delete() { storage.delete(UUID_3); @@ -79,7 +91,7 @@ public void delete() { } @Test(expected = NotExistStorageException.class) - public void deleteStorageException() { + public void deleteNotExistStorageException() { storage.delete(new Resume().getUuid()); } @@ -88,12 +100,4 @@ public void clear() { storage.clear(); Assert.assertEquals(0, storage.size()); } - - @Test(expected = StorageException.class) - public void storageOverflow() { - for (int i = storage.size(); i < STORAGE_LIMIT + 1; i++) { - storage.save(new Resume()); - } - fail("Exception not thrown"); - } } \ No newline at end of file From d350783960cd15d439f935ff85d2bdfcdc292274 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 18 Jul 2018 09:37:59 +0300 Subject: [PATCH 060/220] storageOverflow fix iteration --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 85adeb8a..da0da58a 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -75,9 +75,10 @@ public void saveExistStorageException() { @Test public void storageOverflow() { try { - for (int i = storage.size(); i <= STORAGE_LIMIT; i++) { + for (int i = storage.size(); i < STORAGE_LIMIT; i++) { storage.save(new Resume()); } + storage.save(new Resume()); fail("Exception not thrown"); } catch (Exception e) { Assert.assertEquals("Error: resume storage is full!", e.getMessage()); From 81bd80cbb1350525a975defa05fc2e6f56ae0cda Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 18 Jul 2018 09:46:28 +0300 Subject: [PATCH 061/220] storageOverflow fix iteration --- .../ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index da0da58a..a6a08b36 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -74,10 +74,10 @@ public void saveExistStorageException() { @Test public void storageOverflow() { + for (int i = storage.size(); i < STORAGE_LIMIT; i++) { + storage.save(new Resume()); + } try { - for (int i = storage.size(); i < STORAGE_LIMIT; i++) { - storage.save(new Resume()); - } storage.save(new Resume()); fail("Exception not thrown"); } catch (Exception e) { From 0baaeef43824c0e42d88e8474860e4635d084e45 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 19 Jul 2018 00:11:04 +0300 Subject: [PATCH 062/220] storageOverflow test add second try/catch --- .../javaops/webapp/storage/AbstractArrayStorageTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index a6a08b36..8aac9d0b 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -74,12 +74,15 @@ public void saveExistStorageException() { @Test public void storageOverflow() { - for (int i = storage.size(); i < STORAGE_LIMIT; i++) { - storage.save(new Resume()); + try { + for (int i = storage.size(); i < STORAGE_LIMIT; i++) { + storage.save(new Resume()); + } + } catch (Exception e) { + fail("Storage is not full filled!"); } try { storage.save(new Resume()); - fail("Exception not thrown"); } catch (Exception e) { Assert.assertEquals("Error: resume storage is full!", e.getMessage()); } From 7f729a4941003197003eba37f0f686d52932fdbb Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 19 Jul 2018 00:22:21 +0300 Subject: [PATCH 063/220] storageOverflow test add second try/catch --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 8aac9d0b..89beb9f7 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -79,7 +79,7 @@ public void storageOverflow() { storage.save(new Resume()); } } catch (Exception e) { - fail("Storage is not full filled!"); + fail("Storage is not full filled! " + "Exception: " + e.getMessage()); } try { storage.save(new Resume()); From c308144a74a32770d599085e264977dabf4fedd6 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 19 Jul 2018 09:38:36 +0300 Subject: [PATCH 064/220] storageOverflow fix --- .../javaops/webapp/storage/AbstractArrayStorageTest.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 89beb9f7..d8db8d78 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; +import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; import static org.junit.Assert.*; @@ -72,7 +73,7 @@ public void saveExistStorageException() { storage.save(resume1); } - @Test + @Test(expected = StorageException.class) public void storageOverflow() { try { for (int i = storage.size(); i < STORAGE_LIMIT; i++) { @@ -81,11 +82,7 @@ public void storageOverflow() { } catch (Exception e) { fail("Storage is not full filled! " + "Exception: " + e.getMessage()); } - try { - storage.save(new Resume()); - } catch (Exception e) { - Assert.assertEquals("Error: resume storage is full!", e.getMessage()); - } + storage.save(new Resume()); } @Test(expected = NotExistStorageException.class) From 3ad197922a0d3cb6c1259817da3629177606c8e0 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 19 Jul 2018 15:28:29 +0300 Subject: [PATCH 065/220] add methods compareSize, compareResume --- src/MainReflection.java | 2 +- .../storage/AbstractArrayStorageTest.java | 28 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/MainReflection.java b/src/MainReflection.java index 8f7691e3..2de6b9ea 100644 --- a/src/MainReflection.java +++ b/src/MainReflection.java @@ -19,7 +19,7 @@ public static void main(String[] args) throws IllegalAccessException { try { Method method = resumeClass.getDeclaredMethod("toString", (Class[]) null); System.out.println(method.invoke(r, (Object[]) null)); - }catch (NoSuchMethodException | InvocationTargetException e){ + } catch (NoSuchMethodException | InvocationTargetException e) { System.out.println(e.getMessage()); } diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index d8db8d78..a4ef44c1 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -21,7 +21,7 @@ public abstract class AbstractArrayStorageTest { private static final Resume resume2 = new Resume(UUID_2); private static final Resume resume3 = new Resume(UUID_3); - public AbstractArrayStorageTest(IStorage storage){ + public AbstractArrayStorageTest(IStorage storage) { this.storage = storage; } @@ -35,12 +35,12 @@ public void setUp() { @Test public void size() { - Assert.assertEquals(3, storage.size()); + compareSize(3); } @Test public void get() { - Assert.assertEquals(resume1, storage.get(UUID_1)); + compareResume(resume1); } @Test(expected = NotExistStorageException.class) @@ -58,14 +58,21 @@ public void getAll() { public void update() { Resume resume = storage.get(UUID_3); storage.update(resume); - Assert.assertEquals(resume, storage.get(UUID_3)); + compareSize(3); + compareResume(resume); + } + + @Test(expected = NotExistStorageException.class) + public void updateNotExist() { + storage.update(new Resume()); } @Test public void save() { Resume resume = new Resume(); storage.save(resume); - Assert.assertEquals(resume, storage.get(resume.getUuid())); + compareSize(4); + compareResume(resume); } @Test(expected = ExistStorageException.class) @@ -88,6 +95,7 @@ public void storageOverflow() { @Test(expected = NotExistStorageException.class) public void delete() { storage.delete(UUID_3); + compareSize(2); storage.get(UUID_3); } @@ -99,6 +107,14 @@ public void deleteNotExistStorageException() { @Test public void clear() { storage.clear(); - Assert.assertEquals(0, storage.size()); + compareSize(0); + } + + private void compareSize(int size){ + Assert.assertEquals(size, storage.size()); + } + + private void compareResume(Resume resume){ + Assert.assertEquals(resume, storage.get(resume.getUuid())); } } \ No newline at end of file From 812c0ba77c2ea145ca5e05c396a3026fb6ddc1c9 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 25 Jul 2018 19:11:52 +0300 Subject: [PATCH 066/220] HW5, begin --- .../webapp/storage/AbstractArrayStorage.java | 7 +++- .../webapp/storage/AbstractStorage.java | 41 +++++++++++++++++++ .../javaops/webapp/storage/ListStorage.java | 29 +++++++++++++ src/ru/javaops/webapp/storage/MapStorage.java | 21 ++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/ru/javaops/webapp/storage/AbstractStorage.java create mode 100644 src/ru/javaops/webapp/storage/ListStorage.java create mode 100644 src/ru/javaops/webapp/storage/MapStorage.java diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 3c448a90..8a1ce095 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -6,16 +6,21 @@ import ru.javaops.webapp.model.Resume; import java.util.Arrays; +import java.util.Collection; /** * Array based storage for Resumes */ -public abstract class AbstractArrayStorage implements IStorage { +public abstract class AbstractArrayStorage extends AbstractStorage implements IStorage { protected static final int STORAGE_LIMIT = 100000; protected final Resume[] storage = new Resume[STORAGE_LIMIT]; protected int size = 0; + protected AbstractArrayStorage() {//??? + super(null); + } + public int size() { return size; } diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java new file mode 100644 index 00000000..3ee0910d --- /dev/null +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -0,0 +1,41 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.util.Collection; + +public abstract class AbstractStorage implements IStorage{ + + protected static Collection storage; + + protected AbstractStorage(Collection newStorage){ + storage = newStorage; + } + + public void clear(){ + storage.clear(); + } + + public abstract Resume get(String uuid); + + public void update(Resume resume){ + + } + + public abstract void save(Resume resume); + + public void delete(String uuid){ +// Resume resume = new Resume(); +// resume = storage. +// storage.remove(); + } + + public Resume[] getAll(){ + return storage.toArray(new Resume[storage.size()]); + } + + public int size(){ + return storage.size(); + } + +} diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java new file mode 100644 index 00000000..be63ebb4 --- /dev/null +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -0,0 +1,29 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.util.ArrayList; +import java.util.Iterator; + +public class ListStorage extends AbstractStorage { + + protected ListStorage() { + super(new ArrayList()); + } + + @Override + public Resume get(String uuid) { + Iterator iterator = storage.iterator(); + while (iterator.hasNext()){ + if (iterator.next().getUuid().equals(uuid)){ + return iterator.next(); + } + } + return null; + } + + @Override + public void save(Resume resume) { + storage.add(resume); + } +} diff --git a/src/ru/javaops/webapp/storage/MapStorage.java b/src/ru/javaops/webapp/storage/MapStorage.java new file mode 100644 index 00000000..7b04c4a2 --- /dev/null +++ b/src/ru/javaops/webapp/storage/MapStorage.java @@ -0,0 +1,21 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + + +public class MapStorage extends AbstractStorage { + + protected MapStorage(){ + super(null); + } + + @Override + public Resume get(String uuid) { + return null; + } + + @Override + public void save(Resume resume) { + + } +} From 01212e103b4bda4ca9e96dbdb33a2e8c44408d7a Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 26 Jul 2018 17:50:18 +0300 Subject: [PATCH 067/220] HW5, begin --- src/MainArray.java | 5 ++++- src/ru/javaops/webapp/storage/AbstractStorage.java | 13 ++++++++++--- src/ru/javaops/webapp/storage/ListStorage.java | 2 +- .../webapp/storage/AbstractStorageTest.java | 14 ++++++++++++++ .../ru/javaops/webapp/storage/ListStorageTest.java | 11 +++++++++++ 5 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 test/ru/javaops/webapp/storage/AbstractStorageTest.java create mode 100644 test/ru/javaops/webapp/storage/ListStorageTest.java diff --git a/src/MainArray.java b/src/MainArray.java index 036b046f..be5a4141 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -1,18 +1,21 @@ import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.storage.ArrayStorage; import ru.javaops.webapp.storage.IStorage; +import ru.javaops.webapp.storage.ListStorage; import ru.javaops.webapp.storage.SortedArrayStorage; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.ArrayList; /** * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage */ public class MainArray { //private final static IStorage ARRAY_STORAGE = new ArrayStorage(); - private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); + //private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); + private final static IStorage ARRAY_STORAGE = new ListStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 3ee0910d..3b0c53b8 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -3,6 +3,7 @@ import ru.javaops.webapp.model.Resume; import java.util.Collection; +import java.util.Iterator; public abstract class AbstractStorage implements IStorage{ @@ -25,9 +26,15 @@ public void update(Resume resume){ public abstract void save(Resume resume); public void delete(String uuid){ -// Resume resume = new Resume(); -// resume = storage. -// storage.remove(); + Iterator iterator = storage.iterator(); + while (iterator.hasNext()){ + System.out.println(iterator.next()); + Resume resume = iterator.next(); + if (resume.getUuid().equals(uuid)){ + storage.remove(resume); + break; + } + } } public Resume[] getAll(){ diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index be63ebb4..26e04530 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -7,7 +7,7 @@ public class ListStorage extends AbstractStorage { - protected ListStorage() { + public ListStorage() { super(new ArrayList()); } diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java new file mode 100644 index 00000000..a613f8e4 --- /dev/null +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -0,0 +1,14 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.util.Collection; + +public class AbstractStorageTest { + protected final Collection storage; + + public AbstractStorageTest(Collection storage){ + this.storage = storage; + } + +} diff --git a/test/ru/javaops/webapp/storage/ListStorageTest.java b/test/ru/javaops/webapp/storage/ListStorageTest.java new file mode 100644 index 00000000..30574c55 --- /dev/null +++ b/test/ru/javaops/webapp/storage/ListStorageTest.java @@ -0,0 +1,11 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.util.ArrayList; + +public class ListStorageTest extends AbstractStorageTest { + public ListStorageTest() { + super(new ArrayList()); + } +} From 390bb03806ad6969f93bd32384378bd3339beb12 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 27 Jul 2018 12:54:13 +0300 Subject: [PATCH 068/220] HW5, begin --- .../webapp/storage/AbstractArrayStorage.java | 38 ++++++++-------- .../webapp/storage/AbstractStorage.java | 43 +++++++++++-------- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 8a1ce095..da097822 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -21,8 +21,16 @@ protected AbstractArrayStorage() {//??? super(null); } - public int size() { - return size; + public void save(Resume resume) { + int index = getIndex(resume.getUuid()); + if (index >= 0) { + throw new ExistStorageException(resume.getUuid()); + } else if (size >= STORAGE_LIMIT) { + throw new StorageException("Error: resume storage is full!", resume.getUuid()); + } else { + putResume(index, resume); + size++; + } } public Resume get(String uuid) { @@ -33,11 +41,6 @@ public Resume get(String uuid) { return storage[index]; } - public void clear() { - Arrays.fill(storage, 0, size, null); - size = 0; - } - public Resume[] getAll() { return Arrays.copyOfRange(storage, 0, size); } @@ -51,18 +54,6 @@ public void update(Resume resume) { } } - public void save(Resume resume) { - int index = getIndex(resume.getUuid()); - if (index >= 0) { - throw new ExistStorageException(resume.getUuid()); - } else if (size >= STORAGE_LIMIT) { - throw new StorageException("Error: resume storage is full!", resume.getUuid()); - } else { - putResume(index, resume); - size++; - } - } - public void delete(String uuid) { int index = getIndex(uuid); if (index < 0) { @@ -74,6 +65,15 @@ public void delete(String uuid) { } } + public int size() { + return size; + } + + public void clear() { + Arrays.fill(storage, 0, size, null); + size = 0; + } + protected abstract int getIndex(String uuid); protected abstract void putResume(int index, Resume resume); diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 3b0c53b8..04f82f2c 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -1,5 +1,6 @@ package ru.javaops.webapp.storage; +import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; import java.util.Collection; @@ -13,36 +14,44 @@ protected AbstractStorage(Collection newStorage){ storage = newStorage; } - public void clear(){ - storage.clear(); - } - - public abstract Resume get(String uuid); - - public void update(Resume resume){ - - } - public abstract void save(Resume resume); - public void delete(String uuid){ - Iterator iterator = storage.iterator(); - while (iterator.hasNext()){ - System.out.println(iterator.next()); - Resume resume = iterator.next(); + public Resume get(String uuid){ + for (Resume resume : storage){ if (resume.getUuid().equals(uuid)){ - storage.remove(resume); - break; + return resume; } } + return null; } public Resume[] getAll(){ return storage.toArray(new Resume[storage.size()]); } + public void update(Resume resume){ + if (!storage.contains(resume)){ + throw new NotExistStorageException(resume.getUuid()); + } else { + Resume findResume = get(resume.getUuid()); + findResume = resume; + } + } + + public void delete(String uuid){ + Resume resume = get(uuid); + if (resume == null) { + throw new NotExistStorageException(resume.getUuid()); + } else { + storage.remove(resume); + } + } + public int size(){ return storage.size(); } + public void clear(){ + storage.clear(); + } } From d261f4405fac8af9ea7a97631406294dc2f7df3e Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 27 Jul 2018 13:36:29 +0300 Subject: [PATCH 069/220] HW5, begin --- .../webapp/storage/AbstractStorage.java | 18 ++++++------------ src/ru/javaops/webapp/storage/ListStorage.java | 16 ++++++++-------- src/ru/javaops/webapp/storage/MapStorage.java | 8 ++++---- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 04f82f2c..fe00ba53 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.Iterator; +import java.util.Optional; public abstract class AbstractStorage implements IStorage{ @@ -14,19 +15,8 @@ protected AbstractStorage(Collection newStorage){ storage = newStorage; } - public abstract void save(Resume resume); - - public Resume get(String uuid){ - for (Resume resume : storage){ - if (resume.getUuid().equals(uuid)){ - return resume; - } - } - return null; - } - public Resume[] getAll(){ - return storage.toArray(new Resume[storage.size()]); + return storage.toArray(new Resume[0]); } public void update(Resume resume){ @@ -54,4 +44,8 @@ public int size(){ public void clear(){ storage.clear(); } + + public abstract void save(Resume resume); + + public abstract Resume get(String uuid); } diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 26e04530..44f51a03 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -11,19 +11,19 @@ public ListStorage() { super(new ArrayList()); } + @Override + public void save(Resume resume) { + storage.add(resume); + } + @Override public Resume get(String uuid) { - Iterator iterator = storage.iterator(); - while (iterator.hasNext()){ - if (iterator.next().getUuid().equals(uuid)){ - return iterator.next(); + for (Resume resume : storage){ + if (resume.getUuid().equals(uuid)){ + return resume; } } return null; } - @Override - public void save(Resume resume) { - storage.add(resume); - } } diff --git a/src/ru/javaops/webapp/storage/MapStorage.java b/src/ru/javaops/webapp/storage/MapStorage.java index 7b04c4a2..d0d2d67c 100644 --- a/src/ru/javaops/webapp/storage/MapStorage.java +++ b/src/ru/javaops/webapp/storage/MapStorage.java @@ -10,12 +10,12 @@ protected MapStorage(){ } @Override - public Resume get(String uuid) { - return null; + public void save(Resume resume) { } @Override - public void save(Resume resume) { - + public Resume get(String uuid) { + return null; } + } From 11a6035b318cb79121d6751e4a80a4830c1c757b Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 27 Jul 2018 14:01:56 +0300 Subject: [PATCH 070/220] HW5, begin --- src/ru/javaops/webapp/storage/AbstractStorage.java | 2 +- src/ru/javaops/webapp/storage/ListStorage.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index fe00ba53..e7296875 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -31,7 +31,7 @@ public void update(Resume resume){ public void delete(String uuid){ Resume resume = get(uuid); if (resume == null) { - throw new NotExistStorageException(resume.getUuid()); + throw new NotExistStorageException(uuid); } else { storage.remove(resume); } diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 44f51a03..a3a40445 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Iterator; +import java.util.Optional; public class ListStorage extends AbstractStorage { From 3129f321681f8f08dfff3afce97b5e17cf0fc470 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 27 Jul 2018 14:30:38 +0300 Subject: [PATCH 071/220] HW5, begin --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 2 +- test/ru/javaops/webapp/storage/AbstractStorageTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index a4ef44c1..1f6a8d97 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.*; import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; -public abstract class AbstractArrayStorageTest { +public abstract class AbstractArrayStorageTest{ private final IStorage storage; private static final String UUID_1 = "uuid1"; diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index a613f8e4..f2352046 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -4,7 +4,7 @@ import java.util.Collection; -public class AbstractStorageTest { +public abstract class AbstractStorageTest{ protected final Collection storage; public AbstractStorageTest(Collection storage){ From 4a06dd9ef1e9567d296e408276ff6a1d1815df94 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 27 Jul 2018 14:32:04 +0300 Subject: [PATCH 072/220] HW5, begin --- src/ru/javaops/webapp/storage/AbstractStorage.java | 2 -- src/ru/javaops/webapp/storage/ListStorage.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index e7296875..32d907a8 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -4,8 +4,6 @@ import ru.javaops.webapp.model.Resume; import java.util.Collection; -import java.util.Iterator; -import java.util.Optional; public abstract class AbstractStorage implements IStorage{ diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index a3a40445..80c5f999 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -3,8 +3,6 @@ import ru.javaops.webapp.model.Resume; import java.util.ArrayList; -import java.util.Iterator; -import java.util.Optional; public class ListStorage extends AbstractStorage { From 23da0c4e5ccbc3100fb0a14f2167388ed122609d Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 27 Jul 2018 15:53:00 +0300 Subject: [PATCH 073/220] HW5, begin --- src/ru/javaops/webapp/storage/AbstractArrayStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index da097822..38114b83 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -11,7 +11,7 @@ /** * Array based storage for Resumes */ -public abstract class AbstractArrayStorage extends AbstractStorage implements IStorage { +public abstract class AbstractArrayStorage extends AbstractStorage { protected static final int STORAGE_LIMIT = 100000; protected final Resume[] storage = new Resume[STORAGE_LIMIT]; From ad7f4d46065fd88a3111ae79870f8696e6a939d8 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 31 Jul 2018 17:59:02 +0300 Subject: [PATCH 074/220] HW5, begin --- .../webapp/storage/AbstractStorage.java | 60 +++++++++++++------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 32d907a8..9228f00c 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -1,49 +1,71 @@ package ru.javaops.webapp.storage; +import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; +import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; +import java.util.Arrays; import java.util.Collection; public abstract class AbstractStorage implements IStorage{ - protected static Collection storage; + protected Object getNotExistSearchKey(String uuid){ - protected AbstractStorage(Collection newStorage){ - storage = newStorage; + return null; } - public Resume[] getAll(){ - return storage.toArray(new Resume[0]); + protected abstract void doSave(Resume resume, Object searchKey); + + public void save(Resume resume) { + Object searchKey = getNotExistSearchKey(resume.getUuid()); + doSave(resume, searchKey); + } + + public Resume get(String uuid) { + int index = getIndex(uuid); + if (index < 0) { + throw new NotExistStorageException(uuid); + } + return storage[index]; + } + + public Resume[] getAll() { + return Arrays.copyOfRange(storage, 0, size); } - public void update(Resume resume){ - if (!storage.contains(resume)){ + public void update(Resume resume) { + int index = getIndex(resume.getUuid()); + if (index < 0){ throw new NotExistStorageException(resume.getUuid()); } else { - Resume findResume = get(resume.getUuid()); - findResume = resume; + storage[index] = resume; } } - public void delete(String uuid){ - Resume resume = get(uuid); - if (resume == null) { + public void delete(String uuid) { + int index = getIndex(uuid); + if (index < 0) { throw new NotExistStorageException(uuid); } else { - storage.remove(resume); + size--; + removeResume(index); + storage[size] = null; } } - public int size(){ - return storage.size(); + public int size() { + return size; } - public void clear(){ - storage.clear(); + public void clear() { + Arrays.fill(storage, 0, size, null); + size = 0; } - public abstract void save(Resume resume); + protected abstract int getIndex(String uuid); + + protected abstract void putResume(int index, Resume resume); - public abstract Resume get(String uuid); + protected abstract void removeResume(int index); } From 3475058c6be055fc460c93bb35125700fe6e3ebb Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 1 Aug 2018 13:48:19 +0300 Subject: [PATCH 075/220] HW5, begin --- .../webapp/storage/AbstractStorage.java | 65 ++++++++----------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 9228f00c..183e980c 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -10,12 +10,17 @@ public abstract class AbstractStorage implements IStorage{ - protected Object getNotExistSearchKey(String uuid){ + protected abstract void doSave(Resume resume, Object searchKey); - return null; - } + protected abstract Object getSearchKey(String uuid); - protected abstract void doSave(Resume resume, Object searchKey); + protected abstract Resume doGet(Object searchKey); + + protected abstract void doUpdate(Resume resume, Object searchKey); + + protected abstract void doDelete(Object searchKey); + + protected abstract boolean isExist(Object searchKey); public void save(Resume resume) { Object searchKey = getNotExistSearchKey(resume.getUuid()); @@ -23,49 +28,33 @@ public void save(Resume resume) { } public Resume get(String uuid) { - int index = getIndex(uuid); - if (index < 0) { - throw new NotExistStorageException(uuid); - } - return storage[index]; - } - - public Resume[] getAll() { - return Arrays.copyOfRange(storage, 0, size); + Object searchKey = getSearchKey(uuid); + return doGet(searchKey); } public void update(Resume resume) { - int index = getIndex(resume.getUuid()); - if (index < 0){ - throw new NotExistStorageException(resume.getUuid()); - } else { - storage[index] = resume; - } + Object searchKey = getExistSearchKey(resume.getUuid()); + doUpdate(resume, searchKey); } public void delete(String uuid) { - int index = getIndex(uuid); - if (index < 0) { - throw new NotExistStorageException(uuid); - } else { - size--; - removeResume(index); - storage[size] = null; - } + Object searchKey = getExistSearchKey(uuid); + doDelete(searchKey); } - public int size() { - return size; + protected Object getExistSearchKey(String uuid){ + Object searchKey = getSearchKey(uuid); + if (!isExist(searchKey)){ + throw new NotExistStorageException(uuid); + } + return searchKey; } - public void clear() { - Arrays.fill(storage, 0, size, null); - size = 0; + protected Object getNotExistSearchKey(String uuid){ + Object searchKey = getSearchKey(uuid); + if (isExist(searchKey)){ + throw new ExistStorageException(uuid); + } + return searchKey; } - - protected abstract int getIndex(String uuid); - - protected abstract void putResume(int index, Resume resume); - - protected abstract void removeResume(int index); } From fef8685a46ca2657aae296bf780e8e04c54d5caa Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 1 Aug 2018 13:49:03 +0300 Subject: [PATCH 076/220] HW5, begin --- src/ru/javaops/webapp/storage/AbstractStorage.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 183e980c..6d3d5a93 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -2,11 +2,8 @@ import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; -import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import java.util.Arrays; -import java.util.Collection; public abstract class AbstractStorage implements IStorage{ From 1702a40a4640d76e4bba139c1747fa982249e70a Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 1 Aug 2018 15:05:03 +0300 Subject: [PATCH 077/220] HW5, begin --- .../webapp/storage/AbstractArrayStorage.java | 51 ++++++++++++++++--- .../javaops/webapp/storage/ArrayStorage.java | 1 + .../javaops/webapp/storage/ListStorage.java | 4 -- src/ru/javaops/webapp/storage/MapStorage.java | 4 -- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 38114b83..41c693c2 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -6,7 +6,6 @@ import ru.javaops.webapp.model.Resume; import java.util.Arrays; -import java.util.Collection; /** * Array based storage for Resumes @@ -17,11 +16,8 @@ public abstract class AbstractArrayStorage extends AbstractStorage { protected final Resume[] storage = new Resume[STORAGE_LIMIT]; protected int size = 0; - protected AbstractArrayStorage() {//??? - super(null); - } - - public void save(Resume resume) { + @Override + protected void doSave(Resume resume, Object searchKey) { int index = getIndex(resume.getUuid()); if (index >= 0) { throw new ExistStorageException(resume.getUuid()); @@ -33,7 +29,13 @@ public void save(Resume resume) { } } - public Resume get(String uuid) { + @Override + protected Object getSearchKey(String uuid) { + return null; + } + + @Override + protected Resume doGet(Object searchKey) { int index = getIndex(uuid); if (index < 0) { throw new NotExistStorageException(uuid); @@ -41,6 +43,41 @@ public Resume get(String uuid) { return storage[index]; } + @Override + protected void doUpdate(Resume resume, Object searchKey) { + + } + + @Override + protected void doDelete(Object searchKey) { + + } + + @Override + protected boolean isExist(Object searchKey) { + return false; + } + +// public void save(Resume resume) { +// int index = getIndex(resume.getUuid()); +// if (index >= 0) { +// throw new ExistStorageException(resume.getUuid()); +// } else if (size >= STORAGE_LIMIT) { +// throw new StorageException("Error: resume storage is full!", resume.getUuid()); +// } else { +// putResume(index, resume); +// size++; +// } +// } + + public Resume get(String uuid) { +// int index = getIndex(uuid); +// if (index < 0) { +// throw new NotExistStorageException(uuid); +// } +// return storage[index]; + } + public Resume[] getAll() { return Arrays.copyOfRange(storage, 0, size); } diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 92898283..19e6c76e 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -7,6 +7,7 @@ */ public class ArrayStorage extends AbstractArrayStorage { + @Override protected int getIndex(String uuid) { for (int i = 0; i < size; i++) { if (storage[i].getUuid().equals(uuid)) { diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 80c5f999..51100701 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -6,10 +6,6 @@ public class ListStorage extends AbstractStorage { - public ListStorage() { - super(new ArrayList()); - } - @Override public void save(Resume resume) { storage.add(resume); diff --git a/src/ru/javaops/webapp/storage/MapStorage.java b/src/ru/javaops/webapp/storage/MapStorage.java index d0d2d67c..cb3b704f 100644 --- a/src/ru/javaops/webapp/storage/MapStorage.java +++ b/src/ru/javaops/webapp/storage/MapStorage.java @@ -5,10 +5,6 @@ public class MapStorage extends AbstractStorage { - protected MapStorage(){ - super(null); - } - @Override public void save(Resume resume) { } From 816632970d03e2dc5b4ab9f1621317039dab1c77 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 3 Aug 2018 10:35:36 +0300 Subject: [PATCH 078/220] HW5, AbstractArrayStorage refactoring --- .../webapp/storage/AbstractArrayStorage.java | 112 +++++------------- .../javaops/webapp/storage/ArrayStorage.java | 2 +- 2 files changed, 31 insertions(+), 83 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 41c693c2..28a22594 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -1,7 +1,5 @@ package ru.javaops.webapp.storage; -import ru.javaops.webapp.exception.ExistStorageException; -import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; @@ -16,105 +14,55 @@ public abstract class AbstractArrayStorage extends AbstractStorage { protected final Resume[] storage = new Resume[STORAGE_LIMIT]; protected int size = 0; - @Override - protected void doSave(Resume resume, Object searchKey) { - int index = getIndex(resume.getUuid()); - if (index >= 0) { - throw new ExistStorageException(resume.getUuid()); - } else if (size >= STORAGE_LIMIT) { - throw new StorageException("Error: resume storage is full!", resume.getUuid()); - } else { - putResume(index, resume); - size++; - } + public Resume[] getAll() { + return Arrays.copyOfRange(storage, 0, size); } - @Override - protected Object getSearchKey(String uuid) { - return null; + public int size() { + return size; } - @Override - protected Resume doGet(Object searchKey) { - int index = getIndex(uuid); - if (index < 0) { - throw new NotExistStorageException(uuid); - } - return storage[index]; + public void clear() { + Arrays.fill(storage, 0, size, null); + size = 0; } @Override - protected void doUpdate(Resume resume, Object searchKey) { - - } + protected abstract Integer getSearchKey(String uuid); - @Override - protected void doDelete(Object searchKey) { + protected abstract void putResume(int index, Resume resume); - } + protected abstract void removeResume(int index); @Override - protected boolean isExist(Object searchKey) { - return false; - } - -// public void save(Resume resume) { -// int index = getIndex(resume.getUuid()); -// if (index >= 0) { -// throw new ExistStorageException(resume.getUuid()); -// } else if (size >= STORAGE_LIMIT) { -// throw new StorageException("Error: resume storage is full!", resume.getUuid()); -// } else { -// putResume(index, resume); -// size++; -// } -// } - - public Resume get(String uuid) { -// int index = getIndex(uuid); -// if (index < 0) { -// throw new NotExistStorageException(uuid); -// } -// return storage[index]; - } - - public Resume[] getAll() { - return Arrays.copyOfRange(storage, 0, size); - } - - public void update(Resume resume) { - int index = getIndex(resume.getUuid()); - if (index < 0){ - throw new NotExistStorageException(resume.getUuid()); + protected void doSave(Resume resume, Object index) { + if (size >= STORAGE_LIMIT) { + throw new StorageException("Error: resume storage is full!", resume.getUuid()); } else { - storage[index] = resume; + putResume((Integer) index, resume); + size++; } } - public void delete(String uuid) { - int index = getIndex(uuid); - if (index < 0) { - throw new NotExistStorageException(uuid); - } else { - size--; - removeResume(index); - storage[size] = null; - } + @Override + protected boolean isExist(Object index) { + return (Integer) index >= 0; } - public int size() { - return size; + @Override + protected Resume doGet(Object index) { + return storage[(Integer) index]; } - public void clear() { - Arrays.fill(storage, 0, size, null); - size = 0; + @Override + protected void doUpdate(Resume resume, Object index) { + storage[(Integer) index] = resume; } - protected abstract int getIndex(String uuid); - - protected abstract void putResume(int index, Resume resume); - - protected abstract void removeResume(int index); - + @Override + protected void doDelete(Object index) { + size--; + removeResume((Integer) index); + storage[size] = null; + } } diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 19e6c76e..8e89ab36 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -8,7 +8,7 @@ public class ArrayStorage extends AbstractArrayStorage { @Override - protected int getIndex(String uuid) { + protected Integer getSearchKey(String uuid) { for (int i = 0; i < size; i++) { if (storage[i].getUuid().equals(uuid)) { return i; From 8cbb825dc86b47dd1838c696cb73ffa5acd4b79b Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 3 Aug 2018 11:12:37 +0300 Subject: [PATCH 079/220] HW5, ListStorage implementation --- .../javaops/webapp/storage/ListStorage.java | 40 ++++++++++++++++++- src/ru/javaops/webapp/storage/MapStorage.java | 39 +++++++++++++++++- .../webapp/storage/SortedArrayStorage.java | 2 +- 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 51100701..d2271a25 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -6,13 +6,15 @@ public class ListStorage extends AbstractStorage { + ArrayList storage = new ArrayList<>(); + @Override - public void save(Resume resume) { + protected void doSave(Resume resume, Object searchKey) { storage.add(resume); } @Override - public Resume get(String uuid) { + protected Object getSearchKey(String uuid) { for (Resume resume : storage){ if (resume.getUuid().equals(uuid)){ return resume; @@ -21,4 +23,38 @@ public Resume get(String uuid) { return null; } + @Override + protected Resume doGet(Object searchKey) { + return storage.get(storage.indexOf(searchKey)); + } + + @Override + protected void doUpdate(Resume resume, Object searchKey) { + storage.set(storage.indexOf(searchKey), resume); + } + + @Override + protected void doDelete(Object searchKey) { + storage.remove(storage.indexOf(searchKey)); + } + + @Override + protected boolean isExist(Object searchKey) { + return storage.contains(storage.indexOf(searchKey)); + } + + @Override + public void clear() { + storage.clear(); + } + + @Override + public Resume[] getAll() { + return storage.toArray(new Resume[0]); + } + + @Override + public int size() { + return storage.size(); + } } diff --git a/src/ru/javaops/webapp/storage/MapStorage.java b/src/ru/javaops/webapp/storage/MapStorage.java index cb3b704f..c67af1de 100644 --- a/src/ru/javaops/webapp/storage/MapStorage.java +++ b/src/ru/javaops/webapp/storage/MapStorage.java @@ -6,12 +6,47 @@ public class MapStorage extends AbstractStorage { @Override - public void save(Resume resume) { + protected void doSave(Resume resume, Object searchKey) { + } @Override - public Resume get(String uuid) { + protected Object getSearchKey(String uuid) { return null; } + @Override + protected Resume doGet(Object searchKey) { + return null; + } + + @Override + protected void doUpdate(Resume resume, Object searchKey) { + + } + + @Override + protected void doDelete(Object searchKey) { + + } + + @Override + protected boolean isExist(Object searchKey) { + return false; + } + + @Override + public void clear() { + + } + + @Override + public Resume[] getAll() { + return new Resume[0]; + } + + @Override + public int size() { + return 0; + } } diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index 692b0cda..b6fc1ec8 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -10,7 +10,7 @@ public class SortedArrayStorage extends AbstractArrayStorage{ @Override - protected int getIndex(String uuid) { + protected Integer getSearchKey(String uuid) { Resume searchResume = new Resume(uuid); return Arrays.binarySearch(storage, 0, size, searchResume); } From 0a9a5d7ee5e38ee5f3686899e9fda49a48e45e4b Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 3 Aug 2018 11:19:21 +0300 Subject: [PATCH 080/220] HW5, MapStorage template --- src/ru/javaops/webapp/storage/ListStorage.java | 2 +- src/ru/javaops/webapp/storage/MapStorage.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index d2271a25..e3f89f79 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -6,7 +6,7 @@ public class ListStorage extends AbstractStorage { - ArrayList storage = new ArrayList<>(); + private ArrayList storage = new ArrayList<>(); @Override protected void doSave(Resume resume, Object searchKey) { diff --git a/src/ru/javaops/webapp/storage/MapStorage.java b/src/ru/javaops/webapp/storage/MapStorage.java index c67af1de..d310f5b3 100644 --- a/src/ru/javaops/webapp/storage/MapStorage.java +++ b/src/ru/javaops/webapp/storage/MapStorage.java @@ -2,9 +2,13 @@ import ru.javaops.webapp.model.Resume; +import java.util.HashMap; + public class MapStorage extends AbstractStorage { + private HashMap storage = new HashMap<>(); + @Override protected void doSave(Resume resume, Object searchKey) { From cf43cb40c8cc714453270d7010dadba2d8cc6af8 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 3 Aug 2018 16:20:43 +0300 Subject: [PATCH 081/220] HW5, Add ListStorage Tests --- .../webapp/storage/AbstractStorage.java | 6 +- .../javaops/webapp/storage/ListStorage.java | 6 +- .../storage/AbstractArrayStorageTest.java | 120 ------------------ .../webapp/storage/AbstractStorageTest.java | 114 ++++++++++++++++- .../webapp/storage/ArrayStorageTest.java | 2 +- .../webapp/storage/ListStorageTest.java | 6 +- .../storage/SortedArrayStorageTest.java | 2 +- 7 files changed, 119 insertions(+), 137 deletions(-) delete mode 100644 test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 6d3d5a93..e11c434f 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -25,7 +25,7 @@ public void save(Resume resume) { } public Resume get(String uuid) { - Object searchKey = getSearchKey(uuid); + Object searchKey = getExistSearchKey(uuid); return doGet(searchKey); } @@ -39,7 +39,7 @@ public void delete(String uuid) { doDelete(searchKey); } - protected Object getExistSearchKey(String uuid){ + private Object getExistSearchKey(String uuid){ Object searchKey = getSearchKey(uuid); if (!isExist(searchKey)){ throw new NotExistStorageException(uuid); @@ -47,7 +47,7 @@ protected Object getExistSearchKey(String uuid){ return searchKey; } - protected Object getNotExistSearchKey(String uuid){ + private Object getNotExistSearchKey(String uuid){ Object searchKey = getSearchKey(uuid); if (isExist(searchKey)){ throw new ExistStorageException(uuid); diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index e3f89f79..f68a14fd 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -6,7 +6,7 @@ public class ListStorage extends AbstractStorage { - private ArrayList storage = new ArrayList<>(); + private final ArrayList storage = new ArrayList<>(); @Override protected void doSave(Resume resume, Object searchKey) { @@ -35,12 +35,12 @@ protected void doUpdate(Resume resume, Object searchKey) { @Override protected void doDelete(Object searchKey) { - storage.remove(storage.indexOf(searchKey)); + storage.remove(searchKey); } @Override protected boolean isExist(Object searchKey) { - return storage.contains(storage.indexOf(searchKey)); + return storage.contains(searchKey); } @Override diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java deleted file mode 100644 index 1f6a8d97..00000000 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ /dev/null @@ -1,120 +0,0 @@ -package ru.javaops.webapp.storage; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import ru.javaops.webapp.exception.ExistStorageException; -import ru.javaops.webapp.exception.NotExistStorageException; -import ru.javaops.webapp.exception.StorageException; -import ru.javaops.webapp.model.Resume; - -import static org.junit.Assert.*; -import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; - -public abstract class AbstractArrayStorageTest{ - private final IStorage storage; - - private static final String UUID_1 = "uuid1"; - private static final String UUID_2 = "uuid2"; - private static final String UUID_3 = "uuid3"; - private static final Resume resume1 = new Resume(UUID_1); - private static final Resume resume2 = new Resume(UUID_2); - private static final Resume resume3 = new Resume(UUID_3); - - public AbstractArrayStorageTest(IStorage storage) { - this.storage = storage; - } - - @Before - public void setUp() { - storage.clear(); - storage.save(resume1); - storage.save(resume2); - storage.save(resume3); - } - - @Test - public void size() { - compareSize(3); - } - - @Test - public void get() { - compareResume(resume1); - } - - @Test(expected = NotExistStorageException.class) - public void getNotExist() { - storage.get("dummy"); - } - - @Test - public void getAll() { - Resume[] resumes = new Resume[]{resume1, resume2, resume3}; - Assert.assertArrayEquals(resumes, storage.getAll()); - } - - @Test - public void update() { - Resume resume = storage.get(UUID_3); - storage.update(resume); - compareSize(3); - compareResume(resume); - } - - @Test(expected = NotExistStorageException.class) - public void updateNotExist() { - storage.update(new Resume()); - } - - @Test - public void save() { - Resume resume = new Resume(); - storage.save(resume); - compareSize(4); - compareResume(resume); - } - - @Test(expected = ExistStorageException.class) - public void saveExistStorageException() { - storage.save(resume1); - } - - @Test(expected = StorageException.class) - public void storageOverflow() { - try { - for (int i = storage.size(); i < STORAGE_LIMIT; i++) { - storage.save(new Resume()); - } - } catch (Exception e) { - fail("Storage is not full filled! " + "Exception: " + e.getMessage()); - } - storage.save(new Resume()); - } - - @Test(expected = NotExistStorageException.class) - public void delete() { - storage.delete(UUID_3); - compareSize(2); - storage.get(UUID_3); - } - - @Test(expected = NotExistStorageException.class) - public void deleteNotExistStorageException() { - storage.delete(new Resume().getUuid()); - } - - @Test - public void clear() { - storage.clear(); - compareSize(0); - } - - private void compareSize(int size){ - Assert.assertEquals(size, storage.size()); - } - - private void compareResume(Resume resume){ - Assert.assertEquals(resume, storage.get(resume.getUuid())); - } -} \ No newline at end of file diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index f2352046..2e3389cd 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -1,14 +1,120 @@ package ru.javaops.webapp.storage; +import org.junit.*; +import ru.javaops.webapp.exception.ExistStorageException; +import ru.javaops.webapp.exception.NotExistStorageException; +import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import java.util.Collection; +import static org.junit.Assert.*; +import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; public abstract class AbstractStorageTest{ - protected final Collection storage; + private final IStorage storage; - public AbstractStorageTest(Collection storage){ + private static final String UUID_1 = "uuid1"; + private static final String UUID_2 = "uuid2"; + private static final String UUID_3 = "uuid3"; + private static final Resume resume1 = new Resume(UUID_1); + private static final Resume resume2 = new Resume(UUID_2); + private static final Resume resume3 = new Resume(UUID_3); + + public AbstractStorageTest(IStorage storage) { this.storage = storage; } -} + @Before + public void setUp() { + storage.clear(); + storage.save(resume1); + storage.save(resume2); + storage.save(resume3); + } + + @Test + public void size() { + compareSize(3); + } + + @Test + public void get() { + compareResume(resume1); + } + + @Test(expected = NotExistStorageException.class) + public void getNotExist() { + storage.get("dummy"); + } + + @Test + public void getAll() { + Resume[] resumes = new Resume[]{resume1, resume2, resume3}; + Assert.assertArrayEquals(resumes, storage.getAll()); + } + + @Test + public void update() { + Resume resume = storage.get(UUID_3); + storage.update(resume); + compareSize(3); + compareResume(resume); + } + + @Test(expected = NotExistStorageException.class) + public void updateNotExist() { + storage.update(new Resume()); + } + + @Test + public void save() { + Resume resume = new Resume(); + storage.save(resume); + compareSize(4); + compareResume(resume); + } + + @Test(expected = ExistStorageException.class) + public void saveExistStorageException() { + storage.save(resume1); + } + + //Test only for Arrays. + @Test(expected = StorageException.class) + public void storageOverflow() { + Assume.assumeFalse(storage.getClass().toString().contains("ListStorage") || storage.getClass().toString().contains("MapStorage")); + try { + for (int i = storage.size(); i < STORAGE_LIMIT; i++) { + storage.save(new Resume()); + } + } catch (Exception e) { + fail("Storage is not full filled! " + "Exception: " + e.getMessage()); + } + storage.save(new Resume()); + } + + @Test(expected = NotExistStorageException.class) + public void delete() { + storage.delete(UUID_3); + compareSize(2); + storage.get(UUID_3); + } + + @Test(expected = NotExistStorageException.class) + public void deleteNotExistStorageException() { + storage.delete(new Resume().getUuid()); + } + + @Test + public void clear() { + storage.clear(); + compareSize(0); + } + + private void compareSize(int size){ + Assert.assertEquals(size, storage.size()); + } + + private void compareResume(Resume resume){ + Assert.assertEquals(resume, storage.get(resume.getUuid())); + } +} \ No newline at end of file diff --git a/test/ru/javaops/webapp/storage/ArrayStorageTest.java b/test/ru/javaops/webapp/storage/ArrayStorageTest.java index bc6dcbaa..046410f5 100644 --- a/test/ru/javaops/webapp/storage/ArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/ArrayStorageTest.java @@ -1,6 +1,6 @@ package ru.javaops.webapp.storage; -public class ArrayStorageTest extends AbstractArrayStorageTest { +public class ArrayStorageTest extends AbstractStorageTest { public ArrayStorageTest() { super(new ArrayStorage()); } diff --git a/test/ru/javaops/webapp/storage/ListStorageTest.java b/test/ru/javaops/webapp/storage/ListStorageTest.java index 30574c55..48f7ce9d 100644 --- a/test/ru/javaops/webapp/storage/ListStorageTest.java +++ b/test/ru/javaops/webapp/storage/ListStorageTest.java @@ -1,11 +1,7 @@ package ru.javaops.webapp.storage; -import ru.javaops.webapp.model.Resume; - -import java.util.ArrayList; - public class ListStorageTest extends AbstractStorageTest { public ListStorageTest() { - super(new ArrayList()); + super(new ListStorage()); } } diff --git a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java index f170edf6..2fe4d373 100644 --- a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java @@ -1,6 +1,6 @@ package ru.javaops.webapp.storage; -public class SortedArrayStorageTest extends AbstractArrayStorageTest { +public class SortedArrayStorageTest extends AbstractStorageTest { public SortedArrayStorageTest() { super(new SortedArrayStorage()); } From 500317784da54c016a5774ff27b5ad389a80156e Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 3 Aug 2018 16:42:23 +0300 Subject: [PATCH 082/220] HW5, Add Assume --- test/ru/javaops/webapp/storage/AbstractStorageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 2e3389cd..54d01880 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -81,7 +81,7 @@ public void saveExistStorageException() { //Test only for Arrays. @Test(expected = StorageException.class) public void storageOverflow() { - Assume.assumeFalse(storage.getClass().toString().contains("ListStorage") || storage.getClass().toString().contains("MapStorage")); + Assume.assumeFalse(storage.getClass().getName().contains("ListStorage") || storage.getClass().getName().contains("MapStorage")); try { for (int i = storage.size(); i < STORAGE_LIMIT; i++) { storage.save(new Resume()); From cac70dbdc2bb611518d7dc9cdee9a86702e289cc Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 4 Aug 2018 09:27:36 +0300 Subject: [PATCH 083/220] HW5, Clean comments --- src/MainArray.java | 3 --- src/MainTestArrayStorage.java | 3 --- src/ru/javaops/webapp/model/Resume.java | 3 --- src/ru/javaops/webapp/storage/AbstractArrayStorage.java | 3 --- src/ru/javaops/webapp/storage/ArrayStorage.java | 3 --- src/ru/javaops/webapp/storage/IStorage.java | 3 --- src/ru/javaops/webapp/storage/SortedArrayStorage.java | 3 --- 7 files changed, 21 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index be5a4141..3d2b7af1 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -9,9 +9,6 @@ import java.io.InputStreamReader; import java.util.ArrayList; -/** - * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage - */ public class MainArray { //private final static IStorage ARRAY_STORAGE = new ArrayStorage(); //private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index c678c277..7fc04242 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -3,9 +3,6 @@ import ru.javaops.webapp.storage.IStorage; import ru.javaops.webapp.storage.SortedArrayStorage; -/** - * Test for com.urise.webapp.storage.ru.javaops.webapp.storage.ArrayStorage - */ public class MainTestArrayStorage { private static final IStorage ARRAY_STORAGE = new SortedArrayStorage(); //private static final IStorage ARRAY_STORAGE = new ArrayStorage(); diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index bb4879aa..ccc5e12f 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -2,9 +2,6 @@ import java.util.UUID; -/** - * com.urise.webapp.model.ru.javaops.webapp.model.Resume class - */ public class Resume implements Comparable{ // Unique identifier diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 28a22594..8b522bfd 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -5,9 +5,6 @@ import java.util.Arrays; -/** - * Array based storage for Resumes - */ public abstract class AbstractArrayStorage extends AbstractStorage { protected static final int STORAGE_LIMIT = 100000; diff --git a/src/ru/javaops/webapp/storage/ArrayStorage.java b/src/ru/javaops/webapp/storage/ArrayStorage.java index 8e89ab36..d1b7e311 100644 --- a/src/ru/javaops/webapp/storage/ArrayStorage.java +++ b/src/ru/javaops/webapp/storage/ArrayStorage.java @@ -2,9 +2,6 @@ import ru.javaops.webapp.model.Resume; -/** - * Array based storage for Resumes - */ public class ArrayStorage extends AbstractArrayStorage { @Override diff --git a/src/ru/javaops/webapp/storage/IStorage.java b/src/ru/javaops/webapp/storage/IStorage.java index 1219b5c4..597adc82 100644 --- a/src/ru/javaops/webapp/storage/IStorage.java +++ b/src/ru/javaops/webapp/storage/IStorage.java @@ -2,9 +2,6 @@ import ru.javaops.webapp.model.Resume; -/** - * Array based storage for Resumes - */ public interface IStorage { void clear(); diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index b6fc1ec8..cc1beb7b 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -4,9 +4,6 @@ import java.util.Arrays; -/** - * Array based storage for Resumes - */ public class SortedArrayStorage extends AbstractArrayStorage{ @Override From 973f304637d59e239f43e2ca29b408c1068ebeac Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 4 Aug 2018 09:31:32 +0300 Subject: [PATCH 084/220] HW5, AbstractArrayStorage, abstract methods on top --- .../webapp/storage/AbstractArrayStorage.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 8b522bfd..18957efc 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -11,6 +11,13 @@ public abstract class AbstractArrayStorage extends AbstractStorage { protected final Resume[] storage = new Resume[STORAGE_LIMIT]; protected int size = 0; + @Override + protected abstract Integer getSearchKey(String uuid); + + protected abstract void putResume(int index, Resume resume); + + protected abstract void removeResume(int index); + public Resume[] getAll() { return Arrays.copyOfRange(storage, 0, size); } @@ -24,13 +31,6 @@ public void clear() { size = 0; } - @Override - protected abstract Integer getSearchKey(String uuid); - - protected abstract void putResume(int index, Resume resume); - - protected abstract void removeResume(int index); - @Override protected void doSave(Resume resume, Object index) { if (size >= STORAGE_LIMIT) { From 8179036a071ecd0e2c904860f9fd665ed9fc6f0d Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 4 Aug 2018 10:12:42 +0300 Subject: [PATCH 085/220] HW5, ListStorage, getSearchKey return int --- .../javaops/webapp/storage/ListStorage.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index f68a14fd..2fcd9826 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -9,38 +9,38 @@ public class ListStorage extends AbstractStorage { private final ArrayList storage = new ArrayList<>(); @Override - protected void doSave(Resume resume, Object searchKey) { + protected void doSave(Resume resume, Object index) { storage.add(resume); } @Override protected Object getSearchKey(String uuid) { - for (Resume resume : storage){ - if (resume.getUuid().equals(uuid)){ - return resume; + for (int i = 0; i < storage.size(); i++){ + if (storage.get(i).getUuid().equals(uuid)){ + return i; } } return null; } @Override - protected Resume doGet(Object searchKey) { - return storage.get(storage.indexOf(searchKey)); + protected Resume doGet(Object index) { + return storage.get((Integer) index); } @Override - protected void doUpdate(Resume resume, Object searchKey) { - storage.set(storage.indexOf(searchKey), resume); + protected void doUpdate(Resume resume, Object index) { + storage.set((Integer) index, resume); } @Override - protected void doDelete(Object searchKey) { - storage.remove(searchKey); + protected void doDelete(Object index) { + storage.remove(((Integer) index).intValue()); } @Override - protected boolean isExist(Object searchKey) { - return storage.contains(searchKey); + protected boolean isExist(Object index) { + return (index != null); } @Override From c393d2800c9cb6442a04e6331ae66a2032166c13 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 4 Aug 2018 12:16:40 +0300 Subject: [PATCH 086/220] HW5, Add AbstractArrayStorageTest class --- .../storage/AbstractArrayStorageTest.java | 28 +++++++++++++++++++ .../webapp/storage/AbstractStorageTest.java | 28 +++++++------------ 2 files changed, 38 insertions(+), 18 deletions(-) create mode 100644 test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java new file mode 100644 index 00000000..0b9e9cd1 --- /dev/null +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -0,0 +1,28 @@ +package ru.javaops.webapp.storage; + +import org.junit.Assume; +import org.junit.Test; +import ru.javaops.webapp.exception.StorageException; +import ru.javaops.webapp.model.Resume; + +import static org.junit.Assert.fail; +import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; + +public abstract class AbstractArrayStorageTest extends AbstractStorageTest { + public AbstractArrayStorageTest(IStorage storage) { + super(storage); + } + + @Test(expected = StorageException.class) + public void storageOverflow() { + Assume.assumeFalse(storage.getClass().getName().contains("ListStorage") || storage.getClass().getName().contains("MapStorage")); + try { + for (int i = storage.size(); i < STORAGE_LIMIT; i++) { + storage.save(new Resume()); + } + } catch (Exception e) { + fail("Storage is not full filled! " + "Exception: " + e.getMessage()); + } + storage.save(new Resume()); + } +} diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 54d01880..dcfe9cea 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -10,14 +10,20 @@ import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; public abstract class AbstractStorageTest{ - private final IStorage storage; + protected final IStorage storage; private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; - private static final Resume resume1 = new Resume(UUID_1); - private static final Resume resume2 = new Resume(UUID_2); - private static final Resume resume3 = new Resume(UUID_3); + private static final Resume resume1; + private static final Resume resume2; + private static final Resume resume3; + + static { + resume1 = new Resume(UUID_1); + resume2 = new Resume(UUID_2); + resume3 = new Resume(UUID_3); + } public AbstractStorageTest(IStorage storage) { this.storage = storage; @@ -78,20 +84,6 @@ public void saveExistStorageException() { storage.save(resume1); } - //Test only for Arrays. - @Test(expected = StorageException.class) - public void storageOverflow() { - Assume.assumeFalse(storage.getClass().getName().contains("ListStorage") || storage.getClass().getName().contains("MapStorage")); - try { - for (int i = storage.size(); i < STORAGE_LIMIT; i++) { - storage.save(new Resume()); - } - } catch (Exception e) { - fail("Storage is not full filled! " + "Exception: " + e.getMessage()); - } - storage.save(new Resume()); - } - @Test(expected = NotExistStorageException.class) public void delete() { storage.delete(UUID_3); From 077bb68029a2832bc5a23c4b3de7d0ddc892d0f5 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 4 Aug 2018 12:18:20 +0300 Subject: [PATCH 087/220] HW5, Add AbstractArrayStorageTest class --- test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java | 1 - test/ru/javaops/webapp/storage/AbstractStorageTest.java | 3 --- 2 files changed, 4 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 0b9e9cd1..42aa555e 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -15,7 +15,6 @@ public AbstractArrayStorageTest(IStorage storage) { @Test(expected = StorageException.class) public void storageOverflow() { - Assume.assumeFalse(storage.getClass().getName().contains("ListStorage") || storage.getClass().getName().contains("MapStorage")); try { for (int i = storage.size(); i < STORAGE_LIMIT; i++) { storage.save(new Resume()); diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index dcfe9cea..d5b9b5f6 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -3,11 +3,8 @@ import org.junit.*; import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; -import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import static org.junit.Assert.*; -import static ru.javaops.webapp.storage.AbstractArrayStorage.STORAGE_LIMIT; public abstract class AbstractStorageTest{ protected final IStorage storage; From ffe23c4342bdf3cbb3833e270afa0d15d9dbdab3 Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 5 Aug 2018 10:29:42 +0300 Subject: [PATCH 088/220] HW5, Add AbstractArrayStorageTest class --- .../webapp/storage/AbstractStorageTest.java | 16 +++++----------- .../javaops/webapp/storage/ArrayStorageTest.java | 2 +- .../webapp/storage/SortedArrayStorageTest.java | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index d5b9b5f6..7693f9d4 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -6,21 +6,15 @@ import ru.javaops.webapp.model.Resume; -public abstract class AbstractStorageTest{ +public abstract class AbstractStorageTest { protected final IStorage storage; private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; - private static final Resume resume1; - private static final Resume resume2; - private static final Resume resume3; - - static { - resume1 = new Resume(UUID_1); - resume2 = new Resume(UUID_2); - resume3 = new Resume(UUID_3); - } + private static final Resume resume1 = new Resume(UUID_1); + private static final Resume resume2 = new Resume(UUID_2); + private static final Resume resume3 = new Resume(UUID_3); public AbstractStorageTest(IStorage storage) { this.storage = storage; @@ -51,7 +45,7 @@ public void getNotExist() { @Test public void getAll() { - Resume[] resumes = new Resume[]{resume1, resume2, resume3}; + Resume[] resumes = {resume1, resume2, resume3}; Assert.assertArrayEquals(resumes, storage.getAll()); } diff --git a/test/ru/javaops/webapp/storage/ArrayStorageTest.java b/test/ru/javaops/webapp/storage/ArrayStorageTest.java index 046410f5..bc6dcbaa 100644 --- a/test/ru/javaops/webapp/storage/ArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/ArrayStorageTest.java @@ -1,6 +1,6 @@ package ru.javaops.webapp.storage; -public class ArrayStorageTest extends AbstractStorageTest { +public class ArrayStorageTest extends AbstractArrayStorageTest { public ArrayStorageTest() { super(new ArrayStorage()); } diff --git a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java index 2fe4d373..f170edf6 100644 --- a/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/SortedArrayStorageTest.java @@ -1,6 +1,6 @@ package ru.javaops.webapp.storage; -public class SortedArrayStorageTest extends AbstractStorageTest { +public class SortedArrayStorageTest extends AbstractArrayStorageTest { public SortedArrayStorageTest() { super(new SortedArrayStorage()); } From 0a9c6f55bffa4d49cc3020a09cbf14307047b658 Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 5 Aug 2018 10:37:20 +0300 Subject: [PATCH 089/220] HW5, Add AbstractStorageTest, deleteNotExist refactoring --- test/ru/javaops/webapp/storage/AbstractStorageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 7693f9d4..d236bc33 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -84,7 +84,7 @@ public void delete() { @Test(expected = NotExistStorageException.class) public void deleteNotExistStorageException() { - storage.delete(new Resume().getUuid()); + storage.delete("dummy"); } @Test From 35a156d4ac7dd2f60aad292060b7e135748e45e2 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 8 Aug 2018 18:17:36 +0300 Subject: [PATCH 090/220] HW6, Add Anonymous class, and replace with Lambda --- src/ru/javaops/webapp/model/Resume.java | 7 +------ src/ru/javaops/webapp/storage/SortedArrayStorage.java | 5 ++++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index ccc5e12f..9319c523 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -2,7 +2,7 @@ import java.util.UUID; -public class Resume implements Comparable{ +public class Resume{ // Unique identifier private final String uuid; @@ -38,9 +38,4 @@ public String getUuid() { public String toString() { return uuid; } - - @Override - public int compareTo(Resume o) { - return uuid.compareTo(o.uuid); - } } diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index cc1beb7b..558f01fa 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -3,13 +3,16 @@ import ru.javaops.webapp.model.Resume; import java.util.Arrays; +import java.util.Comparator; public class SortedArrayStorage extends AbstractArrayStorage{ + private static final Comparator RESUME_COMPARATOR = (o1, o2) -> o1.getUuid().compareTo(o2.getUuid()); + @Override protected Integer getSearchKey(String uuid) { Resume searchResume = new Resume(uuid); - return Arrays.binarySearch(storage, 0, size, searchResume); + return Arrays.binarySearch(storage, 0, size, searchResume, RESUME_COMPARATOR); } @Override From 578a0797b961b7a4cd814803ca12192f83ee382a Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 8 Aug 2018 23:31:49 +0300 Subject: [PATCH 091/220] HW6, Add lambda to SortedArrayStorage --- src/ru/javaops/webapp/storage/SortedArrayStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index 558f01fa..4fe88240 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -7,7 +7,7 @@ public class SortedArrayStorage extends AbstractArrayStorage{ - private static final Comparator RESUME_COMPARATOR = (o1, o2) -> o1.getUuid().compareTo(o2.getUuid()); + private static final Comparator RESUME_COMPARATOR = Comparator.comparing(Resume::getUuid); @Override protected Integer getSearchKey(String uuid) { From 1d0672cdb3a7045c98def96596a83a9a6d41e65a Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 9 Aug 2018 00:12:44 +0300 Subject: [PATCH 092/220] HW6, Add class Resume field fullName, modify constuctor --- src/MainArray.java | 2 +- src/MainTestArrayStorage.java | 8 ++++---- src/ru/javaops/webapp/model/Resume.java | 13 ++++++++++--- src/ru/javaops/webapp/storage/IStorage.java | 5 ++--- .../{MapStorage.java => MapUuidStorage.java} | 2 +- .../javaops/webapp/storage/SortedArrayStorage.java | 2 +- .../javaops/webapp/storage/AbstractStorageTest.java | 6 +++--- 7 files changed, 22 insertions(+), 16 deletions(-) rename src/ru/javaops/webapp/storage/{MapStorage.java => MapUuidStorage.java} (94%) diff --git a/src/MainArray.java b/src/MainArray.java index 3d2b7af1..a7a8e2f8 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -36,7 +36,7 @@ public static void main(String[] args) throws IOException { System.out.println(ARRAY_STORAGE.size()); break; case "save": - r = new Resume(uuid); + r = new Resume(uuid, uuid); ARRAY_STORAGE.save(r); printAll(); break; diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index 7fc04242..0e2946e4 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -8,9 +8,9 @@ public class MainTestArrayStorage { //private static final IStorage ARRAY_STORAGE = new ArrayStorage(); public static void main(String[] args) { - final Resume r1 = new Resume("uuid3"); - final Resume r2 = new Resume("uuid1"); - final Resume r3 = new Resume("uuid2"); + final Resume r1 = new Resume("uuid3", ""); + final Resume r2 = new Resume("uuid1", ""); + final Resume r3 = new Resume("uuid2", ""); ARRAY_STORAGE.save(r1); @@ -36,7 +36,7 @@ public static void main(String[] args) { //Test storage overflow for (int i = 0; i < 100001; i++){ - Resume resume = new Resume("uuid" + i); + Resume resume = new Resume("uuid" + i, "uuid" + i); ARRAY_STORAGE.save(resume); } } diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 9319c523..1786b3c1 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -2,17 +2,20 @@ import java.util.UUID; -public class Resume{ +public class Resume { // Unique identifier private final String uuid; + private String fullName; + public Resume(){ - this(UUID.randomUUID().toString()); + this.uuid = (UUID.randomUUID().toString()); } - public Resume(String uuid){ + public Resume(String uuid, String fullName){ this.uuid = uuid; + this.fullName = fullName; } @Override @@ -34,6 +37,10 @@ public String getUuid() { return uuid; } + public String getFullName() { + return fullName; + } + @Override public String toString() { return uuid; diff --git a/src/ru/javaops/webapp/storage/IStorage.java b/src/ru/javaops/webapp/storage/IStorage.java index 597adc82..64f96402 100644 --- a/src/ru/javaops/webapp/storage/IStorage.java +++ b/src/ru/javaops/webapp/storage/IStorage.java @@ -14,10 +14,9 @@ public interface IStorage { void delete(String uuid); - /** - * @return array, contains only Resumes in storage (without null) - */ Resume[] getAll(); + //return sorted by fullName List + //List getAllSorted(); int size(); } diff --git a/src/ru/javaops/webapp/storage/MapStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java similarity index 94% rename from src/ru/javaops/webapp/storage/MapStorage.java rename to src/ru/javaops/webapp/storage/MapUuidStorage.java index d310f5b3..94410ef7 100644 --- a/src/ru/javaops/webapp/storage/MapStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -5,7 +5,7 @@ import java.util.HashMap; -public class MapStorage extends AbstractStorage { +public class MapUuidStorage extends AbstractStorage { private HashMap storage = new HashMap<>(); diff --git a/src/ru/javaops/webapp/storage/SortedArrayStorage.java b/src/ru/javaops/webapp/storage/SortedArrayStorage.java index 4fe88240..23620f45 100644 --- a/src/ru/javaops/webapp/storage/SortedArrayStorage.java +++ b/src/ru/javaops/webapp/storage/SortedArrayStorage.java @@ -11,7 +11,7 @@ public class SortedArrayStorage extends AbstractArrayStorage{ @Override protected Integer getSearchKey(String uuid) { - Resume searchResume = new Resume(uuid); + Resume searchResume = new Resume(uuid, ""); return Arrays.binarySearch(storage, 0, size, searchResume, RESUME_COMPARATOR); } diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index d236bc33..441600e5 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -12,9 +12,9 @@ public abstract class AbstractStorageTest { private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; - private static final Resume resume1 = new Resume(UUID_1); - private static final Resume resume2 = new Resume(UUID_2); - private static final Resume resume3 = new Resume(UUID_3); + private static final Resume resume1 = new Resume(UUID_1, UUID_1); + private static final Resume resume2 = new Resume(UUID_2, UUID_2); + private static final Resume resume3 = new Resume(UUID_3, UUID_3); public AbstractStorageTest(IStorage storage) { this.storage = storage; From b32a91d37b43ee669f8e96b10d0c420a42dc3fce Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 14 Aug 2018 17:49:00 +0300 Subject: [PATCH 093/220] HW6, Add getAllSorted() --- src/ru/javaops/webapp/model/Resume.java | 3 +++ .../webapp/storage/AbstractArrayStorage.java | 15 ++++++++++++--- src/ru/javaops/webapp/storage/IStorage.java | 6 ++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 1786b3c1..5f8c1813 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,5 +1,6 @@ package ru.javaops.webapp.model; +import java.util.Comparator; import java.util.UUID; public class Resume { @@ -28,6 +29,8 @@ public boolean equals(Object o) { return uuid.equals(resume.uuid); } + public static Comparator COMPARE_RESUMES_BY_FULLNAME = (o1, o2) -> o1.fullName.compareToIgnoreCase(o2.fullName); + @Override public int hashCode() { return uuid.hashCode(); diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 18957efc..fb155c1b 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -3,7 +3,9 @@ import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import java.util.Arrays; +import java.util.*; + +import static ru.javaops.webapp.model.Resume.COMPARE_RESUMES_BY_FULLNAME; public abstract class AbstractArrayStorage extends AbstractStorage { protected static final int STORAGE_LIMIT = 100000; @@ -18,8 +20,15 @@ public abstract class AbstractArrayStorage extends AbstractStorage { protected abstract void removeResume(int index); - public Resume[] getAll() { - return Arrays.copyOfRange(storage, 0, size); +// public Resume[] getAll() { +// return Arrays.copyOfRange(storage, 0, size); +// } + + @Override + public List getAllSorted() { + List listStorage = Arrays.asList(storage); + Collections.sort(listStorage, COMPARE_RESUMES_BY_FULLNAME); + return listStorage; } public int size() { diff --git a/src/ru/javaops/webapp/storage/IStorage.java b/src/ru/javaops/webapp/storage/IStorage.java index 64f96402..30470f1c 100644 --- a/src/ru/javaops/webapp/storage/IStorage.java +++ b/src/ru/javaops/webapp/storage/IStorage.java @@ -2,6 +2,8 @@ import ru.javaops.webapp.model.Resume; +import java.util.List; + public interface IStorage { void clear(); @@ -14,9 +16,9 @@ public interface IStorage { void delete(String uuid); - Resume[] getAll(); + //Resume[] getAll(); //return sorted by fullName List - //List getAllSorted(); + List getAllSorted(); int size(); } From 0867799eee12d5ca1cdc26af60f97170744dcf77 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 14 Aug 2018 20:03:51 +0300 Subject: [PATCH 094/220] HW6, MapUuidStrorage methods implementation --- .../webapp/storage/AbstractArrayStorage.java | 4 --- .../javaops/webapp/storage/ListStorage.java | 14 +++++++-- .../webapp/storage/MapUuidStorage.java | 29 ++++++++++++------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index fb155c1b..2fa98ea7 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -20,10 +20,6 @@ public abstract class AbstractArrayStorage extends AbstractStorage { protected abstract void removeResume(int index); -// public Resume[] getAll() { -// return Arrays.copyOfRange(storage, 0, size); -// } - @Override public List getAllSorted() { List listStorage = Arrays.asList(storage); diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 2fcd9826..5ba9e2e0 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -3,6 +3,9 @@ import ru.javaops.webapp.model.Resume; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public class ListStorage extends AbstractStorage { @@ -49,10 +52,17 @@ public void clear() { } @Override - public Resume[] getAll() { - return storage.toArray(new Resume[0]); + public List getAllSorted() { + List listStorage = storage; + Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); + return listStorage; } +// @Override +// public Resume[] getAll() { +// return storage.toArray(new Resume[0]); +// } + @Override public int size() { return storage.size(); diff --git a/src/ru/javaops/webapp/storage/MapUuidStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java index 94410ef7..47034c79 100644 --- a/src/ru/javaops/webapp/storage/MapUuidStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -2,7 +2,7 @@ import ru.javaops.webapp.model.Resume; -import java.util.HashMap; +import java.util.*; public class MapUuidStorage extends AbstractStorage { @@ -11,46 +11,53 @@ public class MapUuidStorage extends AbstractStorage { @Override protected void doSave(Resume resume, Object searchKey) { - + storage.put(resume.getUuid(), resume); } @Override protected Object getSearchKey(String uuid) { - return null; + Iterator it = storage.entrySet().iterator(); + while (it.hasNext()){ + Map.Entry pair = (Map.Entry)it.next(); + if (pair.getKey().equals(uuid)){ + return pair.getKey(); + } + } + return null; } @Override protected Resume doGet(Object searchKey) { - return null; + return storage.get(searchKey); } @Override protected void doUpdate(Resume resume, Object searchKey) { - + storage.replace(searchKey.toString(), resume); } @Override protected void doDelete(Object searchKey) { - + storage.remove(searchKey); } @Override protected boolean isExist(Object searchKey) { - return false; + return storage.containsKey(searchKey); } @Override public void clear() { - + storage.clear(); } @Override - public Resume[] getAll() { - return new Resume[0]; + public List getAllSorted() { + return new ArrayList(storage.values()); } @Override public int size() { - return 0; + return storage.size(); } } From dc4752b7219d5c6054678c0864754c3d3ca31797 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 14 Aug 2018 20:08:35 +0300 Subject: [PATCH 095/220] HW6, MapUuidStrorage methods implementation --- src/ru/javaops/webapp/storage/IStorage.java | 2 -- src/ru/javaops/webapp/storage/ListStorage.java | 5 ----- 2 files changed, 7 deletions(-) diff --git a/src/ru/javaops/webapp/storage/IStorage.java b/src/ru/javaops/webapp/storage/IStorage.java index 30470f1c..d8c0049b 100644 --- a/src/ru/javaops/webapp/storage/IStorage.java +++ b/src/ru/javaops/webapp/storage/IStorage.java @@ -16,8 +16,6 @@ public interface IStorage { void delete(String uuid); - //Resume[] getAll(); - //return sorted by fullName List List getAllSorted(); int size(); diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 5ba9e2e0..e55f9666 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -58,11 +58,6 @@ public List getAllSorted() { return listStorage; } -// @Override -// public Resume[] getAll() { -// return storage.toArray(new Resume[0]); -// } - @Override public int size() { return storage.size(); From edf77a52dd9c9e6663ed46b8fdae7204f69a5b19 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 14 Aug 2018 20:10:31 +0300 Subject: [PATCH 096/220] HW6, MapUuidStrorage methods implementation --- src/MainArray.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index a7a8e2f8..4f525840 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -1,18 +1,17 @@ import ru.javaops.webapp.model.Resume; -import ru.javaops.webapp.storage.ArrayStorage; -import ru.javaops.webapp.storage.IStorage; -import ru.javaops.webapp.storage.ListStorage; -import ru.javaops.webapp.storage.SortedArrayStorage; +import ru.javaops.webapp.storage.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.List; public class MainArray { //private final static IStorage ARRAY_STORAGE = new ArrayStorage(); //private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); - private final static IStorage ARRAY_STORAGE = new ListStorage(); + //private final static IStorage ARRAY_STORAGE = new ListStorage(); + private final static IStorage ARRAY_STORAGE = new MapUuidStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); @@ -61,9 +60,9 @@ public static void main(String[] args) throws IOException { } private static void printAll() { - Resume[] all = ARRAY_STORAGE.getAll(); + List all = ARRAY_STORAGE.getAllSorted(); System.out.println("----------------------------"); - if (all.length == 0) { + if (all.size() == 0) { System.out.println("Empty"); } else { for (Resume r : all) { From 21009c77b1fca4cf6c6ed27ae09a3ea62da09ec5 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 14 Aug 2018 20:11:20 +0300 Subject: [PATCH 097/220] HW6, MapUuidStrorage methods implementation --- src/MainTestArrayStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index 0e2946e4..f8da7200 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -43,7 +43,7 @@ public static void main(String[] args) { private static void printAll() { System.out.println("\nGet All"); - for (Resume r : ARRAY_STORAGE.getAll()) { + for (Resume r : ARRAY_STORAGE.getAllSorted()) { System.out.println(r); } } From a3145084a37e39460b81788ba8c226ad86fd974c Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 14 Aug 2018 20:31:50 +0300 Subject: [PATCH 098/220] HW6, MapUuidStrorage methods implementation --- src/ru/javaops/webapp/storage/MapUuidStorage.java | 2 +- test/ru/javaops/webapp/storage/AbstractStorageTest.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ru/javaops/webapp/storage/MapUuidStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java index 47034c79..d1de90cc 100644 --- a/src/ru/javaops/webapp/storage/MapUuidStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -23,7 +23,7 @@ protected Object getSearchKey(String uuid) { return pair.getKey(); } } - return null; + return null; } @Override diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 441600e5..fcaf97a5 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -5,6 +5,9 @@ import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; +import java.util.Arrays; +import java.util.List; + public abstract class AbstractStorageTest { protected final IStorage storage; @@ -46,7 +49,8 @@ public void getNotExist() { @Test public void getAll() { Resume[] resumes = {resume1, resume2, resume3}; - Assert.assertArrayEquals(resumes, storage.getAll()); + List listStorage = Arrays.asList(resumes); + Assert.assertEquals(listStorage, storage.getAllSorted()); } @Test From d57d27f33f28b90471c8d77e5af5274afb719b94 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 14 Aug 2018 21:14:48 +0300 Subject: [PATCH 099/220] HW6, MapUuidStrorage methods implementation --- test/ru/javaops/webapp/storage/AbstractStorageTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index fcaf97a5..4dea30f0 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -5,6 +5,7 @@ import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -48,9 +49,10 @@ public void getNotExist() { @Test public void getAll() { - Resume[] resumes = {resume1, resume2, resume3}; - List listStorage = Arrays.asList(resumes); - Assert.assertEquals(listStorage, storage.getAllSorted()); + //Resume[] resumes = {resume1, resume2, resume3}; + List listStorage = new ArrayList<>(); //Arrays.asList(resumes); + listStorage.add(resume1);listStorage.add(resume2); listStorage.add(resume3); + Assert.assertEquals(listStorage, storage); } @Test From d476e4356f20d44c152834cb7844ccd7bee7b5c5 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 15 Aug 2018 09:55:50 +0300 Subject: [PATCH 100/220] HW6, Implement class MapFullNameStorage --- .../javaops/webapp/storage/ListStorage.java | 2 +- .../webapp/storage/MapFullNameStorage.java | 64 +++++++++++++++++++ .../webapp/storage/MapUuidStorage.java | 6 +- 3 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/MapFullNameStorage.java diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index e55f9666..6e76051a 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -9,7 +9,7 @@ public class ListStorage extends AbstractStorage { - private final ArrayList storage = new ArrayList<>(); + private final List storage = new ArrayList<>(); @Override protected void doSave(Resume resume, Object index) { diff --git a/src/ru/javaops/webapp/storage/MapFullNameStorage.java b/src/ru/javaops/webapp/storage/MapFullNameStorage.java new file mode 100644 index 00000000..7cf3f354 --- /dev/null +++ b/src/ru/javaops/webapp/storage/MapFullNameStorage.java @@ -0,0 +1,64 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.util.*; + +public class MapFullNameStorage extends AbstractStorage { + + private Map storage = new HashMap<>(); + + @Override + protected void doSave(Resume resume, Object searchKey) { + storage.put(resume.getFullName(), resume); + } + + @Override + protected Object getSearchKey(String uuid) { + Iterator it = storage.entrySet().iterator(); + while (it.hasNext()){ + Map.Entry pair = (Map.Entry)it.next(); + if (pair.getKey().equals(uuid)){ + return pair.getKey(); + } + } + return null; + } + + @Override + protected Resume doGet(Object searchKey) { + return storage.get(searchKey); + } + + @Override + protected void doUpdate(Resume resume, Object searchKey) { + + } + + @Override + protected void doDelete(Object searchKey) { + storage.remove(searchKey); + } + + @Override + protected boolean isExist(Object searchKey) { + return storage.containsKey(searchKey); + } + + @Override + public void clear() { + storage.clear(); + } + + @Override + public List getAllSorted() { + List listStorage = new ArrayList(storage.values()); + Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); + return listStorage; + } + + @Override + public int size() { + return storage.size(); + } +} diff --git a/src/ru/javaops/webapp/storage/MapUuidStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java index d1de90cc..d0ba025c 100644 --- a/src/ru/javaops/webapp/storage/MapUuidStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -7,7 +7,7 @@ public class MapUuidStorage extends AbstractStorage { - private HashMap storage = new HashMap<>(); + private Map storage = new HashMap<>(); @Override protected void doSave(Resume resume, Object searchKey) { @@ -53,7 +53,9 @@ public void clear() { @Override public List getAllSorted() { - return new ArrayList(storage.values()); + List listStorage = new ArrayList(storage.values()); + Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); + return listStorage; } @Override From 10473b03ffb6b0f9b586588918ca82b14e280f35 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 15 Aug 2018 10:01:08 +0300 Subject: [PATCH 101/220] HW6, Implement class MapFullNameStorage --- src/ru/javaops/webapp/storage/ListStorage.java | 1 - src/ru/javaops/webapp/storage/MapFullNameStorage.java | 2 +- src/ru/javaops/webapp/storage/MapUuidStorage.java | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 6e76051a..e6479704 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -3,7 +3,6 @@ import ru.javaops.webapp.model.Resume; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; diff --git a/src/ru/javaops/webapp/storage/MapFullNameStorage.java b/src/ru/javaops/webapp/storage/MapFullNameStorage.java index 7cf3f354..e0cec73a 100644 --- a/src/ru/javaops/webapp/storage/MapFullNameStorage.java +++ b/src/ru/javaops/webapp/storage/MapFullNameStorage.java @@ -52,7 +52,7 @@ public void clear() { @Override public List getAllSorted() { - List listStorage = new ArrayList(storage.values()); + List listStorage = new ArrayList<>(storage.values()); Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); return listStorage; } diff --git a/src/ru/javaops/webapp/storage/MapUuidStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java index d0ba025c..c3f85c05 100644 --- a/src/ru/javaops/webapp/storage/MapUuidStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -53,7 +53,7 @@ public void clear() { @Override public List getAllSorted() { - List listStorage = new ArrayList(storage.values()); + List listStorage = new ArrayList<>(storage.values()); Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); return listStorage; } From 6cb43525e41613d7326ad93e867863dd7d7865a7 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 15 Aug 2018 10:45:18 +0300 Subject: [PATCH 102/220] HW6, Implement class MapFullNameStorage --- src/MainArray.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MainArray.java b/src/MainArray.java index 4f525840..a69c5287 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -11,7 +11,8 @@ public class MainArray { //private final static IStorage ARRAY_STORAGE = new ArrayStorage(); //private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); //private final static IStorage ARRAY_STORAGE = new ListStorage(); - private final static IStorage ARRAY_STORAGE = new MapUuidStorage(); + //private final static IStorage ARRAY_STORAGE = new MapUuidStorage(); + private final static IStorage ARRAY_STORAGE = new MapFullNameStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); From 29f3c1cf5df9530e771f6c35983639548b6efa96 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 15 Aug 2018 16:46:22 +0300 Subject: [PATCH 103/220] HW6, 2 fields Comparator --- src/ru/javaops/webapp/model/Resume.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 5f8c1813..1e319e49 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -29,7 +29,17 @@ public boolean equals(Object o) { return uuid.equals(resume.uuid); } - public static Comparator COMPARE_RESUMES_BY_FULLNAME = (o1, o2) -> o1.fullName.compareToIgnoreCase(o2.fullName); + public static Comparator COMPARE_RESUMES_BY_FULLNAME = new Comparator() { + int compareResult; + @Override + public int compare(Resume o1, Resume o2) { + compareResult = o1.fullName.compareToIgnoreCase(o2.fullName); + if (compareResult != 0){ + return compareResult; + } + return o1.uuid.compareToIgnoreCase(o2.uuid); + } + }; @Override public int hashCode() { From 8c96f2b6b49652bb51ac023acdcb0ab526a8802e Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 15 Aug 2018 17:22:12 +0300 Subject: [PATCH 104/220] HW6, 2 fields Comparator --- src/MainArray.java | 11 ++++++++--- src/ru/javaops/webapp/model/Resume.java | 4 ++-- .../javaops/webapp/storage/AbstractArrayStorage.java | 3 +-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index a69c5287..11e50060 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -20,14 +20,19 @@ public static void main(String[] args) throws IOException { while (true) { System.out.print("Введите одну из команд - (list | save uuid | delete uuid | get uuid | clear | exit): "); String[] params = reader.readLine().trim().toLowerCase().split(" "); - if (params.length < 1 || params.length > 2) { + if (params.length < 1 || params.length > 3) { System.out.println("Неверная команда."); continue; } String uuid = null; + String fullName = null; if (params.length == 2) { uuid = params[1].intern(); } + if (params.length == 3) { + uuid = params[1].intern(); + fullName = params[2].intern(); + } switch (params[0]) { case "list": printAll(); @@ -36,7 +41,7 @@ public static void main(String[] args) throws IOException { System.out.println(ARRAY_STORAGE.size()); break; case "save": - r = new Resume(uuid, uuid); + r = new Resume(uuid, fullName); ARRAY_STORAGE.save(r); printAll(); break; @@ -67,7 +72,7 @@ private static void printAll() { System.out.println("Empty"); } else { for (Resume r : all) { - System.out.println(r); + System.out.println(r.getUuid() + " " + r.getFullName()); } } System.out.println("----------------------------"); diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 1e319e49..79691209 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -33,11 +33,11 @@ public boolean equals(Object o) { int compareResult; @Override public int compare(Resume o1, Resume o2) { - compareResult = o1.fullName.compareToIgnoreCase(o2.fullName); + compareResult = o1.fullName.compareTo(o2.fullName); if (compareResult != 0){ return compareResult; } - return o1.uuid.compareToIgnoreCase(o2.uuid); + return o1.uuid.compareTo(o2.uuid); } }; diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 2fa98ea7..3fa46aca 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -5,7 +5,6 @@ import java.util.*; -import static ru.javaops.webapp.model.Resume.COMPARE_RESUMES_BY_FULLNAME; public abstract class AbstractArrayStorage extends AbstractStorage { protected static final int STORAGE_LIMIT = 100000; @@ -23,7 +22,7 @@ public abstract class AbstractArrayStorage extends AbstractStorage { @Override public List getAllSorted() { List listStorage = Arrays.asList(storage); - Collections.sort(listStorage, COMPARE_RESUMES_BY_FULLNAME); + Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); return listStorage; } From 1b327cb25d50918bc00558133a632d5d36647cdf Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 15 Aug 2018 19:53:38 +0300 Subject: [PATCH 105/220] HW6, MapFullNameStorageTest implementation --- src/MainArray.java | 4 +-- src/ru/javaops/webapp/model/Resume.java | 1 + .../webapp/storage/AbstractArrayStorage.java | 2 +- .../webapp/storage/AbstractStorage.java | 4 +-- .../webapp/storage/MapFullNameStorage.java | 12 +++++++++ .../webapp/storage/AbstractStorageTest.java | 15 ++++++----- .../storage/MapFullNameStorageTest.java | 25 +++++++++++++++++++ .../webapp/storage/MapUuidStorageTest.java | 7 ++++++ 8 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 test/ru/javaops/webapp/storage/MapFullNameStorageTest.java create mode 100644 test/ru/javaops/webapp/storage/MapUuidStorageTest.java diff --git a/src/MainArray.java b/src/MainArray.java index 11e50060..3ca0df9d 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -9,10 +9,10 @@ public class MainArray { //private final static IStorage ARRAY_STORAGE = new ArrayStorage(); - //private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); + private final static IStorage ARRAY_STORAGE = new SortedArrayStorage(); //private final static IStorage ARRAY_STORAGE = new ListStorage(); //private final static IStorage ARRAY_STORAGE = new MapUuidStorage(); - private final static IStorage ARRAY_STORAGE = new MapFullNameStorage(); + //private final static IStorage ARRAY_STORAGE = new MapFullNameStorage(); public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 79691209..9148dd7a 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -12,6 +12,7 @@ public class Resume { public Resume(){ this.uuid = (UUID.randomUUID().toString()); + this.fullName = this.uuid; } public Resume(String uuid, String fullName){ diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 3fa46aca..aa963030 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -21,7 +21,7 @@ public abstract class AbstractArrayStorage extends AbstractStorage { @Override public List getAllSorted() { - List listStorage = Arrays.asList(storage); + List listStorage = Arrays.asList(Arrays.copyOfRange(storage, 0, size)); Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); return listStorage; } diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index e11c434f..0cdc9492 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -39,7 +39,7 @@ public void delete(String uuid) { doDelete(searchKey); } - private Object getExistSearchKey(String uuid){ + protected Object getExistSearchKey(String uuid){ Object searchKey = getSearchKey(uuid); if (!isExist(searchKey)){ throw new NotExistStorageException(uuid); @@ -47,7 +47,7 @@ private Object getExistSearchKey(String uuid){ return searchKey; } - private Object getNotExistSearchKey(String uuid){ + protected Object getNotExistSearchKey(String uuid){ Object searchKey = getSearchKey(uuid); if (isExist(searchKey)){ throw new ExistStorageException(uuid); diff --git a/src/ru/javaops/webapp/storage/MapFullNameStorage.java b/src/ru/javaops/webapp/storage/MapFullNameStorage.java index e0cec73a..0d054cb6 100644 --- a/src/ru/javaops/webapp/storage/MapFullNameStorage.java +++ b/src/ru/javaops/webapp/storage/MapFullNameStorage.java @@ -45,6 +45,18 @@ protected boolean isExist(Object searchKey) { return storage.containsKey(searchKey); } + @Override + public void save(Resume resume) { + Object searchKey = getNotExistSearchKey(resume.getFullName()); + doSave(resume, searchKey); + } + + @Override + public void update(Resume resume) { + Object searchKey = getExistSearchKey(resume.getFullName()); + doUpdate(resume, searchKey); + } + @Override public void clear() { storage.clear(); diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 4dea30f0..b975df3d 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -16,9 +16,12 @@ public abstract class AbstractStorageTest { private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; - private static final Resume resume1 = new Resume(UUID_1, UUID_1); - private static final Resume resume2 = new Resume(UUID_2, UUID_2); - private static final Resume resume3 = new Resume(UUID_3, UUID_3); + private static final String NAME_1 = "Name1"; + private static final String NAME_2 = "Name2"; + protected static final String NAME_3 = "Name3"; + private static final Resume resume1 = new Resume(UUID_1, NAME_1); + private static final Resume resume2 = new Resume(UUID_2, NAME_2); + private static final Resume resume3 = new Resume(UUID_3, NAME_3); public AbstractStorageTest(IStorage storage) { this.storage = storage; @@ -52,7 +55,7 @@ public void getAll() { //Resume[] resumes = {resume1, resume2, resume3}; List listStorage = new ArrayList<>(); //Arrays.asList(resumes); listStorage.add(resume1);listStorage.add(resume2); listStorage.add(resume3); - Assert.assertEquals(listStorage, storage); + Assert.assertEquals(listStorage, storage.getAllSorted()); } @Test @@ -99,11 +102,11 @@ public void clear() { compareSize(0); } - private void compareSize(int size){ + protected void compareSize(int size){ Assert.assertEquals(size, storage.size()); } - private void compareResume(Resume resume){ + protected void compareResume(Resume resume){ Assert.assertEquals(resume, storage.get(resume.getUuid())); } } \ No newline at end of file diff --git a/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java b/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java new file mode 100644 index 00000000..c834e611 --- /dev/null +++ b/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java @@ -0,0 +1,25 @@ +package ru.javaops.webapp.storage; + +import org.junit.Assert; +import org.junit.Test; +import ru.javaops.webapp.model.Resume; + +public class MapFullNameStorageTest extends AbstractStorageTest{ + public MapFullNameStorageTest() { + super(new MapFullNameStorage()); + } + + @Override + @Test + public void update() { + Resume resume = storage.get(NAME_3); + storage.update(resume); + compareSize(3); + compareResume(resume); + } + + @Override + protected void compareResume(Resume resume){ + Assert.assertEquals(resume, storage.get(resume.getFullName())); + } +} diff --git a/test/ru/javaops/webapp/storage/MapUuidStorageTest.java b/test/ru/javaops/webapp/storage/MapUuidStorageTest.java new file mode 100644 index 00000000..9f2bc0fd --- /dev/null +++ b/test/ru/javaops/webapp/storage/MapUuidStorageTest.java @@ -0,0 +1,7 @@ +package ru.javaops.webapp.storage; + +public class MapUuidStorageTest extends AbstractStorageTest { + public MapUuidStorageTest() { + super(new MapUuidStorage()); + } +} From d358add560a288777a500b2c3034bfdf5100382d Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 15 Aug 2018 23:18:18 +0300 Subject: [PATCH 106/220] HW6, JunitTestSuite --- test/ru/javaops/webapp/storage/AbstractStorageTest.java | 3 ++- test/ru/javaops/webapp/storage/JUnitTestSuite.java | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 test/ru/javaops/webapp/storage/JUnitTestSuite.java diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index b975df3d..d127e94b 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -1,12 +1,13 @@ package ru.javaops.webapp.storage; import org.junit.*; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; diff --git a/test/ru/javaops/webapp/storage/JUnitTestSuite.java b/test/ru/javaops/webapp/storage/JUnitTestSuite.java new file mode 100644 index 00000000..4e4cac53 --- /dev/null +++ b/test/ru/javaops/webapp/storage/JUnitTestSuite.java @@ -0,0 +1,9 @@ +package ru.javaops.webapp.storage; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ArrayStorageTest.class, SortedArrayStorageTest.class, ListStorageTest.class, MapUuidStorageTest.class, MapFullNameStorageTest.class}) +public class JUnitTestSuite { +} From f923c96142e5129985e13d00ca713da66534e441 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 15 Aug 2018 23:26:18 +0300 Subject: [PATCH 107/220] HW6, JunitTestSuite --- .../webapp/storage/{JUnitTestSuite.java => JunitTestSuite.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename test/ru/javaops/webapp/storage/{JUnitTestSuite.java => JunitTestSuite.java} (90%) diff --git a/test/ru/javaops/webapp/storage/JUnitTestSuite.java b/test/ru/javaops/webapp/storage/JunitTestSuite.java similarity index 90% rename from test/ru/javaops/webapp/storage/JUnitTestSuite.java rename to test/ru/javaops/webapp/storage/JunitTestSuite.java index 4e4cac53..a1ed0100 100644 --- a/test/ru/javaops/webapp/storage/JUnitTestSuite.java +++ b/test/ru/javaops/webapp/storage/JunitTestSuite.java @@ -5,5 +5,5 @@ @RunWith(Suite.class) @Suite.SuiteClasses({ArrayStorageTest.class, SortedArrayStorageTest.class, ListStorageTest.class, MapUuidStorageTest.class, MapFullNameStorageTest.class}) -public class JUnitTestSuite { +public class JunitTestSuite { } From 7160849a46f9dbef7b1cc3a0cdff66856a34d14f Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 16 Aug 2018 18:02:33 +0300 Subject: [PATCH 108/220] HW6, 16082018 --- src/ru/javaops/webapp/model/Resume.java | 10 ++- .../webapp/storage/AbstractArrayStorage.java | 12 ++- .../webapp/storage/AbstractStorage.java | 12 +++ .../javaops/webapp/storage/ListStorage.java | 10 +-- .../webapp/storage/MapFullNameStorage.java | 76 ------------------- .../webapp/storage/MapResumeStorage.java | 75 ++++++++++++++++++ .../webapp/storage/MapUuidStorage.java | 27 ++++--- 7 files changed, 116 insertions(+), 106 deletions(-) delete mode 100644 src/ru/javaops/webapp/storage/MapFullNameStorage.java create mode 100644 src/ru/javaops/webapp/storage/MapResumeStorage.java diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 9148dd7a..177ff22e 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,6 +1,7 @@ package ru.javaops.webapp.model; import java.util.Comparator; +import java.util.Objects; import java.util.UUID; public class Resume { @@ -10,12 +11,15 @@ public class Resume { private String fullName; - public Resume(){ + public Resume(String fullName){ + Objects.requireNonNull(fullName, "fullName can't be null"); this.uuid = (UUID.randomUUID().toString()); - this.fullName = this.uuid; + this.fullName = fullName; } public Resume(String uuid, String fullName){ + Objects.requireNonNull(uuid, "UUID can't be null"); + Objects.requireNonNull(fullName, "fullName can't be null"); this.uuid = uuid; this.fullName = fullName; } @@ -57,6 +61,6 @@ public String getFullName() { @Override public String toString() { - return uuid; + return uuid + " (" + fullName + ")"; } } diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index aa963030..d832f331 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -19,13 +19,6 @@ public abstract class AbstractArrayStorage extends AbstractStorage { protected abstract void removeResume(int index); - @Override - public List getAllSorted() { - List listStorage = Arrays.asList(Arrays.copyOfRange(storage, 0, size)); - Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); - return listStorage; - } - public int size() { return size; } @@ -50,6 +43,11 @@ protected boolean isExist(Object index) { return (Integer) index >= 0; } + @Override + public List doCopyAll() { + return Arrays.asList(Arrays.copyOfRange(storage, 0, size)); + } + @Override protected Resume doGet(Object index) { return storage[(Integer) index]; diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 0cdc9492..13e6f52c 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -4,6 +4,9 @@ import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; +import java.util.Collections; +import java.util.List; + public abstract class AbstractStorage implements IStorage{ @@ -19,6 +22,8 @@ public abstract class AbstractStorage implements IStorage{ protected abstract boolean isExist(Object searchKey); + protected abstract List doCopyAll(); + public void save(Resume resume) { Object searchKey = getNotExistSearchKey(resume.getUuid()); doSave(resume, searchKey); @@ -47,6 +52,13 @@ protected Object getExistSearchKey(String uuid){ return searchKey; } + @Override + public List getAllSorted() { + List list = doCopyAll(); + Collections.sort(list, Resume.COMPARE_RESUMES_BY_FULLNAME); + return list; + } + protected Object getNotExistSearchKey(String uuid){ Object searchKey = getSearchKey(uuid); if (isExist(searchKey)){ diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index e6479704..60df5eb9 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -46,15 +46,13 @@ protected boolean isExist(Object index) { } @Override - public void clear() { - storage.clear(); + public List doCopyAll() { + return storage; } @Override - public List getAllSorted() { - List listStorage = storage; - Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); - return listStorage; + public void clear() { + storage.clear(); } @Override diff --git a/src/ru/javaops/webapp/storage/MapFullNameStorage.java b/src/ru/javaops/webapp/storage/MapFullNameStorage.java deleted file mode 100644 index 0d054cb6..00000000 --- a/src/ru/javaops/webapp/storage/MapFullNameStorage.java +++ /dev/null @@ -1,76 +0,0 @@ -package ru.javaops.webapp.storage; - -import ru.javaops.webapp.model.Resume; - -import java.util.*; - -public class MapFullNameStorage extends AbstractStorage { - - private Map storage = new HashMap<>(); - - @Override - protected void doSave(Resume resume, Object searchKey) { - storage.put(resume.getFullName(), resume); - } - - @Override - protected Object getSearchKey(String uuid) { - Iterator it = storage.entrySet().iterator(); - while (it.hasNext()){ - Map.Entry pair = (Map.Entry)it.next(); - if (pair.getKey().equals(uuid)){ - return pair.getKey(); - } - } - return null; - } - - @Override - protected Resume doGet(Object searchKey) { - return storage.get(searchKey); - } - - @Override - protected void doUpdate(Resume resume, Object searchKey) { - - } - - @Override - protected void doDelete(Object searchKey) { - storage.remove(searchKey); - } - - @Override - protected boolean isExist(Object searchKey) { - return storage.containsKey(searchKey); - } - - @Override - public void save(Resume resume) { - Object searchKey = getNotExistSearchKey(resume.getFullName()); - doSave(resume, searchKey); - } - - @Override - public void update(Resume resume) { - Object searchKey = getExistSearchKey(resume.getFullName()); - doUpdate(resume, searchKey); - } - - @Override - public void clear() { - storage.clear(); - } - - @Override - public List getAllSorted() { - List listStorage = new ArrayList<>(storage.values()); - Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); - return listStorage; - } - - @Override - public int size() { - return storage.size(); - } -} diff --git a/src/ru/javaops/webapp/storage/MapResumeStorage.java b/src/ru/javaops/webapp/storage/MapResumeStorage.java new file mode 100644 index 00000000..bb4270e2 --- /dev/null +++ b/src/ru/javaops/webapp/storage/MapResumeStorage.java @@ -0,0 +1,75 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.util.*; + +public class MapResumeStorage extends AbstractStorage { + + private Map storage = new HashMap<>(); + + @Override + protected void doSave(Resume resume, Object searchKey) { + storage.put(resume.getUuid(), resume); + } + + @Override + protected Object getSearchKey(String uuid) { +// Iterator it = storage.entrySet().iterator(); +// while (it.hasNext()){ +// Map.Entry pair = (Map.Entry)it.next(); +// if (pair.getKey().equals(uuid)){ +// return pair.getKey(); +// } +// } +// return null; + return storage.get(uuid); + } + + @Override + protected Resume doGet(Object searchKey) { + return storage.get(searchKey); + } + + @Override + protected void doUpdate(Resume resume, Object searchKey) { + storage.put(resume.getUuid(), resume); + } + + @Override + protected void doDelete(Object searchKey) { + storage.remove(searchKey); + } + + @Override + protected boolean isExist(Object searchKey) { + return storage.containsKey(searchKey); + } + + @Override + public List doCopyAll() { + return new ArrayList<>(storage.values()); + } + +// @Override +// public void save(Resume resume) { +// Object searchKey = getNotExistSearchKey(resume.getFullName()); +// doSave(resume, searchKey); +// } + +// @Override +// public void update(Resume resume) { +// Object searchKey = getExistSearchKey(resume.getFullName()); +// doUpdate(resume, searchKey); +// } + + @Override + public void clear() { + storage.clear(); + } + + @Override + public int size() { + return storage.size(); + } +} diff --git a/src/ru/javaops/webapp/storage/MapUuidStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java index c3f85c05..2d76dfbc 100644 --- a/src/ru/javaops/webapp/storage/MapUuidStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -16,14 +16,15 @@ protected void doSave(Resume resume, Object searchKey) { @Override protected Object getSearchKey(String uuid) { - Iterator it = storage.entrySet().iterator(); - while (it.hasNext()){ - Map.Entry pair = (Map.Entry)it.next(); - if (pair.getKey().equals(uuid)){ - return pair.getKey(); - } - } - return null; +// Iterator it = storage.entrySet().iterator(); +// while (it.hasNext()){ +// Map.Entry pair = (Map.Entry)it.next(); +// if (pair.getKey().equals(uuid)){ +// return pair.getKey(); +// } +// } +// return null; + return uuid; } @Override @@ -47,15 +48,13 @@ protected boolean isExist(Object searchKey) { } @Override - public void clear() { - storage.clear(); + public List doCopyAll() { + return new ArrayList<>(storage.values()); } @Override - public List getAllSorted() { - List listStorage = new ArrayList<>(storage.values()); - Collections.sort(listStorage, Resume.COMPARE_RESUMES_BY_FULLNAME); - return listStorage; + public void clear() { + storage.clear(); } @Override From dcc154e009a74959016373b5ef22c1f6b97e5863 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 16 Aug 2018 20:03:52 +0300 Subject: [PATCH 109/220] HW6, JunitTestSuite --- src/MainReflection.java | 2 +- .../javaops/webapp/storage/ListStorage.java | 2 +- .../webapp/storage/MapResumeStorage.java | 11 -------- .../webapp/storage/MapUuidStorage.java | 28 +++++++------------ .../storage/AbstractArrayStorageTest.java | 5 ++-- .../webapp/storage/AbstractStorageTest.java | 25 ++++++----------- .../storage/MapFullNameStorageTest.java | 16 +---------- 7 files changed, 24 insertions(+), 65 deletions(-) diff --git a/src/MainReflection.java b/src/MainReflection.java index 2de6b9ea..74555c49 100644 --- a/src/MainReflection.java +++ b/src/MainReflection.java @@ -7,7 +7,7 @@ public class MainReflection { @SuppressWarnings("unchecked") public static void main(String[] args) throws IllegalAccessException { - Resume r = new Resume(); + Resume r = new Resume("dummy"); Field field = r.getClass().getDeclaredFields()[0]; field.setAccessible(true); System.out.println(field.getName()); diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 60df5eb9..92de62c7 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -47,7 +47,7 @@ protected boolean isExist(Object index) { @Override public List doCopyAll() { - return storage; + return new ArrayList<>(storage); } @Override diff --git a/src/ru/javaops/webapp/storage/MapResumeStorage.java b/src/ru/javaops/webapp/storage/MapResumeStorage.java index bb4270e2..9458f315 100644 --- a/src/ru/javaops/webapp/storage/MapResumeStorage.java +++ b/src/ru/javaops/webapp/storage/MapResumeStorage.java @@ -51,17 +51,6 @@ public List doCopyAll() { return new ArrayList<>(storage.values()); } -// @Override -// public void save(Resume resume) { -// Object searchKey = getNotExistSearchKey(resume.getFullName()); -// doSave(resume, searchKey); -// } - -// @Override -// public void update(Resume resume) { -// Object searchKey = getExistSearchKey(resume.getFullName()); -// doUpdate(resume, searchKey); -// } @Override public void clear() { diff --git a/src/ru/javaops/webapp/storage/MapUuidStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java index 2d76dfbc..1b6b0d27 100644 --- a/src/ru/javaops/webapp/storage/MapUuidStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -10,41 +10,33 @@ public class MapUuidStorage extends AbstractStorage { private Map storage = new HashMap<>(); @Override - protected void doSave(Resume resume, Object searchKey) { - storage.put(resume.getUuid(), resume); + protected void doSave(Resume resume, Object uuid) { + storage.put((String) uuid, resume); } @Override protected Object getSearchKey(String uuid) { -// Iterator it = storage.entrySet().iterator(); -// while (it.hasNext()){ -// Map.Entry pair = (Map.Entry)it.next(); -// if (pair.getKey().equals(uuid)){ -// return pair.getKey(); -// } -// } -// return null; return uuid; } @Override - protected Resume doGet(Object searchKey) { - return storage.get(searchKey); + protected Resume doGet(Object uuid) { + return storage.get((String) uuid); } @Override - protected void doUpdate(Resume resume, Object searchKey) { - storage.replace(searchKey.toString(), resume); + protected void doUpdate(Resume resume, Object uuid) { + storage.replace((String) uuid, resume); } @Override - protected void doDelete(Object searchKey) { - storage.remove(searchKey); + protected void doDelete(Object uuid) { + storage.remove((String) uuid); } @Override - protected boolean isExist(Object searchKey) { - return storage.containsKey(searchKey); + protected boolean isExist(Object uuid) { + return storage.containsKey((String) uuid); } @Override diff --git a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java index 42aa555e..6b16a3f0 100644 --- a/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractArrayStorageTest.java @@ -1,6 +1,5 @@ package ru.javaops.webapp.storage; -import org.junit.Assume; import org.junit.Test; import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; @@ -17,11 +16,11 @@ public AbstractArrayStorageTest(IStorage storage) { public void storageOverflow() { try { for (int i = storage.size(); i < STORAGE_LIMIT; i++) { - storage.save(new Resume()); + storage.save(new Resume("Name" + i)); } } catch (Exception e) { fail("Storage is not full filled! " + "Exception: " + e.getMessage()); } - storage.save(new Resume()); + storage.save(new Resume("dummy")); } } diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index d127e94b..104f5b6d 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -1,13 +1,11 @@ package ru.javaops.webapp.storage; import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; @@ -17,12 +15,9 @@ public abstract class AbstractStorageTest { private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; - private static final String NAME_1 = "Name1"; - private static final String NAME_2 = "Name2"; - protected static final String NAME_3 = "Name3"; - private static final Resume resume1 = new Resume(UUID_1, NAME_1); - private static final Resume resume2 = new Resume(UUID_2, NAME_2); - private static final Resume resume3 = new Resume(UUID_3, NAME_3); + private static final Resume resume1 = new Resume(UUID_1, "Name1"); + private static final Resume resume2 = new Resume(UUID_2, "Name2"); + private static final Resume resume3 = new Resume(UUID_3, "Name3"); public AbstractStorageTest(IStorage storage) { this.storage = storage; @@ -52,11 +47,9 @@ public void getNotExist() { } @Test - public void getAll() { - //Resume[] resumes = {resume1, resume2, resume3}; - List listStorage = new ArrayList<>(); //Arrays.asList(resumes); - listStorage.add(resume1);listStorage.add(resume2); listStorage.add(resume3); - Assert.assertEquals(listStorage, storage.getAllSorted()); + public void getAllSorted() { + List listStorage = storage.getAllSorted(); //Arrays.asList(resumes); + Assert.assertEquals(listStorage, Arrays.asList(resume1, resume2, resume3)); } @Test @@ -69,12 +62,12 @@ public void update() { @Test(expected = NotExistStorageException.class) public void updateNotExist() { - storage.update(new Resume()); + storage.update(new Resume("dummy")); } @Test public void save() { - Resume resume = new Resume(); + Resume resume = new Resume("dummy"); storage.save(resume); compareSize(4); compareResume(resume); diff --git a/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java b/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java index c834e611..dcaaff2b 100644 --- a/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java +++ b/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java @@ -6,20 +6,6 @@ public class MapFullNameStorageTest extends AbstractStorageTest{ public MapFullNameStorageTest() { - super(new MapFullNameStorage()); - } - - @Override - @Test - public void update() { - Resume resume = storage.get(NAME_3); - storage.update(resume); - compareSize(3); - compareResume(resume); - } - - @Override - protected void compareResume(Resume resume){ - Assert.assertEquals(resume, storage.get(resume.getFullName())); + super(new MapResumeStorage()); } } From 7f0c6f505a0a28552e4502e09a250fc11397bdc7 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 16 Aug 2018 20:23:07 +0300 Subject: [PATCH 110/220] HW6, JunitTestSuite --- .../webapp/storage/MapResumeStorage.java | 30 +++++++------------ .../webapp/storage/MapUuidStorage.java | 2 +- ...ageTest.java => MapResumeStorageTest.java} | 4 +-- 3 files changed, 14 insertions(+), 22 deletions(-) rename test/ru/javaops/webapp/storage/{MapFullNameStorageTest.java => MapResumeStorageTest.java} (62%) diff --git a/src/ru/javaops/webapp/storage/MapResumeStorage.java b/src/ru/javaops/webapp/storage/MapResumeStorage.java index 9458f315..63a66373 100644 --- a/src/ru/javaops/webapp/storage/MapResumeStorage.java +++ b/src/ru/javaops/webapp/storage/MapResumeStorage.java @@ -9,41 +9,33 @@ public class MapResumeStorage extends AbstractStorage { private Map storage = new HashMap<>(); @Override - protected void doSave(Resume resume, Object searchKey) { - storage.put(resume.getUuid(), resume); + protected void doSave(Resume newResume, Object resume) { + storage.put(newResume.getUuid(), newResume); } @Override - protected Object getSearchKey(String uuid) { -// Iterator it = storage.entrySet().iterator(); -// while (it.hasNext()){ -// Map.Entry pair = (Map.Entry)it.next(); -// if (pair.getKey().equals(uuid)){ -// return pair.getKey(); -// } -// } -// return null; + protected Resume getSearchKey(String uuid) { return storage.get(uuid); } @Override - protected Resume doGet(Object searchKey) { - return storage.get(searchKey); + protected Resume doGet(Object resume) { + return (Resume) resume; } @Override - protected void doUpdate(Resume resume, Object searchKey) { - storage.put(resume.getUuid(), resume); + protected void doUpdate(Resume newResume, Object resume) { + storage.put(newResume.getUuid(), newResume); } @Override - protected void doDelete(Object searchKey) { - storage.remove(searchKey); + protected void doDelete(Object resume) { + storage.remove(((Resume) resume).getUuid()); } @Override - protected boolean isExist(Object searchKey) { - return storage.containsKey(searchKey); + protected boolean isExist(Object resume) { + return resume != null; } @Override diff --git a/src/ru/javaops/webapp/storage/MapUuidStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java index 1b6b0d27..d317e7df 100644 --- a/src/ru/javaops/webapp/storage/MapUuidStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -15,7 +15,7 @@ protected void doSave(Resume resume, Object uuid) { } @Override - protected Object getSearchKey(String uuid) { + protected String getSearchKey(String uuid) { return uuid; } diff --git a/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java b/test/ru/javaops/webapp/storage/MapResumeStorageTest.java similarity index 62% rename from test/ru/javaops/webapp/storage/MapFullNameStorageTest.java rename to test/ru/javaops/webapp/storage/MapResumeStorageTest.java index dcaaff2b..e33a39e4 100644 --- a/test/ru/javaops/webapp/storage/MapFullNameStorageTest.java +++ b/test/ru/javaops/webapp/storage/MapResumeStorageTest.java @@ -4,8 +4,8 @@ import org.junit.Test; import ru.javaops.webapp.model.Resume; -public class MapFullNameStorageTest extends AbstractStorageTest{ - public MapFullNameStorageTest() { +public class MapResumeStorageTest extends AbstractStorageTest{ + public MapResumeStorageTest() { super(new MapResumeStorage()); } } From 8fdbf1b9c38e4785a1e8ff44dbb1debc7a60f269 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 16 Aug 2018 20:24:32 +0300 Subject: [PATCH 111/220] HW6, JunitTestSuite --- test/ru/javaops/webapp/storage/JunitTestSuite.java | 2 +- test/ru/javaops/webapp/storage/MapResumeStorageTest.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/test/ru/javaops/webapp/storage/JunitTestSuite.java b/test/ru/javaops/webapp/storage/JunitTestSuite.java index a1ed0100..ae2e39c1 100644 --- a/test/ru/javaops/webapp/storage/JunitTestSuite.java +++ b/test/ru/javaops/webapp/storage/JunitTestSuite.java @@ -4,6 +4,6 @@ import org.junit.runners.Suite; @RunWith(Suite.class) -@Suite.SuiteClasses({ArrayStorageTest.class, SortedArrayStorageTest.class, ListStorageTest.class, MapUuidStorageTest.class, MapFullNameStorageTest.class}) +@Suite.SuiteClasses({ArrayStorageTest.class, SortedArrayStorageTest.class, ListStorageTest.class, MapUuidStorageTest.class, MapResumeStorageTest.class}) public class JunitTestSuite { } diff --git a/test/ru/javaops/webapp/storage/MapResumeStorageTest.java b/test/ru/javaops/webapp/storage/MapResumeStorageTest.java index e33a39e4..ee04ab2b 100644 --- a/test/ru/javaops/webapp/storage/MapResumeStorageTest.java +++ b/test/ru/javaops/webapp/storage/MapResumeStorageTest.java @@ -1,9 +1,5 @@ package ru.javaops.webapp.storage; -import org.junit.Assert; -import org.junit.Test; -import ru.javaops.webapp.model.Resume; - public class MapResumeStorageTest extends AbstractStorageTest{ public MapResumeStorageTest() { super(new MapResumeStorage()); From 1dba92f0c1df4bcf3e3bf8ad497e26509e17bbf6 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 17 Aug 2018 15:41:42 +0300 Subject: [PATCH 112/220] HW6, Resume chaining constructor, replace Comparator to Comparable --- src/ru/javaops/webapp/model/Resume.java | 22 ++++++------------- .../webapp/storage/AbstractStorage.java | 2 +- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 177ff22e..c0a54a15 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -4,7 +4,7 @@ import java.util.Objects; import java.util.UUID; -public class Resume { +public class Resume implements Comparable { // Unique identifier private final String uuid; @@ -12,9 +12,7 @@ public class Resume { private String fullName; public Resume(String fullName){ - Objects.requireNonNull(fullName, "fullName can't be null"); - this.uuid = (UUID.randomUUID().toString()); - this.fullName = fullName; + this((UUID.randomUUID().toString()), fullName); } public Resume(String uuid, String fullName){ @@ -34,17 +32,11 @@ public boolean equals(Object o) { return uuid.equals(resume.uuid); } - public static Comparator COMPARE_RESUMES_BY_FULLNAME = new Comparator() { - int compareResult; - @Override - public int compare(Resume o1, Resume o2) { - compareResult = o1.fullName.compareTo(o2.fullName); - if (compareResult != 0){ - return compareResult; - } - return o1.uuid.compareTo(o2.uuid); - } - }; + @Override + public int compareTo(Resume o) { + int comp = this.fullName.compareTo(o.fullName); + return comp != 0 ? comp : this.uuid.compareTo(o.uuid); + } @Override public int hashCode() { diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 13e6f52c..8fc0ecab 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -55,7 +55,7 @@ protected Object getExistSearchKey(String uuid){ @Override public List getAllSorted() { List list = doCopyAll(); - Collections.sort(list, Resume.COMPARE_RESUMES_BY_FULLNAME); + Collections.sort(list); return list; } From ec0bb27bf133068fd7fb7bfe3d709da405c61697 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 21 Aug 2018 14:23:36 +0300 Subject: [PATCH 113/220] HW6, Add Generic --- src/ru/javaops/webapp/model/Resume.java | 1 - .../webapp/storage/AbstractArrayStorage.java | 12 ++++---- .../webapp/storage/AbstractStorage.java | 30 +++++++++---------- .../javaops/webapp/storage/ListStorage.java | 20 ++++++------- .../webapp/storage/MapResumeStorage.java | 16 +++++----- .../webapp/storage/MapUuidStorage.java | 22 +++++++------- 6 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index c0a54a15..a1535ba0 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,6 +1,5 @@ package ru.javaops.webapp.model; -import java.util.Comparator; import java.util.Objects; import java.util.UUID; diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index d832f331..25940e5d 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -6,7 +6,7 @@ import java.util.*; -public abstract class AbstractArrayStorage extends AbstractStorage { +public abstract class AbstractArrayStorage extends AbstractStorage { protected static final int STORAGE_LIMIT = 100000; protected final Resume[] storage = new Resume[STORAGE_LIMIT]; @@ -29,7 +29,7 @@ public void clear() { } @Override - protected void doSave(Resume resume, Object index) { + protected void doSave(Resume resume, Integer index) { if (size >= STORAGE_LIMIT) { throw new StorageException("Error: resume storage is full!", resume.getUuid()); } else { @@ -39,7 +39,7 @@ protected void doSave(Resume resume, Object index) { } @Override - protected boolean isExist(Object index) { + protected boolean isExist(Integer index) { return (Integer) index >= 0; } @@ -49,17 +49,17 @@ public List doCopyAll() { } @Override - protected Resume doGet(Object index) { + protected Resume doGet(Integer index) { return storage[(Integer) index]; } @Override - protected void doUpdate(Resume resume, Object index) { + protected void doUpdate(Resume resume, Integer index) { storage[(Integer) index] = resume; } @Override - protected void doDelete(Object index) { + protected void doDelete(Integer index) { size--; removeResume((Integer) index); storage[size] = null; diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index 8fc0ecab..a6c74435 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -8,44 +8,44 @@ import java.util.List; -public abstract class AbstractStorage implements IStorage{ +public abstract class AbstractStorage implements IStorage{ - protected abstract void doSave(Resume resume, Object searchKey); + protected abstract void doSave(Resume resume, SK searchKey); - protected abstract Object getSearchKey(String uuid); + protected abstract SK getSearchKey(String uuid); - protected abstract Resume doGet(Object searchKey); + protected abstract Resume doGet(SK searchKey); - protected abstract void doUpdate(Resume resume, Object searchKey); + protected abstract void doUpdate(Resume resume, SK searchKey); - protected abstract void doDelete(Object searchKey); + protected abstract void doDelete(SK searchKey); - protected abstract boolean isExist(Object searchKey); + protected abstract boolean isExist(SK searchKey); protected abstract List doCopyAll(); public void save(Resume resume) { - Object searchKey = getNotExistSearchKey(resume.getUuid()); + SK searchKey = getNotExistSearchKey(resume.getUuid()); doSave(resume, searchKey); } public Resume get(String uuid) { - Object searchKey = getExistSearchKey(uuid); + SK searchKey = getExistSearchKey(uuid); return doGet(searchKey); } public void update(Resume resume) { - Object searchKey = getExistSearchKey(resume.getUuid()); + SK searchKey = getExistSearchKey(resume.getUuid()); doUpdate(resume, searchKey); } public void delete(String uuid) { - Object searchKey = getExistSearchKey(uuid); + SK searchKey = getExistSearchKey(uuid); doDelete(searchKey); } - protected Object getExistSearchKey(String uuid){ - Object searchKey = getSearchKey(uuid); + protected SK getExistSearchKey(String uuid){ + SK searchKey = getSearchKey(uuid); if (!isExist(searchKey)){ throw new NotExistStorageException(uuid); } @@ -59,8 +59,8 @@ public List getAllSorted() { return list; } - protected Object getNotExistSearchKey(String uuid){ - Object searchKey = getSearchKey(uuid); + protected SK getNotExistSearchKey(String uuid){ + SK searchKey = getSearchKey(uuid); if (isExist(searchKey)){ throw new ExistStorageException(uuid); } diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index 92de62c7..c5afb216 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -6,17 +6,17 @@ import java.util.Collections; import java.util.List; -public class ListStorage extends AbstractStorage { +public class ListStorage extends AbstractStorage { private final List storage = new ArrayList<>(); @Override - protected void doSave(Resume resume, Object index) { + protected void doSave(Resume resume, Integer index) { storage.add(resume); } @Override - protected Object getSearchKey(String uuid) { + protected Integer getSearchKey(String uuid) { for (int i = 0; i < storage.size(); i++){ if (storage.get(i).getUuid().equals(uuid)){ return i; @@ -26,22 +26,22 @@ protected Object getSearchKey(String uuid) { } @Override - protected Resume doGet(Object index) { - return storage.get((Integer) index); + protected Resume doGet(Integer index) { + return storage.get(index); } @Override - protected void doUpdate(Resume resume, Object index) { - storage.set((Integer) index, resume); + protected void doUpdate(Resume resume, Integer index) { + storage.set(index, resume); } @Override - protected void doDelete(Object index) { - storage.remove(((Integer) index).intValue()); + protected void doDelete(Integer index) { + storage.remove(index.intValue()); } @Override - protected boolean isExist(Object index) { + protected boolean isExist(Integer index) { return (index != null); } diff --git a/src/ru/javaops/webapp/storage/MapResumeStorage.java b/src/ru/javaops/webapp/storage/MapResumeStorage.java index 63a66373..adfafe22 100644 --- a/src/ru/javaops/webapp/storage/MapResumeStorage.java +++ b/src/ru/javaops/webapp/storage/MapResumeStorage.java @@ -4,12 +4,12 @@ import java.util.*; -public class MapResumeStorage extends AbstractStorage { +public class MapResumeStorage extends AbstractStorage { private Map storage = new HashMap<>(); @Override - protected void doSave(Resume newResume, Object resume) { + protected void doSave(Resume newResume, Resume resume) { storage.put(newResume.getUuid(), newResume); } @@ -19,22 +19,22 @@ protected Resume getSearchKey(String uuid) { } @Override - protected Resume doGet(Object resume) { - return (Resume) resume; + protected Resume doGet(Resume resume) { + return resume; } @Override - protected void doUpdate(Resume newResume, Object resume) { + protected void doUpdate(Resume newResume, Resume resume) { storage.put(newResume.getUuid(), newResume); } @Override - protected void doDelete(Object resume) { - storage.remove(((Resume) resume).getUuid()); + protected void doDelete(Resume resume) { + storage.remove(resume.getUuid()); } @Override - protected boolean isExist(Object resume) { + protected boolean isExist(Resume resume) { return resume != null; } diff --git a/src/ru/javaops/webapp/storage/MapUuidStorage.java b/src/ru/javaops/webapp/storage/MapUuidStorage.java index d317e7df..89ac85ab 100644 --- a/src/ru/javaops/webapp/storage/MapUuidStorage.java +++ b/src/ru/javaops/webapp/storage/MapUuidStorage.java @@ -5,13 +5,13 @@ import java.util.*; -public class MapUuidStorage extends AbstractStorage { +public class MapUuidStorage extends AbstractStorage { private Map storage = new HashMap<>(); @Override - protected void doSave(Resume resume, Object uuid) { - storage.put((String) uuid, resume); + protected void doSave(Resume resume, String uuid) { + storage.put(uuid, resume); } @Override @@ -20,23 +20,23 @@ protected String getSearchKey(String uuid) { } @Override - protected Resume doGet(Object uuid) { - return storage.get((String) uuid); + protected Resume doGet(String uuid) { + return storage.get(uuid); } @Override - protected void doUpdate(Resume resume, Object uuid) { - storage.replace((String) uuid, resume); + protected void doUpdate(Resume resume, String uuid) { + storage.replace(uuid, resume); } @Override - protected void doDelete(Object uuid) { - storage.remove((String) uuid); + protected void doDelete(String uuid) { + storage.remove(uuid); } @Override - protected boolean isExist(Object uuid) { - return storage.containsKey((String) uuid); + protected boolean isExist(String uuid) { + return storage.containsKey(uuid); } @Override From 817162f1dabfa42d1870aa55e10b6a60445281d1 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 24 Aug 2018 16:34:37 +0300 Subject: [PATCH 114/220] HW7, Add to model SectionType class --- src/TestSingleton.java | 23 +++++++++++++++++++ src/ru/javaops/webapp/model/SectionType.java | 20 ++++++++++++++++ .../webapp/storage/AbstractStorage.java | 10 ++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/TestSingleton.java create mode 100644 src/ru/javaops/webapp/model/SectionType.java diff --git a/src/TestSingleton.java b/src/TestSingleton.java new file mode 100644 index 00000000..d265197e --- /dev/null +++ b/src/TestSingleton.java @@ -0,0 +1,23 @@ +public class TestSingleton { + private static TestSingleton instance; + + public static TestSingleton getInstance() { + if (instance == null){ + instance = new TestSingleton(); + } + return instance; + } + + private TestSingleton() { + } + + public static void main(String[] args) { + TestSingleton.getInstance().toString(); + Singleton instance = Singleton.valueOf("SECOND"); + System.out.println(instance.ordinal()); + } + + public enum Singleton { + INSTANCE, SECOND + } +} diff --git a/src/ru/javaops/webapp/model/SectionType.java b/src/ru/javaops/webapp/model/SectionType.java new file mode 100644 index 00000000..6acf51da --- /dev/null +++ b/src/ru/javaops/webapp/model/SectionType.java @@ -0,0 +1,20 @@ +package ru.javaops.webapp.model; + +public enum SectionType { + PERSONAL("Личные качества"), + OBJECTIVE("Позиция"), + ACHIEVEMENT("Достижения"), + QUALIFICATIONS("Квалификация"), + EXPERIENCE("Опыт работы"), + EDUCATION("Образование"); + + private String title; + + SectionType(String title){ + this.title = title; + } + + public String getTitle() { + return title; + } +} diff --git a/src/ru/javaops/webapp/storage/AbstractStorage.java b/src/ru/javaops/webapp/storage/AbstractStorage.java index a6c74435..2effdd3f 100644 --- a/src/ru/javaops/webapp/storage/AbstractStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractStorage.java @@ -6,10 +6,13 @@ import java.util.Collections; import java.util.List; +import java.util.logging.Logger; public abstract class AbstractStorage implements IStorage{ + private static final Logger LOG = Logger.getLogger(AbstractStorage.class.getName()); + protected abstract void doSave(Resume resume, SK searchKey); protected abstract SK getSearchKey(String uuid); @@ -25,21 +28,25 @@ public abstract class AbstractStorage implements IStorage{ protected abstract List doCopyAll(); public void save(Resume resume) { + LOG.info("Save " + resume); SK searchKey = getNotExistSearchKey(resume.getUuid()); doSave(resume, searchKey); } public Resume get(String uuid) { + LOG.info("Get " + uuid); SK searchKey = getExistSearchKey(uuid); return doGet(searchKey); } public void update(Resume resume) { + LOG.info("Update " + resume); SK searchKey = getExistSearchKey(resume.getUuid()); doUpdate(resume, searchKey); } public void delete(String uuid) { + LOG.info("Delete " + uuid); SK searchKey = getExistSearchKey(uuid); doDelete(searchKey); } @@ -47,6 +54,7 @@ public void delete(String uuid) { protected SK getExistSearchKey(String uuid){ SK searchKey = getSearchKey(uuid); if (!isExist(searchKey)){ + LOG.warning("Resume " + uuid + " not exist."); throw new NotExistStorageException(uuid); } return searchKey; @@ -54,6 +62,7 @@ protected SK getExistSearchKey(String uuid){ @Override public List getAllSorted() { + LOG.info("getAllSorted"); List list = doCopyAll(); Collections.sort(list); return list; @@ -62,6 +71,7 @@ public List getAllSorted() { protected SK getNotExistSearchKey(String uuid){ SK searchKey = getSearchKey(uuid); if (isExist(searchKey)){ + LOG.warning("Resume " + uuid + " is exist."); throw new ExistStorageException(uuid); } return searchKey; From a50bc54f06557c9846c65dbec1d1826068f7e6de Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 27 Aug 2018 19:06:53 +0300 Subject: [PATCH 115/220] HW7, Add to model TextSection, TableSection, ContactType classes --- src/ru/javaops/webapp/model/ContactType.java | 21 +++++ src/ru/javaops/webapp/model/Resume.java | 6 ++ src/ru/javaops/webapp/model/TableSection.java | 78 +++++++++++++++++++ src/ru/javaops/webapp/model/TextSection.java | 57 ++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 src/ru/javaops/webapp/model/ContactType.java create mode 100644 src/ru/javaops/webapp/model/TableSection.java create mode 100644 src/ru/javaops/webapp/model/TextSection.java diff --git a/src/ru/javaops/webapp/model/ContactType.java b/src/ru/javaops/webapp/model/ContactType.java new file mode 100644 index 00000000..0ece0dfd --- /dev/null +++ b/src/ru/javaops/webapp/model/ContactType.java @@ -0,0 +1,21 @@ +package ru.javaops.webapp.model; + +public enum ContactType { + MOBILEPHONE("Тел."), + EMAIL("E-mail"), + SKYPE("Skype"), + LINKEDIN("LinkedIn"), + GITHUB("GitHub"), + STACKOVERFLOW("Stackoverflow"), + HOMEPAGE("Домашняя страница"); + + private String title; + + ContactType(String title){ + this.title = title; + } + + public String getTitle() { + return title; + } +} diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index a1535ba0..2dd0ab8e 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,5 +1,6 @@ package ru.javaops.webapp.model; +import java.util.List; import java.util.Objects; import java.util.UUID; @@ -10,6 +11,11 @@ public class Resume implements Comparable { private String fullName; + private List personal; + private List objective; + private List experience; + private List education; + public Resume(String fullName){ this((UUID.randomUUID().toString()), fullName); } diff --git a/src/ru/javaops/webapp/model/TableSection.java b/src/ru/javaops/webapp/model/TableSection.java new file mode 100644 index 00000000..427927a0 --- /dev/null +++ b/src/ru/javaops/webapp/model/TableSection.java @@ -0,0 +1,78 @@ +package ru.javaops.webapp.model; + + +import java.util.Date; + +public class TableSection { + private String organisation; + private String web; + private Date startDate; + private Date endDate; + private TextSection text; + private SectionType type; + + public TableSection(String organisation, String web, Date startDate, TextSection text, SectionType type) { + this.organisation = organisation; + this.web = web; + this.startDate = startDate; + this.text = text; + this.type = type; + } + + public TableSection(String organisation, String web, Date startDate, Date endDate, TextSection text, SectionType type) { + this.organisation = organisation; + this.web = web; + this.startDate = startDate; + this.endDate = endDate; + this.text = text; + this.type = type; + } + + public String getOrganisation() { + return organisation; + } + + public void setOrganisation(String organisation) { + this.organisation = organisation; + } + + public String getWeb() { + return web; + } + + public void setWeb(String web) { + this.web = web; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public TextSection getText() { + return text; + } + + public void setText(TextSection text) { + this.text = text; + } + + public SectionType getType() { + return type; + } + + public void setType(SectionType type) { + this.type = type; + } +} diff --git a/src/ru/javaops/webapp/model/TextSection.java b/src/ru/javaops/webapp/model/TextSection.java new file mode 100644 index 00000000..db466730 --- /dev/null +++ b/src/ru/javaops/webapp/model/TextSection.java @@ -0,0 +1,57 @@ +package ru.javaops.webapp.model; + +import java.util.Objects; + +public class TextSection { + private String text; + private SectionType type; + private Resume resume; + + public TextSection(Resume resume, SectionType type, String text) { + this.resume = resume; + this.type = type; + this.text = text; + } + + public void setText(String text) { + this.text = text; + } + + public void setType(SectionType type) { + this.type = type; + } + + public void setResume(Resume resume) { + this.resume = resume; + } + + public SectionType getType() { + return type; + } + + public Resume getResume() { + return resume; + } + + public String getText() { + return text; + } + + @Override + public String toString() { + return text; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TextSection that = (TextSection) o; + return Objects.equals(text, that.text); + } + + @Override + public int hashCode() { + return Objects.hash(text); + } +} From 6fcb3b6903306cbdf072bbf99890353db8f93a47 Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 27 Aug 2018 22:49:14 +0300 Subject: [PATCH 116/220] HW6, 27082018 --- src/ru/javaops/webapp/model/Resume.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 2dd0ab8e..d69405e2 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,5 +1,6 @@ package ru.javaops.webapp.model; +import java.util.HashMap; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -11,10 +12,13 @@ public class Resume implements Comparable { private String fullName; - private List personal; - private List objective; - private List experience; - private List education; + private HashMap textSectionMap; + private HashMap tableSectionMap; + +// private List personal; +// private List objective; +// private List experience; +// private List education; public Resume(String fullName){ this((UUID.randomUUID().toString()), fullName); From 13b07bbbb8a08ba630e926fd3c033e78b9423b89 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 28 Aug 2018 11:39:04 +0300 Subject: [PATCH 117/220] HW7, Add abstract class Section --- src/ru/javaops/webapp/model/Resume.java | 10 ++------ src/ru/javaops/webapp/model/Section.java | 4 ++++ src/ru/javaops/webapp/model/TableSection.java | 2 +- src/ru/javaops/webapp/model/TextSection.java | 24 ++----------------- 4 files changed, 9 insertions(+), 31 deletions(-) create mode 100644 src/ru/javaops/webapp/model/Section.java diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index d69405e2..6587732a 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,7 +1,6 @@ package ru.javaops.webapp.model; import java.util.HashMap; -import java.util.List; import java.util.Objects; import java.util.UUID; @@ -12,13 +11,8 @@ public class Resume implements Comparable { private String fullName; - private HashMap textSectionMap; - private HashMap tableSectionMap; - -// private List personal; -// private List objective; -// private List experience; -// private List education; + private HashMap contactMap; + private HashMap sectionMap; public Resume(String fullName){ this((UUID.randomUUID().toString()), fullName); diff --git a/src/ru/javaops/webapp/model/Section.java b/src/ru/javaops/webapp/model/Section.java new file mode 100644 index 00000000..6c99444d --- /dev/null +++ b/src/ru/javaops/webapp/model/Section.java @@ -0,0 +1,4 @@ +package ru.javaops.webapp.model; + +public abstract class Section { +} diff --git a/src/ru/javaops/webapp/model/TableSection.java b/src/ru/javaops/webapp/model/TableSection.java index 427927a0..08a1ece6 100644 --- a/src/ru/javaops/webapp/model/TableSection.java +++ b/src/ru/javaops/webapp/model/TableSection.java @@ -3,7 +3,7 @@ import java.util.Date; -public class TableSection { +public class TableSection extends Section{ private String organisation; private String web; private Date startDate; diff --git a/src/ru/javaops/webapp/model/TextSection.java b/src/ru/javaops/webapp/model/TextSection.java index db466730..1726ae10 100644 --- a/src/ru/javaops/webapp/model/TextSection.java +++ b/src/ru/javaops/webapp/model/TextSection.java @@ -2,14 +2,10 @@ import java.util.Objects; -public class TextSection { +public class TextSection extends Section { private String text; - private SectionType type; - private Resume resume; - public TextSection(Resume resume, SectionType type, String text) { - this.resume = resume; - this.type = type; + public TextSection(String text) { this.text = text; } @@ -17,22 +13,6 @@ public void setText(String text) { this.text = text; } - public void setType(SectionType type) { - this.type = type; - } - - public void setResume(Resume resume) { - this.resume = resume; - } - - public SectionType getType() { - return type; - } - - public Resume getResume() { - return resume; - } - public String getText() { return text; } From d763cc515067ce843ed05b30e336b557d32832ea Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 29 Aug 2018 18:21:33 +0300 Subject: [PATCH 118/220] HW7, Add to model Organisation & OrganisationSection --- src/ru/javaops/webapp/model/ContactType.java | 6 +- src/ru/javaops/webapp/model/ListSection.java | 36 +++++++++ src/ru/javaops/webapp/model/Organisation.java | 55 +++++++++++++ .../webapp/model/OrganisationSection.java | 33 ++++++++ src/ru/javaops/webapp/model/Resume.java | 5 +- src/ru/javaops/webapp/model/TableSection.java | 78 ------------------- src/ru/javaops/webapp/model/TextSection.java | 16 ++-- 7 files changed, 137 insertions(+), 92 deletions(-) create mode 100644 src/ru/javaops/webapp/model/ListSection.java create mode 100644 src/ru/javaops/webapp/model/Organisation.java create mode 100644 src/ru/javaops/webapp/model/OrganisationSection.java delete mode 100644 src/ru/javaops/webapp/model/TableSection.java diff --git a/src/ru/javaops/webapp/model/ContactType.java b/src/ru/javaops/webapp/model/ContactType.java index 0ece0dfd..80e11a09 100644 --- a/src/ru/javaops/webapp/model/ContactType.java +++ b/src/ru/javaops/webapp/model/ContactType.java @@ -1,13 +1,15 @@ package ru.javaops.webapp.model; public enum ContactType { - MOBILEPHONE("Тел."), + PHONE("Тел."), + MOBILE_PHONE("Мобильный тел."), EMAIL("E-mail"), + TELEGRAM("Telegram"), SKYPE("Skype"), LINKEDIN("LinkedIn"), GITHUB("GitHub"), STACKOVERFLOW("Stackoverflow"), - HOMEPAGE("Домашняя страница"); + HOME_PAGE("Домашняя страница"); private String title; diff --git a/src/ru/javaops/webapp/model/ListSection.java b/src/ru/javaops/webapp/model/ListSection.java new file mode 100644 index 00000000..fbc2b5a1 --- /dev/null +++ b/src/ru/javaops/webapp/model/ListSection.java @@ -0,0 +1,36 @@ +package ru.javaops.webapp.model; + +import java.util.List; +import java.util.Objects; + +public class ListSection extends Section { + private final List stringList; + + public ListSection(List stringList) { + this.stringList = stringList; + } + + public List getStringList() { + return stringList; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ListSection that = (ListSection) o; + return Objects.equals(stringList, that.stringList); + } + + @Override + public int hashCode() { + return Objects.hash(stringList); + } + + @Override + public String toString() { + return "ListSection{" + + "stringList=" + stringList + + '}'; + } +} diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java new file mode 100644 index 00000000..5081321f --- /dev/null +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -0,0 +1,55 @@ +package ru.javaops.webapp.model; + +import java.time.LocalDate; +import java.util.Objects; + +public class Organisation { + private final String name; + private final String url; + private final LocalDate startDate; + private final LocalDate endDate; + private final String head; + private final String description; + + public Organisation(String name, String url, LocalDate startDate, LocalDate endDate, String head, String description) { + Objects.requireNonNull(name, "name can't be NULL"); + Objects.requireNonNull(startDate, "startDate can't be NULL"); + Objects.requireNonNull(head, "head can't be NULL"); + this.name = name; + this.url = url; + this.startDate = startDate; + this.endDate = endDate; + this.head = head; + this.description = description; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Organisation that = (Organisation) o; + return Objects.equals(name, that.name) && + Objects.equals(url, that.url) && + Objects.equals(startDate, that.startDate) && + Objects.equals(endDate, that.endDate) && + Objects.equals(head, that.head) && + Objects.equals(description, that.description); + } + + @Override + public int hashCode() { + return Objects.hash(name, url, startDate, endDate, head, description); + } + + @Override + public String toString() { + return "Organisation{" + + "name='" + name + '\'' + + ", url='" + url + '\'' + + ", startDate=" + startDate + + ", endDate=" + endDate + + ", head='" + head + '\'' + + ", description='" + description + '\'' + + '}'; + } +} diff --git a/src/ru/javaops/webapp/model/OrganisationSection.java b/src/ru/javaops/webapp/model/OrganisationSection.java new file mode 100644 index 00000000..44cf9d08 --- /dev/null +++ b/src/ru/javaops/webapp/model/OrganisationSection.java @@ -0,0 +1,33 @@ +package ru.javaops.webapp.model; + +import java.util.List; +import java.util.Objects; + +public class OrganisationSection extends Section { + private final List organisations; + + public OrganisationSection(List organisations) { + Objects.requireNonNull(organisations, "organisations can't be NULL"); + this.organisations = organisations; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OrganisationSection that = (OrganisationSection) o; + return Objects.equals(organisations, that.organisations); + } + + @Override + public int hashCode() { + return Objects.hash(organisations); + } + + @Override + public String toString() { + return "OrganisationSection{" + + "organisations=" + organisations + + '}'; + } +} diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 6587732a..769b94dd 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,6 +1,7 @@ package ru.javaops.webapp.model; import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -11,8 +12,8 @@ public class Resume implements Comparable { private String fullName; - private HashMap contactMap; - private HashMap sectionMap; + private Map contactMap = new HashMap<>(); + private Map sectionMap = new HashMap<>(); public Resume(String fullName){ this((UUID.randomUUID().toString()), fullName); diff --git a/src/ru/javaops/webapp/model/TableSection.java b/src/ru/javaops/webapp/model/TableSection.java deleted file mode 100644 index 08a1ece6..00000000 --- a/src/ru/javaops/webapp/model/TableSection.java +++ /dev/null @@ -1,78 +0,0 @@ -package ru.javaops.webapp.model; - - -import java.util.Date; - -public class TableSection extends Section{ - private String organisation; - private String web; - private Date startDate; - private Date endDate; - private TextSection text; - private SectionType type; - - public TableSection(String organisation, String web, Date startDate, TextSection text, SectionType type) { - this.organisation = organisation; - this.web = web; - this.startDate = startDate; - this.text = text; - this.type = type; - } - - public TableSection(String organisation, String web, Date startDate, Date endDate, TextSection text, SectionType type) { - this.organisation = organisation; - this.web = web; - this.startDate = startDate; - this.endDate = endDate; - this.text = text; - this.type = type; - } - - public String getOrganisation() { - return organisation; - } - - public void setOrganisation(String organisation) { - this.organisation = organisation; - } - - public String getWeb() { - return web; - } - - public void setWeb(String web) { - this.web = web; - } - - public Date getStartDate() { - return startDate; - } - - public void setStartDate(Date startDate) { - this.startDate = startDate; - } - - public Date getEndDate() { - return endDate; - } - - public void setEndDate(Date endDate) { - this.endDate = endDate; - } - - public TextSection getText() { - return text; - } - - public void setText(TextSection text) { - this.text = text; - } - - public SectionType getType() { - return type; - } - - public void setType(SectionType type) { - this.type = type; - } -} diff --git a/src/ru/javaops/webapp/model/TextSection.java b/src/ru/javaops/webapp/model/TextSection.java index 1726ae10..592b9f5b 100644 --- a/src/ru/javaops/webapp/model/TextSection.java +++ b/src/ru/javaops/webapp/model/TextSection.java @@ -3,25 +3,16 @@ import java.util.Objects; public class TextSection extends Section { - private String text; + private final String text; public TextSection(String text) { this.text = text; } - public void setText(String text) { - this.text = text; - } - public String getText() { return text; } - @Override - public String toString() { - return text; - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -34,4 +25,9 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(text); } + + @Override + public String toString() { + return text; + } } From 636c8cde15d62ab23ca9a96fb56c6079cf3c8ca8 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 29 Aug 2018 18:50:14 +0300 Subject: [PATCH 119/220] HW7, Add requireNonNull to constructors, add getters to resume maps --- src/ru/javaops/webapp/model/ListSection.java | 1 + src/ru/javaops/webapp/model/Resume.java | 16 ++++++++++++---- src/ru/javaops/webapp/model/TextSection.java | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/model/ListSection.java b/src/ru/javaops/webapp/model/ListSection.java index fbc2b5a1..c24538e5 100644 --- a/src/ru/javaops/webapp/model/ListSection.java +++ b/src/ru/javaops/webapp/model/ListSection.java @@ -7,6 +7,7 @@ public class ListSection extends Section { private final List stringList; public ListSection(List stringList) { + Objects.requireNonNull(stringList, "stringList can't be NULL"); this.stringList = stringList; } diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 769b94dd..2a986231 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -12,20 +12,28 @@ public class Resume implements Comparable { private String fullName; - private Map contactMap = new HashMap<>(); - private Map sectionMap = new HashMap<>(); + private final Map contacts = new HashMap<>(); + private final Map sections = new HashMap<>(); public Resume(String fullName){ this((UUID.randomUUID().toString()), fullName); } public Resume(String uuid, String fullName){ - Objects.requireNonNull(uuid, "UUID can't be null"); - Objects.requireNonNull(fullName, "fullName can't be null"); + Objects.requireNonNull(uuid, "UUID can't be NULL"); + Objects.requireNonNull(fullName, "fullName can't be NULL"); this.uuid = uuid; this.fullName = fullName; } + public Map getContacts() { + return contacts; + } + + public Map getSections() { + return sections; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/ru/javaops/webapp/model/TextSection.java b/src/ru/javaops/webapp/model/TextSection.java index 592b9f5b..7967fea0 100644 --- a/src/ru/javaops/webapp/model/TextSection.java +++ b/src/ru/javaops/webapp/model/TextSection.java @@ -6,6 +6,7 @@ public class TextSection extends Section { private final String text; public TextSection(String text) { + Objects.requireNonNull(text, "text can't be NULL"); this.text = text; } From f4533e523b2d70e2349d5ab41eb9d32290b97cf0 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 30 Aug 2018 19:01:10 +0300 Subject: [PATCH 120/220] HW7, Create resume with all fields filled --- src/MainArray.java | 1 - src/MainTestArrayStorage.java | 1 - .../webapp/model/OrganisationSection.java | 5 +++ src/ru/javaops/webapp/model/Resume.java | 32 ++++++++++------- .../javaops/webapp/storage/ListStorage.java | 1 - .../webapp/storage/AbstractStorageTest.java | 35 ++++++++++++++++++- 6 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/MainArray.java b/src/MainArray.java index 3ca0df9d..88d2ef39 100644 --- a/src/MainArray.java +++ b/src/MainArray.java @@ -4,7 +4,6 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.util.ArrayList; import java.util.List; public class MainArray { diff --git a/src/MainTestArrayStorage.java b/src/MainTestArrayStorage.java index f8da7200..316ea638 100644 --- a/src/MainTestArrayStorage.java +++ b/src/MainTestArrayStorage.java @@ -1,5 +1,4 @@ import ru.javaops.webapp.model.Resume; -import ru.javaops.webapp.storage.ArrayStorage; import ru.javaops.webapp.storage.IStorage; import ru.javaops.webapp.storage.SortedArrayStorage; diff --git a/src/ru/javaops/webapp/model/OrganisationSection.java b/src/ru/javaops/webapp/model/OrganisationSection.java index 44cf9d08..2e4811bf 100644 --- a/src/ru/javaops/webapp/model/OrganisationSection.java +++ b/src/ru/javaops/webapp/model/OrganisationSection.java @@ -1,5 +1,6 @@ package ru.javaops.webapp.model; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -11,6 +12,10 @@ public OrganisationSection(List organisations) { this.organisations = organisations; } + public OrganisationSection(Organisation... organisations){ + this(Arrays.asList(organisations)); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 2a986231..8fb157d0 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,9 +1,6 @@ package ru.javaops.webapp.model; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; +import java.util.*; public class Resume implements Comparable { @@ -12,8 +9,8 @@ public class Resume implements Comparable { private String fullName; - private final Map contacts = new HashMap<>(); - private final Map sections = new HashMap<>(); + private final Map contacts = new EnumMap<>(ContactType.class); + private final Map sections = new EnumMap<>(SectionType.class); public Resume(String fullName){ this((UUID.randomUUID().toString()), fullName); @@ -26,6 +23,14 @@ public Resume(String uuid, String fullName){ this.fullName = fullName; } + public void addContact(ContactType type, String value) { + this.contacts.put(type, value); + } + + public void addSection(SectionType type, Section value) { + this.sections.put(type, value); + } + public Map getContacts() { return contacts; } @@ -38,10 +43,16 @@ public Map getSections() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - Resume resume = (Resume) o; + return Objects.equals(uuid, resume.uuid) && + Objects.equals(fullName, resume.fullName) && + Objects.equals(contacts, resume.contacts) && + Objects.equals(sections, resume.sections); + } - return uuid.equals(resume.uuid); + @Override + public int hashCode() { + return Objects.hash(uuid, fullName, contacts, sections); } @Override @@ -50,11 +61,6 @@ public int compareTo(Resume o) { return comp != 0 ? comp : this.uuid.compareTo(o.uuid); } - @Override - public int hashCode() { - return uuid.hashCode(); - } - public String getUuid() { return uuid; } diff --git a/src/ru/javaops/webapp/storage/ListStorage.java b/src/ru/javaops/webapp/storage/ListStorage.java index c5afb216..5c32886e 100644 --- a/src/ru/javaops/webapp/storage/ListStorage.java +++ b/src/ru/javaops/webapp/storage/ListStorage.java @@ -3,7 +3,6 @@ import ru.javaops.webapp.model.Resume; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class ListStorage extends AbstractStorage { diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 104f5b6d..a94743c8 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -3,8 +3,10 @@ import org.junit.*; import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; -import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.model.*; +import java.time.LocalDate; +import java.time.Month; import java.util.Arrays; import java.util.List; @@ -23,6 +25,37 @@ public AbstractStorageTest(IStorage storage) { this.storage = storage; } + static { + resume1.addContact(ContactType.PHONE, "+71231231212"); + resume1.addContact(ContactType.MOBILE_PHONE, "+79217340000"); + resume1.addContact(ContactType.EMAIL, "name1@mail.ru"); + resume1.addContact(ContactType.TELEGRAM, "telegram1"); + resume1.addContact(ContactType.SKYPE, "skype1"); + resume1.addContact(ContactType.LINKEDIN, "LinkedIn/name1"); + resume1.addContact(ContactType.GITHUB, "GitHub/name1"); + resume1.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name1"); + resume1.addContact(ContactType.HOME_PAGE, "homepage/name1"); + + resume1.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); + resume1.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 1")); + + resume1.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); + resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); + + resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( + new Organisation("Organisation 3", "url3", LocalDate.of(2008, Month.MAY, 15), LocalDate.now(), "Синьйор", "Работаю синьйором"), + new Organisation("Organisation 2", "url2", LocalDate.of(2005, Month.DECEMBER, 3), LocalDate.of(2008, Month.MAY, 14), "Миддл", "Работал миддлом"), + new Organisation("Organisation 1", "url1", LocalDate.of(2004, Month.APRIL, 1), LocalDate.of(2005, Month.DECEMBER, 2), "Джуниор", "Работал джуном") + )); + + resume1.addSection(SectionType.EDUCATION, new OrganisationSection( + new Organisation("Study 1", "urlStudy1", LocalDate.of(2000, Month.SEPTEMBER, 1), LocalDate.of(2004, Month.JUNE, 15), "Student", "Was a student") + )); + System.out.println(resume1); + System.out.println(resume1.getContacts()); + System.out.println(resume1.getSections()); + } + @Before public void setUp() { storage.clear(); From 6505e5d8e0a0812bac5160181a76b8cce12bbb96 Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 31 Aug 2018 19:31:51 +0300 Subject: [PATCH 121/220] Add DateUtil class --- src/MainDate.java | 30 ++++++++++++++++++++++++ src/ru/javaops/webapp/util/DateUtil.java | 10 ++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/MainDate.java create mode 100644 src/ru/javaops/webapp/util/DateUtil.java diff --git a/src/MainDate.java b/src/MainDate.java new file mode 100644 index 00000000..74d205cf --- /dev/null +++ b/src/MainDate.java @@ -0,0 +1,30 @@ +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; + +public class MainDate { + public static void main(String[] args) { + long start = System.currentTimeMillis(); + Date date = new Date(); + System.out.println(date); + System.out.println(System.currentTimeMillis() - start); + Calendar cal = Calendar.getInstance(); + System.out.println(cal.getTime()); + + LocalDate localDate = LocalDate.now(); + LocalTime localTime = LocalTime.now(); + LocalDateTime localDateTime = LocalDateTime.now(); + System.out.println(localDateTime); + System.out.println(localDate + " - " + localTime); + + SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd"); + System.out.println(sdf.format(date)); + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd"); + System.out.println(dtf.format(localDateTime)); + } +} diff --git a/src/ru/javaops/webapp/util/DateUtil.java b/src/ru/javaops/webapp/util/DateUtil.java new file mode 100644 index 00000000..697a7833 --- /dev/null +++ b/src/ru/javaops/webapp/util/DateUtil.java @@ -0,0 +1,10 @@ +package ru.javaops.webapp.util; + +import java.time.LocalDate; +import java.time.Month; + +public class DateUtil { + public static LocalDate of(int year, Month month){ + return LocalDate.of(year, month, 1); + } +} From e8c91636ac0f79ef2d3655b0f8d5833f9e9f407f Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 6 Sep 2018 14:10:46 +0300 Subject: [PATCH 122/220] HW8, Create class MainFile --- lesson/lesson1.md | 2 +- lesson/lesson4.md | 2 +- src/{ => ru/javaops/webapp}/MainArray.java | 2 ++ src/{ => ru/javaops/webapp}/MainDate.java | 2 ++ src/ru/javaops/webapp/MainFile.java | 31 +++++++++++++++++++ .../javaops/webapp}/MainReflection.java | 2 ++ .../javaops/webapp}/MainTestArrayStorage.java | 2 ++ .../javaops/webapp}/TestSingleton.java | 2 ++ 8 files changed, 43 insertions(+), 2 deletions(-) rename src/{ => ru/javaops/webapp}/MainArray.java (99%) rename src/{ => ru/javaops/webapp}/MainDate.java (97%) create mode 100644 src/ru/javaops/webapp/MainFile.java rename src/{ => ru/javaops/webapp}/MainReflection.java (97%) rename src/{ => ru/javaops/webapp}/MainTestArrayStorage.java (98%) rename src/{ => ru/javaops/webapp}/TestSingleton.java (95%) diff --git a/lesson/lesson1.md b/lesson/lesson1.md index 59fecf5b..04a2fab9 100644 --- a/lesson/lesson1.md +++ b/lesson/lesson1.md @@ -86,7 +86,7 @@ r1, r2, r3,..., rn, null, null,..., null <------- storage.length (10000) -------> ``` - Посмотрите на класс `java.util.Arrays`. В нем есть полезные методы, которые помогут вам написать более простой и понятный код -- Протестируйте вашу реализацию с помощью классов `MainArray.main()` и `MainTestArrayStorage.main()` +- Протестируйте вашу реализацию с помощью классов `ru.javaops.webapp.MainArray.main()` и `ru.javaops.webapp.MainTestArrayStorage.main()` - Изучите дополнительные материалы по IntelliJ IDEA: - [Idea Wiki](https://github.com/JavaOPs/topjava/wiki/IDEA) ([поставьте кодировку UTF-8](https://github.com/JavaOPs/topjava/wiki/IDEA#Поставить-кодировку-utf-8), [поменяйте шрифт по умолчанию на DejaVu](https://github.com/JavaOPs/topjava/wiki/IDEA#Поменять-фонт-по-умолчанию-dejavu)) - [Руководство пользователя IntelliJ IDEA. Отладчик](http://info.javarush.ru/idea_help/2014/01/22/Руководство-пользователя-IntelliJ-IDEA-Отладчик-.html) diff --git a/lesson/lesson4.md b/lesson/lesson4.md index 4207304b..c365e5d8 100644 --- a/lesson/lesson4.md +++ b/lesson/lesson4.md @@ -25,4 +25,4 @@ ## Домашнее задание Реализовать `AbstractStorageTest` и тесты `ArrayStorageTest` и `SortedArrayStorageTest`. -В `MainReflection` сделать вызов метода `toString` через отражение. +В `ru.javaops.webapp.MainReflection` сделать вызов метода `toString` через отражение. diff --git a/src/MainArray.java b/src/ru/javaops/webapp/MainArray.java similarity index 99% rename from src/MainArray.java rename to src/ru/javaops/webapp/MainArray.java index 88d2ef39..6823ffce 100644 --- a/src/MainArray.java +++ b/src/ru/javaops/webapp/MainArray.java @@ -1,3 +1,5 @@ +package ru.javaops.webapp; + import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.storage.*; diff --git a/src/MainDate.java b/src/ru/javaops/webapp/MainDate.java similarity index 97% rename from src/MainDate.java rename to src/ru/javaops/webapp/MainDate.java index 74d205cf..c9a54b4f 100644 --- a/src/MainDate.java +++ b/src/ru/javaops/webapp/MainDate.java @@ -1,3 +1,5 @@ +package ru.javaops.webapp; + import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java new file mode 100644 index 00000000..e8328009 --- /dev/null +++ b/src/ru/javaops/webapp/MainFile.java @@ -0,0 +1,31 @@ +package ru.javaops.webapp; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +public class MainFile { + public static void main(String[] args) { + File filePath = new File("./.gitignore"); + try { + System.out.println(filePath.getCanonicalPath()); + } catch (IOException e) { + throw new RuntimeException("Error", e); + } + File dir = new File("D:/JAVA/basejava/src/ru/javaops/webapp"); + System.out.println(dir.isDirectory()); + String[] list = dir.list(); + if (list != null){ + for (String name:dir.list()) { + System.out.println(name); + } + } + + try (FileInputStream fis = new FileInputStream(filePath)) { + System.out.println(fis.read()); + } catch (IOException e){ + throw new RuntimeException(e); + } + } +} diff --git a/src/MainReflection.java b/src/ru/javaops/webapp/MainReflection.java similarity index 97% rename from src/MainReflection.java rename to src/ru/javaops/webapp/MainReflection.java index 74555c49..857db452 100644 --- a/src/MainReflection.java +++ b/src/ru/javaops/webapp/MainReflection.java @@ -1,3 +1,5 @@ +package ru.javaops.webapp; + import ru.javaops.webapp.model.Resume; import java.lang.reflect.Field; diff --git a/src/MainTestArrayStorage.java b/src/ru/javaops/webapp/MainTestArrayStorage.java similarity index 98% rename from src/MainTestArrayStorage.java rename to src/ru/javaops/webapp/MainTestArrayStorage.java index 316ea638..267e8b5f 100644 --- a/src/MainTestArrayStorage.java +++ b/src/ru/javaops/webapp/MainTestArrayStorage.java @@ -1,3 +1,5 @@ +package ru.javaops.webapp; + import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.storage.IStorage; import ru.javaops.webapp.storage.SortedArrayStorage; diff --git a/src/TestSingleton.java b/src/ru/javaops/webapp/TestSingleton.java similarity index 95% rename from src/TestSingleton.java rename to src/ru/javaops/webapp/TestSingleton.java index d265197e..8737543f 100644 --- a/src/TestSingleton.java +++ b/src/ru/javaops/webapp/TestSingleton.java @@ -1,3 +1,5 @@ +package ru.javaops.webapp; + public class TestSingleton { private static TestSingleton instance; From 9e17082d26b30e3507e8543e39f27d059eee44dc Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 7 Sep 2018 17:19:07 +0300 Subject: [PATCH 123/220] HW8, Create class MainFile --- src/ru/javaops/webapp/MainFile.java | 1 - test/ru/javaops/webapp/storage/AbstractStorageTest.java | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index e8328009..d06c9f41 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -2,7 +2,6 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; public class MainFile { diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index a94743c8..b6aab3ce 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -43,9 +43,9 @@ public AbstractStorageTest(IStorage storage) { resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( - new Organisation("Organisation 3", "url3", LocalDate.of(2008, Month.MAY, 15), LocalDate.now(), "Синьйор", "Работаю синьйором"), - new Organisation("Organisation 2", "url2", LocalDate.of(2005, Month.DECEMBER, 3), LocalDate.of(2008, Month.MAY, 14), "Миддл", "Работал миддлом"), - new Organisation("Organisation 1", "url1", LocalDate.of(2004, Month.APRIL, 1), LocalDate.of(2005, Month.DECEMBER, 2), "Джуниор", "Работал джуном") + new Organisation("Yandex", "url3", LocalDate.of(2008, Month.MAY, 15), LocalDate.now(), "Синьйор", "Работаю синьйором"), + new Organisation("JetBrains", "url2", LocalDate.of(2005, Month.DECEMBER, 3), LocalDate.of(2008, Month.MAY, 14), "Миддл", "Работал миддлом"), + new Organisation("JetBrains", "url1", LocalDate.of(2004, Month.APRIL, 1), LocalDate.of(2005, Month.DECEMBER, 2), "Джуниор", "Работал джуном") )); resume1.addSection(SectionType.EDUCATION, new OrganisationSection( From de5fb10971ffe19b5af30375ef7def7199f9f969 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 7 Sep 2018 18:33:16 +0300 Subject: [PATCH 124/220] HW8, Add Position class in Organisation --- src/ru/javaops/webapp/model/Organisation.java | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 5081321f..a1e6b5f5 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -1,55 +1,49 @@ package ru.javaops.webapp.model; import java.time.LocalDate; +import java.time.Month; +import java.util.Arrays; +import java.util.List; import java.util.Objects; +import static ru.javaops.webapp.util.DateUtil.of; + public class Organisation { private final String name; private final String url; - private final LocalDate startDate; - private final LocalDate endDate; - private final String head; - private final String description; + private final List positions; - public Organisation(String name, String url, LocalDate startDate, LocalDate endDate, String head, String description) { + public Organisation(String name, String url, Position... positions){ Objects.requireNonNull(name, "name can't be NULL"); - Objects.requireNonNull(startDate, "startDate can't be NULL"); - Objects.requireNonNull(head, "head can't be NULL"); this.name = name; this.url = url; - this.startDate = startDate; - this.endDate = endDate; - this.head = head; - this.description = description; + this.positions = Arrays.asList(positions); } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Organisation that = (Organisation) o; - return Objects.equals(name, that.name) && - Objects.equals(url, that.url) && - Objects.equals(startDate, that.startDate) && - Objects.equals(endDate, that.endDate) && - Objects.equals(head, that.head) && - Objects.equals(description, that.description); - } - @Override - public int hashCode() { - return Objects.hash(name, url, startDate, endDate, head, description); - } - @Override - public String toString() { - return "Organisation{" + - "name='" + name + '\'' + - ", url='" + url + '\'' + - ", startDate=" + startDate + - ", endDate=" + endDate + - ", head='" + head + '\'' + - ", description='" + description + '\'' + - '}'; + public class Position{ + private final LocalDate startDate; + private final LocalDate endDate; + private final String head; + private final String description; + + public Position(int year, Month month, String head, String description) { + this(of(year, month), LocalDate.now(), head, description); + } + + public Position(LocalDate startDate, LocalDate endDate, String head, String description) { + this(startDate, endDate, head, description); + } + + public Position(LocalDate startDate, LocalDate endDate, String head, String description) { + Objects.requireNonNull(startDate, "startDate can't be NULL"); + Objects.requireNonNull(head, "head can't be NULL"); + this.startDate = startDate; + this.endDate = endDate; + this.head = head; + this.description = description; + } + } } From eafd623e70692da44e0c4387a91649241150f369 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 8 Sep 2018 15:10:02 +0300 Subject: [PATCH 125/220] Test Positions --- src/ru/javaops/webapp/model/Organisation.java | 56 +++++++++++++++++-- src/ru/javaops/webapp/util/DateUtil.java | 4 ++ .../webapp/storage/AbstractStorageTest.java | 2 +- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index a1e6b5f5..8965432c 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Objects; +import static ru.javaops.webapp.util.DateUtil.NOW; import static ru.javaops.webapp.util.DateUtil.of; public class Organisation { @@ -20,7 +21,29 @@ public Organisation(String name, String url, Position... positions){ this.positions = Arrays.asList(positions); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Organisation that = (Organisation) o; + return Objects.equals(name, that.name) && + Objects.equals(url, that.url) && + Objects.equals(positions, that.positions); + } + @Override + public int hashCode() { + return Objects.hash(name, url, positions); + } + + @Override + public String toString() { + return "Organisation{" + + "name='" + name + '\'' + + ", url='" + url + '\'' + + ", positions=" + positions + + '}'; + } public class Position{ private final LocalDate startDate; @@ -28,12 +51,12 @@ public class Position{ private final String head; private final String description; - public Position(int year, Month month, String head, String description) { - this(of(year, month), LocalDate.now(), head, description); + public Position(int startYear, Month startMonth, String head, String description) { + this(of(startYear, startMonth), NOW(), head, description); } - public Position(LocalDate startDate, LocalDate endDate, String head, String description) { - this(startDate, endDate, head, description); + public Position(int startYear, Month startMonth, int endYear, Month endMonth, String head, String description) { + this(of(startYear, startMonth), of(endYear, endMonth), head, description); } public Position(LocalDate startDate, LocalDate endDate, String head, String description) { @@ -45,5 +68,30 @@ public Position(LocalDate startDate, LocalDate endDate, String head, String desc this.description = description; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Position position = (Position) o; + return Objects.equals(startDate, position.startDate) && + Objects.equals(endDate, position.endDate) && + Objects.equals(head, position.head) && + Objects.equals(description, position.description); + } + + @Override + public int hashCode() { + return Objects.hash(startDate, endDate, head, description); + } + + @Override + public String toString() { + return "Position{" + + "startDate=" + startDate + + ", endDate=" + endDate + + ", head='" + head + '\'' + + ", description='" + description + '\'' + + '}'; + } } } diff --git a/src/ru/javaops/webapp/util/DateUtil.java b/src/ru/javaops/webapp/util/DateUtil.java index 697a7833..d4193550 100644 --- a/src/ru/javaops/webapp/util/DateUtil.java +++ b/src/ru/javaops/webapp/util/DateUtil.java @@ -7,4 +7,8 @@ public class DateUtil { public static LocalDate of(int year, Month month){ return LocalDate.of(year, month, 1); } + + public static LocalDate NOW(){ + return LocalDate.now(); + } } diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index b6aab3ce..06283447 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -43,7 +43,7 @@ public AbstractStorageTest(IStorage storage) { resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( - new Organisation("Yandex", "url3", LocalDate.of(2008, Month.MAY, 15), LocalDate.now(), "Синьйор", "Работаю синьйором"), + new Organisation("Yandex", "url3", new Organisation.Position[(LocalDate.of(2008, Month.MAY, 15), LocalDate.now(), "Синьйор", "Работаю синьйором")]), new Organisation("JetBrains", "url2", LocalDate.of(2005, Month.DECEMBER, 3), LocalDate.of(2008, Month.MAY, 14), "Миддл", "Работал миддлом"), new Organisation("JetBrains", "url1", LocalDate.of(2004, Month.APRIL, 1), LocalDate.of(2005, Month.DECEMBER, 2), "Джуниор", "Работал джуном") )); From 30a65480b79b5fbf1262c289d98e615e108a7b04 Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 9 Sep 2018 09:55:10 +0300 Subject: [PATCH 126/220] Get project filenames recursively --- src/ru/javaops/webapp/MainFile.java | 35 +++++++++++++++---- src/ru/javaops/webapp/model/Organisation.java | 2 +- .../webapp/storage/AbstractStorageTest.java | 14 +++++--- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index d06c9f41..b6ad374c 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -12,19 +12,40 @@ public static void main(String[] args) { } catch (IOException e) { throw new RuntimeException("Error", e); } - File dir = new File("D:/JAVA/basejava/src/ru/javaops/webapp"); - System.out.println(dir.isDirectory()); - String[] list = dir.list(); - if (list != null){ - for (String name:dir.list()) { - System.out.println(name); - } + //File dir = new File("D:/JAVA/basejava/src/ru/javaops/webapp"); + File dir = new File("/Users/nick/Documents/JAVA/PROJECTS/basejava/src/ru/javaops/webapp"); + + if (dir.isDirectory()){ + getDirectoryFileNames(dir); + } else if (!dir.exists()){ + System.out.println("dir is not exist"); + } else { + System.out.println("dir is not directory"); } +// String[] list = dir.list(); +// if (list != null){ +// for (String name:dir.list()) { +// System.out.println(name); +// } +// } + try (FileInputStream fis = new FileInputStream(filePath)) { System.out.println(fis.read()); } catch (IOException e){ throw new RuntimeException(e); } } + + public static void getDirectoryFileNames(File dir){ + File filePath; + for (String name:dir.list()) { + filePath = new File(dir + "/" + name); + if (filePath.isDirectory()){ + getDirectoryFileNames(filePath); + } else { + System.out.println(name); + } + } + } } diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 8965432c..749e1aac 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -45,7 +45,7 @@ public String toString() { '}'; } - public class Position{ + public static class Position{ private final LocalDate startDate; private final LocalDate endDate; private final String head; diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 06283447..de0170e7 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -43,13 +43,19 @@ public AbstractStorageTest(IStorage storage) { resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( - new Organisation("Yandex", "url3", new Organisation.Position[(LocalDate.of(2008, Month.MAY, 15), LocalDate.now(), "Синьйор", "Работаю синьйором")]), - new Organisation("JetBrains", "url2", LocalDate.of(2005, Month.DECEMBER, 3), LocalDate.of(2008, Month.MAY, 14), "Миддл", "Работал миддлом"), - new Organisation("JetBrains", "url1", LocalDate.of(2004, Month.APRIL, 1), LocalDate.of(2005, Month.DECEMBER, 2), "Джуниор", "Работал джуном") + new Organisation("Yandex", "yandex.ru", + new Organisation.Position(2008, Month.MAY, "Синьйор", "Работаю синьйором") + ), + new Organisation("JetBrains", "jetbrains.com", + new Organisation.Position(2005, Month.DECEMBER, 2008, Month.MAY, "Миддл", "Работал миддлом"), + new Organisation.Position(2004, Month.APRIL, 2005, Month.DECEMBER, "Джуниор", "Работал джуном") + ) )); resume1.addSection(SectionType.EDUCATION, new OrganisationSection( - new Organisation("Study 1", "urlStudy1", LocalDate.of(2000, Month.SEPTEMBER, 1), LocalDate.of(2004, Month.JUNE, 15), "Student", "Was a student") + new Organisation("Study 1", "urlStudy1", + new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", "Was a student") + ) )); System.out.println(resume1); System.out.println(resume1.getContacts()); From b54a8ad63aceda5d6d69df80284d304402a14d7d Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 10 Sep 2018 13:24:49 +0300 Subject: [PATCH 127/220] HW8, Add ResumeTestData class --- src/ru/javaops/webapp/MainFile.java | 15 ++---- .../webapp/storage/AbstractStorageTest.java | 41 +-------------- .../webapp/storage/ResumeTestData.java | 52 +++++++++++++++++++ 3 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 test/ru/javaops/webapp/storage/ResumeTestData.java diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index b6ad374c..cf51dabd 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -12,10 +12,10 @@ public static void main(String[] args) { } catch (IOException e) { throw new RuntimeException("Error", e); } - //File dir = new File("D:/JAVA/basejava/src/ru/javaops/webapp"); - File dir = new File("/Users/nick/Documents/JAVA/PROJECTS/basejava/src/ru/javaops/webapp"); - if (dir.isDirectory()){ + File dir = new File("./src/ru/javaops/webapp"); + + if (dir.isDirectory() && dir.list() != null){ getDirectoryFileNames(dir); } else if (!dir.exists()){ System.out.println("dir is not exist"); @@ -23,13 +23,6 @@ public static void main(String[] args) { System.out.println("dir is not directory"); } -// String[] list = dir.list(); -// if (list != null){ -// for (String name:dir.list()) { -// System.out.println(name); -// } -// } - try (FileInputStream fis = new FileInputStream(filePath)) { System.out.println(fis.read()); } catch (IOException e){ @@ -37,7 +30,7 @@ public static void main(String[] args) { } } - public static void getDirectoryFileNames(File dir){ + private static void getDirectoryFileNames(File dir){ File filePath; for (String name:dir.list()) { filePath = new File(dir + "/" + name); diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index de0170e7..8c254d57 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -14,10 +14,10 @@ public abstract class AbstractStorageTest { protected final IStorage storage; - private static final String UUID_1 = "uuid1"; + //private static final String UUID_1 = "uuid1"; private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; - private static final Resume resume1 = new Resume(UUID_1, "Name1"); + private static final Resume resume1 = ResumeTestData.getResume1();//new Resume(UUID_1, "Name1"); private static final Resume resume2 = new Resume(UUID_2, "Name2"); private static final Resume resume3 = new Resume(UUID_3, "Name3"); @@ -25,43 +25,6 @@ public AbstractStorageTest(IStorage storage) { this.storage = storage; } - static { - resume1.addContact(ContactType.PHONE, "+71231231212"); - resume1.addContact(ContactType.MOBILE_PHONE, "+79217340000"); - resume1.addContact(ContactType.EMAIL, "name1@mail.ru"); - resume1.addContact(ContactType.TELEGRAM, "telegram1"); - resume1.addContact(ContactType.SKYPE, "skype1"); - resume1.addContact(ContactType.LINKEDIN, "LinkedIn/name1"); - resume1.addContact(ContactType.GITHUB, "GitHub/name1"); - resume1.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name1"); - resume1.addContact(ContactType.HOME_PAGE, "homepage/name1"); - - resume1.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); - resume1.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 1")); - - resume1.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); - resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); - - resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( - new Organisation("Yandex", "yandex.ru", - new Organisation.Position(2008, Month.MAY, "Синьйор", "Работаю синьйором") - ), - new Organisation("JetBrains", "jetbrains.com", - new Organisation.Position(2005, Month.DECEMBER, 2008, Month.MAY, "Миддл", "Работал миддлом"), - new Organisation.Position(2004, Month.APRIL, 2005, Month.DECEMBER, "Джуниор", "Работал джуном") - ) - )); - - resume1.addSection(SectionType.EDUCATION, new OrganisationSection( - new Organisation("Study 1", "urlStudy1", - new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", "Was a student") - ) - )); - System.out.println(resume1); - System.out.println(resume1.getContacts()); - System.out.println(resume1.getSections()); - } - @Before public void setUp() { storage.clear(); diff --git a/test/ru/javaops/webapp/storage/ResumeTestData.java b/test/ru/javaops/webapp/storage/ResumeTestData.java new file mode 100644 index 00000000..de126f71 --- /dev/null +++ b/test/ru/javaops/webapp/storage/ResumeTestData.java @@ -0,0 +1,52 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.*; + +import java.time.Month; +import java.util.Arrays; + +public class ResumeTestData { + + protected static Resume resume1 = new Resume("uuid1", "Name1"); + + public static Resume getResume1() { + return resume1; + } + + static { + resume1.addContact(ContactType.PHONE, "+71231231212"); + resume1.addContact(ContactType.MOBILE_PHONE, "+79217340000"); + resume1.addContact(ContactType.EMAIL, "name1@mail.ru"); + resume1.addContact(ContactType.TELEGRAM, "telegram1"); + resume1.addContact(ContactType.SKYPE, "skype1"); + resume1.addContact(ContactType.LINKEDIN, "LinkedIn/name1"); + resume1.addContact(ContactType.GITHUB, "GitHub/name1"); + resume1.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name1"); + resume1.addContact(ContactType.HOME_PAGE, "homepage/name1"); + + resume1.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); + resume1.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 1")); + + resume1.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); + resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); + + resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( + new Organisation("Yandex", "yandex.ru", + new Organisation.Position(2008, Month.MAY, "Синьйор", "Работаю синьйором") + ), + new Organisation("JetBrains", "jetbrains.com", + new Organisation.Position(2005, Month.DECEMBER, 2008, Month.MAY, "Миддл", "Работал миддлом"), + new Organisation.Position(2004, Month.APRIL, 2005, Month.DECEMBER, "Джуниор", "Работал джуном") + ) + )); + + resume1.addSection(SectionType.EDUCATION, new OrganisationSection( + new Organisation("Study 1", "urlStudy1", + new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", "Was a student") + ) + )); +// System.out.println(resume1); +// System.out.println(resume1.getContacts()); +// System.out.println(resume1.getSections()); + } +} From 804775e6d5885db75f3dadec47443b7c9e5e55fd Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 10 Sep 2018 17:17:50 +0300 Subject: [PATCH 128/220] HW8, AbstractFileStorage implementation --- .../webapp/exception/StorageException.java | 5 ++ .../webapp/storage/AbstractArrayStorage.java | 10 +-- .../webapp/storage/AbstractFileStorage.java | 88 +++++++++++++++++++ .../webapp/storage/AbstractStorageTest.java | 2 - 4 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/AbstractFileStorage.java diff --git a/src/ru/javaops/webapp/exception/StorageException.java b/src/ru/javaops/webapp/exception/StorageException.java index 971852d5..2756f1a5 100644 --- a/src/ru/javaops/webapp/exception/StorageException.java +++ b/src/ru/javaops/webapp/exception/StorageException.java @@ -12,6 +12,11 @@ public StorageException(String message, String uuid) { this.uuid = uuid; } + public StorageException(String message, String uuid, Exception e) { + super(message, e); + this.uuid = uuid; + } + public String getUuid() { return uuid; } diff --git a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java index 25940e5d..26e778fd 100644 --- a/src/ru/javaops/webapp/storage/AbstractArrayStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractArrayStorage.java @@ -33,14 +33,14 @@ protected void doSave(Resume resume, Integer index) { if (size >= STORAGE_LIMIT) { throw new StorageException("Error: resume storage is full!", resume.getUuid()); } else { - putResume((Integer) index, resume); + putResume(index, resume); size++; } } @Override protected boolean isExist(Integer index) { - return (Integer) index >= 0; + return index >= 0; } @Override @@ -50,18 +50,18 @@ public List doCopyAll() { @Override protected Resume doGet(Integer index) { - return storage[(Integer) index]; + return storage[index]; } @Override protected void doUpdate(Resume resume, Integer index) { - storage[(Integer) index] = resume; + storage[index] = resume; } @Override protected void doDelete(Integer index) { size--; - removeResume((Integer) index); + removeResume(index); storage[size] = null; } } diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java new file mode 100644 index 00000000..f379e1d4 --- /dev/null +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -0,0 +1,88 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.exception.StorageException; +import ru.javaops.webapp.model.Resume; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public abstract class AbstractFileStorage extends AbstractStorage { + private File directory; + protected AbstractFileStorage(File directory) { + Objects.requireNonNull(directory, "directory must not be null"); + if (!directory.isDirectory()){ + throw new IllegalArgumentException(directory.getAbsolutePath() + " is not directory"); + } + if (!directory.canRead() || !directory.canWrite()){ + throw new IllegalArgumentException(directory.getAbsolutePath() + " is not readable/writable"); + } + this.directory = directory; + } + + @Override + protected void doSave(Resume resume, File file) { + try { + file.createNewFile(); + doWrite(resume, file); + } catch (IOException e) { + throw new StorageException("IO error", file.getName(), e); + } + } + + protected abstract void doWrite(Resume resume, File file) throws IOException; + + @Override + protected File getSearchKey(String uuid) { + return new File(directory, uuid); + } + + @Override + protected Resume doGet(File file) { + return doRead(file); + } + + protected abstract Resume doRead(File file); + + @Override + protected void doUpdate(Resume resume, File file) { + try { + doWrite(resume, file); + } catch (IOException e) { + throw new StorageException("IO error", file.getName(), e); + } + } + + @Override + protected void doDelete(File file) { + file.delete(); + } + + @Override + protected boolean isExist(File file) { + return file.exists(); + } + + @Override + protected List doCopyAll() { + List resumes = new ArrayList<>(); + for (File file:directory.listFiles()) { + resumes.add(doRead(file)); + } + return resumes; + } + + @Override + public void clear() { + for (File file:directory.listFiles()) { + file.delete(); + } + } + + @Override + public int size() { + return directory.list().length; + } +} diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 8c254d57..039236b6 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -5,8 +5,6 @@ import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.*; -import java.time.LocalDate; -import java.time.Month; import java.util.Arrays; import java.util.List; From 2aecac90039faaa26ab1805da5037d4ead4e9325 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 10 Sep 2018 17:24:48 +0300 Subject: [PATCH 129/220] HW8, Rename class JunitTestSuite to TestAll --- .../webapp/storage/{JunitTestSuite.java => TestAll.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename test/ru/javaops/webapp/storage/{JunitTestSuite.java => TestAll.java} (90%) diff --git a/test/ru/javaops/webapp/storage/JunitTestSuite.java b/test/ru/javaops/webapp/storage/TestAll.java similarity index 90% rename from test/ru/javaops/webapp/storage/JunitTestSuite.java rename to test/ru/javaops/webapp/storage/TestAll.java index ae2e39c1..55a04452 100644 --- a/test/ru/javaops/webapp/storage/JunitTestSuite.java +++ b/test/ru/javaops/webapp/storage/TestAll.java @@ -5,5 +5,5 @@ @RunWith(Suite.class) @Suite.SuiteClasses({ArrayStorageTest.class, SortedArrayStorageTest.class, ListStorageTest.class, MapUuidStorageTest.class, MapResumeStorageTest.class}) -public class JunitTestSuite { +public class TestAll { } From 53a9be2a8e9261e46f07410283b4faf04a2b0442 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 10 Sep 2018 17:56:38 +0300 Subject: [PATCH 130/220] HW8, !file.delete() StorageException --- src/ru/javaops/webapp/storage/AbstractFileStorage.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java index f379e1d4..bcf0a721 100644 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -57,7 +57,9 @@ protected void doUpdate(Resume resume, File file) { @Override protected void doDelete(File file) { - file.delete(); + if (!file.delete()){ + throw new StorageException("IO error", file.getName()); + } } @Override @@ -77,7 +79,9 @@ protected List doCopyAll() { @Override public void clear() { for (File file:directory.listFiles()) { - file.delete(); + if (!file.delete()){ + throw new StorageException("IO error", file.getName()); + } } } From a208a707ff68c840ac47fdcec7f7a2e61aff17b3 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 11 Sep 2018 13:12:12 +0300 Subject: [PATCH 131/220] HW8, AbstractFileStorage refactoring --- src/ru/javaops/webapp/MainFile.java | 24 +++++----- .../webapp/storage/AbstractFileStorage.java | 46 ++++++++++++------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index cf51dabd..599a196c 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -1,5 +1,7 @@ package ru.javaops.webapp; +import ru.javaops.webapp.exception.StorageException; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -15,13 +17,7 @@ public static void main(String[] args) { File dir = new File("./src/ru/javaops/webapp"); - if (dir.isDirectory() && dir.list() != null){ - getDirectoryFileNames(dir); - } else if (!dir.exists()){ - System.out.println("dir is not exist"); - } else { - System.out.println("dir is not directory"); - } + getDirectoryFileNames(dir); try (FileInputStream fis = new FileInputStream(filePath)) { System.out.println(fis.read()); @@ -31,13 +27,15 @@ public static void main(String[] args) { } private static void getDirectoryFileNames(File dir){ - File filePath; - for (String name:dir.list()) { - filePath = new File(dir + "/" + name); - if (filePath.isDirectory()){ - getDirectoryFileNames(filePath); + File[] files = dir.listFiles(); + if (files == null){ + throw new StorageException(dir.getName() + " is not directory, or IO Error"); + } + for (File file:files) { + if (file.isDirectory()){ + getDirectoryFileNames(file); } else { - System.out.println(name); + System.out.println(file.getName()); } } } diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java index bcf0a721..98b89687 100644 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -11,29 +11,32 @@ public abstract class AbstractFileStorage extends AbstractStorage { private File directory; + protected AbstractFileStorage(File directory) { Objects.requireNonNull(directory, "directory must not be null"); - if (!directory.isDirectory()){ + if (!directory.isDirectory()) { throw new IllegalArgumentException(directory.getAbsolutePath() + " is not directory"); } - if (!directory.canRead() || !directory.canWrite()){ + if (!directory.canRead() || !directory.canWrite()) { throw new IllegalArgumentException(directory.getAbsolutePath() + " is not readable/writable"); } this.directory = directory; } + protected abstract Resume doRead(File file) throws IOException; + + protected abstract void doWrite(Resume resume, File file) throws IOException; + @Override protected void doSave(Resume resume, File file) { try { file.createNewFile(); - doWrite(resume, file); + doUpdate(resume, file); } catch (IOException e) { throw new StorageException("IO error", file.getName(), e); } } - protected abstract void doWrite(Resume resume, File file) throws IOException; - @Override protected File getSearchKey(String uuid) { return new File(directory, uuid); @@ -41,11 +44,13 @@ protected File getSearchKey(String uuid) { @Override protected Resume doGet(File file) { - return doRead(file); + try { + return doRead(file); + } catch (IOException e) { + throw new StorageException("IO error", file.getName(), e); + } } - protected abstract Resume doRead(File file); - @Override protected void doUpdate(Resume resume, File file) { try { @@ -57,7 +62,7 @@ protected void doUpdate(Resume resume, File file) { @Override protected void doDelete(File file) { - if (!file.delete()){ + if (!file.delete()) { throw new StorageException("IO error", file.getName()); } } @@ -70,23 +75,32 @@ protected boolean isExist(File file) { @Override protected List doCopyAll() { List resumes = new ArrayList<>(); - for (File file:directory.listFiles()) { - resumes.add(doRead(file)); + File[] files = getFiles(); + for (File file : files) { + resumes.add(doGet(file)); } return resumes; } @Override public void clear() { - for (File file:directory.listFiles()) { - if (!file.delete()){ - throw new StorageException("IO error", file.getName()); - } + File[] files = getFiles(); + for (File file : files) { + doDelete(file); } } @Override public int size() { - return directory.list().length; + File[] files = getFiles(); + return files.length; + } + + private File[] getFiles() { + File[] files = directory.listFiles(); + if (files == null) { + throw new StorageException(directory.getName() + " is not directory, or IO Error"); + } + return files; } } From 17514f13c930f5e1d5fe6c2375e9eb7b265dc498 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 11 Sep 2018 13:21:06 +0300 Subject: [PATCH 132/220] HW8, AbstractFileStorage refactoring --- src/ru/javaops/webapp/MainFile.java | 2 +- src/ru/javaops/webapp/storage/AbstractFileStorage.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index 599a196c..2a2dbb05 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -29,7 +29,7 @@ public static void main(String[] args) { private static void getDirectoryFileNames(File dir){ File[] files = dir.listFiles(); if (files == null){ - throw new StorageException(dir.getName() + " is not directory, or IO Error"); + throw new StorageException("IO Error", dir.getName()); } for (File file:files) { if (file.isDirectory()){ diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java index 98b89687..c53b08f5 100644 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -99,7 +99,7 @@ public int size() { private File[] getFiles() { File[] files = directory.listFiles(); if (files == null) { - throw new StorageException(directory.getName() + " is not directory, or IO Error"); + throw new StorageException("IO error", directory.getName()); } return files; } From 70955e65b4a2202c70d7477a4d5a0f2e52fb1d4c Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 11 Sep 2018 13:25:21 +0300 Subject: [PATCH 133/220] HW8, AbstractFileStorage refactoring --- src/ru/javaops/webapp/MainFile.java | 2 +- src/ru/javaops/webapp/storage/AbstractFileStorage.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index 2a2dbb05..599a196c 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -29,7 +29,7 @@ public static void main(String[] args) { private static void getDirectoryFileNames(File dir){ File[] files = dir.listFiles(); if (files == null){ - throw new StorageException("IO Error", dir.getName()); + throw new StorageException(dir.getName() + " is not directory, or IO Error"); } for (File file:files) { if (file.isDirectory()){ diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java index c53b08f5..8a981323 100644 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -99,7 +99,7 @@ public int size() { private File[] getFiles() { File[] files = directory.listFiles(); if (files == null) { - throw new StorageException("IO error", directory.getName()); + throw new StorageException(directory.getName() + " IO Error"); } return files; } From 11847407ebe4c5d3a237d4898d6b082c00ad3c0f Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 12 Sep 2018 06:33:02 +0300 Subject: [PATCH 134/220] HW8, ListSection refactoring --- src/ru/javaops/webapp/model/ListSection.java | 23 ++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/ru/javaops/webapp/model/ListSection.java b/src/ru/javaops/webapp/model/ListSection.java index c24538e5..41285ab1 100644 --- a/src/ru/javaops/webapp/model/ListSection.java +++ b/src/ru/javaops/webapp/model/ListSection.java @@ -1,18 +1,23 @@ package ru.javaops.webapp.model; +import java.util.Arrays; import java.util.List; import java.util.Objects; public class ListSection extends Section { - private final List stringList; + private final List items; - public ListSection(List stringList) { - Objects.requireNonNull(stringList, "stringList can't be NULL"); - this.stringList = stringList; + public ListSection(String... items){ + this(Arrays.asList(items)); } - public List getStringList() { - return stringList; + public ListSection(List items) { + Objects.requireNonNull(items, "items can't be NULL"); + this.items = items; + } + + public List getItems() { + return items; } @Override @@ -20,18 +25,18 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ListSection that = (ListSection) o; - return Objects.equals(stringList, that.stringList); + return Objects.equals(items, that.items); } @Override public int hashCode() { - return Objects.hash(stringList); + return Objects.hash(items); } @Override public String toString() { return "ListSection{" + - "stringList=" + stringList + + "items=" + items + '}'; } } From 07cfd14da192c04066d21343c1d3dea4c3bc1ef9 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 12 Sep 2018 06:39:44 +0300 Subject: [PATCH 135/220] HW8, OrganisationSections refactoring --- src/ru/javaops/webapp/model/OrganisationSection.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/model/OrganisationSection.java b/src/ru/javaops/webapp/model/OrganisationSection.java index 2e4811bf..437b6df5 100644 --- a/src/ru/javaops/webapp/model/OrganisationSection.java +++ b/src/ru/javaops/webapp/model/OrganisationSection.java @@ -7,15 +7,15 @@ public class OrganisationSection extends Section { private final List organisations; + public OrganisationSection(Organisation... organisations){ + this(Arrays.asList(organisations)); + } + public OrganisationSection(List organisations) { Objects.requireNonNull(organisations, "organisations can't be NULL"); this.organisations = organisations; } - public OrganisationSection(Organisation... organisations){ - this(Arrays.asList(organisations)); - } - @Override public boolean equals(Object o) { if (this == o) return true; From 3989347dfc76267419c3c527204610f7b6c22b69 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 12 Sep 2018 06:59:31 +0300 Subject: [PATCH 136/220] HW8, MainFile refactoring --- src/ru/javaops/webapp/MainFile.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index 599a196c..671dced4 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -21,21 +21,22 @@ public static void main(String[] args) { try (FileInputStream fis = new FileInputStream(filePath)) { System.out.println(fis.read()); - } catch (IOException e){ + } catch (IOException e) { throw new RuntimeException(e); } } - private static void getDirectoryFileNames(File dir){ + private static void getDirectoryFileNames(File dir) { File[] files = dir.listFiles(); - if (files == null){ + if (files == null) { throw new StorageException(dir.getName() + " is not directory, or IO Error"); } - for (File file:files) { - if (file.isDirectory()){ + for (File file : files) { + if (file.isDirectory()) { + System.out.println("Directory: " + file.getName()); getDirectoryFileNames(file); } else { - System.out.println(file.getName()); + System.out.println(" File: " + file.getName()); } } } From 510920bf4d08bf81554ddd65ab888dc2016ea719 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 12 Sep 2018 07:12:09 +0300 Subject: [PATCH 137/220] HW8, AbstractFileStorage refactoring --- src/ru/javaops/webapp/storage/AbstractFileStorage.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java index 8a981323..2e768ffd 100644 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -30,10 +30,11 @@ protected AbstractFileStorage(File directory) { @Override protected void doSave(Resume resume, File file) { try { - file.createNewFile(); - doUpdate(resume, file); + if (file.createNewFile()) { + doUpdate(resume, file); + } } catch (IOException e) { - throw new StorageException("IO error", file.getName(), e); + throw new StorageException("Can't create file " + file.getAbsolutePath(), file.getName(), e); } } @@ -63,7 +64,7 @@ protected void doUpdate(Resume resume, File file) { @Override protected void doDelete(File file) { if (!file.delete()) { - throw new StorageException("IO error", file.getName()); + throw new StorageException("File delete error", file.getName()); } } From 521530ef0e83e895d2387e8eef274b3b6b2a7d85 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 12 Sep 2018 07:15:08 +0300 Subject: [PATCH 138/220] HW8, AbstractFileStorage refactoring --- src/ru/javaops/webapp/storage/AbstractFileStorage.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java index 2e768ffd..49ba5f96 100644 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -34,7 +34,7 @@ protected void doSave(Resume resume, File file) { doUpdate(resume, file); } } catch (IOException e) { - throw new StorageException("Can't create file " + file.getAbsolutePath(), file.getName(), e); + throw new StorageException("File create error " + file.getAbsolutePath(), file.getName(), e); } } @@ -48,7 +48,7 @@ protected Resume doGet(File file) { try { return doRead(file); } catch (IOException e) { - throw new StorageException("IO error", file.getName(), e); + throw new StorageException("File read error", file.getName(), e); } } @@ -57,7 +57,7 @@ protected void doUpdate(Resume resume, File file) { try { doWrite(resume, file); } catch (IOException e) { - throw new StorageException("IO error", file.getName(), e); + throw new StorageException("File write error", file.getName(), e); } } From cf08d3af73f1b09119f9153c43f2488a7e4e7e0c Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 12 Sep 2018 07:22:58 +0300 Subject: [PATCH 139/220] HW8, AbstractFileStorage refactoring --- src/ru/javaops/webapp/storage/AbstractFileStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java index 49ba5f96..d2d4d3c9 100644 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -100,7 +100,7 @@ public int size() { private File[] getFiles() { File[] files = directory.listFiles(); if (files == null) { - throw new StorageException(directory.getName() + " IO Error"); + throw new StorageException("Directory error " + directory.getName()); } return files; } From 2b8f0bac39c9329d7d046f65f9bc506b7c5b6889 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 12 Sep 2018 12:33:09 +0300 Subject: [PATCH 140/220] HW9, AbstractFileStorage Add BufferedInputStream, BufferedOutputSteram FileInputStream, FileOutputStream --- .../webapp/storage/AbstractFileStorage.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java index d2d4d3c9..42f47b6a 100644 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractFileStorage.java @@ -3,8 +3,7 @@ import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -12,6 +11,10 @@ public abstract class AbstractFileStorage extends AbstractStorage { private File directory; + protected abstract Resume doRead(InputStream inputStream) throws IOException; + + protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; + protected AbstractFileStorage(File directory) { Objects.requireNonNull(directory, "directory must not be null"); if (!directory.isDirectory()) { @@ -23,10 +26,6 @@ protected AbstractFileStorage(File directory) { this.directory = directory; } - protected abstract Resume doRead(File file) throws IOException; - - protected abstract void doWrite(Resume resume, File file) throws IOException; - @Override protected void doSave(Resume resume, File file) { try { @@ -46,7 +45,7 @@ protected File getSearchKey(String uuid) { @Override protected Resume doGet(File file) { try { - return doRead(file); + return doRead(new BufferedInputStream(new FileInputStream(file))); } catch (IOException e) { throw new StorageException("File read error", file.getName(), e); } @@ -55,7 +54,7 @@ protected Resume doGet(File file) { @Override protected void doUpdate(Resume resume, File file) { try { - doWrite(resume, file); + doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); } catch (IOException e) { throw new StorageException("File write error", file.getName(), e); } From 7a3c3f115a5df252e3c9de3ad93a8eb38abc5858 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 12 Sep 2018 18:29:23 +0300 Subject: [PATCH 141/220] HW9, DateUtil refactoring --- src/ru/javaops/webapp/model/Organisation.java | 2 +- src/ru/javaops/webapp/util/DateUtil.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 749e1aac..8213f430 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -52,7 +52,7 @@ public static class Position{ private final String description; public Position(int startYear, Month startMonth, String head, String description) { - this(of(startYear, startMonth), NOW(), head, description); + this(of(startYear, startMonth), NOW, head, description); } public Position(int startYear, Month startMonth, int endYear, Month endMonth, String head, String description) { diff --git a/src/ru/javaops/webapp/util/DateUtil.java b/src/ru/javaops/webapp/util/DateUtil.java index d4193550..af5c0352 100644 --- a/src/ru/javaops/webapp/util/DateUtil.java +++ b/src/ru/javaops/webapp/util/DateUtil.java @@ -8,7 +8,5 @@ public static LocalDate of(int year, Month month){ return LocalDate.of(year, month, 1); } - public static LocalDate NOW(){ - return LocalDate.now(); - } + public static final LocalDate NOW = LocalDate.of(3000, 1, 1); } From 2b84b81a63550a88f71f0e198bc7ef62ca201f58 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 20 Sep 2018 07:22:49 +0300 Subject: [PATCH 142/220] HW9, ObjectStreamStorage implementation --- src/ru/javaops/webapp/model/ListSection.java | 2 ++ src/ru/javaops/webapp/model/Organisation.java | 9 ++++-- .../webapp/model/OrganisationSection.java | 2 ++ src/ru/javaops/webapp/model/Resume.java | 4 ++- src/ru/javaops/webapp/model/Section.java | 4 ++- src/ru/javaops/webapp/model/TextSection.java | 2 ++ .../webapp/storage/ObjectStreamStorage.java | 28 +++++++++++++++++++ .../webapp/storage/AbstractStorageTest.java | 3 ++ .../storage/ObjectStreamStorageTest.java | 8 ++++++ 9 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/ObjectStreamStorage.java create mode 100644 test/ru/javaops/webapp/storage/ObjectStreamStorageTest.java diff --git a/src/ru/javaops/webapp/model/ListSection.java b/src/ru/javaops/webapp/model/ListSection.java index 41285ab1..ff833e33 100644 --- a/src/ru/javaops/webapp/model/ListSection.java +++ b/src/ru/javaops/webapp/model/ListSection.java @@ -5,6 +5,8 @@ import java.util.Objects; public class ListSection extends Section { + private static final long serialVersionUID = 1L; + private final List items; public ListSection(String... items){ diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 8213f430..836c5d33 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -1,5 +1,6 @@ package ru.javaops.webapp.model; +import java.io.Serializable; import java.time.LocalDate; import java.time.Month; import java.util.Arrays; @@ -9,7 +10,9 @@ import static ru.javaops.webapp.util.DateUtil.NOW; import static ru.javaops.webapp.util.DateUtil.of; -public class Organisation { +public class Organisation implements Serializable { + private static final long serialVersionUID = 1L; + private final String name; private final String url; private final List positions; @@ -45,7 +48,9 @@ public String toString() { '}'; } - public static class Position{ + public static class Position implements Serializable { + private static final long serialVersionUID = 1L; + private final LocalDate startDate; private final LocalDate endDate; private final String head; diff --git a/src/ru/javaops/webapp/model/OrganisationSection.java b/src/ru/javaops/webapp/model/OrganisationSection.java index 437b6df5..ac65e8d9 100644 --- a/src/ru/javaops/webapp/model/OrganisationSection.java +++ b/src/ru/javaops/webapp/model/OrganisationSection.java @@ -5,6 +5,8 @@ import java.util.Objects; public class OrganisationSection extends Section { + private static final long serialVersionUID = 1L; + private final List organisations; public OrganisationSection(Organisation... organisations){ diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 8fb157d0..0cabcac3 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,8 +1,10 @@ package ru.javaops.webapp.model; +import java.io.Serializable; import java.util.*; -public class Resume implements Comparable { +public class Resume implements Comparable, Serializable { + private static final long serialVersionUID = 1L; // Unique identifier private final String uuid; diff --git a/src/ru/javaops/webapp/model/Section.java b/src/ru/javaops/webapp/model/Section.java index 6c99444d..38f460d0 100644 --- a/src/ru/javaops/webapp/model/Section.java +++ b/src/ru/javaops/webapp/model/Section.java @@ -1,4 +1,6 @@ package ru.javaops.webapp.model; -public abstract class Section { +import java.io.Serializable; + +public abstract class Section implements Serializable { } diff --git a/src/ru/javaops/webapp/model/TextSection.java b/src/ru/javaops/webapp/model/TextSection.java index 7967fea0..eac470c7 100644 --- a/src/ru/javaops/webapp/model/TextSection.java +++ b/src/ru/javaops/webapp/model/TextSection.java @@ -3,6 +3,8 @@ import java.util.Objects; public class TextSection extends Section { + private static final long serialVersionUID = 1L; + private final String text; public TextSection(String text) { diff --git a/src/ru/javaops/webapp/storage/ObjectStreamStorage.java b/src/ru/javaops/webapp/storage/ObjectStreamStorage.java new file mode 100644 index 00000000..d13de339 --- /dev/null +++ b/src/ru/javaops/webapp/storage/ObjectStreamStorage.java @@ -0,0 +1,28 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.exception.StorageException; +import ru.javaops.webapp.model.Resume; + +import java.io.*; + +public class ObjectStreamStorage extends AbstractFileStorage { + protected ObjectStreamStorage(File directory) { + super(directory); + } + + @Override + protected Resume doRead(InputStream inputStream) throws IOException { + try (ObjectInputStream ois = new ObjectInputStream(inputStream)) { + return (Resume) ois.readObject(); + } catch (ClassNotFoundException e) { + throw new StorageException("Resume read error", null, e); + } + } + + @Override + protected void doWrite(Resume resume, OutputStream outputStream) throws IOException { + try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) { + oos.writeObject(resume); + } + } +} diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 039236b6..2042a5d0 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -5,11 +5,14 @@ import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.*; +import java.io.File; import java.util.Arrays; import java.util.List; public abstract class AbstractStorageTest { + protected final static File STORAGE_DIR = new File("./storage"); + protected final IStorage storage; //private static final String UUID_1 = "uuid1"; diff --git a/test/ru/javaops/webapp/storage/ObjectStreamStorageTest.java b/test/ru/javaops/webapp/storage/ObjectStreamStorageTest.java new file mode 100644 index 00000000..e042869d --- /dev/null +++ b/test/ru/javaops/webapp/storage/ObjectStreamStorageTest.java @@ -0,0 +1,8 @@ +package ru.javaops.webapp.storage; + +public class ObjectStreamStorageTest extends AbstractStorageTest { + + public ObjectStreamStorageTest() { + super(new ObjectStreamStorage(STORAGE_DIR)); + } +} From 3307c517853f0f9ea8c4323171b0becc0af86052 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 20 Sep 2018 17:59:47 +0300 Subject: [PATCH 143/220] HW9, AbstractPathStorage --- .../webapp/storage/AbstractPathStorage.java | 114 ++++++++++++++++++ .../webapp/storage/AbstractStorageTest.java | 2 +- 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/ru/javaops/webapp/storage/AbstractPathStorage.java diff --git a/src/ru/javaops/webapp/storage/AbstractPathStorage.java b/src/ru/javaops/webapp/storage/AbstractPathStorage.java new file mode 100644 index 00000000..8674e794 --- /dev/null +++ b/src/ru/javaops/webapp/storage/AbstractPathStorage.java @@ -0,0 +1,114 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.exception.StorageException; +import ru.javaops.webapp.model.Resume; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public abstract class AbstractPathStorage extends AbstractStorage { + private Path directory; + + protected abstract Resume doRead(InputStream inputStream) throws IOException; + + protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; + + protected AbstractPathStorage(String dir) { + directory = Paths.get(dir); + Objects.requireNonNull(directory, "directory must not be null"); + if (!Files.isDirectory(directory)) { + throw new IllegalArgumentException(dir + " is not directory"); + } + if (!Files.isReadable(directory) || !Files.isWritable(directory)) { + throw new IllegalArgumentException(dir + " is not readable/writable"); + } + } + + @Override + protected void doSave(Resume resume, Path path) { + try { + if (path.createNewPath()) { + doUpdate(resume, file); + } + } catch (IOException e) { + throw new StorageException("File create error " + file.getAbsolutePath(), file.getName(), e); + } + } + + @Override + protected Path getSearchKey(String uuid) { + return new Path(directory, uuid); + } + + @Override + protected Resume doGet(Path file) { + try { + return doRead(new BufferedInputStream(new FileInputStream(file))); + } catch (IOException e) { + throw new StorageException("File read error", file.getName(), e); + } + } + + @Override + protected void doUpdate(Resume resume, Path file) { + try { + doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); + } catch (IOException e) { + throw new StorageException("File write error", file.getName(), e); + } + } + + @Override + protected void doDelete(Path file) { + if (!file.delete()) { + throw new StorageException("File delete error", file.getName()); + } + } + + @Override + protected boolean isExist(Path file) { + return file.exists(); + } + + @Override + protected List doCopyAll() { + List resumes = new ArrayList<>(); + File[] files = getFiles(); + for (File file : files) { + resumes.add(doGet(file)); + } + return resumes; + } + + @Override + public void clear() { + try { + Files.list(directory).forEach(this::doDelete); + } catch (IOException e) { + throw new StorageException("Path delete error", null); + } + } + + @Override + public int size() { + try { + return Math.toIntExact(Files.list(directory).count()); + } catch (IOException e) { + e.printStackTrace(); + } + return 0; + } + + private File[] getFiles() { + File[] files = directory.listFiles(); + if (files == null) { + throw new StorageException("Directory error " + directory.getName()); + } + return files; + } +} diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 2042a5d0..516c4547 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -11,7 +11,7 @@ public abstract class AbstractStorageTest { - protected final static File STORAGE_DIR = new File("./storage"); + protected final static File STORAGE_DIR = new File("storage"); protected final IStorage storage; From 0e3609f205fe6003fe8e03a02ad9be1a5d5ebf78 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 24 Sep 2018 20:00:35 +0300 Subject: [PATCH 144/220] HW9, AbstractPathStorage implementation --- src/ru/javaops/webapp/MainFile.java | 20 +++++--- .../webapp/storage/AbstractPathStorage.java | 46 ++++++++----------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index 671dced4..5fde2f02 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -15,9 +15,9 @@ public static void main(String[] args) { throw new RuntimeException("Error", e); } - File dir = new File("./src/ru/javaops/webapp"); + File dir = new File("./src/ru/javaops"); // /webapp - getDirectoryFileNames(dir); + getDirectoryFileNames(dir, 0); try (FileInputStream fis = new FileInputStream(filePath)) { System.out.println(fis.read()); @@ -26,17 +26,23 @@ public static void main(String[] args) { } } - private static void getDirectoryFileNames(File dir) { + private static void getDirectoryFileNames(File dir, int level) { File[] files = dir.listFiles(); if (files == null) { throw new StorageException(dir.getName() + " is not directory, or IO Error"); } for (File file : files) { - if (file.isDirectory()) { - System.out.println("Directory: " + file.getName()); - getDirectoryFileNames(file); + if (file.isFile()) { + for (int i = 0; i < level; i++){ + System.out.print("\t"); + } + System.out.println(file.getName()); } else { - System.out.println(" File: " + file.getName()); + for (int i = 0; i < level; i++){ + System.out.print("\t"); + } + System.out.println("[" + file.getName() + "]"); + getDirectoryFileNames(file, level + 1); } } } diff --git a/src/ru/javaops/webapp/storage/AbstractPathStorage.java b/src/ru/javaops/webapp/storage/AbstractPathStorage.java index 8674e794..4a4e1996 100644 --- a/src/ru/javaops/webapp/storage/AbstractPathStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractPathStorage.java @@ -32,55 +32,55 @@ protected AbstractPathStorage(String dir) { @Override protected void doSave(Resume resume, Path path) { try { - if (path.createNewPath()) { - doUpdate(resume, file); - } + Files.createFile(path); + doUpdate(resume, path); } catch (IOException e) { - throw new StorageException("File create error " + file.getAbsolutePath(), file.getName(), e); + throw new StorageException("File create error " + path.toString(), path.getFileName().toString(), e); } } @Override protected Path getSearchKey(String uuid) { - return new Path(directory, uuid); + return Paths.get(uuid); } @Override - protected Resume doGet(Path file) { + protected Resume doGet(Path path) { try { - return doRead(new BufferedInputStream(new FileInputStream(file))); + return doRead(new BufferedInputStream(new FileInputStream(path.toFile()))); } catch (IOException e) { - throw new StorageException("File read error", file.getName(), e); + throw new StorageException("File read error", path.getFileName().toString(), e); } } @Override - protected void doUpdate(Resume resume, Path file) { + protected void doUpdate(Resume resume, Path path) { try { - doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); + doWrite(resume, new BufferedOutputStream(new FileOutputStream(path.toFile()))); } catch (IOException e) { - throw new StorageException("File write error", file.getName(), e); + throw new StorageException("File write error", path.getFileName().toString(), e); } } @Override - protected void doDelete(Path file) { - if (!file.delete()) { - throw new StorageException("File delete error", file.getName()); + protected void doDelete(Path path) { + try { + Files.delete(path); + } catch (IOException e) { + throw new StorageException("File delete error", path.getFileName().toString(), e); } } @Override - protected boolean isExist(Path file) { - return file.exists(); + protected boolean isExist(Path path) { + return Files.exists(path); } @Override protected List doCopyAll() { List resumes = new ArrayList<>(); - File[] files = getFiles(); - for (File file : files) { - resumes.add(doGet(file)); + for (Path path : directory) { + resumes.add(doGet(path)); } return resumes; } @@ -103,12 +103,4 @@ public int size() { } return 0; } - - private File[] getFiles() { - File[] files = directory.listFiles(); - if (files == null) { - throw new StorageException("Directory error " + directory.getName()); - } - return files; - } } From b59d612c1954838502628710d107fdd1bf266f4a Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 25 Sep 2018 06:09:34 +0300 Subject: [PATCH 145/220] HW9, Get file tree recursive --- src/ru/javaops/webapp/MainFile.java | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index 5fde2f02..7a5e84ed 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -5,6 +5,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class MainFile { public static void main(String[] args) { @@ -15,15 +17,14 @@ public static void main(String[] args) { throw new RuntimeException("Error", e); } - File dir = new File("./src/ru/javaops"); // /webapp - - getDirectoryFileNames(dir, 0); - try (FileInputStream fis = new FileInputStream(filePath)) { System.out.println(fis.read()); } catch (IOException e) { throw new RuntimeException(e); } + + File dir = new File("./src/ru/javaops"); // /webapp + getDirectoryFileNames(dir, 0); } private static void getDirectoryFileNames(File dir, int level) { @@ -32,16 +33,11 @@ private static void getDirectoryFileNames(File dir, int level) { throw new StorageException(dir.getName() + " is not directory, or IO Error"); } for (File file : files) { + String sRepeated = IntStream.range(0, level).mapToObj(i -> "\t").collect(Collectors.joining("")); if (file.isFile()) { - for (int i = 0; i < level; i++){ - System.out.print("\t"); - } - System.out.println(file.getName()); + System.out.println(sRepeated + file.getName()); } else { - for (int i = 0; i < level; i++){ - System.out.print("\t"); - } - System.out.println("[" + file.getName() + "]"); + System.out.println(sRepeated + "[" + file.getName() + "]"); getDirectoryFileNames(file, level + 1); } } From d462e63c6ef07318632ddb11e56079b4a6e495b6 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 25 Sep 2018 07:31:09 +0300 Subject: [PATCH 146/220] HW9, AbstractPathStroage refactoring --- .../webapp/storage/AbstractPathStorage.java | 11 +++++-- .../storage/ObjectStreamPathStorage.java | 29 +++++++++++++++++++ .../storage/ObjectStreamPathStorageTest.java | 7 +++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/ObjectStreamPathStorage.java create mode 100644 test/ru/javaops/webapp/storage/ObjectStreamPathStorageTest.java diff --git a/src/ru/javaops/webapp/storage/AbstractPathStorage.java b/src/ru/javaops/webapp/storage/AbstractPathStorage.java index 4a4e1996..b4b0437a 100644 --- a/src/ru/javaops/webapp/storage/AbstractPathStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractPathStorage.java @@ -41,7 +41,7 @@ protected void doSave(Resume resume, Path path) { @Override protected Path getSearchKey(String uuid) { - return Paths.get(uuid); + return directory.resolve(uuid); } @Override @@ -79,9 +79,14 @@ protected boolean isExist(Path path) { @Override protected List doCopyAll() { List resumes = new ArrayList<>(); - for (Path path : directory) { - resumes.add(doGet(path)); + try { + Files.list(directory).forEach(resumes.add(doGet())); + } catch (IOException e) { + e.printStackTrace(); } +// for (Path path : directory) { +// resumes.add(doGet(path)); +// } return resumes; } diff --git a/src/ru/javaops/webapp/storage/ObjectStreamPathStorage.java b/src/ru/javaops/webapp/storage/ObjectStreamPathStorage.java new file mode 100644 index 00000000..149b0f54 --- /dev/null +++ b/src/ru/javaops/webapp/storage/ObjectStreamPathStorage.java @@ -0,0 +1,29 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.exception.StorageException; +import ru.javaops.webapp.model.Resume; + +import java.io.*; +import java.nio.file.Path; + +public class ObjectStreamPathStorage extends AbstractPathStorage { + protected ObjectStreamPathStorage(String directory) { + super(directory); + } + + @Override + protected Resume doRead(InputStream inputStream) throws IOException { + try (ObjectInputStream ois = new ObjectInputStream(inputStream)) { + return (Resume) ois.readObject(); + } catch (ClassNotFoundException e) { + throw new StorageException("Resume read error", null, e); + } + } + + @Override + protected void doWrite(Resume resume, OutputStream outputStream) throws IOException { + try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) { + oos.writeObject(resume); + } + } +} diff --git a/test/ru/javaops/webapp/storage/ObjectStreamPathStorageTest.java b/test/ru/javaops/webapp/storage/ObjectStreamPathStorageTest.java new file mode 100644 index 00000000..990324e4 --- /dev/null +++ b/test/ru/javaops/webapp/storage/ObjectStreamPathStorageTest.java @@ -0,0 +1,7 @@ +package ru.javaops.webapp.storage; + +public class ObjectStreamPathStorageTest extends AbstractStorageTest { + public ObjectStreamPathStorageTest() { + super(new ObjectStreamPathStorage(STORAGE_DIR.toString())); + } +} From d561cf3f94b5a7b1fb066ffbab8786394c82c725 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 25 Sep 2018 17:46:06 +0300 Subject: [PATCH 147/220] HW9, FileStorage implementation --- .../webapp/storage/AbstractPathStorage.java | 8 +-- .../javaops/webapp/storage/FileStorage.java | 55 +++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/FileStorage.java diff --git a/src/ru/javaops/webapp/storage/AbstractPathStorage.java b/src/ru/javaops/webapp/storage/AbstractPathStorage.java index b4b0437a..01222547 100644 --- a/src/ru/javaops/webapp/storage/AbstractPathStorage.java +++ b/src/ru/javaops/webapp/storage/AbstractPathStorage.java @@ -80,13 +80,11 @@ protected boolean isExist(Path path) { protected List doCopyAll() { List resumes = new ArrayList<>(); try { - Files.list(directory).forEach(resumes.add(doGet())); + Files.list(directory) + .forEach(file -> resumes.add(doGet(file.toAbsolutePath()))); } catch (IOException e) { - e.printStackTrace(); + throw new IllegalArgumentException(directory.toString() + " is not directory", e); } -// for (Path path : directory) { -// resumes.add(doGet(path)); -// } return resumes; } diff --git a/src/ru/javaops/webapp/storage/FileStorage.java b/src/ru/javaops/webapp/storage/FileStorage.java new file mode 100644 index 00000000..d118b400 --- /dev/null +++ b/src/ru/javaops/webapp/storage/FileStorage.java @@ -0,0 +1,55 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.io.File; +import java.util.List; + + +public class FileStorage extends AbstractStorage { + + @Override + protected void doSave(Resume resume, File searchKey) { + + } + + @Override + protected File getSearchKey(String uuid) { + return null; + } + + @Override + protected Resume doGet(File searchKey) { + return null; + } + + @Override + protected void doUpdate(Resume resume, File searchKey) { + + } + + @Override + protected void doDelete(File searchKey) { + + } + + @Override + protected boolean isExist(File searchKey) { + return false; + } + + @Override + protected List doCopyAll() { + return null; + } + + @Override + public void clear() { + + } + + @Override + public int size() { + return 0; + } +} From 7247da8bfe4f58b62b9f155fa605793cd626c0eb Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 26 Sep 2018 07:48:48 +0300 Subject: [PATCH 148/220] HW9, PathStorage implementation --- .../javaops/webapp/storage/FileStorage.java | 83 ++++++++++--- .../javaops/webapp/storage/PathStorage.java | 109 ++++++++++++++++++ 2 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/PathStorage.java diff --git a/src/ru/javaops/webapp/storage/FileStorage.java b/src/ru/javaops/webapp/storage/FileStorage.java index d118b400..4f4d3efd 100644 --- a/src/ru/javaops/webapp/storage/FileStorage.java +++ b/src/ru/javaops/webapp/storage/FileStorage.java @@ -1,55 +1,106 @@ package ru.javaops.webapp.storage; +import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import java.io.File; +import java.io.*; +import java.util.ArrayList; import java.util.List; - +import java.util.Objects; public class FileStorage extends AbstractStorage { + private File directory; + +// protected abstract Resume doRead(InputStream inputStream) throws IOException; +// +// protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; + + protected FileStorage(File directory) { + Objects.requireNonNull(directory, "directory must not be null"); + if (!directory.isDirectory()) { + throw new IllegalArgumentException(directory.getAbsolutePath() + " is not directory"); + } + if (!directory.canRead() || !directory.canWrite()) { + throw new IllegalArgumentException(directory.getAbsolutePath() + " is not readable/writable"); + } + this.directory = directory; + } @Override - protected void doSave(Resume resume, File searchKey) { - + protected void doSave(Resume resume, File file) { + try { + if (file.createNewFile()) { + doUpdate(resume, file); + } + } catch (IOException e) { + throw new StorageException("File create error " + file.getAbsolutePath(), file.getName(), e); + } } @Override protected File getSearchKey(String uuid) { - return null; + return new File(directory, uuid); } @Override - protected Resume doGet(File searchKey) { - return null; + protected Resume doGet(File file) { + try { + return doRead(new BufferedInputStream(new FileInputStream(file))); + } catch (IOException e) { + throw new StorageException("File read error", file.getName(), e); + } } @Override - protected void doUpdate(Resume resume, File searchKey) { - + protected void doUpdate(Resume resume, File file) { + try { + doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); + } catch (IOException e) { + throw new StorageException("File write error", file.getName(), e); + } } @Override - protected void doDelete(File searchKey) { - + protected void doDelete(File file) { + if (!file.delete()) { + throw new StorageException("File delete error", file.getName()); + } } @Override - protected boolean isExist(File searchKey) { - return false; + protected boolean isExist(File file) { + return file.exists(); } @Override protected List doCopyAll() { - return null; + List resumes = new ArrayList<>(); + File[] files = getFiles(); + for (File file : files) { + resumes.add(doGet(file)); + } + return resumes; } @Override public void clear() { - + File[] files = getFiles(); + for (File file : files) { + doDelete(file); + } } @Override public int size() { - return 0; + File[] files = getFiles(); + return files.length; + } + + private File[] getFiles() { + File[] files = directory.listFiles(); + if (files == null) { + throw new StorageException("Directory error " + directory.getName()); + } + return files; } } diff --git a/src/ru/javaops/webapp/storage/PathStorage.java b/src/ru/javaops/webapp/storage/PathStorage.java new file mode 100644 index 00000000..fcd420fa --- /dev/null +++ b/src/ru/javaops/webapp/storage/PathStorage.java @@ -0,0 +1,109 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.exception.StorageException; +import ru.javaops.webapp.model.Resume; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class PathStorage extends AbstractStorage { + private Path directory; + +// protected abstract Resume doRead(InputStream inputStream) throws IOException; +// +// protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; + + protected PathStorage(String dir) { + directory = Paths.get(dir); + Objects.requireNonNull(directory, "directory must not be null"); + if (!Files.isDirectory(directory)) { + throw new IllegalArgumentException(dir + " is not directory"); + } + if (!Files.isReadable(directory) || !Files.isWritable(directory)) { + throw new IllegalArgumentException(dir + " is not readable/writable"); + } + } + + @Override + protected void doSave(Resume resume, Path path) { + try { + Files.createFile(path); + doUpdate(resume, path); + } catch (IOException e) { + throw new StorageException("File create error " + path.toString(), path.getFileName().toString(), e); + } + } + + @Override + protected Path getSearchKey(String uuid) { + return directory.resolve(uuid); + } + + @Override + protected Resume doGet(Path path) { + try { + return doRead(new BufferedInputStream(new FileInputStream(path.toFile()))); + } catch (IOException e) { + throw new StorageException("File read error", path.getFileName().toString(), e); + } + } + + @Override + protected void doUpdate(Resume resume, Path path) { + try { + doWrite(resume, new BufferedOutputStream(new FileOutputStream(path.toFile()))); + } catch (IOException e) { + throw new StorageException("File write error", path.getFileName().toString(), e); + } + } + + @Override + protected void doDelete(Path path) { + try { + Files.delete(path); + } catch (IOException e) { + throw new StorageException("File delete error", path.getFileName().toString(), e); + } + } + + @Override + protected boolean isExist(Path path) { + return Files.exists(path); + } + + @Override + protected List doCopyAll() { + List resumes = new ArrayList<>(); + try { + Files.list(directory) + .forEach(file -> resumes.add(doGet(file.toAbsolutePath()))); + } catch (IOException e) { + throw new IllegalArgumentException(directory.toString() + " is not directory", e); + } + return resumes; + } + + @Override + public void clear() { + try { + Files.list(directory).forEach(this::doDelete); + } catch (IOException e) { + throw new StorageException("Path delete error", null); + } + } + + @Override + public int size() { + try { + return Math.toIntExact(Files.list(directory).count()); + } catch (IOException e) { + e.printStackTrace(); + } + return 0; + } +} From da098b32a05af926e94b574b5054bd5191dfac8a Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 26 Sep 2018 17:37:35 +0300 Subject: [PATCH 149/220] HW9, ISerializeStrategy interface & StreamSerialize implementation --- .../javaops/webapp/storage/FileStorage.java | 8 +++--- .../webapp/storage/ISerializeStrategy.java | 12 +++++++++ .../javaops/webapp/storage/PathStorage.java | 8 +++--- .../webapp/storage/StreamSerialize.java | 26 +++++++++++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 src/ru/javaops/webapp/storage/ISerializeStrategy.java create mode 100644 src/ru/javaops/webapp/storage/StreamSerialize.java diff --git a/src/ru/javaops/webapp/storage/FileStorage.java b/src/ru/javaops/webapp/storage/FileStorage.java index 4f4d3efd..5295a26d 100644 --- a/src/ru/javaops/webapp/storage/FileStorage.java +++ b/src/ru/javaops/webapp/storage/FileStorage.java @@ -10,12 +10,13 @@ public class FileStorage extends AbstractStorage { private File directory; + private StreamSerialize streamSerialize; // protected abstract Resume doRead(InputStream inputStream) throws IOException; // // protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; - protected FileStorage(File directory) { + protected FileStorage(File directory, StreamSerialize streamSerialize) { Objects.requireNonNull(directory, "directory must not be null"); if (!directory.isDirectory()) { throw new IllegalArgumentException(directory.getAbsolutePath() + " is not directory"); @@ -24,6 +25,7 @@ protected FileStorage(File directory) { throw new IllegalArgumentException(directory.getAbsolutePath() + " is not readable/writable"); } this.directory = directory; + this.streamSerialize = streamSerialize; } @Override @@ -45,7 +47,7 @@ protected File getSearchKey(String uuid) { @Override protected Resume doGet(File file) { try { - return doRead(new BufferedInputStream(new FileInputStream(file))); + return streamSerialize.doRead(new BufferedInputStream(new FileInputStream(file))); } catch (IOException e) { throw new StorageException("File read error", file.getName(), e); } @@ -54,7 +56,7 @@ protected Resume doGet(File file) { @Override protected void doUpdate(Resume resume, File file) { try { - doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); + streamSerialize.doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); } catch (IOException e) { throw new StorageException("File write error", file.getName(), e); } diff --git a/src/ru/javaops/webapp/storage/ISerializeStrategy.java b/src/ru/javaops/webapp/storage/ISerializeStrategy.java new file mode 100644 index 00000000..a48ab6b0 --- /dev/null +++ b/src/ru/javaops/webapp/storage/ISerializeStrategy.java @@ -0,0 +1,12 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.model.Resume; + +import java.io.InputStream; +import java.io.OutputStream; + +public interface ISerializeStrategy { + void doWrite(Resume resume, OutputStream outputStream); + + Resume doRead(InputStream inputStream); +} diff --git a/src/ru/javaops/webapp/storage/PathStorage.java b/src/ru/javaops/webapp/storage/PathStorage.java index fcd420fa..9e293312 100644 --- a/src/ru/javaops/webapp/storage/PathStorage.java +++ b/src/ru/javaops/webapp/storage/PathStorage.java @@ -13,12 +13,13 @@ public class PathStorage extends AbstractStorage { private Path directory; + private StreamSerialize streamSerialize; // protected abstract Resume doRead(InputStream inputStream) throws IOException; // // protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; - protected PathStorage(String dir) { + protected PathStorage(String dir, StreamSerialize streamSerialize) { directory = Paths.get(dir); Objects.requireNonNull(directory, "directory must not be null"); if (!Files.isDirectory(directory)) { @@ -27,6 +28,7 @@ protected PathStorage(String dir) { if (!Files.isReadable(directory) || !Files.isWritable(directory)) { throw new IllegalArgumentException(dir + " is not readable/writable"); } + this.streamSerialize = streamSerialize; } @Override @@ -47,7 +49,7 @@ protected Path getSearchKey(String uuid) { @Override protected Resume doGet(Path path) { try { - return doRead(new BufferedInputStream(new FileInputStream(path.toFile()))); + return streamSerialize.doRead(new BufferedInputStream(new FileInputStream(path.toFile()))); } catch (IOException e) { throw new StorageException("File read error", path.getFileName().toString(), e); } @@ -56,7 +58,7 @@ protected Resume doGet(Path path) { @Override protected void doUpdate(Resume resume, Path path) { try { - doWrite(resume, new BufferedOutputStream(new FileOutputStream(path.toFile()))); + streamSerialize.doWrite(resume, new BufferedOutputStream(new FileOutputStream(path.toFile()))); } catch (IOException e) { throw new StorageException("File write error", path.getFileName().toString(), e); } diff --git a/src/ru/javaops/webapp/storage/StreamSerialize.java b/src/ru/javaops/webapp/storage/StreamSerialize.java new file mode 100644 index 00000000..d30493a1 --- /dev/null +++ b/src/ru/javaops/webapp/storage/StreamSerialize.java @@ -0,0 +1,26 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.exception.StorageException; +import ru.javaops.webapp.model.Resume; + +import java.io.*; + +public class StreamSerialize implements ISerializeStrategy { + @Override + public void doWrite(Resume resume, OutputStream outputStream) { + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);) { + objectOutputStream.writeObject(resume); + } catch (IOException e) { + throw new StorageException("Resume write error", resume.getUuid(), e); + } + } + + @Override + public Resume doRead(InputStream inputStream) { + try (ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) { + return (Resume) objectInputStream.readObject(); + } catch (IOException | ClassNotFoundException e) { + throw new StorageException("Resume read error", null, e); + } + } +} From 64d9a80ccf21ed640ca9b31f3379ec1ed96eb75e Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 27 Sep 2018 08:47:10 +0300 Subject: [PATCH 150/220] HW9, FileStorageTest & PathStorageTest implementation --- test/ru/javaops/webapp/storage/AbstractStorageTest.java | 1 + test/ru/javaops/webapp/storage/FileStorageTest.java | 7 +++++++ test/ru/javaops/webapp/storage/PathStorageTest.java | 7 +++++++ 3 files changed, 15 insertions(+) create mode 100644 test/ru/javaops/webapp/storage/FileStorageTest.java create mode 100644 test/ru/javaops/webapp/storage/PathStorageTest.java diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 516c4547..3808c15a 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -12,6 +12,7 @@ public abstract class AbstractStorageTest { protected final static File STORAGE_DIR = new File("storage"); + protected final static StreamSerialize STREAM_SERIALIZE = new StreamSerialize(); protected final IStorage storage; diff --git a/test/ru/javaops/webapp/storage/FileStorageTest.java b/test/ru/javaops/webapp/storage/FileStorageTest.java new file mode 100644 index 00000000..c7487978 --- /dev/null +++ b/test/ru/javaops/webapp/storage/FileStorageTest.java @@ -0,0 +1,7 @@ +package ru.javaops.webapp.storage; + +public class FileStorageTest extends AbstractStorageTest { + public FileStorageTest() { + super(new FileStorage(STORAGE_DIR, STREAM_SERIALIZE)); + } +} diff --git a/test/ru/javaops/webapp/storage/PathStorageTest.java b/test/ru/javaops/webapp/storage/PathStorageTest.java new file mode 100644 index 00000000..e4003d11 --- /dev/null +++ b/test/ru/javaops/webapp/storage/PathStorageTest.java @@ -0,0 +1,7 @@ +package ru.javaops.webapp.storage; + +public class PathStorageTest extends AbstractStorageTest { + public PathStorageTest() { + super(new PathStorage(STORAGE_DIR.toString(), STREAM_SERIALIZE)); + } +} From e30b132e33ca38c8537b53b7f82e499b5243b49f Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 27 Sep 2018 12:32:53 +0300 Subject: [PATCH 151/220] HW9, PathStorage refactoring --- .../webapp/storage/AbstractFileStorage.java | 106 ----------------- .../webapp/storage/AbstractPathStorage.java | 109 ------------------ .../javaops/webapp/storage/FileStorage.java | 5 +- .../storage/ObjectStreamPathStorage.java | 29 ----- .../webapp/storage/ObjectStreamStorage.java | 28 ----- .../javaops/webapp/storage/PathStorage.java | 15 +-- .../{ => serialize}/ISerializeStrategy.java | 2 +- .../{ => serialize}/StreamSerialize.java | 4 +- .../webapp/storage/AbstractStorageTest.java | 1 + .../storage/ObjectStreamPathStorageTest.java | 7 -- .../storage/ObjectStreamStorageTest.java | 8 -- 11 files changed, 10 insertions(+), 304 deletions(-) delete mode 100644 src/ru/javaops/webapp/storage/AbstractFileStorage.java delete mode 100644 src/ru/javaops/webapp/storage/AbstractPathStorage.java delete mode 100644 src/ru/javaops/webapp/storage/ObjectStreamPathStorage.java delete mode 100644 src/ru/javaops/webapp/storage/ObjectStreamStorage.java rename src/ru/javaops/webapp/storage/{ => serialize}/ISerializeStrategy.java (84%) rename src/ru/javaops/webapp/storage/{ => serialize}/StreamSerialize.java (92%) delete mode 100644 test/ru/javaops/webapp/storage/ObjectStreamPathStorageTest.java delete mode 100644 test/ru/javaops/webapp/storage/ObjectStreamStorageTest.java diff --git a/src/ru/javaops/webapp/storage/AbstractFileStorage.java b/src/ru/javaops/webapp/storage/AbstractFileStorage.java deleted file mode 100644 index 42f47b6a..00000000 --- a/src/ru/javaops/webapp/storage/AbstractFileStorage.java +++ /dev/null @@ -1,106 +0,0 @@ -package ru.javaops.webapp.storage; - -import ru.javaops.webapp.exception.StorageException; -import ru.javaops.webapp.model.Resume; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public abstract class AbstractFileStorage extends AbstractStorage { - private File directory; - - protected abstract Resume doRead(InputStream inputStream) throws IOException; - - protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; - - protected AbstractFileStorage(File directory) { - Objects.requireNonNull(directory, "directory must not be null"); - if (!directory.isDirectory()) { - throw new IllegalArgumentException(directory.getAbsolutePath() + " is not directory"); - } - if (!directory.canRead() || !directory.canWrite()) { - throw new IllegalArgumentException(directory.getAbsolutePath() + " is not readable/writable"); - } - this.directory = directory; - } - - @Override - protected void doSave(Resume resume, File file) { - try { - if (file.createNewFile()) { - doUpdate(resume, file); - } - } catch (IOException e) { - throw new StorageException("File create error " + file.getAbsolutePath(), file.getName(), e); - } - } - - @Override - protected File getSearchKey(String uuid) { - return new File(directory, uuid); - } - - @Override - protected Resume doGet(File file) { - try { - return doRead(new BufferedInputStream(new FileInputStream(file))); - } catch (IOException e) { - throw new StorageException("File read error", file.getName(), e); - } - } - - @Override - protected void doUpdate(Resume resume, File file) { - try { - doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); - } catch (IOException e) { - throw new StorageException("File write error", file.getName(), e); - } - } - - @Override - protected void doDelete(File file) { - if (!file.delete()) { - throw new StorageException("File delete error", file.getName()); - } - } - - @Override - protected boolean isExist(File file) { - return file.exists(); - } - - @Override - protected List doCopyAll() { - List resumes = new ArrayList<>(); - File[] files = getFiles(); - for (File file : files) { - resumes.add(doGet(file)); - } - return resumes; - } - - @Override - public void clear() { - File[] files = getFiles(); - for (File file : files) { - doDelete(file); - } - } - - @Override - public int size() { - File[] files = getFiles(); - return files.length; - } - - private File[] getFiles() { - File[] files = directory.listFiles(); - if (files == null) { - throw new StorageException("Directory error " + directory.getName()); - } - return files; - } -} diff --git a/src/ru/javaops/webapp/storage/AbstractPathStorage.java b/src/ru/javaops/webapp/storage/AbstractPathStorage.java deleted file mode 100644 index 01222547..00000000 --- a/src/ru/javaops/webapp/storage/AbstractPathStorage.java +++ /dev/null @@ -1,109 +0,0 @@ -package ru.javaops.webapp.storage; - -import ru.javaops.webapp.exception.StorageException; -import ru.javaops.webapp.model.Resume; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public abstract class AbstractPathStorage extends AbstractStorage { - private Path directory; - - protected abstract Resume doRead(InputStream inputStream) throws IOException; - - protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; - - protected AbstractPathStorage(String dir) { - directory = Paths.get(dir); - Objects.requireNonNull(directory, "directory must not be null"); - if (!Files.isDirectory(directory)) { - throw new IllegalArgumentException(dir + " is not directory"); - } - if (!Files.isReadable(directory) || !Files.isWritable(directory)) { - throw new IllegalArgumentException(dir + " is not readable/writable"); - } - } - - @Override - protected void doSave(Resume resume, Path path) { - try { - Files.createFile(path); - doUpdate(resume, path); - } catch (IOException e) { - throw new StorageException("File create error " + path.toString(), path.getFileName().toString(), e); - } - } - - @Override - protected Path getSearchKey(String uuid) { - return directory.resolve(uuid); - } - - @Override - protected Resume doGet(Path path) { - try { - return doRead(new BufferedInputStream(new FileInputStream(path.toFile()))); - } catch (IOException e) { - throw new StorageException("File read error", path.getFileName().toString(), e); - } - } - - @Override - protected void doUpdate(Resume resume, Path path) { - try { - doWrite(resume, new BufferedOutputStream(new FileOutputStream(path.toFile()))); - } catch (IOException e) { - throw new StorageException("File write error", path.getFileName().toString(), e); - } - } - - @Override - protected void doDelete(Path path) { - try { - Files.delete(path); - } catch (IOException e) { - throw new StorageException("File delete error", path.getFileName().toString(), e); - } - } - - @Override - protected boolean isExist(Path path) { - return Files.exists(path); - } - - @Override - protected List doCopyAll() { - List resumes = new ArrayList<>(); - try { - Files.list(directory) - .forEach(file -> resumes.add(doGet(file.toAbsolutePath()))); - } catch (IOException e) { - throw new IllegalArgumentException(directory.toString() + " is not directory", e); - } - return resumes; - } - - @Override - public void clear() { - try { - Files.list(directory).forEach(this::doDelete); - } catch (IOException e) { - throw new StorageException("Path delete error", null); - } - } - - @Override - public int size() { - try { - return Math.toIntExact(Files.list(directory).count()); - } catch (IOException e) { - e.printStackTrace(); - } - return 0; - } -} diff --git a/src/ru/javaops/webapp/storage/FileStorage.java b/src/ru/javaops/webapp/storage/FileStorage.java index 5295a26d..f48bf2a9 100644 --- a/src/ru/javaops/webapp/storage/FileStorage.java +++ b/src/ru/javaops/webapp/storage/FileStorage.java @@ -2,6 +2,7 @@ import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.storage.serialize.StreamSerialize; import java.io.*; import java.util.ArrayList; @@ -12,10 +13,6 @@ public class FileStorage extends AbstractStorage { private File directory; private StreamSerialize streamSerialize; -// protected abstract Resume doRead(InputStream inputStream) throws IOException; -// -// protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; - protected FileStorage(File directory, StreamSerialize streamSerialize) { Objects.requireNonNull(directory, "directory must not be null"); if (!directory.isDirectory()) { diff --git a/src/ru/javaops/webapp/storage/ObjectStreamPathStorage.java b/src/ru/javaops/webapp/storage/ObjectStreamPathStorage.java deleted file mode 100644 index 149b0f54..00000000 --- a/src/ru/javaops/webapp/storage/ObjectStreamPathStorage.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.javaops.webapp.storage; - -import ru.javaops.webapp.exception.StorageException; -import ru.javaops.webapp.model.Resume; - -import java.io.*; -import java.nio.file.Path; - -public class ObjectStreamPathStorage extends AbstractPathStorage { - protected ObjectStreamPathStorage(String directory) { - super(directory); - } - - @Override - protected Resume doRead(InputStream inputStream) throws IOException { - try (ObjectInputStream ois = new ObjectInputStream(inputStream)) { - return (Resume) ois.readObject(); - } catch (ClassNotFoundException e) { - throw new StorageException("Resume read error", null, e); - } - } - - @Override - protected void doWrite(Resume resume, OutputStream outputStream) throws IOException { - try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) { - oos.writeObject(resume); - } - } -} diff --git a/src/ru/javaops/webapp/storage/ObjectStreamStorage.java b/src/ru/javaops/webapp/storage/ObjectStreamStorage.java deleted file mode 100644 index d13de339..00000000 --- a/src/ru/javaops/webapp/storage/ObjectStreamStorage.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.javaops.webapp.storage; - -import ru.javaops.webapp.exception.StorageException; -import ru.javaops.webapp.model.Resume; - -import java.io.*; - -public class ObjectStreamStorage extends AbstractFileStorage { - protected ObjectStreamStorage(File directory) { - super(directory); - } - - @Override - protected Resume doRead(InputStream inputStream) throws IOException { - try (ObjectInputStream ois = new ObjectInputStream(inputStream)) { - return (Resume) ois.readObject(); - } catch (ClassNotFoundException e) { - throw new StorageException("Resume read error", null, e); - } - } - - @Override - protected void doWrite(Resume resume, OutputStream outputStream) throws IOException { - try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) { - oos.writeObject(resume); - } - } -} diff --git a/src/ru/javaops/webapp/storage/PathStorage.java b/src/ru/javaops/webapp/storage/PathStorage.java index 9e293312..b26f5d15 100644 --- a/src/ru/javaops/webapp/storage/PathStorage.java +++ b/src/ru/javaops/webapp/storage/PathStorage.java @@ -2,6 +2,7 @@ import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.storage.serialize.StreamSerialize; import java.io.*; import java.nio.file.Files; @@ -10,15 +11,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; public class PathStorage extends AbstractStorage { private Path directory; private StreamSerialize streamSerialize; -// protected abstract Resume doRead(InputStream inputStream) throws IOException; -// -// protected abstract void doWrite(Resume resume, OutputStream outputStream) throws IOException; - protected PathStorage(String dir, StreamSerialize streamSerialize) { directory = Paths.get(dir); Objects.requireNonNull(directory, "directory must not be null"); @@ -49,7 +47,7 @@ protected Path getSearchKey(String uuid) { @Override protected Resume doGet(Path path) { try { - return streamSerialize.doRead(new BufferedInputStream(new FileInputStream(path.toFile()))); + return streamSerialize.doRead(new BufferedInputStream(Files.newInputStream(path))); } catch (IOException e) { throw new StorageException("File read error", path.getFileName().toString(), e); } @@ -58,7 +56,7 @@ protected Resume doGet(Path path) { @Override protected void doUpdate(Resume resume, Path path) { try { - streamSerialize.doWrite(resume, new BufferedOutputStream(new FileOutputStream(path.toFile()))); + streamSerialize.doWrite(resume, new BufferedOutputStream(Files.newOutputStream(path))); } catch (IOException e) { throw new StorageException("File write error", path.getFileName().toString(), e); } @@ -80,14 +78,11 @@ protected boolean isExist(Path path) { @Override protected List doCopyAll() { - List resumes = new ArrayList<>(); try { - Files.list(directory) - .forEach(file -> resumes.add(doGet(file.toAbsolutePath()))); + return Files.list(directory).map(this::doGet).collect(Collectors.toList()); } catch (IOException e) { throw new IllegalArgumentException(directory.toString() + " is not directory", e); } - return resumes; } @Override diff --git a/src/ru/javaops/webapp/storage/ISerializeStrategy.java b/src/ru/javaops/webapp/storage/serialize/ISerializeStrategy.java similarity index 84% rename from src/ru/javaops/webapp/storage/ISerializeStrategy.java rename to src/ru/javaops/webapp/storage/serialize/ISerializeStrategy.java index a48ab6b0..3351dfde 100644 --- a/src/ru/javaops/webapp/storage/ISerializeStrategy.java +++ b/src/ru/javaops/webapp/storage/serialize/ISerializeStrategy.java @@ -1,4 +1,4 @@ -package ru.javaops.webapp.storage; +package ru.javaops.webapp.storage.serialize; import ru.javaops.webapp.model.Resume; diff --git a/src/ru/javaops/webapp/storage/StreamSerialize.java b/src/ru/javaops/webapp/storage/serialize/StreamSerialize.java similarity index 92% rename from src/ru/javaops/webapp/storage/StreamSerialize.java rename to src/ru/javaops/webapp/storage/serialize/StreamSerialize.java index d30493a1..f5fbb86a 100644 --- a/src/ru/javaops/webapp/storage/StreamSerialize.java +++ b/src/ru/javaops/webapp/storage/serialize/StreamSerialize.java @@ -1,4 +1,4 @@ -package ru.javaops.webapp.storage; +package ru.javaops.webapp.storage.serialize; import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; @@ -8,7 +8,7 @@ public class StreamSerialize implements ISerializeStrategy { @Override public void doWrite(Resume resume, OutputStream outputStream) { - try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);) { + try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) { objectOutputStream.writeObject(resume); } catch (IOException e) { throw new StorageException("Resume write error", resume.getUuid(), e); diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 3808c15a..fbda5d62 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -4,6 +4,7 @@ import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.*; +import ru.javaops.webapp.storage.serialize.StreamSerialize; import java.io.File; import java.util.Arrays; diff --git a/test/ru/javaops/webapp/storage/ObjectStreamPathStorageTest.java b/test/ru/javaops/webapp/storage/ObjectStreamPathStorageTest.java deleted file mode 100644 index 990324e4..00000000 --- a/test/ru/javaops/webapp/storage/ObjectStreamPathStorageTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.javaops.webapp.storage; - -public class ObjectStreamPathStorageTest extends AbstractStorageTest { - public ObjectStreamPathStorageTest() { - super(new ObjectStreamPathStorage(STORAGE_DIR.toString())); - } -} diff --git a/test/ru/javaops/webapp/storage/ObjectStreamStorageTest.java b/test/ru/javaops/webapp/storage/ObjectStreamStorageTest.java deleted file mode 100644 index e042869d..00000000 --- a/test/ru/javaops/webapp/storage/ObjectStreamStorageTest.java +++ /dev/null @@ -1,8 +0,0 @@ -package ru.javaops.webapp.storage; - -public class ObjectStreamStorageTest extends AbstractStorageTest { - - public ObjectStreamStorageTest() { - super(new ObjectStreamStorage(STORAGE_DIR)); - } -} From 58fc4b3d61dd8f30ccc08ea6090f7413e9ee8441 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 28 Sep 2018 08:56:33 +0300 Subject: [PATCH 152/220] HW9, MainFile refactoring --- src/ru/javaops/webapp/MainFile.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index 7a5e84ed..228739b6 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -24,21 +24,20 @@ public static void main(String[] args) { } File dir = new File("./src/ru/javaops"); // /webapp - getDirectoryFileNames(dir, 0); + getDirectoryFileNames(dir, ""); } - private static void getDirectoryFileNames(File dir, int level) { + private static void getDirectoryFileNames(File dir, String space) { File[] files = dir.listFiles(); if (files == null) { throw new StorageException(dir.getName() + " is not directory, or IO Error"); } for (File file : files) { - String sRepeated = IntStream.range(0, level).mapToObj(i -> "\t").collect(Collectors.joining("")); if (file.isFile()) { - System.out.println(sRepeated + file.getName()); + System.out.println(space + file.getName()); } else { - System.out.println(sRepeated + "[" + file.getName() + "]"); - getDirectoryFileNames(file, level + 1); + System.out.println(space + "[" + file.getName() + "]"); + getDirectoryFileNames(file, space + " "); } } } From 1eb6a7881a73573b6dd544306782f20a20915ef9 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 28 Sep 2018 17:26:14 +0300 Subject: [PATCH 153/220] HW9, MainFile refactoring --- src/ru/javaops/webapp/MainFile.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ru/javaops/webapp/MainFile.java b/src/ru/javaops/webapp/MainFile.java index 228739b6..69bc2407 100644 --- a/src/ru/javaops/webapp/MainFile.java +++ b/src/ru/javaops/webapp/MainFile.java @@ -5,8 +5,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.util.stream.Collectors; -import java.util.stream.IntStream; + public class MainFile { public static void main(String[] args) { From fca87f0478e2cb615c16d60980e01bc67a639c67 Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 1 Oct 2018 07:22:10 +0300 Subject: [PATCH 154/220] HW9, PathStorage refactoring --- .../webapp/exception/StorageException.java | 4 +++ .../javaops/webapp/storage/PathStorage.java | 34 +++++++++---------- .../storage/serialize/StreamSerialize.java | 2 +- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/ru/javaops/webapp/exception/StorageException.java b/src/ru/javaops/webapp/exception/StorageException.java index 2756f1a5..1575bdfc 100644 --- a/src/ru/javaops/webapp/exception/StorageException.java +++ b/src/ru/javaops/webapp/exception/StorageException.java @@ -12,6 +12,10 @@ public StorageException(String message, String uuid) { this.uuid = uuid; } + public StorageException(String message, Exception e) { + this(message, null, e); + } + public StorageException(String message, String uuid, Exception e) { super(message, e); this.uuid = uuid; diff --git a/src/ru/javaops/webapp/storage/PathStorage.java b/src/ru/javaops/webapp/storage/PathStorage.java index b26f5d15..3685ebb5 100644 --- a/src/ru/javaops/webapp/storage/PathStorage.java +++ b/src/ru/javaops/webapp/storage/PathStorage.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; +import java.util.stream.Stream; public class PathStorage extends AbstractStorage { private Path directory; @@ -35,7 +36,7 @@ protected void doSave(Resume resume, Path path) { Files.createFile(path); doUpdate(resume, path); } catch (IOException e) { - throw new StorageException("File create error " + path.toString(), path.getFileName().toString(), e); + throw new StorageException("File create error " + path.toString(), getFileName(path), e); } } @@ -49,7 +50,7 @@ protected Resume doGet(Path path) { try { return streamSerialize.doRead(new BufferedInputStream(Files.newInputStream(path))); } catch (IOException e) { - throw new StorageException("File read error", path.getFileName().toString(), e); + throw new StorageException("File read error", getFileName(path), e); } } @@ -58,7 +59,7 @@ protected void doUpdate(Resume resume, Path path) { try { streamSerialize.doWrite(resume, new BufferedOutputStream(Files.newOutputStream(path))); } catch (IOException e) { - throw new StorageException("File write error", path.getFileName().toString(), e); + throw new StorageException("File write error", getFileName(path), e); } } @@ -67,7 +68,7 @@ protected void doDelete(Path path) { try { Files.delete(path); } catch (IOException e) { - throw new StorageException("File delete error", path.getFileName().toString(), e); + throw new StorageException("File delete error", getFileName(path), e); } } @@ -78,29 +79,28 @@ protected boolean isExist(Path path) { @Override protected List doCopyAll() { - try { - return Files.list(directory).map(this::doGet).collect(Collectors.toList()); - } catch (IOException e) { - throw new IllegalArgumentException(directory.toString() + " is not directory", e); - } + return getFilesList().map(this::doGet).collect(Collectors.toList()); } @Override public void clear() { - try { - Files.list(directory).forEach(this::doDelete); - } catch (IOException e) { - throw new StorageException("Path delete error", null); - } + getFilesList().forEach(this::doDelete); } @Override public int size() { + return (int) getFilesList().count(); + } + + private String getFileName(Path path) { + return path.getFileName().toString(); + } + + private Stream getFilesList() { try { - return Math.toIntExact(Files.list(directory).count()); + return Files.list(directory); } catch (IOException e) { - e.printStackTrace(); + throw new StorageException("Files get error", e); } - return 0; } } diff --git a/src/ru/javaops/webapp/storage/serialize/StreamSerialize.java b/src/ru/javaops/webapp/storage/serialize/StreamSerialize.java index f5fbb86a..636144c3 100644 --- a/src/ru/javaops/webapp/storage/serialize/StreamSerialize.java +++ b/src/ru/javaops/webapp/storage/serialize/StreamSerialize.java @@ -20,7 +20,7 @@ public Resume doRead(InputStream inputStream) { try (ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) { return (Resume) objectInputStream.readObject(); } catch (IOException | ClassNotFoundException e) { - throw new StorageException("Resume read error", null, e); + throw new StorageException("Resume read error", e); } } } From abfb84659fdd71c8dc3f0b060a850050d2221815 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 3 Oct 2018 11:57:08 +0300 Subject: [PATCH 155/220] HW9, MainFile refactoring --- src/ru/javaops/webapp/model/ListSection.java | 5 ++- src/ru/javaops/webapp/model/Organisation.java | 29 +++++++++--- .../webapp/model/OrganisationSection.java | 5 ++- src/ru/javaops/webapp/model/Resume.java | 10 ++++- src/ru/javaops/webapp/model/Section.java | 3 ++ src/ru/javaops/webapp/model/TextSection.java | 5 ++- .../javaops/webapp/storage/FileStorage.java | 13 +++--- .../javaops/webapp/storage/PathStorage.java | 14 +++--- .../storage/serialize/ISerializeStrategy.java | 5 ++- ...amSerialize.java => StreamSerializer.java} | 2 +- .../serialize/XmlStreamSerializer.java | 31 +++++++++++++ .../javaops/webapp/util/LocalDateAdapter.java | 16 +++++++ src/ru/javaops/webapp/util/XmlParser.java | 44 +++++++++++++++++++ .../webapp/storage/AbstractStorageTest.java | 4 +- .../webapp/storage/FileStorageTest.java | 2 +- .../webapp/storage/PathStorageTest.java | 4 +- .../webapp/storage/XmlPathStorageTest.java | 9 ++++ 17 files changed, 170 insertions(+), 31 deletions(-) rename src/ru/javaops/webapp/storage/serialize/{StreamSerialize.java => StreamSerializer.java} (93%) create mode 100644 src/ru/javaops/webapp/storage/serialize/XmlStreamSerializer.java create mode 100644 src/ru/javaops/webapp/util/LocalDateAdapter.java create mode 100644 src/ru/javaops/webapp/util/XmlParser.java create mode 100644 test/ru/javaops/webapp/storage/XmlPathStorageTest.java diff --git a/src/ru/javaops/webapp/model/ListSection.java b/src/ru/javaops/webapp/model/ListSection.java index ff833e33..76b3358d 100644 --- a/src/ru/javaops/webapp/model/ListSection.java +++ b/src/ru/javaops/webapp/model/ListSection.java @@ -7,7 +7,10 @@ public class ListSection extends Section { private static final long serialVersionUID = 1L; - private final List items; + private List items; + + public ListSection() { + } public ListSection(String... items){ this(Arrays.asList(items)); diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 836c5d33..904c09b9 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -1,5 +1,10 @@ package ru.javaops.webapp.model; +import ru.javaops.webapp.util.LocalDateAdapter; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.io.Serializable; import java.time.LocalDate; import java.time.Month; @@ -10,12 +15,16 @@ import static ru.javaops.webapp.util.DateUtil.NOW; import static ru.javaops.webapp.util.DateUtil.of; +@XmlAccessorType(XmlAccessType.FIELD) public class Organisation implements Serializable { private static final long serialVersionUID = 1L; - private final String name; - private final String url; - private final List positions; + private String name; + private String url; + private List positions; + + public Organisation() { + } public Organisation(String name, String url, Position... positions){ Objects.requireNonNull(name, "name can't be NULL"); @@ -48,13 +57,19 @@ public String toString() { '}'; } + @XmlAccessorType(XmlAccessType.FIELD) public static class Position implements Serializable { private static final long serialVersionUID = 1L; - private final LocalDate startDate; - private final LocalDate endDate; - private final String head; - private final String description; + @XmlJavaTypeAdapter(LocalDateAdapter.class) + private LocalDate startDate; + @XmlJavaTypeAdapter(LocalDateAdapter.class) + private LocalDate endDate; + private String head; + private String description; + + public Position() { + } public Position(int startYear, Month startMonth, String head, String description) { this(of(startYear, startMonth), NOW, head, description); diff --git a/src/ru/javaops/webapp/model/OrganisationSection.java b/src/ru/javaops/webapp/model/OrganisationSection.java index ac65e8d9..6d0ebf4b 100644 --- a/src/ru/javaops/webapp/model/OrganisationSection.java +++ b/src/ru/javaops/webapp/model/OrganisationSection.java @@ -7,7 +7,10 @@ public class OrganisationSection extends Section { private static final long serialVersionUID = 1L; - private final List organisations; + private List organisations; + + public OrganisationSection() { + } public OrganisationSection(Organisation... organisations){ this(Arrays.asList(organisations)); diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 0cabcac3..9b46b2db 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -1,19 +1,27 @@ package ru.javaops.webapp.model; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; import java.io.Serializable; import java.util.*; +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) public class Resume implements Comparable, Serializable { private static final long serialVersionUID = 1L; // Unique identifier - private final String uuid; + private String uuid; private String fullName; private final Map contacts = new EnumMap<>(ContactType.class); private final Map sections = new EnumMap<>(SectionType.class); + public Resume() { + } + public Resume(String fullName){ this((UUID.randomUUID().toString()), fullName); } diff --git a/src/ru/javaops/webapp/model/Section.java b/src/ru/javaops/webapp/model/Section.java index 38f460d0..3c00573a 100644 --- a/src/ru/javaops/webapp/model/Section.java +++ b/src/ru/javaops/webapp/model/Section.java @@ -1,6 +1,9 @@ package ru.javaops.webapp.model; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; import java.io.Serializable; +@XmlAccessorType(XmlAccessType.FIELD) public abstract class Section implements Serializable { } diff --git a/src/ru/javaops/webapp/model/TextSection.java b/src/ru/javaops/webapp/model/TextSection.java index eac470c7..28c3806c 100644 --- a/src/ru/javaops/webapp/model/TextSection.java +++ b/src/ru/javaops/webapp/model/TextSection.java @@ -5,7 +5,10 @@ public class TextSection extends Section { private static final long serialVersionUID = 1L; - private final String text; + private String text; + + public TextSection() { + } public TextSection(String text) { Objects.requireNonNull(text, "text can't be NULL"); diff --git a/src/ru/javaops/webapp/storage/FileStorage.java b/src/ru/javaops/webapp/storage/FileStorage.java index f48bf2a9..c0f320f7 100644 --- a/src/ru/javaops/webapp/storage/FileStorage.java +++ b/src/ru/javaops/webapp/storage/FileStorage.java @@ -2,7 +2,8 @@ import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import ru.javaops.webapp.storage.serialize.StreamSerialize; +import ru.javaops.webapp.storage.serialize.ISerializeStrategy; +import ru.javaops.webapp.storage.serialize.StreamSerializer; import java.io.*; import java.util.ArrayList; @@ -11,9 +12,9 @@ public class FileStorage extends AbstractStorage { private File directory; - private StreamSerialize streamSerialize; + private ISerializeStrategy streamSerializer; - protected FileStorage(File directory, StreamSerialize streamSerialize) { + protected FileStorage(File directory, ISerializeStrategy streamSerializer) { Objects.requireNonNull(directory, "directory must not be null"); if (!directory.isDirectory()) { throw new IllegalArgumentException(directory.getAbsolutePath() + " is not directory"); @@ -22,7 +23,7 @@ protected FileStorage(File directory, StreamSerialize streamSerialize) { throw new IllegalArgumentException(directory.getAbsolutePath() + " is not readable/writable"); } this.directory = directory; - this.streamSerialize = streamSerialize; + this.streamSerializer = streamSerializer; } @Override @@ -44,7 +45,7 @@ protected File getSearchKey(String uuid) { @Override protected Resume doGet(File file) { try { - return streamSerialize.doRead(new BufferedInputStream(new FileInputStream(file))); + return streamSerializer.doRead(new BufferedInputStream(new FileInputStream(file))); } catch (IOException e) { throw new StorageException("File read error", file.getName(), e); } @@ -53,7 +54,7 @@ protected Resume doGet(File file) { @Override protected void doUpdate(Resume resume, File file) { try { - streamSerialize.doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); + streamSerializer.doWrite(resume, new BufferedOutputStream(new FileOutputStream(file))); } catch (IOException e) { throw new StorageException("File write error", file.getName(), e); } diff --git a/src/ru/javaops/webapp/storage/PathStorage.java b/src/ru/javaops/webapp/storage/PathStorage.java index 3685ebb5..22c13af0 100644 --- a/src/ru/javaops/webapp/storage/PathStorage.java +++ b/src/ru/javaops/webapp/storage/PathStorage.java @@ -2,13 +2,13 @@ import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import ru.javaops.webapp.storage.serialize.StreamSerialize; +import ru.javaops.webapp.storage.serialize.ISerializeStrategy; +import ru.javaops.webapp.storage.serialize.StreamSerializer; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -16,10 +16,11 @@ public class PathStorage extends AbstractStorage { private Path directory; - private StreamSerialize streamSerialize; + private ISerializeStrategy streamSerializer; - protected PathStorage(String dir, StreamSerialize streamSerialize) { + protected PathStorage(String dir, ISerializeStrategy streamSerializer) { directory = Paths.get(dir); + this.streamSerializer = streamSerializer; Objects.requireNonNull(directory, "directory must not be null"); if (!Files.isDirectory(directory)) { throw new IllegalArgumentException(dir + " is not directory"); @@ -27,7 +28,6 @@ protected PathStorage(String dir, StreamSerialize streamSerialize) { if (!Files.isReadable(directory) || !Files.isWritable(directory)) { throw new IllegalArgumentException(dir + " is not readable/writable"); } - this.streamSerialize = streamSerialize; } @Override @@ -48,7 +48,7 @@ protected Path getSearchKey(String uuid) { @Override protected Resume doGet(Path path) { try { - return streamSerialize.doRead(new BufferedInputStream(Files.newInputStream(path))); + return streamSerializer.doRead(new BufferedInputStream(Files.newInputStream(path))); } catch (IOException e) { throw new StorageException("File read error", getFileName(path), e); } @@ -57,7 +57,7 @@ protected Resume doGet(Path path) { @Override protected void doUpdate(Resume resume, Path path) { try { - streamSerialize.doWrite(resume, new BufferedOutputStream(Files.newOutputStream(path))); + streamSerializer.doWrite(resume, new BufferedOutputStream(Files.newOutputStream(path))); } catch (IOException e) { throw new StorageException("File write error", getFileName(path), e); } diff --git a/src/ru/javaops/webapp/storage/serialize/ISerializeStrategy.java b/src/ru/javaops/webapp/storage/serialize/ISerializeStrategy.java index 3351dfde..6c3cb724 100644 --- a/src/ru/javaops/webapp/storage/serialize/ISerializeStrategy.java +++ b/src/ru/javaops/webapp/storage/serialize/ISerializeStrategy.java @@ -2,11 +2,12 @@ import ru.javaops.webapp.model.Resume; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public interface ISerializeStrategy { - void doWrite(Resume resume, OutputStream outputStream); + void doWrite(Resume resume, OutputStream outputStream) throws IOException; - Resume doRead(InputStream inputStream); + Resume doRead(InputStream inputStream) throws IOException; } diff --git a/src/ru/javaops/webapp/storage/serialize/StreamSerialize.java b/src/ru/javaops/webapp/storage/serialize/StreamSerializer.java similarity index 93% rename from src/ru/javaops/webapp/storage/serialize/StreamSerialize.java rename to src/ru/javaops/webapp/storage/serialize/StreamSerializer.java index 636144c3..fb9fd728 100644 --- a/src/ru/javaops/webapp/storage/serialize/StreamSerialize.java +++ b/src/ru/javaops/webapp/storage/serialize/StreamSerializer.java @@ -5,7 +5,7 @@ import java.io.*; -public class StreamSerialize implements ISerializeStrategy { +public class StreamSerializer implements ISerializeStrategy { @Override public void doWrite(Resume resume, OutputStream outputStream) { try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) { diff --git a/src/ru/javaops/webapp/storage/serialize/XmlStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/XmlStreamSerializer.java new file mode 100644 index 00000000..97f59641 --- /dev/null +++ b/src/ru/javaops/webapp/storage/serialize/XmlStreamSerializer.java @@ -0,0 +1,31 @@ +package ru.javaops.webapp.storage.serialize; + +import ru.javaops.webapp.model.*; +import ru.javaops.webapp.util.XmlParser; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class XmlStreamSerializer implements ISerializeStrategy { + private XmlParser xmlParser; + + public XmlStreamSerializer() { + xmlParser = new XmlParser( + Resume.class, Organisation.class, OrganisationSection.class, + TextSection.class, ListSection.class, Organisation.Position.class); + } + + @Override + public void doWrite(Resume r, OutputStream os) throws IOException { + try (Writer w = new OutputStreamWriter(os, StandardCharsets.UTF_8)) { + xmlParser.marshall(r, w); + } + } + + @Override + public Resume doRead(InputStream is) throws IOException { + try (Reader r = new InputStreamReader(is, StandardCharsets.UTF_8)) { + return xmlParser.unmarshall(r); + } + } +} diff --git a/src/ru/javaops/webapp/util/LocalDateAdapter.java b/src/ru/javaops/webapp/util/LocalDateAdapter.java new file mode 100644 index 00000000..0f8af698 --- /dev/null +++ b/src/ru/javaops/webapp/util/LocalDateAdapter.java @@ -0,0 +1,16 @@ +package ru.javaops.webapp.util; + +import javax.xml.bind.annotation.adapters.XmlAdapter; +import java.time.LocalDate; + +public class LocalDateAdapter extends XmlAdapter { + @Override + public LocalDate unmarshal(String str) throws Exception { + return LocalDate.parse(str); + } + + @Override + public String marshal(LocalDate ld) throws Exception { + return ld.toString(); + } +} diff --git a/src/ru/javaops/webapp/util/XmlParser.java b/src/ru/javaops/webapp/util/XmlParser.java new file mode 100644 index 00000000..e42de7b3 --- /dev/null +++ b/src/ru/javaops/webapp/util/XmlParser.java @@ -0,0 +1,44 @@ +package ru.javaops.webapp.util; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import java.io.Reader; +import java.io.Writer; + +public class XmlParser { + private final Marshaller marshaller; + private final Unmarshaller unmarshaller; + + public XmlParser(Class... classesToBeBound) { + try { + JAXBContext ctx = JAXBContext.newInstance(classesToBeBound); + + marshaller = ctx.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); +// marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); + + unmarshaller = ctx.createUnmarshaller(); + } catch (JAXBException e) { + throw new IllegalStateException(e); + } + } + + public T unmarshall(Reader reader) { + try { + return (T) unmarshaller.unmarshal(reader); + } catch (JAXBException e) { + throw new IllegalStateException(e); + } + } + + public void marshall(Object instance, Writer writer) { + try { + marshaller.marshal(instance, writer); + } catch (JAXBException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index fbda5d62..00da80cb 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -4,7 +4,7 @@ import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.*; -import ru.javaops.webapp.storage.serialize.StreamSerialize; +import ru.javaops.webapp.storage.serialize.StreamSerializer; import java.io.File; import java.util.Arrays; @@ -13,7 +13,7 @@ public abstract class AbstractStorageTest { protected final static File STORAGE_DIR = new File("storage"); - protected final static StreamSerialize STREAM_SERIALIZE = new StreamSerialize(); + protected final static StreamSerializer STREAM_SERIALIZER = new StreamSerializer(); protected final IStorage storage; diff --git a/test/ru/javaops/webapp/storage/FileStorageTest.java b/test/ru/javaops/webapp/storage/FileStorageTest.java index c7487978..5cd7f0bf 100644 --- a/test/ru/javaops/webapp/storage/FileStorageTest.java +++ b/test/ru/javaops/webapp/storage/FileStorageTest.java @@ -2,6 +2,6 @@ public class FileStorageTest extends AbstractStorageTest { public FileStorageTest() { - super(new FileStorage(STORAGE_DIR, STREAM_SERIALIZE)); + super(new FileStorage(STORAGE_DIR, STREAM_SERIALIZER)); } } diff --git a/test/ru/javaops/webapp/storage/PathStorageTest.java b/test/ru/javaops/webapp/storage/PathStorageTest.java index e4003d11..2697c238 100644 --- a/test/ru/javaops/webapp/storage/PathStorageTest.java +++ b/test/ru/javaops/webapp/storage/PathStorageTest.java @@ -1,7 +1,9 @@ package ru.javaops.webapp.storage; +import ru.javaops.webapp.storage.serialize.StreamSerializer; + public class PathStorageTest extends AbstractStorageTest { public PathStorageTest() { - super(new PathStorage(STORAGE_DIR.toString(), STREAM_SERIALIZE)); + super(new PathStorage(STORAGE_DIR.toString(), new StreamSerializer())); } } diff --git a/test/ru/javaops/webapp/storage/XmlPathStorageTest.java b/test/ru/javaops/webapp/storage/XmlPathStorageTest.java new file mode 100644 index 00000000..662dd9b0 --- /dev/null +++ b/test/ru/javaops/webapp/storage/XmlPathStorageTest.java @@ -0,0 +1,9 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.storage.serialize.XmlStreamSerializer; + +public class XmlPathStorageTest extends AbstractStorageTest{ + public XmlPathStorageTest() { + super(new PathStorage(STORAGE_DIR.toString(), new XmlStreamSerializer())); + } +} From 10599862bce2a91cafa67bf769914e1eebd5c726 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 3 Oct 2018 18:21:47 +0300 Subject: [PATCH 156/220] HW9, XmlStreamSerializer, XmlPathStorageTest implementation --- test/ru/javaops/webapp/storage/TestAll.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/ru/javaops/webapp/storage/TestAll.java b/test/ru/javaops/webapp/storage/TestAll.java index 55a04452..27c51142 100644 --- a/test/ru/javaops/webapp/storage/TestAll.java +++ b/test/ru/javaops/webapp/storage/TestAll.java @@ -4,6 +4,15 @@ import org.junit.runners.Suite; @RunWith(Suite.class) -@Suite.SuiteClasses({ArrayStorageTest.class, SortedArrayStorageTest.class, ListStorageTest.class, MapUuidStorageTest.class, MapResumeStorageTest.class}) +@Suite.SuiteClasses({ + ArrayStorageTest.class, + SortedArrayStorageTest.class, + ListStorageTest.class, + MapUuidStorageTest.class, + MapResumeStorageTest.class, + FileStorage.class, + PathStorage.class, + XmlPathStorageTest.class +}) public class TestAll { } From d35fc24409fde65c1ccdae0e7de2cea8a96d39c2 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 3 Oct 2018 18:31:44 +0300 Subject: [PATCH 157/220] HW9, TestAll refactoring --- test/ru/javaops/webapp/storage/TestAll.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ru/javaops/webapp/storage/TestAll.java b/test/ru/javaops/webapp/storage/TestAll.java index 27c51142..6ea67477 100644 --- a/test/ru/javaops/webapp/storage/TestAll.java +++ b/test/ru/javaops/webapp/storage/TestAll.java @@ -10,8 +10,8 @@ ListStorageTest.class, MapUuidStorageTest.class, MapResumeStorageTest.class, - FileStorage.class, - PathStorage.class, + FileStorageTest.class, + PathStorageTest.class, XmlPathStorageTest.class }) public class TestAll { From 11d93146bfa7ffc2e15ccb56408afdf133e76daf Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 3 Oct 2018 18:49:28 +0300 Subject: [PATCH 158/220] HW10, JsonStreamSrializer implementation --- .../serialize/JsonStreamSerializer.java | 23 +++++++++++++ src/ru/javaops/webapp/util/JsonParser.java | 22 ++++++++++++ .../webapp/util/JsonSectionAdapter.java | 34 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 src/ru/javaops/webapp/storage/serialize/JsonStreamSerializer.java create mode 100644 src/ru/javaops/webapp/util/JsonParser.java create mode 100644 src/ru/javaops/webapp/util/JsonSectionAdapter.java diff --git a/src/ru/javaops/webapp/storage/serialize/JsonStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/JsonStreamSerializer.java new file mode 100644 index 00000000..35822a27 --- /dev/null +++ b/src/ru/javaops/webapp/storage/serialize/JsonStreamSerializer.java @@ -0,0 +1,23 @@ +package ru.javaops.webapp.storage.serialize; + +import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.util.JsonParser; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class JsonStreamSerializer implements ISerializeStrategy { + @Override + public void doWrite(Resume r, OutputStream os) throws IOException { + try (Writer writer = new OutputStreamWriter(os, StandardCharsets.UTF_8)) { + JsonParser.write(r, writer); + } + } + + @Override + public Resume doRead(InputStream is) throws IOException { + try (Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) { + return JsonParser.read(reader, Resume.class); + } + } +} diff --git a/src/ru/javaops/webapp/util/JsonParser.java b/src/ru/javaops/webapp/util/JsonParser.java new file mode 100644 index 00000000..1e40439f --- /dev/null +++ b/src/ru/javaops/webapp/util/JsonParser.java @@ -0,0 +1,22 @@ +package ru.javaops.webapp.util; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import ru.javaops.webapp.model.Section; + +import java.io.Reader; +import java.io.Writer; + +public class JsonParser { + private static Gson GSON = new GsonBuilder() + .registerTypeAdapter(Section.class, new JsonSectionAdapter()) + .create(); + + public static T read(Reader reader, Class clazz) { + return GSON.fromJson(reader, clazz); + } + + public static void write(T object, Writer writer) { + GSON.toJson(object, writer); + } +} diff --git a/src/ru/javaops/webapp/util/JsonSectionAdapter.java b/src/ru/javaops/webapp/util/JsonSectionAdapter.java new file mode 100644 index 00000000..92ddd6aa --- /dev/null +++ b/src/ru/javaops/webapp/util/JsonSectionAdapter.java @@ -0,0 +1,34 @@ +package ru.javaops.webapp.util; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +public class JsonSectionAdapter implements JsonSerializer, JsonDeserializer { + private static final String CLASSNAME = "CLASSNAME"; + private static final String INSTANCE = "INSTANCE"; + + @Override + public T deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { + JsonObject jsonObject = json.getAsJsonObject(); + JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME); + String className = prim.getAsString(); + + try { + Class clazz = Class.forName(className); + return context.deserialize(jsonObject.get(INSTANCE), clazz); + } catch (ClassNotFoundException e) { + throw new JsonParseException(e.getMessage()); + } + } + + + @Override + public JsonElement serialize(T section, Type type, JsonSerializationContext context) { + JsonObject retValue = new JsonObject(); + retValue.addProperty(CLASSNAME, section.getClass().getName()); + JsonElement elem = context.serialize(section); + retValue.add(INSTANCE, elem); + return retValue; + } +} From b37b4da9738d8f14cb33a337db40eadf2ab3eb15 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 3 Oct 2018 18:53:47 +0300 Subject: [PATCH 159/220] HW10, JsonPathStorageTest implementation --- .../ru/javaops/webapp/storage/JsonPathStorageTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 test/ru/javaops/webapp/storage/JsonPathStorageTest.java diff --git a/test/ru/javaops/webapp/storage/JsonPathStorageTest.java b/test/ru/javaops/webapp/storage/JsonPathStorageTest.java new file mode 100644 index 00000000..24948632 --- /dev/null +++ b/test/ru/javaops/webapp/storage/JsonPathStorageTest.java @@ -0,0 +1,10 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.storage.serialize.JsonStreamSerializer; + +public class JsonPathStorageTest extends AbstractStorageTest { + + public JsonPathStorageTest() { + super(new PathStorage(STORAGE_DIR.toString(), new JsonStreamSerializer())); + } +} From d59f9a92a5a782f8fab61c55cbe250101290131a Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 3 Oct 2018 19:13:57 +0300 Subject: [PATCH 160/220] HW10, DataPathStorageTest implementation --- .../serialize/DateStreamSerializer.java | 39 +++++++++++++++++++ .../webapp/storage/DataPathStorageTest.java | 9 +++++ test/ru/javaops/webapp/storage/TestAll.java | 3 +- 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/ru/javaops/webapp/storage/serialize/DateStreamSerializer.java create mode 100644 test/ru/javaops/webapp/storage/DataPathStorageTest.java diff --git a/src/ru/javaops/webapp/storage/serialize/DateStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DateStreamSerializer.java new file mode 100644 index 00000000..6d62cd8d --- /dev/null +++ b/src/ru/javaops/webapp/storage/serialize/DateStreamSerializer.java @@ -0,0 +1,39 @@ +package ru.javaops.webapp.storage.serialize; + +import ru.javaops.webapp.model.ContactType; +import ru.javaops.webapp.model.Resume; + +import java.io.*; +import java.util.Map; + +public class DateStreamSerializer implements ISerializeStrategy { + @Override + public void doWrite(Resume r, OutputStream os) throws IOException { + try (DataOutputStream dos = new DataOutputStream(os)) { + dos.writeUTF(r.getUuid()); + dos.writeUTF(r.getFullName()); + Map contacts = r.getContacts(); + dos.writeInt(contacts.size()); + for (Map.Entry entry : contacts.entrySet()) { + dos.writeUTF(entry.getKey().name()); + dos.writeUTF(entry.getValue()); + } + // TODO implements sections + } + } + + @Override + public Resume doRead(InputStream is) throws IOException { + try (DataInputStream dis = new DataInputStream(is)) { + String uuid = dis.readUTF(); + String fullName = dis.readUTF(); + Resume resume = new Resume(uuid, fullName); + int size = dis.readInt(); + for (int i = 0; i < size; i++) { + resume.addContact(ContactType.valueOf(dis.readUTF()), dis.readUTF()); + } + // TODO implements sections + return resume; + } + } +} diff --git a/test/ru/javaops/webapp/storage/DataPathStorageTest.java b/test/ru/javaops/webapp/storage/DataPathStorageTest.java new file mode 100644 index 00000000..424759fa --- /dev/null +++ b/test/ru/javaops/webapp/storage/DataPathStorageTest.java @@ -0,0 +1,9 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.storage.serialize.DateStreamSerializer; + +public class DataPathStorageTest extends AbstractStorageTest{ + public DataPathStorageTest() { + super(new PathStorage(STORAGE_DIR.toString(), new DateStreamSerializer())); + } +} diff --git a/test/ru/javaops/webapp/storage/TestAll.java b/test/ru/javaops/webapp/storage/TestAll.java index 6ea67477..21f90469 100644 --- a/test/ru/javaops/webapp/storage/TestAll.java +++ b/test/ru/javaops/webapp/storage/TestAll.java @@ -12,7 +12,8 @@ MapResumeStorageTest.class, FileStorageTest.class, PathStorageTest.class, - XmlPathStorageTest.class + XmlPathStorageTest.class, + JsonPathStorageTest.class }) public class TestAll { } From 1e6a2887cd5a8721ff23b147ac62c6f9e2401e7e Mon Sep 17 00:00:00 2001 From: Nikolai Dvinin Date: Thu, 4 Oct 2018 07:23:18 +0300 Subject: [PATCH 161/220] HW10, DataStreamSerializer implementation --- ...Serializer.java => DataStreamSerializer.java} | 16 +++++++++++++--- .../webapp/storage/DataPathStorageTest.java | 4 ++-- test/ru/javaops/webapp/storage/TestAll.java | 3 ++- 3 files changed, 17 insertions(+), 6 deletions(-) rename src/ru/javaops/webapp/storage/serialize/{DateStreamSerializer.java => DataStreamSerializer.java} (64%) diff --git a/src/ru/javaops/webapp/storage/serialize/DateStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java similarity index 64% rename from src/ru/javaops/webapp/storage/serialize/DateStreamSerializer.java rename to src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index 6d62cd8d..2a7d10a9 100644 --- a/src/ru/javaops/webapp/storage/serialize/DateStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -1,12 +1,11 @@ package ru.javaops.webapp.storage.serialize; -import ru.javaops.webapp.model.ContactType; -import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.model.*; import java.io.*; import java.util.Map; -public class DateStreamSerializer implements ISerializeStrategy { +public class DataStreamSerializer implements ISerializeStrategy { @Override public void doWrite(Resume r, OutputStream os) throws IOException { try (DataOutputStream dos = new DataOutputStream(os)) { @@ -19,6 +18,13 @@ public void doWrite(Resume r, OutputStream os) throws IOException { dos.writeUTF(entry.getValue()); } // TODO implements sections + Map sections = r.getSections(); + dos.writeInt(sections.size()); + for (Map.Entry entry : sections.entrySet()) { + dos.writeUTF(entry.getKey().getTitle()); + dos.writeUTF(entry.getValue().toString()); + //Section sec = entry.getValue(); + } } } @@ -33,6 +39,10 @@ public Resume doRead(InputStream is) throws IOException { resume.addContact(ContactType.valueOf(dis.readUTF()), dis.readUTF()); } // TODO implements sections + int sectionsCount = dis.readInt(); + for (int i = 0; i < sectionsCount; i++){ + //resume.addSection(SectionType.valueOf(dis.readUTF()), dis.readUTF()); + } return resume; } } diff --git a/test/ru/javaops/webapp/storage/DataPathStorageTest.java b/test/ru/javaops/webapp/storage/DataPathStorageTest.java index 424759fa..f1d90d35 100644 --- a/test/ru/javaops/webapp/storage/DataPathStorageTest.java +++ b/test/ru/javaops/webapp/storage/DataPathStorageTest.java @@ -1,9 +1,9 @@ package ru.javaops.webapp.storage; -import ru.javaops.webapp.storage.serialize.DateStreamSerializer; +import ru.javaops.webapp.storage.serialize.DataStreamSerializer; public class DataPathStorageTest extends AbstractStorageTest{ public DataPathStorageTest() { - super(new PathStorage(STORAGE_DIR.toString(), new DateStreamSerializer())); + super(new PathStorage(STORAGE_DIR.toString(), new DataStreamSerializer())); } } diff --git a/test/ru/javaops/webapp/storage/TestAll.java b/test/ru/javaops/webapp/storage/TestAll.java index 21f90469..81a32ee3 100644 --- a/test/ru/javaops/webapp/storage/TestAll.java +++ b/test/ru/javaops/webapp/storage/TestAll.java @@ -13,7 +13,8 @@ FileStorageTest.class, PathStorageTest.class, XmlPathStorageTest.class, - JsonPathStorageTest.class + JsonPathStorageTest.class, + DataPathStorageTest.class }) public class TestAll { } From 5c8972098f7bcfdbc18afa700732c6175c109145 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 4 Oct 2018 17:29:42 +0300 Subject: [PATCH 162/220] HW10, DataPathStorageTest implementation2 --- src/ru/javaops/webapp/model/Organisation.java | 35 ++++++ .../webapp/model/OrganisationSection.java | 4 + .../serialize/DataStreamSerializer.java | 116 ++++++++++++++++-- 3 files changed, 148 insertions(+), 7 deletions(-) diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 904c09b9..d2fc56fe 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -33,6 +33,25 @@ public Organisation(String name, String url, Position... positions){ this.positions = Arrays.asList(positions); } + public Organisation(String name, String url, List positions){ + Objects.requireNonNull(name, "name can't be NULL"); + this.name = name; + this.url = url; + this.positions = positions; + } + + public String getName() { + return name; + } + + public String getUrl() { + return url; + } + + public List getPositions() { + return positions; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -88,6 +107,22 @@ public Position(LocalDate startDate, LocalDate endDate, String head, String desc this.description = description; } + public LocalDate getStartDate() { + return startDate; + } + + public LocalDate getEndDate() { + return endDate; + } + + public String getHead() { + return head; + } + + public String getDescription() { + return description; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/ru/javaops/webapp/model/OrganisationSection.java b/src/ru/javaops/webapp/model/OrganisationSection.java index 6d0ebf4b..f6a69aee 100644 --- a/src/ru/javaops/webapp/model/OrganisationSection.java +++ b/src/ru/javaops/webapp/model/OrganisationSection.java @@ -21,6 +21,10 @@ public OrganisationSection(List organisations) { this.organisations = organisations; } + public List getOrganisations() { + return organisations; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index 2a7d10a9..d7b51035 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -3,7 +3,10 @@ import ru.javaops.webapp.model.*; import java.io.*; -import java.util.Map; +import java.text.ParseException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; public class DataStreamSerializer implements ISerializeStrategy { @Override @@ -21,15 +24,64 @@ public void doWrite(Resume r, OutputStream os) throws IOException { Map sections = r.getSections(); dos.writeInt(sections.size()); for (Map.Entry entry : sections.entrySet()) { - dos.writeUTF(entry.getKey().getTitle()); - dos.writeUTF(entry.getValue().toString()); - //Section sec = entry.getValue(); + SectionType sType = entry.getKey(); + Section section = entry.getValue(); + switch (sType) { + case PERSONAL: + dos.writeUTF(sType.name()); + dos.writeUTF(section.toString()); + break; + case OBJECTIVE: + dos.writeUTF(sType.name()); + dos.writeUTF(section.toString()); + break; + case ACHIEVEMENT: + dos.writeUTF(sType.name()); + writeList(dos, (ListSection) section); + break; + case QUALIFICATIONS: + dos.writeUTF(sType.name()); + writeList(dos, (ListSection) section); + break; + case EXPERIENCE: + dos.writeUTF(sType.name()); + writeOrg(dos, (OrganisationSection) section); + break; + case EDUCATION: + dos.writeUTF(sType.name()); + writeOrg(dos, (OrganisationSection) section); + break; + } + } + } + } + + private void writeList(DataOutputStream dos, ListSection section) throws IOException { + dos.writeInt(section.getItems().size()); + for (String str : section.getItems()) { + dos.writeUTF(str); + } + } + + private void writeOrg(DataOutputStream dos, OrganisationSection section) throws IOException { + dos.writeInt(section.getOrganisations().size()); + for (Organisation organisation : section.getOrganisations()) { + dos.writeUTF(organisation.getName()); + dos.writeUTF(organisation.getUrl()); + List positions = organisation.getPositions(); + dos.writeInt(positions.size()); + for (Organisation.Position pos : positions) { + dos.writeUTF(pos.getStartDate().toString()); + dos.writeUTF(pos.getEndDate().toString()); + dos.writeUTF(pos.getHead()); + dos.writeUTF(pos.getDescription()); } } } @Override public Resume doRead(InputStream is) throws IOException { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); try (DataInputStream dis = new DataInputStream(is)) { String uuid = dis.readUTF(); String fullName = dis.readUTF(); @@ -39,11 +91,61 @@ public Resume doRead(InputStream is) throws IOException { resume.addContact(ContactType.valueOf(dis.readUTF()), dis.readUTF()); } // TODO implements sections - int sectionsCount = dis.readInt(); - for (int i = 0; i < sectionsCount; i++){ - //resume.addSection(SectionType.valueOf(dis.readUTF()), dis.readUTF()); + int secSize = dis.readInt(); + for (int j = 0; j < secSize; j++) { + String sec = dis.readUTF(); + switch (sec) { + case "PERSONAL": + resume.addSection(SectionType.PERSONAL, new TextSection(dis.readUTF())); + break; + case "OBJECTIVE": + resume.addSection(SectionType.OBJECTIVE, new TextSection(dis.readUTF())); + break; + case "ACHIEVEMENT": + List listRead = getStringList(dis); + resume.addSection(SectionType.ACHIEVEMENT, new ListSection(listRead)); + break; + case "QUALIFICATIONS": + List listRead1 = getStringList(dis); + resume.addSection(SectionType.QUALIFICATIONS, new ListSection(listRead1)); + break; + case "EXPERIENCE": + int orgSize = dis.readInt(); + readOrg(dtf, dis, resume, orgSize); + break; + case "EDUCATION": + int orgSize1 = dis.readInt(); + readOrg(dtf, dis, resume, orgSize1); + break; + } } return resume; } } + + private void readOrg(DateTimeFormatter dtf, DataInputStream dis, Resume resume, int orgSize1) throws IOException { + for (int y = 0; y < orgSize1; y++) { + Organisation org = new Organisation(dis.readUTF(), dis.readUTF()); + List positionsList = new ArrayList<>(); + int posCount = dis.readInt(); + for (int p = 0; p < posCount; p++) { + positionsList.add(new Organisation.Position( + LocalDate.parse(dis.readUTF(), dtf), + LocalDate.parse(dis.readUTF(), dtf), + dis.readUTF(), dis.readUTF()) + ); + } + resume.addSection(SectionType.EXPERIENCE, new OrganisationSection( + new Organisation(org.getName(), org.getUrl(), positionsList))); + } + } + + private List getStringList(DataInputStream dis) throws IOException { + int listSize = dis.readInt(); + List listRead = new ArrayList(); + for (int k = 0; k < listSize; k++) { + listRead.add(dis.readUTF()); + } + return listRead; + } } From 79fb76d7cbc07d1f2871e7077e1d45b3fb033d64 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 4 Oct 2018 19:29:04 +0300 Subject: [PATCH 163/220] HW10, DataPathStorageTest work, need refactoring --- .../storage/serialize/DataStreamSerializer.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index d7b51035..f32487af 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -111,11 +111,11 @@ public Resume doRead(InputStream is) throws IOException { break; case "EXPERIENCE": int orgSize = dis.readInt(); - readOrg(dtf, dis, resume, orgSize); + resume.addSection(SectionType.EXPERIENCE, new OrganisationSection(readOrg(dtf, dis, resume, orgSize))); break; case "EDUCATION": int orgSize1 = dis.readInt(); - readOrg(dtf, dis, resume, orgSize1); + resume.addSection(SectionType.EDUCATION, new OrganisationSection(readOrg(dtf, dis, resume, orgSize1))); break; } } @@ -123,7 +123,8 @@ public Resume doRead(InputStream is) throws IOException { } } - private void readOrg(DateTimeFormatter dtf, DataInputStream dis, Resume resume, int orgSize1) throws IOException { + private List readOrg(DateTimeFormatter dtf, DataInputStream dis, Resume resume, int orgSize1) throws IOException { + List orgList = new ArrayList<>(); for (int y = 0; y < orgSize1; y++) { Organisation org = new Organisation(dis.readUTF(), dis.readUTF()); List positionsList = new ArrayList<>(); @@ -135,9 +136,9 @@ private void readOrg(DateTimeFormatter dtf, DataInputStream dis, Resume resume, dis.readUTF(), dis.readUTF()) ); } - resume.addSection(SectionType.EXPERIENCE, new OrganisationSection( - new Organisation(org.getName(), org.getUrl(), positionsList))); + orgList.add(new Organisation(org.getName(), org.getUrl(), positionsList)); } + return orgList; } private List getStringList(DataInputStream dis) throws IOException { From 2e1189dd6ba9f5de1c3f36a345f93a8ab65cf398 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 4 Oct 2018 19:33:57 +0300 Subject: [PATCH 164/220] HW10, DataPathStorageTest work, need refactoring --- .../webapp/storage/serialize/DataStreamSerializer.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index f32487af..df1d3a5a 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -3,7 +3,6 @@ import ru.javaops.webapp.model.*; import java.io.*; -import java.text.ParseException; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; @@ -102,11 +101,11 @@ public Resume doRead(InputStream is) throws IOException { resume.addSection(SectionType.OBJECTIVE, new TextSection(dis.readUTF())); break; case "ACHIEVEMENT": - List listRead = getStringList(dis); + List listRead = readList(dis); resume.addSection(SectionType.ACHIEVEMENT, new ListSection(listRead)); break; case "QUALIFICATIONS": - List listRead1 = getStringList(dis); + List listRead1 = readList(dis); resume.addSection(SectionType.QUALIFICATIONS, new ListSection(listRead1)); break; case "EXPERIENCE": @@ -141,7 +140,7 @@ private List readOrg(DateTimeFormatter dtf, DataInputStream dis, R return orgList; } - private List getStringList(DataInputStream dis) throws IOException { + private List readList(DataInputStream dis) throws IOException { int listSize = dis.readInt(); List listRead = new ArrayList(); for (int k = 0; k < listSize; k++) { From bcaa45f0960bcf8007a52579b2ab43a0d3dab44f Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 5 Oct 2018 13:22:39 +0300 Subject: [PATCH 165/220] HW10, DataPathStorageTest refactoring --- .../serialize/DataStreamSerializer.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index df1d3a5a..32592151 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -44,11 +44,11 @@ public void doWrite(Resume r, OutputStream os) throws IOException { break; case EXPERIENCE: dos.writeUTF(sType.name()); - writeOrg(dos, (OrganisationSection) section); + writeOrganisations(dos, (OrganisationSection) section); break; case EDUCATION: dos.writeUTF(sType.name()); - writeOrg(dos, (OrganisationSection) section); + writeOrganisations(dos, (OrganisationSection) section); break; } } @@ -62,7 +62,7 @@ private void writeList(DataOutputStream dos, ListSection section) throws IOExcep } } - private void writeOrg(DataOutputStream dos, OrganisationSection section) throws IOException { + private void writeOrganisations(DataOutputStream dos, OrganisationSection section) throws IOException { dos.writeInt(section.getOrganisations().size()); for (Organisation organisation : section.getOrganisations()) { dos.writeUTF(organisation.getName()); @@ -110,11 +110,11 @@ public Resume doRead(InputStream is) throws IOException { break; case "EXPERIENCE": int orgSize = dis.readInt(); - resume.addSection(SectionType.EXPERIENCE, new OrganisationSection(readOrg(dtf, dis, resume, orgSize))); + resume.addSection(SectionType.EXPERIENCE, new OrganisationSection(readOrganisations(dtf, dis, resume, orgSize))); break; case "EDUCATION": int orgSize1 = dis.readInt(); - resume.addSection(SectionType.EDUCATION, new OrganisationSection(readOrg(dtf, dis, resume, orgSize1))); + resume.addSection(SectionType.EDUCATION, new OrganisationSection(readOrganisations(dtf, dis, resume, orgSize1))); break; } } @@ -122,8 +122,8 @@ public Resume doRead(InputStream is) throws IOException { } } - private List readOrg(DateTimeFormatter dtf, DataInputStream dis, Resume resume, int orgSize1) throws IOException { - List orgList = new ArrayList<>(); + private List readOrganisations(DateTimeFormatter dtf, DataInputStream dis, Resume resume, int orgSize1) throws IOException { + List listOrg = new ArrayList<>(); for (int y = 0; y < orgSize1; y++) { Organisation org = new Organisation(dis.readUTF(), dis.readUTF()); List positionsList = new ArrayList<>(); @@ -135,17 +135,17 @@ private List readOrg(DateTimeFormatter dtf, DataInputStream dis, R dis.readUTF(), dis.readUTF()) ); } - orgList.add(new Organisation(org.getName(), org.getUrl(), positionsList)); + listOrg.add(new Organisation(org.getName(), org.getUrl(), positionsList)); } - return orgList; + return listOrg; } private List readList(DataInputStream dis) throws IOException { int listSize = dis.readInt(); - List listRead = new ArrayList(); + List list = new ArrayList<>(); for (int k = 0; k < listSize; k++) { - listRead.add(dis.readUTF()); + list.add(dis.readUTF()); } - return listRead; + return list; } } From ca246844c146c73309c9109f2e66f144ee0436cd Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 5 Oct 2018 13:44:12 +0300 Subject: [PATCH 166/220] HW10, DataPathStorageTest refactoring v2 --- .../serialize/DataStreamSerializer.java | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index 32592151..63889eb5 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -85,15 +85,15 @@ public Resume doRead(InputStream is) throws IOException { String uuid = dis.readUTF(); String fullName = dis.readUTF(); Resume resume = new Resume(uuid, fullName); - int size = dis.readInt(); - for (int i = 0; i < size; i++) { + int contactsCount = dis.readInt(); + for (int i = 0; i < contactsCount; i++) { resume.addContact(ContactType.valueOf(dis.readUTF()), dis.readUTF()); } // TODO implements sections - int secSize = dis.readInt(); - for (int j = 0; j < secSize; j++) { - String sec = dis.readUTF(); - switch (sec) { + int sectionsCount = dis.readInt(); + for (int j = 0; j < sectionsCount; j++) { + String currentSection = dis.readUTF(); + switch (currentSection) { case "PERSONAL": resume.addSection(SectionType.PERSONAL, new TextSection(dis.readUTF())); break; @@ -101,20 +101,16 @@ public Resume doRead(InputStream is) throws IOException { resume.addSection(SectionType.OBJECTIVE, new TextSection(dis.readUTF())); break; case "ACHIEVEMENT": - List listRead = readList(dis); - resume.addSection(SectionType.ACHIEVEMENT, new ListSection(listRead)); + resume.addSection(SectionType.ACHIEVEMENT, new ListSection(readList(dis))); break; case "QUALIFICATIONS": - List listRead1 = readList(dis); - resume.addSection(SectionType.QUALIFICATIONS, new ListSection(listRead1)); + resume.addSection(SectionType.QUALIFICATIONS, new ListSection(readList(dis))); break; case "EXPERIENCE": - int orgSize = dis.readInt(); - resume.addSection(SectionType.EXPERIENCE, new OrganisationSection(readOrganisations(dtf, dis, resume, orgSize))); + resume.addSection(SectionType.EXPERIENCE, new OrganisationSection(readOrganisations(dtf, dis))); break; case "EDUCATION": - int orgSize1 = dis.readInt(); - resume.addSection(SectionType.EDUCATION, new OrganisationSection(readOrganisations(dtf, dis, resume, orgSize1))); + resume.addSection(SectionType.EDUCATION, new OrganisationSection(readOrganisations(dtf, dis))); break; } } @@ -122,9 +118,10 @@ public Resume doRead(InputStream is) throws IOException { } } - private List readOrganisations(DateTimeFormatter dtf, DataInputStream dis, Resume resume, int orgSize1) throws IOException { + private List readOrganisations(DateTimeFormatter dtf, DataInputStream dis) throws IOException { + int orgSize = dis.readInt(); List listOrg = new ArrayList<>(); - for (int y = 0; y < orgSize1; y++) { + for (int y = 0; y < orgSize; y++) { Organisation org = new Organisation(dis.readUTF(), dis.readUTF()); List positionsList = new ArrayList<>(); int posCount = dis.readInt(); From fd5691fc0eafaa2f29016c0c51322be401e7d767 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 5 Oct 2018 15:42:17 +0300 Subject: [PATCH 167/220] HW10, DataPathStorageTest refactoring v3 --- .../webapp/storage/serialize/DataStreamSerializer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index 63889eb5..93e9fd87 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -119,13 +119,13 @@ public Resume doRead(InputStream is) throws IOException { } private List readOrganisations(DateTimeFormatter dtf, DataInputStream dis) throws IOException { - int orgSize = dis.readInt(); + int organisationsCount = dis.readInt(); List listOrg = new ArrayList<>(); - for (int y = 0; y < orgSize; y++) { + for (int y = 0; y < organisationsCount; y++) { Organisation org = new Organisation(dis.readUTF(), dis.readUTF()); List positionsList = new ArrayList<>(); - int posCount = dis.readInt(); - for (int p = 0; p < posCount; p++) { + int positionsCount = dis.readInt(); + for (int p = 0; p < positionsCount; p++) { positionsList.add(new Organisation.Position( LocalDate.parse(dis.readUTF(), dtf), LocalDate.parse(dis.readUTF(), dtf), From ce7973c7c64636437924bd9160f943bf770a93dd Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 10 Oct 2018 15:50:18 +0300 Subject: [PATCH 168/220] HW10, DataPathStorageTest nullReplacer() method implementation --- .../serialize/DataStreamSerializer.java | 29 ++++++------- .../webapp/storage/AbstractStorageTest.java | 6 +-- .../webapp/storage/ResumeTestData.java | 41 +++++++++++++++++-- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index 93e9fd87..6f2fe27e 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -8,6 +8,7 @@ import java.util.*; public class DataStreamSerializer implements ISerializeStrategy { + private static final String NULL_HOLDER = "NuLl_HoLdEr"; @Override public void doWrite(Resume r, OutputStream os) throws IOException { try (DataOutputStream dos = new DataOutputStream(os)) { @@ -19,7 +20,7 @@ public void doWrite(Resume r, OutputStream os) throws IOException { dos.writeUTF(entry.getKey().name()); dos.writeUTF(entry.getValue()); } - // TODO implements sections + Map sections = r.getSections(); dos.writeInt(sections.size()); for (Map.Entry entry : sections.entrySet()) { @@ -27,25 +28,16 @@ public void doWrite(Resume r, OutputStream os) throws IOException { Section section = entry.getValue(); switch (sType) { case PERSONAL: - dos.writeUTF(sType.name()); - dos.writeUTF(section.toString()); - break; case OBJECTIVE: dos.writeUTF(sType.name()); dos.writeUTF(section.toString()); break; case ACHIEVEMENT: - dos.writeUTF(sType.name()); - writeList(dos, (ListSection) section); - break; case QUALIFICATIONS: dos.writeUTF(sType.name()); writeList(dos, (ListSection) section); break; case EXPERIENCE: - dos.writeUTF(sType.name()); - writeOrganisations(dos, (OrganisationSection) section); - break; case EDUCATION: dos.writeUTF(sType.name()); writeOrganisations(dos, (OrganisationSection) section); @@ -66,14 +58,14 @@ private void writeOrganisations(DataOutputStream dos, OrganisationSection sectio dos.writeInt(section.getOrganisations().size()); for (Organisation organisation : section.getOrganisations()) { dos.writeUTF(organisation.getName()); - dos.writeUTF(organisation.getUrl()); + dos.writeUTF(nullReplacer(organisation.getUrl())); List positions = organisation.getPositions(); dos.writeInt(positions.size()); for (Organisation.Position pos : positions) { dos.writeUTF(pos.getStartDate().toString()); dos.writeUTF(pos.getEndDate().toString()); dos.writeUTF(pos.getHead()); - dos.writeUTF(pos.getDescription()); + dos.writeUTF(nullReplacer(pos.getDescription())); } } } @@ -122,14 +114,14 @@ private List readOrganisations(DateTimeFormatter dtf, DataInputStr int organisationsCount = dis.readInt(); List listOrg = new ArrayList<>(); for (int y = 0; y < organisationsCount; y++) { - Organisation org = new Organisation(dis.readUTF(), dis.readUTF()); + Organisation org = new Organisation(dis.readUTF(), nullReplacer(dis.readUTF())); List positionsList = new ArrayList<>(); int positionsCount = dis.readInt(); for (int p = 0; p < positionsCount; p++) { positionsList.add(new Organisation.Position( LocalDate.parse(dis.readUTF(), dtf), LocalDate.parse(dis.readUTF(), dtf), - dis.readUTF(), dis.readUTF()) + dis.readUTF(), nullReplacer(dis.readUTF())) ); } listOrg.add(new Organisation(org.getName(), org.getUrl(), positionsList)); @@ -145,4 +137,13 @@ private List readList(DataInputStream dis) throws IOException { } return list; } + + private String nullReplacer(String description){ + if (description == null){ + return NULL_HOLDER; + } else if (description.equals(NULL_HOLDER)) { + return null; + } + return description; + } } diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 00da80cb..097ab8ec 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -17,11 +17,9 @@ public abstract class AbstractStorageTest { protected final IStorage storage; - //private static final String UUID_1 = "uuid1"; - private static final String UUID_2 = "uuid2"; private static final String UUID_3 = "uuid3"; - private static final Resume resume1 = ResumeTestData.getResume1();//new Resume(UUID_1, "Name1"); - private static final Resume resume2 = new Resume(UUID_2, "Name2"); + private static final Resume resume1 = ResumeTestData.getResume1(); + private static final Resume resume2 = ResumeTestData.getResume2(); private static final Resume resume3 = new Resume(UUID_3, "Name3"); public AbstractStorageTest(IStorage storage) { diff --git a/test/ru/javaops/webapp/storage/ResumeTestData.java b/test/ru/javaops/webapp/storage/ResumeTestData.java index de126f71..d301395a 100644 --- a/test/ru/javaops/webapp/storage/ResumeTestData.java +++ b/test/ru/javaops/webapp/storage/ResumeTestData.java @@ -8,10 +8,14 @@ public class ResumeTestData { protected static Resume resume1 = new Resume("uuid1", "Name1"); + protected static Resume resume2 = new Resume("uuid2", "Name2"); public static Resume getResume1() { return resume1; } + public static Resume getResume2() { + return resume2; + } static { resume1.addContact(ContactType.PHONE, "+71231231212"); @@ -32,7 +36,7 @@ public static Resume getResume1() { resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( new Organisation("Yandex", "yandex.ru", - new Organisation.Position(2008, Month.MAY, "Синьйор", "Работаю синьйором") + new Organisation.Position(2008, Month.MAY, "Синьйор", null) ), new Organisation("JetBrains", "jetbrains.com", new Organisation.Position(2005, Month.DECEMBER, 2008, Month.MAY, "Миддл", "Работал миддлом"), @@ -45,8 +49,37 @@ public static Resume getResume1() { new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", "Was a student") ) )); -// System.out.println(resume1); -// System.out.println(resume1.getContacts()); -// System.out.println(resume1.getSections()); + + resume2.addContact(ContactType.PHONE, "+79999999999"); + resume2.addContact(ContactType.MOBILE_PHONE, "+79119999991"); + resume2.addContact(ContactType.EMAIL, "name2@mail.ru"); + resume2.addContact(ContactType.TELEGRAM, "telegram2"); + resume2.addContact(ContactType.SKYPE, "skype2"); + resume2.addContact(ContactType.LINKEDIN, "LinkedIn/name2"); + resume2.addContact(ContactType.GITHUB, "GitHub/name2"); + resume2.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name2"); + resume2.addContact(ContactType.HOME_PAGE, "homepage/name2"); + + resume2.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 2")); + resume2.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 2")); + + resume2.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); + resume2.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); + + resume2.addSection(SectionType.EXPERIENCE, new OrganisationSection( + new Organisation("Google", "google.com", + new Organisation.Position(2009, Month.MAY, "Старший уборщик", "Работаю старшим уборщиком") + ), + new Organisation("JetBrains", null, + new Organisation.Position(2005, Month.DECEMBER, 2008, Month.MAY, "Заместитель старшего уборщика", null), + new Organisation.Position(2004, Month.APRIL, 2005, Month.DECEMBER, "Младший убощик", null) + ) + )); + + resume2.addSection(SectionType.EDUCATION, new OrganisationSection( + new Organisation("Study 2", "urlStudy2", + new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", null) + ) + )); } } From 66bcdd095dca2579bc0a759fd7a9e1daa8cfb9cf Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 11 Oct 2018 19:38:36 +0300 Subject: [PATCH 169/220] HW10, DataPathStorageTest refactoring --- .../serialize/DataStreamSerializer.java | 119 +++++++++--------- 1 file changed, 58 insertions(+), 61 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index 6f2fe27e..f9d9197c 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -1,11 +1,13 @@ package ru.javaops.webapp.storage.serialize; +import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils; import ru.javaops.webapp.model.*; import java.io.*; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.function.Consumer; public class DataStreamSerializer implements ISerializeStrategy { private static final String NULL_HOLDER = "NuLl_HoLdEr"; @@ -15,102 +17,97 @@ public void doWrite(Resume r, OutputStream os) throws IOException { dos.writeUTF(r.getUuid()); dos.writeUTF(r.getFullName()); Map contacts = r.getContacts(); - dos.writeInt(contacts.size()); - for (Map.Entry entry : contacts.entrySet()) { + writeCollection(dos, contacts.entrySet(), entry -> { dos.writeUTF(entry.getKey().name()); dos.writeUTF(entry.getValue()); - } - + }); Map sections = r.getSections(); - dos.writeInt(sections.size()); - for (Map.Entry entry : sections.entrySet()) { + writeCollection(dos, sections.entrySet(), entry -> { SectionType sType = entry.getKey(); Section section = entry.getValue(); + dos.writeUTF(sType.name()); switch (sType) { case PERSONAL: case OBJECTIVE: - dos.writeUTF(sType.name()); dos.writeUTF(section.toString()); break; case ACHIEVEMENT: case QUALIFICATIONS: - dos.writeUTF(sType.name()); - writeList(dos, (ListSection) section); + writeCollection(dos, ((ListSection) section).getItems(), dos::writeUTF); break; case EXPERIENCE: case EDUCATION: - dos.writeUTF(sType.name()); - writeOrganisations(dos, (OrganisationSection) section); + writeCollection(dos, ((OrganisationSection) section).getOrganisations(), organisation -> { + dos.writeUTF(organisation.getName()); + dos.writeUTF(nullReplacer(organisation.getUrl())); + writeCollection(dos, organisation.getPositions(), position -> { + dos.writeUTF(position.getStartDate().toString()); + dos.writeUTF(position.getEndDate().toString()); + dos.writeUTF(position.getHead()); + dos.writeUTF(nullReplacer(position.getDescription())); + }); + }); break; } - } + }); } } - private void writeList(DataOutputStream dos, ListSection section) throws IOException { - dos.writeInt(section.getItems().size()); - for (String str : section.getItems()) { - dos.writeUTF(str); - } + private interface ItemWriter { + void accept(T t) throws IOException; } - private void writeOrganisations(DataOutputStream dos, OrganisationSection section) throws IOException { - dos.writeInt(section.getOrganisations().size()); - for (Organisation organisation : section.getOrganisations()) { - dos.writeUTF(organisation.getName()); - dos.writeUTF(nullReplacer(organisation.getUrl())); - List positions = organisation.getPositions(); - dos.writeInt(positions.size()); - for (Organisation.Position pos : positions) { - dos.writeUTF(pos.getStartDate().toString()); - dos.writeUTF(pos.getEndDate().toString()); - dos.writeUTF(pos.getHead()); - dos.writeUTF(nullReplacer(pos.getDescription())); - } + private void writeCollection(DataOutputStream dos, Collection collection, ItemWriter writer) throws IOException { + dos.writeInt(collection.size()); + for (T item : collection){ + writer.accept(item); } } @Override public Resume doRead(InputStream is) throws IOException { - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); try (DataInputStream dis = new DataInputStream(is)) { String uuid = dis.readUTF(); String fullName = dis.readUTF(); Resume resume = new Resume(uuid, fullName); - int contactsCount = dis.readInt(); - for (int i = 0; i < contactsCount; i++) { - resume.addContact(ContactType.valueOf(dis.readUTF()), dis.readUTF()); - } - // TODO implements sections - int sectionsCount = dis.readInt(); - for (int j = 0; j < sectionsCount; j++) { - String currentSection = dis.readUTF(); - switch (currentSection) { - case "PERSONAL": - resume.addSection(SectionType.PERSONAL, new TextSection(dis.readUTF())); - break; - case "OBJECTIVE": - resume.addSection(SectionType.OBJECTIVE, new TextSection(dis.readUTF())); - break; - case "ACHIEVEMENT": - resume.addSection(SectionType.ACHIEVEMENT, new ListSection(readList(dis))); - break; - case "QUALIFICATIONS": - resume.addSection(SectionType.QUALIFICATIONS, new ListSection(readList(dis))); - break; - case "EXPERIENCE": - resume.addSection(SectionType.EXPERIENCE, new OrganisationSection(readOrganisations(dtf, dis))); - break; - case "EDUCATION": - resume.addSection(SectionType.EDUCATION, new OrganisationSection(readOrganisations(dtf, dis))); - break; - } - } + readCollection(dis, () -> resume.addContact(ContactType.valueOf(dis.readUTF()), dis.readUTF())); + readCollection(dis, () -> { + SectionType currentSection = SectionType.valueOf(dis.readUTF()); + resume.addSection(currentSection, readSection(dis, currentSection)); + }); return resume; } } - private List readOrganisations(DateTimeFormatter dtf, DataInputStream dis) throws IOException { + interface ItemReader { + void read() throws IOException; + } + + private void readCollection(DataInputStream dis, ItemReader reader) throws IOException { + int size = dis.readInt(); + for (int i = 0; i < size; i++) { + reader.read(); + } + } + + private Section readSection(DataInputStream dis, SectionType currentSection) throws IOException { + switch (currentSection) { + case PERSONAL: + case OBJECTIVE: + return new TextSection(dis.readUTF()); + case ACHIEVEMENT: + case QUALIFICATIONS: + return new ListSection(readList(dis)); + case EXPERIENCE: + case EDUCATION: + return new OrganisationSection(readOrganisations(dis)); + default: + throw new IllegalArgumentException(); + } + } + + private List readOrganisations(DataInputStream dis) throws IOException { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); int organisationsCount = dis.readInt(); List listOrg = new ArrayList<>(); for (int y = 0; y < organisationsCount; y++) { From 4051d5c6b29db802f41e8ddf0b5e302623ee5f70 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 11 Oct 2018 20:17:11 +0300 Subject: [PATCH 170/220] HW10, DataPathStorageTest refactoring, can't find mistake --- .../serialize/DataStreamSerializer.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index f9d9197c..0c537f02 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -79,7 +79,7 @@ public Resume doRead(InputStream is) throws IOException { } } - interface ItemReader { + private interface ItemReader { void read() throws IOException; } @@ -91,16 +91,27 @@ private void readCollection(DataInputStream dis, ItemReader reader) throws IOExc } private Section readSection(DataInputStream dis, SectionType currentSection) throws IOException { + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); switch (currentSection) { case PERSONAL: case OBJECTIVE: return new TextSection(dis.readUTF()); case ACHIEVEMENT: case QUALIFICATIONS: - return new ListSection(readList(dis)); + return new ListSection(readList(dis, dis::readUTF)); case EXPERIENCE: case EDUCATION: - return new OrganisationSection(readOrganisations(dis)); + return new OrganisationSection( + readList(dis, () -> new Organisation( + dis.readUTF(), + dis.readUTF(), + readList(dis, () -> new Organisation.Position( + LocalDate.parse(dis.readUTF(), dtf), + LocalDate.parse(dis.readUTF(), dtf), + dis.readUTF(), nullReplacer(dis.readUTF())) + ) + ) + )); default: throw new IllegalArgumentException(); } @@ -126,11 +137,15 @@ private List readOrganisations(DataInputStream dis) throws IOExcep return listOrg; } - private List readList(DataInputStream dis) throws IOException { - int listSize = dis.readInt(); - List list = new ArrayList<>(); - for (int k = 0; k < listSize; k++) { - list.add(dis.readUTF()); + private interface ElemReader{ + T read() throws IOException; + } + + private List readList(DataInputStream dis, ElemReader reader) throws IOException { + int size = dis.readInt(); + List list = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + list.add(reader.read()); } return list; } From f9f9563fb59634c4bf98d56d03e2534a15d2f363 Mon Sep 17 00:00:00 2001 From: Nikolai Dvinin Date: Thu, 11 Oct 2018 23:26:55 +0300 Subject: [PATCH 171/220] HW10, DataStreamSerializer implementation --- .../serialize/DataStreamSerializer.java | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index 0c537f02..ce5305ad 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -1,13 +1,11 @@ package ru.javaops.webapp.storage.serialize; -import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils; import ru.javaops.webapp.model.*; import java.io.*; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; -import java.util.function.Consumer; public class DataStreamSerializer implements ISerializeStrategy { private static final String NULL_HOLDER = "NuLl_HoLdEr"; @@ -79,7 +77,7 @@ public Resume doRead(InputStream is) throws IOException { } } - private interface ItemReader { + private interface ItemReader { void read() throws IOException; } @@ -104,7 +102,7 @@ private Section readSection(DataInputStream dis, SectionType currentSection) thr return new OrganisationSection( readList(dis, () -> new Organisation( dis.readUTF(), - dis.readUTF(), + nullReplacer(dis.readUTF()), readList(dis, () -> new Organisation.Position( LocalDate.parse(dis.readUTF(), dtf), LocalDate.parse(dis.readUTF(), dtf), @@ -113,28 +111,8 @@ private Section readSection(DataInputStream dis, SectionType currentSection) thr ) )); default: - throw new IllegalArgumentException(); - } - } - - private List readOrganisations(DataInputStream dis) throws IOException { - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - int organisationsCount = dis.readInt(); - List listOrg = new ArrayList<>(); - for (int y = 0; y < organisationsCount; y++) { - Organisation org = new Organisation(dis.readUTF(), nullReplacer(dis.readUTF())); - List positionsList = new ArrayList<>(); - int positionsCount = dis.readInt(); - for (int p = 0; p < positionsCount; p++) { - positionsList.add(new Organisation.Position( - LocalDate.parse(dis.readUTF(), dtf), - LocalDate.parse(dis.readUTF(), dtf), - dis.readUTF(), nullReplacer(dis.readUTF())) - ); - } - listOrg.add(new Organisation(org.getName(), org.getUrl(), positionsList)); + throw new IllegalStateException(); } - return listOrg; } private interface ElemReader{ From cc890fbb428476e10c9e8e8105e35ca04a7143e0 Mon Sep 17 00:00:00 2001 From: Nikolai Dvinin Date: Thu, 11 Oct 2018 23:57:54 +0300 Subject: [PATCH 172/220] HW10, DataStreamSerializer, add parseLocalDate method --- .../webapp/storage/serialize/DataStreamSerializer.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index ce5305ad..a4adecad 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -89,7 +89,6 @@ private void readCollection(DataInputStream dis, ItemReader reader) throws IOExc } private Section readSection(DataInputStream dis, SectionType currentSection) throws IOException { - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); switch (currentSection) { case PERSONAL: case OBJECTIVE: @@ -104,8 +103,8 @@ private Section readSection(DataInputStream dis, SectionType currentSection) thr dis.readUTF(), nullReplacer(dis.readUTF()), readList(dis, () -> new Organisation.Position( - LocalDate.parse(dis.readUTF(), dtf), - LocalDate.parse(dis.readUTF(), dtf), + parseLocalDate(dis.readUTF()), + parseLocalDate(dis.readUTF()), dis.readUTF(), nullReplacer(dis.readUTF())) ) ) @@ -128,6 +127,11 @@ private List readList(DataInputStream dis, ElemReader reader) throws I return list; } + private LocalDate parseLocalDate(String string){ + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + return LocalDate.parse(string, dtf); + } + private String nullReplacer(String description){ if (description == null){ return NULL_HOLDER; From 4db15f63297c1f2405f1475c8b1ad5423b2aae01 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 16 Oct 2018 09:25:37 +0300 Subject: [PATCH 173/220] HW10, refactor nullReplacer method to replace in Organisation & Position constructor --- src/ru/javaops/webapp/model/Organisation.java | 9 +++------ .../serialize/DataStreamSerializer.java | 20 ++++--------------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index d2fc56fe..74ed1f00 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -27,16 +27,13 @@ public Organisation() { } public Organisation(String name, String url, Position... positions){ - Objects.requireNonNull(name, "name can't be NULL"); - this.name = name; - this.url = url; - this.positions = Arrays.asList(positions); + this(name, url, Arrays.asList(positions)); } public Organisation(String name, String url, List positions){ Objects.requireNonNull(name, "name can't be NULL"); this.name = name; - this.url = url; + this.url = url == null ? "" : url; this.positions = positions; } @@ -104,7 +101,7 @@ public Position(LocalDate startDate, LocalDate endDate, String head, String desc this.startDate = startDate; this.endDate = endDate; this.head = head; - this.description = description; + this.description = description == null ? "" : description; } public LocalDate getStartDate() { diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index a4adecad..919e17d1 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -8,7 +8,6 @@ import java.util.*; public class DataStreamSerializer implements ISerializeStrategy { - private static final String NULL_HOLDER = "NuLl_HoLdEr"; @Override public void doWrite(Resume r, OutputStream os) throws IOException { try (DataOutputStream dos = new DataOutputStream(os)) { @@ -37,12 +36,12 @@ public void doWrite(Resume r, OutputStream os) throws IOException { case EDUCATION: writeCollection(dos, ((OrganisationSection) section).getOrganisations(), organisation -> { dos.writeUTF(organisation.getName()); - dos.writeUTF(nullReplacer(organisation.getUrl())); + dos.writeUTF(organisation.getUrl()); writeCollection(dos, organisation.getPositions(), position -> { dos.writeUTF(position.getStartDate().toString()); dos.writeUTF(position.getEndDate().toString()); dos.writeUTF(position.getHead()); - dos.writeUTF(nullReplacer(position.getDescription())); + dos.writeUTF(position.getDescription()); }); }); break; @@ -99,13 +98,11 @@ private Section readSection(DataInputStream dis, SectionType currentSection) thr case EXPERIENCE: case EDUCATION: return new OrganisationSection( - readList(dis, () -> new Organisation( - dis.readUTF(), - nullReplacer(dis.readUTF()), + readList(dis, () -> new Organisation(dis.readUTF(), dis.readUTF(), readList(dis, () -> new Organisation.Position( parseLocalDate(dis.readUTF()), parseLocalDate(dis.readUTF()), - dis.readUTF(), nullReplacer(dis.readUTF())) + dis.readUTF(), dis.readUTF()) ) ) )); @@ -131,13 +128,4 @@ private LocalDate parseLocalDate(String string){ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); return LocalDate.parse(string, dtf); } - - private String nullReplacer(String description){ - if (description == null){ - return NULL_HOLDER; - } else if (description.equals(NULL_HOLDER)) { - return null; - } - return description; - } } From 551097393aa8a1aac20563ef9d10094f20c94694 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 24 Oct 2018 15:56:12 +0300 Subject: [PATCH 174/220] HW11, MainConcurrancy implementation --- src/ru/javaops/webapp/MainConcurrancy.java | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/ru/javaops/webapp/MainConcurrancy.java diff --git a/src/ru/javaops/webapp/MainConcurrancy.java b/src/ru/javaops/webapp/MainConcurrancy.java new file mode 100644 index 00000000..1f3f3b1f --- /dev/null +++ b/src/ru/javaops/webapp/MainConcurrancy.java @@ -0,0 +1,79 @@ +package ru.javaops.webapp; + +import java.util.ArrayList; +import java.util.List; + +public class MainConcurrancy { + private static int counter; + private static final Object LOCK = new Object(); + private static final int THREADS_COUNT = 10000; + + public static void main(String[] args) throws InterruptedException { + + Thread thread0 = new Thread() { + public void run() { + System.out.println(getName() + ", " + getState()); + } + }; + thread0.start(); + + Thread thread1 = new Thread(new Runnable() { + @Override + public void run() { + Thread currentThred = Thread.currentThread(); + System.out.println(currentThred.getName() + ", " + currentThred.getState()); + } + }); + thread1.start(); + + + new Thread(() -> { + Thread currentThred = Thread.currentThread(); + System.out.println(currentThred.getName() + ", " + currentThred.getState()); + }).start(); + + System.out.println(thread0.getName() + ", " + thread0.getState()); + System.out.println(thread1.getName() + ", " + thread1.getState()); + + //Thread.currentThread().sleep(500); + //Thread.currentThread().join(); + //System.out.println(counter); + + //final Object lock2 = new Object(); + final MainConcurrancy mainConcurancy = new MainConcurrancy(); + List threads = new ArrayList<>(THREADS_COUNT); + for (int i = 0; i < THREADS_COUNT; i++) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + for (int j = 0; j < 100; j++) { + mainConcurancy.inc(); + } + } + }); + thread.start(); + threads.add(thread); + } + + System.out.println(counter); + + threads.forEach(thread -> { + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + + Thread.sleep(500); + System.out.println(counter); + } + + private void inc() { + double sin = Math.sin(123); + synchronized (this) { + counter++; + } + } +} From 967b15828fb272730f0b1f64fea092c665c04cd3 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 30 Oct 2018 06:12:38 +0300 Subject: [PATCH 175/220] HW11, MainConcurrancy implementation --- src/ru/javaops/webapp/MainConcurrancy.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ru/javaops/webapp/MainConcurrancy.java b/src/ru/javaops/webapp/MainConcurrancy.java index 1f3f3b1f..579224a7 100644 --- a/src/ru/javaops/webapp/MainConcurrancy.java +++ b/src/ru/javaops/webapp/MainConcurrancy.java @@ -22,14 +22,16 @@ public void run() { public void run() { Thread currentThred = Thread.currentThread(); System.out.println(currentThred.getName() + ", " + currentThred.getState()); + + throw new IllegalStateException(); } }); thread1.start(); new Thread(() -> { - Thread currentThred = Thread.currentThread(); - System.out.println(currentThred.getName() + ", " + currentThred.getState()); + Thread currentThread = Thread.currentThread(); + System.out.println(currentThread.getName() + ", " + currentThread.getState()); }).start(); System.out.println(thread0.getName() + ", " + thread0.getState()); @@ -52,6 +54,7 @@ public void run() { } }); thread.start(); + //thread.join(); threads.add(thread); } @@ -66,7 +69,7 @@ public void run() { }); - Thread.sleep(500); + //Thread.sleep(500); System.out.println(counter); } From 6db2633c74863f9a80e97195b86fcd7a53e525a5 Mon Sep 17 00:00:00 2001 From: Nikolai Dvinin Date: Tue, 30 Oct 2018 07:17:06 +0300 Subject: [PATCH 176/220] HW11, LazySingleton implementation --- src/ru/javaops/webapp/MainConcurrancy.java | 3 +++ src/ru/javaops/webapp/util/LazySingleton.java | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/ru/javaops/webapp/util/LazySingleton.java diff --git a/src/ru/javaops/webapp/MainConcurrancy.java b/src/ru/javaops/webapp/MainConcurrancy.java index 579224a7..226a9e1b 100644 --- a/src/ru/javaops/webapp/MainConcurrancy.java +++ b/src/ru/javaops/webapp/MainConcurrancy.java @@ -1,5 +1,7 @@ package ru.javaops.webapp; +import ru.javaops.webapp.util.LazySingleton; + import java.util.ArrayList; import java.util.List; @@ -70,6 +72,7 @@ public void run() { //Thread.sleep(500); + LazySingleton.getInstance(); System.out.println(counter); } diff --git a/src/ru/javaops/webapp/util/LazySingleton.java b/src/ru/javaops/webapp/util/LazySingleton.java new file mode 100644 index 00000000..a42d9038 --- /dev/null +++ b/src/ru/javaops/webapp/util/LazySingleton.java @@ -0,0 +1,24 @@ +package ru.javaops.webapp.util; + +public class LazySingleton { + volatile private static LazySingleton INSTANCE; + + private LazySingleton() { + } + + private static class LazySingletonHolder { + private static final LazySingleton INSTANCE = new LazySingleton(); + } + + public static LazySingleton getInstance() { + return LazySingletonHolder.INSTANCE; +// if (INSTANCE == null) { +// synchronized (LazySingleton.class) { +// if (INSTANCE == null) { +// INSTANCE = new LazySingleton(); +// } +// } +// } +// return INSTANCE; + } +} From 810437b061c17b9bf14d8fa396f53c444e517ffc Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 31 Oct 2018 13:44:36 +0300 Subject: [PATCH 177/220] HW11, MainDeadLockExample implementation --- .../javaops/webapp/MainDeadLockExample.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/ru/javaops/webapp/MainDeadLockExample.java diff --git a/src/ru/javaops/webapp/MainDeadLockExample.java b/src/ru/javaops/webapp/MainDeadLockExample.java new file mode 100644 index 00000000..75dd4a16 --- /dev/null +++ b/src/ru/javaops/webapp/MainDeadLockExample.java @@ -0,0 +1,74 @@ +package ru.javaops.webapp; + +public class MainDeadLockExample { + + public static void main(String[] args) { + Account accountA = new Account(1, "AAA", 100000.); + Account accountB = new Account(2, "BBB", 50000.); + + for (int i = 1; i < 100000; i++) { + Thread thread01 = new Thread() { + @Override + public void run() { + doTransfer(accountA, accountB, 1); + System.out.println(accountA.getAmount() + " " + accountB.getAmount()); + } + }; + thread01.start(); + + Thread thread02 = new Thread() { + @Override + public void run() { + doTransfer(accountB, accountA, 1); + System.out.println(accountA.getAmount() + " " + accountB.getAmount()); + } + }; + thread02.start(); + } + } + + private static void doTransfer(Account fromAcc, Account toAcc, double amount) { + synchronized (fromAcc) { + if (fromAcc.getAmount() < amount) { + System.out.println("Error, not enough amount at account ID: " + fromAcc.getId()); + } else { + synchronized (toAcc) { + fromAcc.credit(amount); + toAcc.debit(amount); + } + } + } + } + + private static class Account { + private final int id; + private final String owner; + private double amount; + + Account(int id, String owner, double amount) { + this.id = id; + this.owner = owner; + this.amount = amount; + } + + public int getId() { + return id; + } + + public String getOwner() { + return owner; + } + + public double getAmount() { + return amount; + } + + private void debit(double amount) { + this.amount += amount; + } + + private void credit(double amount) { + this.amount -= amount; + } + } +} From 3b75c98cc18807d0677f77f234ce4c6183b61e09 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 31 Oct 2018 14:07:57 +0300 Subject: [PATCH 178/220] HW11, MainDeadLockExample implementation --- .../javaops/webapp/MainDeadLockExample.java | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/ru/javaops/webapp/MainDeadLockExample.java b/src/ru/javaops/webapp/MainDeadLockExample.java index 75dd4a16..f8b36633 100644 --- a/src/ru/javaops/webapp/MainDeadLockExample.java +++ b/src/ru/javaops/webapp/MainDeadLockExample.java @@ -7,22 +7,16 @@ public static void main(String[] args) { Account accountB = new Account(2, "BBB", 50000.); for (int i = 1; i < 100000; i++) { - Thread thread01 = new Thread() { - @Override - public void run() { - doTransfer(accountA, accountB, 1); - System.out.println(accountA.getAmount() + " " + accountB.getAmount()); - } - }; + Thread thread01 = new Thread(() -> { + doTransfer(accountA, accountB, 1); + System.out.println(accountA.getAmount() + " " + accountB.getAmount()); + }); thread01.start(); - Thread thread02 = new Thread() { - @Override - public void run() { - doTransfer(accountB, accountA, 1); - System.out.println(accountA.getAmount() + " " + accountB.getAmount()); - } - }; + Thread thread02 = new Thread(() -> { + doTransfer(accountB, accountA, 1); + System.out.println(accountA.getAmount() + " " + accountB.getAmount()); + }); thread02.start(); } } From cf6edf9334293fb35a80a90c2b40b4f48bb4490f Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 2 Nov 2018 08:56:17 +0300 Subject: [PATCH 179/220] HW11, to MainConcurrent add Kislin deadlock implementation --- src/ru/javaops/webapp/MainConcurrancy.java | 22 +++++++++++++++++++ .../javaops/webapp/MainDeadLockExample.java | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/src/ru/javaops/webapp/MainConcurrancy.java b/src/ru/javaops/webapp/MainConcurrancy.java index 226a9e1b..894b3bfb 100644 --- a/src/ru/javaops/webapp/MainConcurrancy.java +++ b/src/ru/javaops/webapp/MainConcurrancy.java @@ -74,6 +74,28 @@ public void run() { //Thread.sleep(500); LazySingleton.getInstance(); System.out.println(counter); + + String lock1 = "lock1"; + String lock2 = "lock2"; + doDeadLock(lock1, lock2); + doDeadLock(lock2, lock1); + } + + private static void doDeadLock(String lock1, String lock2) { + new Thread(() -> { + synchronized (lock1){ + System.out.println("Holding lock1"); + System.out.println("Waiting lock2"); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + synchronized (lock2){ + System.out.println("Holding lock2"); + } + } + }).start(); } private void inc() { diff --git a/src/ru/javaops/webapp/MainDeadLockExample.java b/src/ru/javaops/webapp/MainDeadLockExample.java index f8b36633..ed83474f 100644 --- a/src/ru/javaops/webapp/MainDeadLockExample.java +++ b/src/ru/javaops/webapp/MainDeadLockExample.java @@ -26,6 +26,11 @@ private static void doTransfer(Account fromAcc, Account toAcc, double amount) { if (fromAcc.getAmount() < amount) { System.out.println("Error, not enough amount at account ID: " + fromAcc.getId()); } else { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } synchronized (toAcc) { fromAcc.credit(amount); toAcc.debit(amount); From 9a8cf48d30c389cda17cd6adddda9beb8a0f2607 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 8 Nov 2018 19:35:31 +0300 Subject: [PATCH 180/220] HW12, Draft of minValue and oddOrEven methods --- src/ru/javaops/webapp/MainConcurrancy.java | 42 ++++++++++++++-------- src/ru/javaops/webapp/MainStreams.java | 29 +++++++++++++++ 2 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 src/ru/javaops/webapp/MainStreams.java diff --git a/src/ru/javaops/webapp/MainConcurrancy.java b/src/ru/javaops/webapp/MainConcurrancy.java index 894b3bfb..a77e62bb 100644 --- a/src/ru/javaops/webapp/MainConcurrancy.java +++ b/src/ru/javaops/webapp/MainConcurrancy.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.concurrent.*; public class MainConcurrancy { private static int counter; @@ -45,40 +46,51 @@ public void run() { //final Object lock2 = new Object(); final MainConcurrancy mainConcurancy = new MainConcurrancy(); - List threads = new ArrayList<>(THREADS_COUNT); + CountDownLatch latch = new CountDownLatch(THREADS_COUNT); + ExecutorService executorService = Executors.newCachedThreadPool(); +// List threads = new ArrayList<>(THREADS_COUNT); for (int i = 0; i < THREADS_COUNT; i++) { - Thread thread = new Thread(new Runnable() { + executorService.submit(() -> { + { + for (int j = 0; j < 100; j++) { + mainConcurancy.inc(); + } + latch.countDown(); + } + }); + /*Thread thread = new Thread(new Runnable() { @Override public void run() { for (int j = 0; j < 100; j++) { mainConcurancy.inc(); } + latch.countDown(); } }); - thread.start(); + thread.start();*/ //thread.join(); - threads.add(thread); +// threads.add(thread); } System.out.println(counter); - threads.forEach(thread -> { - try { - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - }); - - +// threads.forEach(thread -> { +// try { +// thread.join(); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// }); + latch.await(10, TimeUnit.SECONDS); + executorService.shutdown(); //Thread.sleep(500); LazySingleton.getInstance(); System.out.println(counter); String lock1 = "lock1"; String lock2 = "lock2"; - doDeadLock(lock1, lock2); - doDeadLock(lock2, lock1); +// doDeadLock(lock1, lock2); +// doDeadLock(lock2, lock1); } private static void doDeadLock(String lock1, String lock2) { diff --git a/src/ru/javaops/webapp/MainStreams.java b/src/ru/javaops/webapp/MainStreams.java new file mode 100644 index 00000000..6cd44d7b --- /dev/null +++ b/src/ru/javaops/webapp/MainStreams.java @@ -0,0 +1,29 @@ +package ru.javaops.webapp; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class MainStreams { + public static void main(String[] args) { + System.out.println(minValue(new int[]{9 , 8})); + System.out.println(oddOrEven(Arrays.asList(1, 2, 3, 3, 2, 3))); + } + + private static int minValue(int[] values) { + return Arrays.stream(values) + .distinct() + .sorted() + .reduce((s1, s2) -> Integer.parseInt(String.valueOf(s1) + String.valueOf(s2))) + .orElse(0); + } + + private static List oddOrEven(List integers) { + long sum = integers.stream().mapToInt(Integer::intValue).sum(); + if (sum % 2 == 0) { + return integers.stream().filter((s) -> s % 2 != 0).collect(Collectors.toList()); + } else { + return integers.stream().filter((s) -> s % 2 == 0).collect(Collectors.toList()); + } + } +} From cc3f7f1c7769705229426f43c455cb89e3dc9fe1 Mon Sep 17 00:00:00 2001 From: Nikolai Dvinin Date: Sun, 11 Nov 2018 22:19:28 +0300 Subject: [PATCH 181/220] HW12, refactoring --- src/ru/javaops/webapp/MainStreams.java | 28 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/ru/javaops/webapp/MainStreams.java b/src/ru/javaops/webapp/MainStreams.java index 6cd44d7b..d5736498 100644 --- a/src/ru/javaops/webapp/MainStreams.java +++ b/src/ru/javaops/webapp/MainStreams.java @@ -6,24 +6,34 @@ public class MainStreams { public static void main(String[] args) { - System.out.println(minValue(new int[]{9 , 8})); + System.out.println(minValue(new int[]{9, 8})); System.out.println(oddOrEven(Arrays.asList(1, 2, 3, 3, 2, 3))); } private static int minValue(int[] values) { - return Arrays.stream(values) + return (int) Arrays.stream(values) .distinct() .sorted() - .reduce((s1, s2) -> Integer.parseInt(String.valueOf(s1) + String.valueOf(s2))) + .mapToDouble(num -> (double) num) + .reduce((s1, s2) -> (s1 + (s2 / 10)) * 10) .orElse(0); } private static List oddOrEven(List integers) { - long sum = integers.stream().mapToInt(Integer::intValue).sum(); - if (sum % 2 == 0) { - return integers.stream().filter((s) -> s % 2 != 0).collect(Collectors.toList()); - } else { - return integers.stream().filter((s) -> s % 2 == 0).collect(Collectors.toList()); - } + + + int sum = integers.stream().mapToInt(Integer::intValue).sum(); + System.out.println(sum); + return integers.stream().filter((s) -> { + if (sum % 2 == 0 && s % 2 == 0) { + return false; + } else return sum % 2 == 0 || s % 2 == 0; + }).collect(Collectors.toList()); + +// if (sum % 2 == 0) { +// return integers.stream().filter((s) -> s % 2 != 0).collect(Collectors.toList()); +// } else { +// return integers.stream().filter((s) -> s % 2 == 0).collect(Collectors.toList()); +// } } } From 256bccc065774302f4d7a8e196612eb4e7677464 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 14 Nov 2018 13:18:56 +0300 Subject: [PATCH 182/220] HW12, Refactoring --- src/ru/javaops/webapp/MainStreams.java | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/ru/javaops/webapp/MainStreams.java b/src/ru/javaops/webapp/MainStreams.java index d5736498..3d4dfc34 100644 --- a/src/ru/javaops/webapp/MainStreams.java +++ b/src/ru/javaops/webapp/MainStreams.java @@ -11,29 +11,15 @@ public static void main(String[] args) { } private static int minValue(int[] values) { - return (int) Arrays.stream(values) + return Arrays.stream(values) .distinct() .sorted() - .mapToDouble(num -> (double) num) - .reduce((s1, s2) -> (s1 + (s2 / 10)) * 10) + .reduce((s1, s2) -> s1 * 10 + s2) .orElse(0); } private static List oddOrEven(List integers) { - - int sum = integers.stream().mapToInt(Integer::intValue).sum(); - System.out.println(sum); - return integers.stream().filter((s) -> { - if (sum % 2 == 0 && s % 2 == 0) { - return false; - } else return sum % 2 == 0 || s % 2 == 0; - }).collect(Collectors.toList()); - -// if (sum % 2 == 0) { -// return integers.stream().filter((s) -> s % 2 != 0).collect(Collectors.toList()); -// } else { -// return integers.stream().filter((s) -> s % 2 == 0).collect(Collectors.toList()); -// } + return integers.stream().filter(s -> s % 2 != sum % 2).collect(Collectors.toList()); } } From 049393ef3b0ec9a0858c49f6dea85281dd0c19c6 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 16 Nov 2018 16:54:07 +0300 Subject: [PATCH 183/220] HW12, MainConcurrency refactoring --- src/ru/javaops/webapp/MainConcurrancy.java | 29 +++++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/MainConcurrancy.java b/src/ru/javaops/webapp/MainConcurrancy.java index a77e62bb..0a8b0f90 100644 --- a/src/ru/javaops/webapp/MainConcurrancy.java +++ b/src/ru/javaops/webapp/MainConcurrancy.java @@ -5,10 +5,13 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; public class MainConcurrancy { private static int counter; - private static final Object LOCK = new Object(); + //private static final Object LOCK = new Object(); + private static final Lock lock = new ReentrantLock(); private static final int THREADS_COUNT = 10000; public static void main(String[] args) throws InterruptedException { @@ -26,7 +29,7 @@ public void run() { Thread currentThred = Thread.currentThread(); System.out.println(currentThred.getName() + ", " + currentThred.getState()); - throw new IllegalStateException(); +// throw new IllegalStateException(); } }); thread1.start(); @@ -47,17 +50,28 @@ public void run() { //final Object lock2 = new Object(); final MainConcurrancy mainConcurancy = new MainConcurrancy(); CountDownLatch latch = new CountDownLatch(THREADS_COUNT); + //Создать кол-во потоков равное кол-ву ядер на ПК/Сервере +// ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); ExecutorService executorService = Executors.newCachedThreadPool(); +// CompletionService completionService = new ExecutorCompletionService(executorService); // List threads = new ArrayList<>(THREADS_COUNT); for (int i = 0; i < THREADS_COUNT; i++) { - executorService.submit(() -> { + Future future = executorService.submit(() -> { { for (int j = 0; j < 100; j++) { mainConcurancy.inc(); } latch.countDown(); + return 5; } }); +// completionService.poll(); + /*System.out.println(future.isDone()); + try { + System.out.println(future.get()); + } catch (ExecutionException e) { + e.printStackTrace(); + }*/ /*Thread thread = new Thread(new Runnable() { @Override public void run() { @@ -112,8 +126,15 @@ private static void doDeadLock(String lock1, String lock2) { private void inc() { double sin = Math.sin(123); - synchronized (this) { + lock.lock(); + try { counter++; + } finally { + lock.unlock(); } + + /*synchronized (this) { + counter++; + }*/ } } From f23dd632bbce776ebab3b6e3f8a17bfdfa47b4f6 Mon Sep 17 00:00:00 2001 From: Nikolai Dvinin Date: Sat, 17 Nov 2018 10:57:00 +0300 Subject: [PATCH 184/220] HW12, MainConcurrency complete --- src/ru/javaops/webapp/MainConcurrancy.java | 33 ++++++++++++++++------ 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/ru/javaops/webapp/MainConcurrancy.java b/src/ru/javaops/webapp/MainConcurrancy.java index 0a8b0f90..2a549c28 100644 --- a/src/ru/javaops/webapp/MainConcurrancy.java +++ b/src/ru/javaops/webapp/MainConcurrancy.java @@ -2,9 +2,12 @@ import ru.javaops.webapp.util.LazySingleton; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -12,8 +15,16 @@ public class MainConcurrancy { private static int counter; //private static final Object LOCK = new Object(); private static final Lock lock = new ReentrantLock(); + private final static AtomicInteger atomicCounter = new AtomicInteger(); private static final int THREADS_COUNT = 10000; + private static final ThreadLocal threadLocal = new ThreadLocal(){ + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat(); + } + }; + public static void main(String[] args) throws InterruptedException { Thread thread0 = new Thread() { @@ -60,6 +71,7 @@ public void run() { { for (int j = 0; j < 100; j++) { mainConcurancy.inc(); + //System.out.println(threadLocal.get().format(new Date())); } latch.countDown(); return 5; @@ -86,7 +98,8 @@ public void run() { // threads.add(thread); } - System.out.println(counter); + //System.out.println(counter); + System.out.println(atomicCounter.get()); // threads.forEach(thread -> { // try { @@ -99,7 +112,8 @@ public void run() { executorService.shutdown(); //Thread.sleep(500); LazySingleton.getInstance(); - System.out.println(counter); + //System.out.println(counter); + System.out.println(atomicCounter.get()); String lock1 = "lock1"; String lock2 = "lock2"; @@ -126,12 +140,15 @@ private static void doDeadLock(String lock1, String lock2) { private void inc() { double sin = Math.sin(123); - lock.lock(); - try { - counter++; - } finally { - lock.unlock(); - } + + atomicCounter.incrementAndGet(); + +// lock.lock(); +// try { +// counter++; +// } finally { +// lock.unlock(); +// } /*synchronized (this) { counter++; From e2fd016b558a11535ee9f2decc55d9c56e397958 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 21 Nov 2018 16:53:56 +0300 Subject: [PATCH 185/220] HW13, ./config/init_db.sql for refactoring --- config/init_db.sql | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 config/init_db.sql diff --git a/config/init_db.sql b/config/init_db.sql new file mode 100644 index 00000000..6c78d342 --- /dev/null +++ b/config/init_db.sql @@ -0,0 +1,29 @@ +create table resume ( + uuid char(36) not null + constraint resume_pkey + primary key, + full_name text NOT NULL +); + +alter table resume + owner to postgres; + +create table contact +( + id serial not null + constraint contact_pkey + primary key, + type text not null, + value text not null, + resume_uuid char(36) not null + constraint contact_resume_uuid_fk + references resume + on delete cascade +); + +alter table contact + owner to postgres; + +create unique index contact_uuid_type_index + on contact (resume_uuid, type); + From b68872371946376e609ff450c79fa5a9cb6d02d0 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 21 Nov 2018 17:36:13 +0300 Subject: [PATCH 186/220] HW13, ./config/init_db_gkislin.sql for example --- config/init_db_gkislin.sql | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 config/init_db_gkislin.sql diff --git a/config/init_db_gkislin.sql b/config/init_db_gkislin.sql new file mode 100644 index 00000000..e5d0242a --- /dev/null +++ b/config/init_db_gkislin.sql @@ -0,0 +1,13 @@ +CREATE TABLE resume ( + uuid CHAR(36) PRIMARY KEY NOT NULL, + full_name TEXT NOT NULL +); + +CREATE TABLE contact ( + id SERIAL, + resume_uuid CHAR(36) NOT NULL REFERENCES resume (uuid) ON DELETE CASCADE, + type TEXT NOT NULL, + value TEXT NOT NULL +); +CREATE UNIQUE INDEX contact_uuid_type_index + ON contact (resume_uuid, type); From 53e7c3778a2a1114f952c92fa3a0f4382a53c55b Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 21 Nov 2018 22:01:00 +0300 Subject: [PATCH 187/220] HW13, resumes.properties --- config/resumes.properties | 4 +++ src/ru/javaops/webapp/Config.java | 29 +++++++++++++++++++ .../webapp/storage/AbstractStorageTest.java | 3 +- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 config/resumes.properties create mode 100644 src/ru/javaops/webapp/Config.java diff --git a/config/resumes.properties b/config/resumes.properties new file mode 100644 index 00000000..b3cd9ba2 --- /dev/null +++ b/config/resumes.properties @@ -0,0 +1,4 @@ +storage.dir=storage +db.url=jdbc:postgresql://localhost:5432/resumes +db.user=postgres +db.password=postgres diff --git a/src/ru/javaops/webapp/Config.java b/src/ru/javaops/webapp/Config.java new file mode 100644 index 00000000..8e8ffc5f --- /dev/null +++ b/src/ru/javaops/webapp/Config.java @@ -0,0 +1,29 @@ +package ru.javaops.webapp; + +import java.io.*; +import java.util.Properties; + +public class Config { + private final static File PROPS = new File("config/resumes.properties"); + private static final Config INSTANCE = new Config(); + + private File storageDir; + + public static Config getInstance() { + return INSTANCE; + } + + private Config() { + try (InputStream is = new FileInputStream(PROPS)) { + Properties prop = new Properties(); + prop.load(is); + storageDir = new File(prop.getProperty("storage.dir")); + } catch (IOException e) { + throw new IllegalStateException("Invalid config file " + PROPS.getAbsolutePath()); + } + } + + public File getStorageDir() { + return storageDir; + } +} diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 097ab8ec..9c77beab 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -1,6 +1,7 @@ package ru.javaops.webapp.storage; import org.junit.*; +import ru.javaops.webapp.Config; import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.*; @@ -12,7 +13,7 @@ public abstract class AbstractStorageTest { - protected final static File STORAGE_DIR = new File("storage"); + protected final static File STORAGE_DIR = Config.getInstance().getStorageDir(); //new File("storage"); protected final static StreamSerializer STREAM_SERIALIZER = new StreamSerializer(); protected final IStorage storage; From 495f45b6a642080b1ebd417935568c4508a66f72 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 22 Nov 2018 21:32:57 +0300 Subject: [PATCH 188/220] HW13, SqlStorage for refactoring --- .../webapp/exception/StorageException.java | 4 + .../javaops/webapp/sql/ConnectionFactory.java | 8 ++ src/ru/javaops/webapp/storage/SqlStorage.java | 75 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 src/ru/javaops/webapp/sql/ConnectionFactory.java create mode 100644 src/ru/javaops/webapp/storage/SqlStorage.java diff --git a/src/ru/javaops/webapp/exception/StorageException.java b/src/ru/javaops/webapp/exception/StorageException.java index 1575bdfc..6636d33d 100644 --- a/src/ru/javaops/webapp/exception/StorageException.java +++ b/src/ru/javaops/webapp/exception/StorageException.java @@ -7,6 +7,10 @@ public StorageException(String uuid){ this.uuid = uuid; } + public StorageException(Exception e) { + this(e.getMessage(), e); + } + public StorageException(String message, String uuid) { super(message); this.uuid = uuid; diff --git a/src/ru/javaops/webapp/sql/ConnectionFactory.java b/src/ru/javaops/webapp/sql/ConnectionFactory.java new file mode 100644 index 00000000..cf4bfdbf --- /dev/null +++ b/src/ru/javaops/webapp/sql/ConnectionFactory.java @@ -0,0 +1,8 @@ +package ru.javaops.webapp.sql; + +import java.sql.Connection; +import java.sql.SQLException; + +public interface ConnectionFactory { + Connection getConnection() throws SQLException; +} diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java new file mode 100644 index 00000000..c5d4b2f9 --- /dev/null +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -0,0 +1,75 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.exception.NotExistStorageException; +import ru.javaops.webapp.exception.StorageException; +import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.sql.ConnectionFactory; + +import java.sql.*; +import java.util.List; + +public class SqlStorage implements IStorage { + private final ConnectionFactory connectionFactory; + + public SqlStorage(String dbUrl, String dbUser, String dbPassword) { + connectionFactory = () -> DriverManager.getConnection(dbUrl, dbUser, dbPassword); + } + + @Override + public void clear() { + try(Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("DELETE FROM resume")){ + ps.execute(); + } catch (SQLException e) { + throw new StorageException(e); + } + } + + @Override + public Resume get(String uuid) { + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r WHERE r.uuid =?")) { + ps.setString(1, uuid); + ResultSet rs = ps.executeQuery(); + if(!rs.next()) { + throw new NotExistStorageException(uuid); + } + return new Resume(uuid, rs.getString("full_name")); + } catch (SQLException e) { + throw new StorageException(e); + } + } + + @Override + public void update(Resume resume) { + + } + + @Override + public void save(Resume resume) { + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("INSERT INTO resume (uuid, full_name) VALUES (?,?)")) { + ps.setString(1, resume.getUuid()); + ps.setString(2, resume.getFullName()); + ps.execute(); + } catch (SQLException e) { + throw new StorageException(e); + } + + } + + @Override + public void delete(String uuid) { + + } + + @Override + public List getAllSorted() { + return null; + } + + @Override + public int size() { + return 0; + } +} From 9e5efe8636d2c88264f7a4835a387ba2a1715c0a Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 23 Nov 2018 17:28:38 +0300 Subject: [PATCH 189/220] HW13, SqlStorage v2 for refactoring --- src/ru/javaops/webapp/storage/SqlStorage.java | 29 +++++++++++++++---- .../webapp/storage/ResumeTestData.java | 4 +-- .../webapp/storage/SqlStorageTest.java | 12 ++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 test/ru/javaops/webapp/storage/SqlStorageTest.java diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index c5d4b2f9..9f9d90ab 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -28,7 +28,7 @@ public void clear() { @Override public Resume get(String uuid) { try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r WHERE r.uuid =?")) { + PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r WHERE r.uuid = ?")) { ps.setString(1, uuid); ResultSet rs = ps.executeQuery(); if(!rs.next()) { @@ -42,7 +42,14 @@ public Resume get(String uuid) { @Override public void update(Resume resume) { - + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("UPDATE resume SET full_name = ? WHERE uuid = ?")) { + ps.setString(1, resume.getFullName()); + ps.setString(2, resume.getUuid()); + ps.executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } } @Override @@ -55,12 +62,17 @@ public void save(Resume resume) { } catch (SQLException e) { throw new StorageException(e); } - } @Override public void delete(String uuid) { - + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("DELETE FROM resume r WHERE r.uuid = ?")) { + ps.setString(1, uuid); + ps.executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } } @Override @@ -70,6 +82,13 @@ public List getAllSorted() { @Override public int size() { - return 0; + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("SELECT COUNT(*) FROM resume")) { + ResultSet rs = ps.executeQuery(); + rs.next(); + return rs.getInt(1); + } catch (SQLException e) { + throw new StorageException(e); + } } } diff --git a/test/ru/javaops/webapp/storage/ResumeTestData.java b/test/ru/javaops/webapp/storage/ResumeTestData.java index d301395a..fe092a9d 100644 --- a/test/ru/javaops/webapp/storage/ResumeTestData.java +++ b/test/ru/javaops/webapp/storage/ResumeTestData.java @@ -17,7 +17,7 @@ public static Resume getResume2() { return resume2; } - static { + /*static { resume1.addContact(ContactType.PHONE, "+71231231212"); resume1.addContact(ContactType.MOBILE_PHONE, "+79217340000"); resume1.addContact(ContactType.EMAIL, "name1@mail.ru"); @@ -81,5 +81,5 @@ public static Resume getResume2() { new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", null) ) )); - } + }*/ } diff --git a/test/ru/javaops/webapp/storage/SqlStorageTest.java b/test/ru/javaops/webapp/storage/SqlStorageTest.java new file mode 100644 index 00000000..eec1923c --- /dev/null +++ b/test/ru/javaops/webapp/storage/SqlStorageTest.java @@ -0,0 +1,12 @@ +package ru.javaops.webapp.storage; + +import ru.javaops.webapp.Config; + +import java.util.Properties; + +public class SqlStorageTest extends AbstractStorageTest { + public SqlStorageTest() { + //super(new SqlStorage(Config.getInstance().getStorageDir().toString(), "postgres", "postgres")); + super(new SqlStorage("jdbc:postgresql://localhost:5432/resumes", "postgres", "postgres")); + } +} From 334d878fb9a185e65d627f460b0c230b2bcfb716 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 26 Nov 2018 17:40:11 +0300 Subject: [PATCH 190/220] HW13, SqlStorage v3 for refactoring --- src/ru/javaops/webapp/storage/SqlStorage.java | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 9f9d90ab..5977d30f 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -1,5 +1,6 @@ package ru.javaops.webapp.storage; +import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; @@ -42,13 +43,15 @@ public Resume get(String uuid) { @Override public void update(Resume resume) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("UPDATE resume SET full_name = ? WHERE uuid = ?")) { - ps.setString(1, resume.getFullName()); - ps.setString(2, resume.getUuid()); - ps.executeUpdate(); - } catch (SQLException e) { - throw new StorageException(e); + if (get(resume.getUuid()).equals(resume)) { + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("UPDATE resume SET full_name = ? WHERE uuid = ?")) { + ps.setString(1, resume.getFullName()); + ps.setString(2, resume.getUuid()); + ps.executeUpdate(); + } catch (SQLException e) { + throw new StorageException(e); + } } } @@ -60,18 +63,20 @@ public void save(Resume resume) { ps.setString(2, resume.getFullName()); ps.execute(); } catch (SQLException e) { - throw new StorageException(e); + throw new ExistStorageException(resume.getUuid()); } } @Override public void delete(String uuid) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("DELETE FROM resume r WHERE r.uuid = ?")) { - ps.setString(1, uuid); - ps.executeUpdate(); - } catch (SQLException e) { - throw new StorageException(e); + if (get(uuid).getUuid().equals(uuid)) { + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("DELETE FROM resume r WHERE r.uuid = ?")) { + ps.setString(1, uuid); + ps.executeUpdate(); + } catch (SQLException e) { + throw new NotExistStorageException(uuid); + } } } From eb215e62ee02590204050649f23b79595b1992e4 Mon Sep 17 00:00:00 2001 From: Nikolai Dvinin Date: Tue, 27 Nov 2018 23:48:54 +0300 Subject: [PATCH 191/220] HW13, SqlHelper for implementation --- src/ru/javaops/webapp/Config.java | 9 ++++ src/ru/javaops/webapp/MainConcurrancy.java | 6 +-- src/ru/javaops/webapp/sql/SqlHelper.java | 5 ++ src/ru/javaops/webapp/storage/SqlStorage.java | 52 ++++++++++++------- .../webapp/storage/SqlStorageTest.java | 3 +- 5 files changed, 51 insertions(+), 24 deletions(-) create mode 100644 src/ru/javaops/webapp/sql/SqlHelper.java diff --git a/src/ru/javaops/webapp/Config.java b/src/ru/javaops/webapp/Config.java index 8e8ffc5f..0e82d9e4 100644 --- a/src/ru/javaops/webapp/Config.java +++ b/src/ru/javaops/webapp/Config.java @@ -1,5 +1,8 @@ package ru.javaops.webapp; +import ru.javaops.webapp.storage.IStorage; +import ru.javaops.webapp.storage.SqlStorage; + import java.io.*; import java.util.Properties; @@ -8,6 +11,7 @@ public class Config { private static final Config INSTANCE = new Config(); private File storageDir; + private IStorage storage; public static Config getInstance() { return INSTANCE; @@ -18,6 +22,7 @@ private Config() { Properties prop = new Properties(); prop.load(is); storageDir = new File(prop.getProperty("storage.dir")); + storage = new SqlStorage(prop.getProperty("db.url"), prop.getProperty("db.user"), prop.getProperty("db.password")); } catch (IOException e) { throw new IllegalStateException("Invalid config file " + PROPS.getAbsolutePath()); } @@ -26,4 +31,8 @@ private Config() { public File getStorageDir() { return storageDir; } + + public IStorage getStorage() { + return storage; + } } diff --git a/src/ru/javaops/webapp/MainConcurrancy.java b/src/ru/javaops/webapp/MainConcurrancy.java index 2a549c28..50b7fbd9 100644 --- a/src/ru/javaops/webapp/MainConcurrancy.java +++ b/src/ru/javaops/webapp/MainConcurrancy.java @@ -60,7 +60,7 @@ public void run() { //final Object lock2 = new Object(); final MainConcurrancy mainConcurancy = new MainConcurrancy(); - CountDownLatch latch = new CountDownLatch(THREADS_COUNT); + //CountDownLatch latch = new CountDownLatch(THREADS_COUNT); //Создать кол-во потоков равное кол-ву ядер на ПК/Сервере // ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); ExecutorService executorService = Executors.newCachedThreadPool(); @@ -73,7 +73,7 @@ public void run() { mainConcurancy.inc(); //System.out.println(threadLocal.get().format(new Date())); } - latch.countDown(); + //latch.countDown(); return 5; } }); @@ -108,7 +108,7 @@ public void run() { // e.printStackTrace(); // } // }); - latch.await(10, TimeUnit.SECONDS); + //latch.await(10, TimeUnit.SECONDS); executorService.shutdown(); //Thread.sleep(500); LazySingleton.getInstance(); diff --git a/src/ru/javaops/webapp/sql/SqlHelper.java b/src/ru/javaops/webapp/sql/SqlHelper.java new file mode 100644 index 00000000..847eb7bb --- /dev/null +++ b/src/ru/javaops/webapp/sql/SqlHelper.java @@ -0,0 +1,5 @@ +package ru.javaops.webapp.sql; + +public class SqlHelper { + +} diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 5977d30f..850eb0b9 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -7,6 +7,7 @@ import ru.javaops.webapp.sql.ConnectionFactory; import java.sql.*; +import java.util.ArrayList; import java.util.List; public class SqlStorage implements IStorage { @@ -18,8 +19,8 @@ public SqlStorage(String dbUrl, String dbUser, String dbPassword) { @Override public void clear() { - try(Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("DELETE FROM resume")){ + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("DELETE FROM resume")) { ps.execute(); } catch (SQLException e) { throw new StorageException(e); @@ -29,10 +30,10 @@ public void clear() { @Override public Resume get(String uuid) { try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r WHERE r.uuid = ?")) { + PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r WHERE r.uuid = ?")) { ps.setString(1, uuid); ResultSet rs = ps.executeQuery(); - if(!rs.next()) { + if (!rs.next()) { throw new NotExistStorageException(uuid); } return new Resume(uuid, rs.getString("full_name")); @@ -43,15 +44,16 @@ public Resume get(String uuid) { @Override public void update(Resume resume) { - if (get(resume.getUuid()).equals(resume)) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("UPDATE resume SET full_name = ? WHERE uuid = ?")) { - ps.setString(1, resume.getFullName()); - ps.setString(2, resume.getUuid()); - ps.executeUpdate(); - } catch (SQLException e) { - throw new StorageException(e); + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("UPDATE resume SET full_name = ? WHERE uuid = ?")) { + ps.setString(1, resume.getFullName()); + ps.setString(2, resume.getUuid()); + if (ps.executeUpdate() == 0) { + throw new NotExistStorageException(resume.getUuid()); } + } catch (SQLException e) { + throw new StorageException(e); + } } @@ -69,20 +71,32 @@ public void save(Resume resume) { @Override public void delete(String uuid) { - if (get(uuid).getUuid().equals(uuid)) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("DELETE FROM resume r WHERE r.uuid = ?")) { - ps.setString(1, uuid); - ps.executeUpdate(); - } catch (SQLException e) { + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("DELETE FROM resume r WHERE r.uuid = ?")) { + ps.setString(1, uuid); + if (ps.executeUpdate() == 0) { throw new NotExistStorageException(uuid); } + } catch (SQLException e) { + throw new StorageException(e); } } @Override public List getAllSorted() { - return null; + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement("SELECT uuid, full_name FROM resume ORDER BY uuid ASC ")) { + ResultSet rs = ps.executeQuery(); + List resumes = new ArrayList<>(); + while (rs.next()) { + String uuid = rs.getString(1).replaceAll("\\s", ""); + String fullName = rs.getString(2); + resumes.add(new Resume(uuid, fullName)); + } + return resumes; + } catch (SQLException e) { + throw new StorageException(e); + } } @Override diff --git a/test/ru/javaops/webapp/storage/SqlStorageTest.java b/test/ru/javaops/webapp/storage/SqlStorageTest.java index eec1923c..2a917ef0 100644 --- a/test/ru/javaops/webapp/storage/SqlStorageTest.java +++ b/test/ru/javaops/webapp/storage/SqlStorageTest.java @@ -6,7 +6,6 @@ public class SqlStorageTest extends AbstractStorageTest { public SqlStorageTest() { - //super(new SqlStorage(Config.getInstance().getStorageDir().toString(), "postgres", "postgres")); - super(new SqlStorage("jdbc:postgresql://localhost:5432/resumes", "postgres", "postgres")); + super(Config.getInstance().getStorage()); } } From 280e1a78d2cc8ee93ca406f1f0e33148f8e40288 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 29 Nov 2018 16:35:07 +0300 Subject: [PATCH 192/220] HW13, SqlHelper implementation, SqlStorage refactoring --- ...onFactory.java => IConnectionFactory.java} | 2 +- src/ru/javaops/webapp/sql/ISqlExecutor.java | 8 +++ src/ru/javaops/webapp/sql/SqlHelper.java | 23 +++++++ src/ru/javaops/webapp/storage/SqlStorage.java | 66 +++++++------------ 4 files changed, 56 insertions(+), 43 deletions(-) rename src/ru/javaops/webapp/sql/{ConnectionFactory.java => IConnectionFactory.java} (79%) create mode 100644 src/ru/javaops/webapp/sql/ISqlExecutor.java diff --git a/src/ru/javaops/webapp/sql/ConnectionFactory.java b/src/ru/javaops/webapp/sql/IConnectionFactory.java similarity index 79% rename from src/ru/javaops/webapp/sql/ConnectionFactory.java rename to src/ru/javaops/webapp/sql/IConnectionFactory.java index cf4bfdbf..45d77f34 100644 --- a/src/ru/javaops/webapp/sql/ConnectionFactory.java +++ b/src/ru/javaops/webapp/sql/IConnectionFactory.java @@ -3,6 +3,6 @@ import java.sql.Connection; import java.sql.SQLException; -public interface ConnectionFactory { +public interface IConnectionFactory { Connection getConnection() throws SQLException; } diff --git a/src/ru/javaops/webapp/sql/ISqlExecutor.java b/src/ru/javaops/webapp/sql/ISqlExecutor.java new file mode 100644 index 00000000..1fade9d9 --- /dev/null +++ b/src/ru/javaops/webapp/sql/ISqlExecutor.java @@ -0,0 +1,8 @@ +package ru.javaops.webapp.sql; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public interface ISqlExecutor { + T execute(PreparedStatement st) throws SQLException; +} diff --git a/src/ru/javaops/webapp/sql/SqlHelper.java b/src/ru/javaops/webapp/sql/SqlHelper.java index 847eb7bb..493bf03d 100644 --- a/src/ru/javaops/webapp/sql/SqlHelper.java +++ b/src/ru/javaops/webapp/sql/SqlHelper.java @@ -1,5 +1,28 @@ package ru.javaops.webapp.sql; +import ru.javaops.webapp.exception.StorageException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + public class SqlHelper { + private final IConnectionFactory connectionFactory; + + public SqlHelper(IConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + + public void execute(String sql) { + execute(sql, PreparedStatement::execute); + } + public T execute(String sql, ISqlExecutor executor) { + try (Connection conn = connectionFactory.getConnection(); + PreparedStatement ps = conn.prepareStatement(sql)) { + return executor.execute(ps); + } catch (SQLException e) { + throw new StorageException(e); + } + } } diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 850eb0b9..a2f32a09 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -2,90 +2,77 @@ import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; -import ru.javaops.webapp.exception.StorageException; import ru.javaops.webapp.model.Resume; -import ru.javaops.webapp.sql.ConnectionFactory; +import ru.javaops.webapp.sql.SqlHelper; import java.sql.*; import java.util.ArrayList; import java.util.List; public class SqlStorage implements IStorage { - private final ConnectionFactory connectionFactory; + private final SqlHelper sqlHelper; public SqlStorage(String dbUrl, String dbUser, String dbPassword) { - connectionFactory = () -> DriverManager.getConnection(dbUrl, dbUser, dbPassword); + sqlHelper = new SqlHelper(() -> DriverManager.getConnection(dbUrl, dbUser, dbPassword)); } @Override public void clear() { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("DELETE FROM resume")) { - ps.execute(); - } catch (SQLException e) { - throw new StorageException(e); - } + sqlHelper.execute("DELETE FROM resume"); } @Override public Resume get(String uuid) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r WHERE r.uuid = ?")) { + return sqlHelper.execute("SELECT * FROM resume r WHERE r.uuid = ?", (ps) -> { ps.setString(1, uuid); ResultSet rs = ps.executeQuery(); if (!rs.next()) { throw new NotExistStorageException(uuid); } return new Resume(uuid, rs.getString("full_name")); - } catch (SQLException e) { - throw new StorageException(e); - } + }); } @Override public void update(Resume resume) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("UPDATE resume SET full_name = ? WHERE uuid = ?")) { + sqlHelper.execute("UPDATE resume SET full_name = ? WHERE uuid = ?", (ps) -> { ps.setString(1, resume.getFullName()); ps.setString(2, resume.getUuid()); if (ps.executeUpdate() == 0) { throw new NotExistStorageException(resume.getUuid()); } - } catch (SQLException e) { - throw new StorageException(e); - - } + return null; + }); } @Override public void save(Resume resume) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("INSERT INTO resume (uuid, full_name) VALUES (?,?)")) { + sqlHelper.execute("INSERT INTO resume (uuid, full_name) VALUES (?,?)", (ps) -> { ps.setString(1, resume.getUuid()); ps.setString(2, resume.getFullName()); - ps.execute(); - } catch (SQLException e) { - throw new ExistStorageException(resume.getUuid()); - } + try { + ps.execute(); + } catch (SQLException e) { + throw new ExistStorageException(resume.getUuid()); + } + return null; + }); } @Override public void delete(String uuid) { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("DELETE FROM resume r WHERE r.uuid = ?")) { + sqlHelper.execute("DELETE FROM resume r WHERE r.uuid = ?", (ps) -> { ps.setString(1, uuid); if (ps.executeUpdate() == 0) { throw new NotExistStorageException(uuid); } - } catch (SQLException e) { - throw new StorageException(e); - } + return null; + }); } @Override public List getAllSorted() { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("SELECT uuid, full_name FROM resume ORDER BY uuid ASC ")) { + return sqlHelper.execute("SELECT uuid, full_name FROM resume ORDER BY uuid ASC ", (ps) -> { ResultSet rs = ps.executeQuery(); List resumes = new ArrayList<>(); while (rs.next()) { @@ -94,20 +81,15 @@ public List getAllSorted() { resumes.add(new Resume(uuid, fullName)); } return resumes; - } catch (SQLException e) { - throw new StorageException(e); - } + }); } @Override public int size() { - try (Connection conn = connectionFactory.getConnection(); - PreparedStatement ps = conn.prepareStatement("SELECT COUNT(*) FROM resume")) { + return sqlHelper.execute("SELECT COUNT(*) FROM resume", (ps) -> { ResultSet rs = ps.executeQuery(); rs.next(); return rs.getInt(1); - } catch (SQLException e) { - throw new StorageException(e); - } + }); } } From 9b03b6edd078135b77c5da2f128a4220cddeeb2c Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 29 Nov 2018 20:06:45 +0300 Subject: [PATCH 193/220] HW13, SqlStorage refactoring --- src/ru/javaops/webapp/Config.java | 4 ++-- src/ru/javaops/webapp/storage/SqlStorage.java | 17 +++++++---------- test/ru/javaops/webapp/storage/TestAll.java | 3 ++- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/ru/javaops/webapp/Config.java b/src/ru/javaops/webapp/Config.java index 0e82d9e4..362f33b4 100644 --- a/src/ru/javaops/webapp/Config.java +++ b/src/ru/javaops/webapp/Config.java @@ -10,8 +10,8 @@ public class Config { private final static File PROPS = new File("config/resumes.properties"); private static final Config INSTANCE = new Config(); - private File storageDir; - private IStorage storage; + private final File storageDir; + private final IStorage storage; public static Config getInstance() { return INSTANCE; diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index a2f32a09..4e5dc8e4 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -23,7 +23,7 @@ public void clear() { @Override public Resume get(String uuid) { - return sqlHelper.execute("SELECT * FROM resume r WHERE r.uuid = ?", (ps) -> { + return sqlHelper.execute("SELECT * FROM resume r WHERE r.uuid = ?", ps -> { ps.setString(1, uuid); ResultSet rs = ps.executeQuery(); if (!rs.next()) { @@ -35,7 +35,7 @@ public Resume get(String uuid) { @Override public void update(Resume resume) { - sqlHelper.execute("UPDATE resume SET full_name = ? WHERE uuid = ?", (ps) -> { + sqlHelper.execute("UPDATE resume SET full_name = ? WHERE uuid = ?", ps -> { ps.setString(1, resume.getFullName()); ps.setString(2, resume.getUuid()); if (ps.executeUpdate() == 0) { @@ -47,7 +47,7 @@ public void update(Resume resume) { @Override public void save(Resume resume) { - sqlHelper.execute("INSERT INTO resume (uuid, full_name) VALUES (?,?)", (ps) -> { + sqlHelper.execute("INSERT INTO resume (uuid, full_name) VALUES (?,?)", ps -> { ps.setString(1, resume.getUuid()); ps.setString(2, resume.getFullName()); try { @@ -61,7 +61,7 @@ public void save(Resume resume) { @Override public void delete(String uuid) { - sqlHelper.execute("DELETE FROM resume r WHERE r.uuid = ?", (ps) -> { + sqlHelper.execute("DELETE FROM resume r WHERE r.uuid = ?", ps -> { ps.setString(1, uuid); if (ps.executeUpdate() == 0) { throw new NotExistStorageException(uuid); @@ -72,13 +72,11 @@ public void delete(String uuid) { @Override public List getAllSorted() { - return sqlHelper.execute("SELECT uuid, full_name FROM resume ORDER BY uuid ASC ", (ps) -> { + return sqlHelper.execute("SELECT * FROM resume ORDER BY full_name, uuid ASC ", ps -> { ResultSet rs = ps.executeQuery(); List resumes = new ArrayList<>(); while (rs.next()) { - String uuid = rs.getString(1).replaceAll("\\s", ""); - String fullName = rs.getString(2); - resumes.add(new Resume(uuid, fullName)); + resumes.add(new Resume(rs.getString(1).replaceAll("\\s", ""), rs.getString(2))); } return resumes; }); @@ -88,8 +86,7 @@ public List getAllSorted() { public int size() { return sqlHelper.execute("SELECT COUNT(*) FROM resume", (ps) -> { ResultSet rs = ps.executeQuery(); - rs.next(); - return rs.getInt(1); + return rs.next() ? rs.getInt(1) : 0; }); } } diff --git a/test/ru/javaops/webapp/storage/TestAll.java b/test/ru/javaops/webapp/storage/TestAll.java index 81a32ee3..d3ce8b59 100644 --- a/test/ru/javaops/webapp/storage/TestAll.java +++ b/test/ru/javaops/webapp/storage/TestAll.java @@ -14,7 +14,8 @@ PathStorageTest.class, XmlPathStorageTest.class, JsonPathStorageTest.class, - DataPathStorageTest.class + DataPathStorageTest.class, + SqlStorageTest.class }) public class TestAll { } From b3f1dc13e765dc11438fa9be4b96487f894d85bb Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 29 Nov 2018 20:14:58 +0300 Subject: [PATCH 194/220] HW13, ExceptionUtil copy GKislin implementation --- src/ru/javaops/webapp/sql/ExceptionUtil.java | 23 +++++++++++++++++++ src/ru/javaops/webapp/sql/SqlHelper.java | 3 +-- src/ru/javaops/webapp/storage/SqlStorage.java | 7 +----- 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 src/ru/javaops/webapp/sql/ExceptionUtil.java diff --git a/src/ru/javaops/webapp/sql/ExceptionUtil.java b/src/ru/javaops/webapp/sql/ExceptionUtil.java new file mode 100644 index 00000000..facc37a7 --- /dev/null +++ b/src/ru/javaops/webapp/sql/ExceptionUtil.java @@ -0,0 +1,23 @@ +package ru.javaops.webapp.sql; + +import org.postgresql.util.PSQLException; +import ru.javaops.webapp.exception.ExistStorageException; +import ru.javaops.webapp.exception.StorageException; + +import java.sql.SQLException; + +public class ExceptionUtil { + private ExceptionUtil() { + } + + public static StorageException convertException(SQLException e) { + if (e instanceof PSQLException) { + +// http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html + if (e.getSQLState().equals("23505")) { + return new ExistStorageException(null); + } + } + return new StorageException(e); + } +} diff --git a/src/ru/javaops/webapp/sql/SqlHelper.java b/src/ru/javaops/webapp/sql/SqlHelper.java index 493bf03d..c75988d1 100644 --- a/src/ru/javaops/webapp/sql/SqlHelper.java +++ b/src/ru/javaops/webapp/sql/SqlHelper.java @@ -1,6 +1,5 @@ package ru.javaops.webapp.sql; -import ru.javaops.webapp.exception.StorageException; import java.sql.Connection; import java.sql.PreparedStatement; @@ -22,7 +21,7 @@ public T execute(String sql, ISqlExecutor executor) { PreparedStatement ps = conn.prepareStatement(sql)) { return executor.execute(ps); } catch (SQLException e) { - throw new StorageException(e); + throw ExceptionUtil.convertException(e); } } } diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 4e5dc8e4..26f598ef 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -1,6 +1,5 @@ package ru.javaops.webapp.storage; -import ru.javaops.webapp.exception.ExistStorageException; import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.sql.SqlHelper; @@ -50,11 +49,7 @@ public void save(Resume resume) { sqlHelper.execute("INSERT INTO resume (uuid, full_name) VALUES (?,?)", ps -> { ps.setString(1, resume.getUuid()); ps.setString(2, resume.getFullName()); - try { - ps.execute(); - } catch (SQLException e) { - throw new ExistStorageException(resume.getUuid()); - } + ps.execute(); return null; }); } From 106f297b997f0d4dd743ed6f728d9bb9b39801fd Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 29 Nov 2018 22:17:47 +0300 Subject: [PATCH 195/220] HW14, SqlStorage, get, update methods refactoring --- config/populate.sql | 4 +++ src/ru/javaops/webapp/storage/SqlStorage.java | 27 ++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 config/populate.sql diff --git a/config/populate.sql b/config/populate.sql new file mode 100644 index 00000000..6d8c9404 --- /dev/null +++ b/config/populate.sql @@ -0,0 +1,4 @@ +INSERT INTO resume (uuid, full_name) VALUES +('7de882da-02f2-4d16-8daa-60660aaf4071', 'Name1'), +('a97b3ac3-3817-4c3f-8a5f-178497311f1d', 'Name2'), +('dd0a70d1-5ed3-479a-b452-d5e04f21ca73', 'Name3'); \ No newline at end of file diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 26f598ef..5120b2dd 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -1,12 +1,14 @@ package ru.javaops.webapp.storage; import ru.javaops.webapp.exception.NotExistStorageException; +import ru.javaops.webapp.model.ContactType; import ru.javaops.webapp.model.Resume; import ru.javaops.webapp.sql.SqlHelper; import java.sql.*; import java.util.ArrayList; import java.util.List; +import java.util.Map; public class SqlStorage implements IStorage { private final SqlHelper sqlHelper; @@ -22,13 +24,23 @@ public void clear() { @Override public Resume get(String uuid) { - return sqlHelper.execute("SELECT * FROM resume r WHERE r.uuid = ?", ps -> { + return sqlHelper.execute("" + + " SELECT * FROM resume r " + + " LEFT JOIN contact c " + + " ON r.uuid = c.resume_uuid" + + " WHERE r.uuid = ?", ps -> { ps.setString(1, uuid); ResultSet rs = ps.executeQuery(); if (!rs.next()) { throw new NotExistStorageException(uuid); } - return new Resume(uuid, rs.getString("full_name")); + Resume resume = new Resume(uuid, rs.getString("full_name")); + do { + String value = rs.getString("value"); + ContactType contactType = ContactType.valueOf(rs.getString("type")); + resume.addContact(contactType, value); + } while (rs.next()); + return resume; }); } @@ -52,6 +64,15 @@ public void save(Resume resume) { ps.execute(); return null; }); + for (Map.Entry e : resume.getContacts().entrySet()) { + sqlHelper.execute("INSERT INTO contact (resume_uuid, type, value) VALUES (?,?,?)", ps -> { + ps.setString(1, resume.getUuid()); + ps.setString(2, e.getKey().name()); + ps.setString(3, e.getValue()); + ps.execute(); + return null; + }); + } } @Override @@ -71,7 +92,7 @@ public List getAllSorted() { ResultSet rs = ps.executeQuery(); List resumes = new ArrayList<>(); while (rs.next()) { - resumes.add(new Resume(rs.getString(1).replaceAll("\\s", ""), rs.getString(2))); + resumes.add(new Resume(rs.getString("uuid").replaceAll("\\s", ""), rs.getString("full_name"))); } return resumes; }); From 07ee85db0081dc93321d97a3d3de44e568b9a30f Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 1 Dec 2018 20:00:16 +0300 Subject: [PATCH 196/220] HW14, SqlStorage SQL transactions implementation, for refactoring --- .../javaops/webapp/sql/ISqlTransaction.java | 8 ++ src/ru/javaops/webapp/sql/SqlHelper.java | 18 ++++ src/ru/javaops/webapp/storage/SqlStorage.java | 101 ++++++++++++------ .../webapp/storage/ResumeTestData.java | 12 +-- 4 files changed, 100 insertions(+), 39 deletions(-) create mode 100644 src/ru/javaops/webapp/sql/ISqlTransaction.java diff --git a/src/ru/javaops/webapp/sql/ISqlTransaction.java b/src/ru/javaops/webapp/sql/ISqlTransaction.java new file mode 100644 index 00000000..9919fb09 --- /dev/null +++ b/src/ru/javaops/webapp/sql/ISqlTransaction.java @@ -0,0 +1,8 @@ +package ru.javaops.webapp.sql; + +import java.sql.Connection; +import java.sql.SQLException; + +public interface ISqlTransaction { + T execute(Connection conn) throws SQLException; +} diff --git a/src/ru/javaops/webapp/sql/SqlHelper.java b/src/ru/javaops/webapp/sql/SqlHelper.java index c75988d1..d5f49e3d 100644 --- a/src/ru/javaops/webapp/sql/SqlHelper.java +++ b/src/ru/javaops/webapp/sql/SqlHelper.java @@ -1,6 +1,8 @@ package ru.javaops.webapp.sql; +import ru.javaops.webapp.exception.StorageException; + import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -24,4 +26,20 @@ public T execute(String sql, ISqlExecutor executor) { throw ExceptionUtil.convertException(e); } } + + public T transactionalExecute(ISqlTransaction executor) { + try (Connection conn = connectionFactory.getConnection()) { + try { + conn.setAutoCommit(false); + T res = executor.execute(conn); + conn.commit(); + return res; + } catch (SQLException e) { + conn.rollback(); + throw ExceptionUtil.convertException(e); + } + } catch (SQLException e) { + throw new StorageException(e); + } + } } diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 5120b2dd..5281bbb4 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -25,54 +25,49 @@ public void clear() { @Override public Resume get(String uuid) { return sqlHelper.execute("" + - " SELECT * FROM resume r " + - " LEFT JOIN contact c " + - " ON r.uuid = c.resume_uuid" + - " WHERE r.uuid = ?", ps -> { + " SELECT * FROM resume r " + + " LEFT JOIN contact c " + + " ON r.uuid = c.resume_uuid" + + " WHERE r.uuid = ?", ps -> { ps.setString(1, uuid); ResultSet rs = ps.executeQuery(); if (!rs.next()) { throw new NotExistStorageException(uuid); } Resume resume = new Resume(uuid, rs.getString("full_name")); - do { - String value = rs.getString("value"); - ContactType contactType = ContactType.valueOf(rs.getString("type")); - resume.addContact(contactType, value); - } while (rs.next()); + addContacts(rs, resume); return resume; }); } @Override public void update(Resume resume) { - sqlHelper.execute("UPDATE resume SET full_name = ? WHERE uuid = ?", ps -> { - ps.setString(1, resume.getFullName()); - ps.setString(2, resume.getUuid()); - if (ps.executeUpdate() == 0) { - throw new NotExistStorageException(resume.getUuid()); + sqlHelper.transactionalExecute(conn -> { + try (PreparedStatement ps = conn.prepareStatement("UPDATE resume SET full_name = ? WHERE uuid = ?")) { + ps.setString(1, resume.getFullName()); + ps.setString(2, resume.getUuid()); + if (ps.executeUpdate() == 0) { + throw new NotExistStorageException(resume.getUuid()); + } } + deleteContacts(resume, conn); + saveContacts(resume, conn); return null; }); + } @Override public void save(Resume resume) { - sqlHelper.execute("INSERT INTO resume (uuid, full_name) VALUES (?,?)", ps -> { - ps.setString(1, resume.getUuid()); - ps.setString(2, resume.getFullName()); - ps.execute(); - return null; - }); - for (Map.Entry e : resume.getContacts().entrySet()) { - sqlHelper.execute("INSERT INTO contact (resume_uuid, type, value) VALUES (?,?,?)", ps -> { + sqlHelper.transactionalExecute(conn -> { + try (PreparedStatement ps = conn.prepareStatement("INSERT INTO resume (uuid, full_name) VALUES (?,?)")) { ps.setString(1, resume.getUuid()); - ps.setString(2, e.getKey().name()); - ps.setString(3, e.getValue()); + ps.setString(2, resume.getFullName()); ps.execute(); - return null; - }); - } + } + saveContacts(resume, conn); + return null; + }); } @Override @@ -88,13 +83,23 @@ public void delete(String uuid) { @Override public List getAllSorted() { - return sqlHelper.execute("SELECT * FROM resume ORDER BY full_name, uuid ASC ", ps -> { - ResultSet rs = ps.executeQuery(); - List resumes = new ArrayList<>(); - while (rs.next()) { - resumes.add(new Resume(rs.getString("uuid").replaceAll("\\s", ""), rs.getString("full_name"))); + return sqlHelper.transactionalExecute(conn -> { + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume ORDER BY full_name, uuid ASC ")) { + ResultSet rs = ps.executeQuery(); + List resumes = new ArrayList<>(); + while (rs.next()) { + Resume resume = new Resume(rs.getString("uuid").replaceAll("\\s", ""), rs.getString("full_name")); + try (PreparedStatement ps1 = conn.prepareStatement("SELECT * FROM contact c WHERE c.resume_uuid = ?")) { + ps1.setString(1, resume.getUuid()); + ResultSet rs1 = ps1.executeQuery(); + if (rs1.next()) { + addContacts(rs1, resume); + } + } + resumes.add(resume); + } + return resumes; } - return resumes; }); } @@ -105,4 +110,34 @@ public int size() { return rs.next() ? rs.getInt(1) : 0; }); } + + private void addContacts(ResultSet rs, Resume resume) throws SQLException { + do { + if (rs.getString("type") != null) { + String value = rs.getString("value"); + ContactType contactType = ContactType.valueOf(rs.getString("type")); + resume.addContact(contactType, value); + } + } while (rs.next()); + } + + private void saveContacts(Resume resume, Connection conn) throws SQLException { + try (PreparedStatement ps = conn.prepareStatement("INSERT INTO contact (resume_uuid, type, value) VALUES (?,?,?)")) { + for (Map.Entry e : resume.getContacts().entrySet()) { + ps.setString(1, resume.getUuid()); + ps.setString(2, e.getKey().name()); + ps.setString(3, e.getValue()); + ps.addBatch(); + } + ps.executeBatch(); + } + } + + private void deleteContacts(Resume resume, Connection conn) throws SQLException { + try (PreparedStatement ps = conn.prepareStatement("DELETE FROM contact c WHERE c.resume_uuid = ?")) { + ps.setString(1, resume.getUuid()); + ps.execute(); + } + } + } diff --git a/test/ru/javaops/webapp/storage/ResumeTestData.java b/test/ru/javaops/webapp/storage/ResumeTestData.java index fe092a9d..5593b2bb 100644 --- a/test/ru/javaops/webapp/storage/ResumeTestData.java +++ b/test/ru/javaops/webapp/storage/ResumeTestData.java @@ -17,7 +17,7 @@ public static Resume getResume2() { return resume2; } - /*static { + static { resume1.addContact(ContactType.PHONE, "+71231231212"); resume1.addContact(ContactType.MOBILE_PHONE, "+79217340000"); resume1.addContact(ContactType.EMAIL, "name1@mail.ru"); @@ -28,7 +28,7 @@ public static Resume getResume2() { resume1.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name1"); resume1.addContact(ContactType.HOME_PAGE, "homepage/name1"); - resume1.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); +/* resume1.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); resume1.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 1")); resume1.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); @@ -48,7 +48,7 @@ public static Resume getResume2() { new Organisation("Study 1", "urlStudy1", new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", "Was a student") ) - )); + ));*/ resume2.addContact(ContactType.PHONE, "+79999999999"); resume2.addContact(ContactType.MOBILE_PHONE, "+79119999991"); @@ -60,7 +60,7 @@ public static Resume getResume2() { resume2.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name2"); resume2.addContact(ContactType.HOME_PAGE, "homepage/name2"); - resume2.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 2")); + /*resume2.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 2")); resume2.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 2")); resume2.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); @@ -80,6 +80,6 @@ public static Resume getResume2() { new Organisation("Study 2", "urlStudy2", new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", null) ) - )); - }*/ + ));*/ + } } From 6a791ac895b6b32cd627cd3809a384658692bfcf Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 2 Dec 2018 17:07:14 +0300 Subject: [PATCH 197/220] HW14, SqlStorage SQL transactions implementation --- src/ru/javaops/webapp/storage/SqlStorage.java | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 5281bbb4..a9359325 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -7,6 +7,7 @@ import java.sql.*; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -35,7 +36,9 @@ public Resume get(String uuid) { throw new NotExistStorageException(uuid); } Resume resume = new Resume(uuid, rs.getString("full_name")); - addContacts(rs, resume); + do { + addContacts(rs, resume); + } while (rs.next()); return resume; }); } @@ -83,23 +86,23 @@ public void delete(String uuid) { @Override public List getAllSorted() { - return sqlHelper.transactionalExecute(conn -> { - try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume ORDER BY full_name, uuid ASC ")) { - ResultSet rs = ps.executeQuery(); - List resumes = new ArrayList<>(); - while (rs.next()) { - Resume resume = new Resume(rs.getString("uuid").replaceAll("\\s", ""), rs.getString("full_name")); - try (PreparedStatement ps1 = conn.prepareStatement("SELECT * FROM contact c WHERE c.resume_uuid = ?")) { - ps1.setString(1, resume.getUuid()); - ResultSet rs1 = ps1.executeQuery(); - if (rs1.next()) { - addContacts(rs1, resume); - } - } - resumes.add(resume); + return sqlHelper.execute(" SELECT * FROM resume " + + "LEFT JOIN contact " + + " ON resume.uuid = contact.resume_uuid " + + " ORDER BY full_name, uuid ASC", ps -> { + ResultSet rs = ps.executeQuery(); + Map resumes = new LinkedHashMap<>(); + while (rs.next()) { + String uuid = rs.getString("uuid").replaceAll("\\s", ""); + Resume resume = resumes.get(uuid); + if (resume == null) { + resume = new Resume(rs.getString("uuid").replaceAll("\\s", ""), rs.getString("full_name")); + resumes.put(uuid, resume); } - return resumes; + addContacts(rs, resume); + } + return new ArrayList<>(resumes.values()); }); } @@ -112,13 +115,11 @@ public int size() { } private void addContacts(ResultSet rs, Resume resume) throws SQLException { - do { - if (rs.getString("type") != null) { - String value = rs.getString("value"); - ContactType contactType = ContactType.valueOf(rs.getString("type")); - resume.addContact(contactType, value); - } - } while (rs.next()); + if (rs.getString("type") != null) { + String value = rs.getString("value"); + ContactType contactType = ContactType.valueOf(rs.getString("type")); + resume.addContact(contactType, value); + } } private void saveContacts(Resume resume, Connection conn) throws SQLException { From 4e76f241951d8bc95239a4f074e71fc76c082e1a Mon Sep 17 00:00:00 2001 From: nickbeam Date: Wed, 5 Dec 2018 14:03:06 +0300 Subject: [PATCH 198/220] HW14, SqlStorage refactoring Final --- src/ru/javaops/webapp/storage/SqlStorage.java | 21 +++++++++---------- .../webapp/storage/AbstractStorageTest.java | 5 ++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index a9359325..ace307bb 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -37,7 +37,7 @@ public Resume get(String uuid) { } Resume resume = new Resume(uuid, rs.getString("full_name")); do { - addContacts(rs, resume); + addContact(rs, resume); } while (rs.next()); return resume; }); @@ -54,7 +54,7 @@ public void update(Resume resume) { } } deleteContacts(resume, conn); - saveContacts(resume, conn); + insertContacts(resume, conn); return null; }); @@ -68,7 +68,7 @@ public void save(Resume resume) { ps.setString(2, resume.getFullName()); ps.execute(); } - saveContacts(resume, conn); + insertContacts(resume, conn); return null; }); } @@ -96,10 +96,10 @@ public List getAllSorted() { String uuid = rs.getString("uuid").replaceAll("\\s", ""); Resume resume = resumes.get(uuid); if (resume == null) { - resume = new Resume(rs.getString("uuid").replaceAll("\\s", ""), rs.getString("full_name")); + resume = new Resume(uuid, rs.getString("full_name")); resumes.put(uuid, resume); } - addContacts(rs, resume); + addContact(rs, resume); } return new ArrayList<>(resumes.values()); @@ -114,15 +114,14 @@ public int size() { }); } - private void addContacts(ResultSet rs, Resume resume) throws SQLException { - if (rs.getString("type") != null) { - String value = rs.getString("value"); - ContactType contactType = ContactType.valueOf(rs.getString("type")); - resume.addContact(contactType, value); + private void addContact(ResultSet rs, Resume resume) throws SQLException { + String value = rs.getString("value"); + if (rs.getString("value") != null) { + resume.addContact(ContactType.valueOf(rs.getString("type")), value); } } - private void saveContacts(Resume resume, Connection conn) throws SQLException { + private void insertContacts(Resume resume, Connection conn) throws SQLException { try (PreparedStatement ps = conn.prepareStatement("INSERT INTO contact (resume_uuid, type, value) VALUES (?,?,?)")) { for (Map.Entry e : resume.getContacts().entrySet()) { ps.setString(1, resume.getUuid()); diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 9c77beab..096204f9 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -53,12 +53,15 @@ public void getNotExist() { @Test public void getAllSorted() { List listStorage = storage.getAllSorted(); //Arrays.asList(resumes); - Assert.assertEquals(listStorage, Arrays.asList(resume1, resume2, resume3)); + Assert.assertEquals(Arrays.asList(resume1, resume2, resume3), listStorage); } @Test public void update() { Resume resume = storage.get(UUID_3); + resume3.addContact(ContactType.PHONE, "+79898989898"); + resume3.addContact(ContactType.MOBILE_PHONE, "+7555444554"); + resume3.addContact(ContactType.EMAIL, "name33@mail.ru"); storage.update(resume); compareSize(3); compareResume(resume); From 1bde85cf87fa182d9afd32763164dd20f89c6d19 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 5 Dec 2018 21:52:06 +0300 Subject: [PATCH 199/220] HW15, Web implementation --- web/META-INF/MANIFEST.MF | 2 ++ web/WEB-INF/web.xml | 6 ++++++ web/css/style.css | 13 +++++++++++++ web/index.html | 14 ++++++++++++++ web/test.html | 10 ++++++++++ 5 files changed, 45 insertions(+) create mode 100644 web/META-INF/MANIFEST.MF create mode 100644 web/WEB-INF/web.xml create mode 100644 web/css/style.css create mode 100644 web/index.html create mode 100644 web/test.html diff --git a/web/META-INF/MANIFEST.MF b/web/META-INF/MANIFEST.MF new file mode 100644 index 00000000..59499bce --- /dev/null +++ b/web/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml new file mode 100644 index 00000000..d80081d1 --- /dev/null +++ b/web/WEB-INF/web.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/web/css/style.css b/web/css/style.css new file mode 100644 index 00000000..672cdf5a --- /dev/null +++ b/web/css/style.css @@ -0,0 +1,13 @@ +header { + background: none repeat scroll 0 0 #A6C9E2; + color: #2E6E9E; + font-size: 20px; + padding: 5px 20px; +} + +footer { + background: none repeat scroll 0 0 #A6C9E2; + color: #2E6E9E; + font-size: 20px; + padding: 5px 20px; +} diff --git a/web/index.html b/web/index.html new file mode 100644 index 00000000..5ba20327 --- /dev/null +++ b/web/index.html @@ -0,0 +1,14 @@ + + + + + + Практика Java. Разработка Web приложения. + + +
This is Header
+

Приложение вебинара Практика Java. Разработка Web + приложения."

+
This is Footer
+ + \ No newline at end of file diff --git a/web/test.html b/web/test.html new file mode 100644 index 00000000..9830809c --- /dev/null +++ b/web/test.html @@ -0,0 +1,10 @@ + + + + + Title + + +Test + + \ No newline at end of file From 188169ef9fc175cb364f0f2b8b4d9c9ed9d6e1b2 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 6 Dec 2018 09:32:17 +0300 Subject: [PATCH 200/220] HW15, ResumeServlet implementation --- src/ru/javaops/webapp/web/ResumeServlet.java | 13 +++++++++++++ web/WEB-INF/web.xml | 9 +++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/ru/javaops/webapp/web/ResumeServlet.java diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java new file mode 100644 index 00000000..3e220991 --- /dev/null +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -0,0 +1,13 @@ +package ru.javaops.webapp.web; + +import java.io.IOException; + +public class ResumeServlet extends javax.servlet.http.HttpServlet { + protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { + + } + + protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { + + } +} diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml index d80081d1..0282a864 100644 --- a/web/WEB-INF/web.xml +++ b/web/WEB-INF/web.xml @@ -3,4 +3,13 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> + + + resumeServlet + ru.javaops.webapp.web.ResumeServlet + + + resumeServlet + /resume + \ No newline at end of file From 8930ad0391f6bbbb3efc83081282ca3779e4690d Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 6 Dec 2018 14:04:01 +0300 Subject: [PATCH 201/220] HW15, ResumeServlet refactoring --- src/ru/javaops/webapp/web/ResumeServlet.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 3e220991..757f7d0f 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -1,13 +1,22 @@ package ru.javaops.webapp.web; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.IOException; -public class ResumeServlet extends javax.servlet.http.HttpServlet { - protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { +public class ResumeServlet extends HttpServlet { + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } - protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { - + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String name = request.getParameter("name"); + if (name == null) { + response.getWriter().write("Hello Resumes!"); + } else { + response.getWriter().write("Hello " + name + "!"); + } } } From 692394e065a92cbecd0d6f42f0073ca9b73e3ed1 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 6 Dec 2018 21:43:28 +0300 Subject: [PATCH 202/220] HW15, ResumeServlet refactoring v2 --- src/ru/javaops/webapp/web/ResumeServlet.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 757f7d0f..02beee1d 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -12,11 +12,10 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + request.setCharacterEncoding("UTF-8"); + response.setCharacterEncoding("UTF-8"); + response.setContentType("text/html; charset=UTF-8"); String name = request.getParameter("name"); - if (name == null) { - response.getWriter().write("Hello Resumes!"); - } else { - response.getWriter().write("Hello " + name + "!"); - } + response.getWriter().write(name == null ? "Hello Resumes!" : "Hello " + name + "!"); } } From 6be7f4e0a2a45c519251a805b7a54f64b284276e Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 12 Dec 2018 21:44:39 +0300 Subject: [PATCH 203/220] HW15, SqlStorage insertSections method for refactoring --- config/init_db.sql | 18 ++++++ src/ru/javaops/webapp/storage/SqlStorage.java | 63 ++++++++++++------- .../webapp/storage/ResumeTestData.java | 8 +-- 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/config/init_db.sql b/config/init_db.sql index 6c78d342..19d8073a 100644 --- a/config/init_db.sql +++ b/config/init_db.sql @@ -27,3 +27,21 @@ alter table contact create unique index contact_uuid_type_index on contact (resume_uuid, type); +create table section +( + id serial not null + constraint section_pk + primary key, + type text not null, + value text not null, + resume_uuid char(36) not null + constraint section_resume_uuid_fk + references resume + on delete cascade +); + +alter table section owner to postgres; + +create unique index section_uuid_type_index + on section (resume_uuid, type); + diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index ace307bb..73f00af8 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -1,13 +1,12 @@ package ru.javaops.webapp.storage; import ru.javaops.webapp.exception.NotExistStorageException; -import ru.javaops.webapp.model.ContactType; -import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.model.*; import ru.javaops.webapp.sql.SqlHelper; import java.sql.*; import java.util.ArrayList; -import java.util.LinkedHashMap; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -36,9 +35,7 @@ public Resume get(String uuid) { throw new NotExistStorageException(uuid); } Resume resume = new Resume(uuid, rs.getString("full_name")); - do { - addContact(rs, resume); - } while (rs.next()); + addContacts(rs, resume); return resume; }); } @@ -69,6 +66,7 @@ public void save(Resume resume) { ps.execute(); } insertContacts(resume, conn); + insertSections(resume, conn); return null; }); } @@ -86,23 +84,27 @@ public void delete(String uuid) { @Override public List getAllSorted() { - return sqlHelper.execute(" SELECT * FROM resume " + - "LEFT JOIN contact " + - " ON resume.uuid = contact.resume_uuid " + - " ORDER BY full_name, uuid ASC", ps -> { - ResultSet rs = ps.executeQuery(); - Map resumes = new LinkedHashMap<>(); - while (rs.next()) { - String uuid = rs.getString("uuid").replaceAll("\\s", ""); - Resume resume = resumes.get(uuid); - if (resume == null) { - resume = new Resume(uuid, rs.getString("full_name")); - resumes.put(uuid, resume); + return sqlHelper.transactionalExecute(conn -> { + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume ORDER BY full_name, uuid ASC ")) { + ResultSet rs = ps.executeQuery(); + List resumes = new ArrayList<>(); + while (rs.next()) { + String uuid = rs.getString("uuid").replaceAll("\\s", ""); + String fullname = rs.getString("full_name"); + sqlHelper.execute("SELECT * FROM contact c WHERE c.resume_uuid = ?", ps1 -> { + ps1.setString(1, uuid); + ResultSet rs1 = ps1.executeQuery(); + if (!rs1.next()) { + throw new NotExistStorageException(uuid); + } + Resume resume = new Resume(uuid, fullname); + addContacts(rs1, resume); + resumes.add(resume); + return null; + }); } - addContact(rs, resume); - + return resumes; } - return new ArrayList<>(resumes.values()); }); } @@ -133,6 +135,25 @@ private void insertContacts(Resume resume, Connection conn) throws SQLException } } + private void insertSections(Resume resume, Connection conn) throws SQLException { + try (PreparedStatement ps = conn.prepareStatement("INSERT INTO section (resume_uuid, type, value) VALUES (?,?,?)")) { + for (Map.Entry e : resume.getSections().entrySet()) { + ps.setString(1, resume.getUuid()); + ps.setString(2, e.getKey().name()); + //ListSection list = new ListSection(String.valueOf(Arrays.asList(e.getValue()))); + ps.setString(3, String.valueOf(e.getValue())); + ps.addBatch(); + } + ps.executeBatch(); + } + } + + private void addContacts(ResultSet rs, Resume resume) throws SQLException { + do { + addContact(rs, resume); + } while (rs.next()); + } + private void deleteContacts(Resume resume, Connection conn) throws SQLException { try (PreparedStatement ps = conn.prepareStatement("DELETE FROM contact c WHERE c.resume_uuid = ?")) { ps.setString(1, resume.getUuid()); diff --git a/test/ru/javaops/webapp/storage/ResumeTestData.java b/test/ru/javaops/webapp/storage/ResumeTestData.java index 5593b2bb..50612395 100644 --- a/test/ru/javaops/webapp/storage/ResumeTestData.java +++ b/test/ru/javaops/webapp/storage/ResumeTestData.java @@ -28,13 +28,13 @@ public static Resume getResume2() { resume1.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name1"); resume1.addContact(ContactType.HOME_PAGE, "homepage/name1"); -/* resume1.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); + resume1.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); resume1.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 1")); resume1.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); - resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( +/* resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( new Organisation("Yandex", "yandex.ru", new Organisation.Position(2008, Month.MAY, "Синьйор", null) ), @@ -60,13 +60,13 @@ public static Resume getResume2() { resume2.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name2"); resume2.addContact(ContactType.HOME_PAGE, "homepage/name2"); - /*resume2.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 2")); + resume2.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 2")); resume2.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 2")); resume2.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); resume2.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); - resume2.addSection(SectionType.EXPERIENCE, new OrganisationSection( +/* resume2.addSection(SectionType.EXPERIENCE, new OrganisationSection( new Organisation("Google", "google.com", new Organisation.Position(2009, Month.MAY, "Старший уборщик", "Работаю старшим уборщиком") ), From 7998f8b9e5de25591f73af950560c1b0e8ec7f93 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 13 Dec 2018 17:46:09 +0300 Subject: [PATCH 204/220] HW15, SqlStorage for refactoring v2 --- src/ru/javaops/webapp/storage/SqlStorage.java | 86 ++++++++++++++----- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 73f00af8..3b829e9e 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -5,10 +5,7 @@ import ru.javaops.webapp.sql.SqlHelper; import java.sql.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; public class SqlStorage implements IStorage { private final SqlHelper sqlHelper; @@ -24,19 +21,25 @@ public void clear() { @Override public Resume get(String uuid) { - return sqlHelper.execute("" + - " SELECT * FROM resume r " + - " LEFT JOIN contact c " + - " ON r.uuid = c.resume_uuid" + - " WHERE r.uuid = ?", ps -> { - ps.setString(1, uuid); - ResultSet rs = ps.executeQuery(); - if (!rs.next()) { - throw new NotExistStorageException(uuid); + return sqlHelper.transactionalExecute(conn -> { + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r LEFT JOIN contact c on r.uuid = c.resume_uuid WHERE c.resume_uuid = ?")) { + ps.setString(1, uuid); + ResultSet rs = ps.executeQuery(); + if (!rs.next()) { + throw new NotExistStorageException(uuid); + } + Resume resume = new Resume(uuid, rs.getString("full_name")); + addContacts(rs, resume); + try (PreparedStatement ps1 = conn.prepareStatement("SELECT * FROM resume r LEFT JOIN section s on r.uuid = s.resume_uuid WHERE s.resume_uuid = ?")) { + ps1.setString(1, uuid); + ResultSet rs1 = ps1.executeQuery(); + if (!rs1.next()) { + throw new NotExistStorageException(uuid); + } + addSections(rs1, resume); + } + return resume; } - Resume resume = new Resume(uuid, rs.getString("full_name")); - addContacts(rs, resume); - return resume; }); } @@ -50,7 +53,7 @@ public void update(Resume resume) { throw new NotExistStorageException(resume.getUuid()); } } - deleteContacts(resume, conn); + deleteContactsAndSections(resume, conn); insertContacts(resume, conn); return null; }); @@ -123,6 +126,30 @@ private void addContact(ResultSet rs, Resume resume) throws SQLException { } } + private void addSection(ResultSet rs, Resume resume) throws SQLException { + if (rs.getString("value") != null) { + String type = rs.getString("type"); + String value = rs.getString("value"); + switch (SectionType.valueOf(type)) { + case PERSONAL: + case OBJECTIVE: + resume.addSection(SectionType.valueOf(type), new TextSection(value)); + break; + case ACHIEVEMENT: + case QUALIFICATIONS: + resume.addSection(SectionType.valueOf(type), new ListSection(Arrays.asList(value.split("\n")))); + break; + case EDUCATION: + break; + case EXPERIENCE: + break; + default: + //resume.addContact(ContactType.valueOf(rs.getString("type")), value); + break; + } + } + } + private void insertContacts(Resume resume, Connection conn) throws SQLException { try (PreparedStatement ps = conn.prepareStatement("INSERT INTO contact (resume_uuid, type, value) VALUES (?,?,?)")) { for (Map.Entry e : resume.getContacts().entrySet()) { @@ -136,12 +163,21 @@ private void insertContacts(Resume resume, Connection conn) throws SQLException } private void insertSections(Resume resume, Connection conn) throws SQLException { + List list; try (PreparedStatement ps = conn.prepareStatement("INSERT INTO section (resume_uuid, type, value) VALUES (?,?,?)")) { for (Map.Entry e : resume.getSections().entrySet()) { ps.setString(1, resume.getUuid()); ps.setString(2, e.getKey().name()); - //ListSection list = new ListSection(String.valueOf(Arrays.asList(e.getValue()))); - ps.setString(3, String.valueOf(e.getValue())); + if (e.getValue() instanceof TextSection) { + ps.setString(3, ((TextSection) e.getValue()).getText()); + } else { + list = ((ListSection) e.getValue()).getItems(); + final String[] string = {""}; + list.forEach((str) -> { + string[0] += str + "\n"; + }); + ps.setString(3, string[0]); + } ps.addBatch(); } ps.executeBatch(); @@ -154,11 +190,21 @@ private void addContacts(ResultSet rs, Resume resume) throws SQLException { } while (rs.next()); } - private void deleteContacts(Resume resume, Connection conn) throws SQLException { + private void addSections(ResultSet rs, Resume resume) throws SQLException { + do { + addSection(rs, resume); + } while (rs.next()); + } + + private void deleteContactsAndSections(Resume resume, Connection conn) throws SQLException { try (PreparedStatement ps = conn.prepareStatement("DELETE FROM contact c WHERE c.resume_uuid = ?")) { ps.setString(1, resume.getUuid()); ps.execute(); } + try (PreparedStatement ps = conn.prepareStatement("DELETE FROM section s WHERE s.resume_uuid = ?")) { + ps.setString(1, resume.getUuid()); + ps.execute(); + } } } From ca3012081363d8d6c8e95d18fea9150bd319a617 Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 16 Dec 2018 21:40:44 +0300 Subject: [PATCH 205/220] HW15, SqlStorage get method for refactoring --- src/ru/javaops/webapp/storage/SqlStorage.java | 29 +++++++------------ src/ru/javaops/webapp/web/ResumeServlet.java | 8 +++-- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 3b829e9e..abc083b0 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -22,21 +22,26 @@ public void clear() { @Override public Resume get(String uuid) { return sqlHelper.transactionalExecute(conn -> { - try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r LEFT JOIN contact c on r.uuid = c.resume_uuid WHERE c.resume_uuid = ?")) { + try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM resume r WHERE r.uuid = ?")) { ps.setString(1, uuid); ResultSet rs = ps.executeQuery(); if (!rs.next()) { throw new NotExistStorageException(uuid); } Resume resume = new Resume(uuid, rs.getString("full_name")); - addContacts(rs, resume); + try (PreparedStatement ps2 = conn.prepareStatement("SELECT * FROM resume r LEFT JOIN contact c on r.uuid = c.resume_uuid WHERE c.resume_uuid = ?")) { + ps2.setString(1, uuid); + ResultSet rs2 = ps2.executeQuery(); + if (rs2.next()) { + addContacts(rs2, resume); + } + } try (PreparedStatement ps1 = conn.prepareStatement("SELECT * FROM resume r LEFT JOIN section s on r.uuid = s.resume_uuid WHERE s.resume_uuid = ?")) { ps1.setString(1, uuid); ResultSet rs1 = ps1.executeQuery(); - if (!rs1.next()) { - throw new NotExistStorageException(uuid); + if (rs1.next()) { + addSections(rs1, resume); } - addSections(rs1, resume); } return resume; } @@ -93,18 +98,7 @@ public List getAllSorted() { List resumes = new ArrayList<>(); while (rs.next()) { String uuid = rs.getString("uuid").replaceAll("\\s", ""); - String fullname = rs.getString("full_name"); - sqlHelper.execute("SELECT * FROM contact c WHERE c.resume_uuid = ?", ps1 -> { - ps1.setString(1, uuid); - ResultSet rs1 = ps1.executeQuery(); - if (!rs1.next()) { - throw new NotExistStorageException(uuid); - } - Resume resume = new Resume(uuid, fullname); - addContacts(rs1, resume); - resumes.add(resume); - return null; - }); + resumes.add(get(uuid)); } return resumes; } @@ -144,7 +138,6 @@ private void addSection(ResultSet rs, Resume resume) throws SQLException { case EXPERIENCE: break; default: - //resume.addContact(ContactType.valueOf(rs.getString("type")), value); break; } } diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 02beee1d..b236fc5c 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -15,7 +15,11 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=UTF-8"); - String name = request.getParameter("name"); - response.getWriter().write(name == null ? "Hello Resumes!" : "Hello " + name + "!"); + String uuid = request.getParameter("uuid"); + if (uuid != null) { + response.getWriter().write("Get resume " + uuid + "!"); + } +// String name = request.getParameter("name"); +// response.getWriter().write(name == null ? "Hello Resumes!" : "Hello " + name + "!"); } } From 03801e4de7f80de05e869d8b5a6102e4790d06a0 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 18 Dec 2018 21:57:04 +0300 Subject: [PATCH 206/220] HW15, SqlStorage, ResumeServlet GK implementation --- src/ru/javaops/webapp/Config.java | 12 +++- src/ru/javaops/webapp/model/Resume.java | 40 +++++++----- src/ru/javaops/webapp/storage/SqlStorage.java | 65 ++++++++----------- src/ru/javaops/webapp/util/JsonParser.java | 8 +++ src/ru/javaops/webapp/web/ResumeServlet.java | 46 +++++++++++-- .../webapp/storage/ResumeTestData.java | 8 +-- 6 files changed, 115 insertions(+), 64 deletions(-) diff --git a/src/ru/javaops/webapp/Config.java b/src/ru/javaops/webapp/Config.java index 362f33b4..6692f133 100644 --- a/src/ru/javaops/webapp/Config.java +++ b/src/ru/javaops/webapp/Config.java @@ -1,5 +1,6 @@ package ru.javaops.webapp; +import ru.javaops.webapp.storage.FileStorage; import ru.javaops.webapp.storage.IStorage; import ru.javaops.webapp.storage.SqlStorage; @@ -7,7 +8,7 @@ import java.util.Properties; public class Config { - private final static File PROPS = new File("config/resumes.properties"); + private final static File PROPS = new File(getHomeDir(), "config/resumes.properties"); private static final Config INSTANCE = new Config(); private final File storageDir; @@ -35,4 +36,13 @@ public File getStorageDir() { public IStorage getStorage() { return storage; } + + private static File getHomeDir(){ + String prop = System.getProperty("homeDir"); + File homeDir = new File(prop == null? "." : prop); + if (!homeDir.isDirectory()){ + throw new IllegalStateException(homeDir + " is not directory."); + } + return homeDir; + } } diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 9b46b2db..9fbc5d41 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -33,22 +33,6 @@ public Resume(String uuid, String fullName){ this.fullName = fullName; } - public void addContact(ContactType type, String value) { - this.contacts.put(type, value); - } - - public void addSection(SectionType type, Section value) { - this.sections.put(type, value); - } - - public Map getContacts() { - return contacts; - } - - public Map getSections() { - return sections; - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -79,6 +63,30 @@ public String getFullName() { return fullName; } + public String getContact(ContactType type) { + return contacts.get(type); + } + + public Section getSection(SectionType type) { + return sections.get(type); + } + + public void addContact(ContactType type, String value) { + this.contacts.put(type, value); + } + + public void addSection(SectionType type, Section value) { + this.sections.put(type, value); + } + + public Map getContacts() { + return contacts; + } + + public Map getSections() { + return sections; + } + @Override public String toString() { return uuid + " (" + fullName + ")"; diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index abc083b0..0b2c36ff 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -3,6 +3,7 @@ import ru.javaops.webapp.exception.NotExistStorageException; import ru.javaops.webapp.model.*; import ru.javaops.webapp.sql.SqlHelper; +import ru.javaops.webapp.util.JsonParser; import java.sql.*; import java.util.*; @@ -11,6 +12,11 @@ public class SqlStorage implements IStorage { private final SqlHelper sqlHelper; public SqlStorage(String dbUrl, String dbUser, String dbPassword) { + try { + Class.forName("org.postgresql.Driver"); + } catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } sqlHelper = new SqlHelper(() -> DriverManager.getConnection(dbUrl, dbUser, dbPassword)); } @@ -37,8 +43,8 @@ public Resume get(String uuid) { } } try (PreparedStatement ps1 = conn.prepareStatement("SELECT * FROM resume r LEFT JOIN section s on r.uuid = s.resume_uuid WHERE s.resume_uuid = ?")) { - ps1.setString(1, uuid); - ResultSet rs1 = ps1.executeQuery(); + ps1.setString(1, uuid); + ResultSet rs1 = ps1.executeQuery(); if (rs1.next()) { addSections(rs1, resume); } @@ -58,8 +64,10 @@ public void update(Resume resume) { throw new NotExistStorageException(resume.getUuid()); } } - deleteContactsAndSections(resume, conn); + deleteContacts(resume, conn); + deleteSections(resume, conn); insertContacts(resume, conn); + insertSections(resume, conn); return null; }); @@ -121,25 +129,10 @@ private void addContact(ResultSet rs, Resume resume) throws SQLException { } private void addSection(ResultSet rs, Resume resume) throws SQLException { - if (rs.getString("value") != null) { - String type = rs.getString("type"); - String value = rs.getString("value"); - switch (SectionType.valueOf(type)) { - case PERSONAL: - case OBJECTIVE: - resume.addSection(SectionType.valueOf(type), new TextSection(value)); - break; - case ACHIEVEMENT: - case QUALIFICATIONS: - resume.addSection(SectionType.valueOf(type), new ListSection(Arrays.asList(value.split("\n")))); - break; - case EDUCATION: - break; - case EXPERIENCE: - break; - default: - break; - } + String value = rs.getString("value"); + if (value != null) { + SectionType type = SectionType.valueOf(rs.getString("type")); + resume.addSection(type, JsonParser.read(value, Section.class)); } } @@ -161,16 +154,8 @@ private void insertSections(Resume resume, Connection conn) throws SQLException for (Map.Entry e : resume.getSections().entrySet()) { ps.setString(1, resume.getUuid()); ps.setString(2, e.getKey().name()); - if (e.getValue() instanceof TextSection) { - ps.setString(3, ((TextSection) e.getValue()).getText()); - } else { - list = ((ListSection) e.getValue()).getItems(); - final String[] string = {""}; - list.forEach((str) -> { - string[0] += str + "\n"; - }); - ps.setString(3, string[0]); - } + Section section = e.getValue(); + ps.setString(3, JsonParser.write(section, Section.class)); ps.addBatch(); } ps.executeBatch(); @@ -189,12 +174,16 @@ private void addSections(ResultSet rs, Resume resume) throws SQLException { } while (rs.next()); } - private void deleteContactsAndSections(Resume resume, Connection conn) throws SQLException { - try (PreparedStatement ps = conn.prepareStatement("DELETE FROM contact c WHERE c.resume_uuid = ?")) { - ps.setString(1, resume.getUuid()); - ps.execute(); - } - try (PreparedStatement ps = conn.prepareStatement("DELETE FROM section s WHERE s.resume_uuid = ?")) { + private void deleteContacts(Resume resume, Connection conn) throws SQLException { + deleteAttributes(resume, conn, "DELETE FROM contact c WHERE c.resume_uuid = ?"); + } + + private void deleteSections(Resume resume, Connection conn) throws SQLException { + deleteAttributes(resume, conn, "DELETE FROM section s WHERE s.resume_uuid = ?"); + } + + private void deleteAttributes(Resume resume, Connection conn, String sql) throws SQLException { + try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, resume.getUuid()); ps.execute(); } diff --git a/src/ru/javaops/webapp/util/JsonParser.java b/src/ru/javaops/webapp/util/JsonParser.java index 1e40439f..22bf1e2b 100644 --- a/src/ru/javaops/webapp/util/JsonParser.java +++ b/src/ru/javaops/webapp/util/JsonParser.java @@ -16,7 +16,15 @@ public static T read(Reader reader, Class clazz) { return GSON.fromJson(reader, clazz); } + public static T read(String content, Class clazz) { + return GSON.fromJson(content, clazz); + } + public static void write(T object, Writer writer) { GSON.toJson(object, writer); } + + public static String write(T object, Class clazz) { + return GSON.toJson(object, clazz); + } } diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index b236fc5c..6b3c747c 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -1,12 +1,27 @@ package ru.javaops.webapp.web; +import ru.javaops.webapp.Config; +import ru.javaops.webapp.model.ContactType; +import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.storage.IStorage; + +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.io.Writer; public class ResumeServlet extends HttpServlet { + IStorage storage; + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + storage = Config.getInstance().getStorage(); + } + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } @@ -14,12 +29,33 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); +// response.setHeader("Content-Type", "text/html; charset=UTF-8"); response.setContentType("text/html; charset=UTF-8"); - String uuid = request.getParameter("uuid"); - if (uuid != null) { - response.getWriter().write("Get resume " + uuid + "!"); + Writer writer = response.getWriter(); + writer.write( + "\n" + + "\n" + + " \n" + + " \n" + + " Список всех резюме\n" + + "\n" + + "\n" + + "
\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n"); + for (Resume resume : storage.getAllSorted()) { + writer.write( + "\n" + + " \n" + + " \n" + + "\n"); } -// String name = request.getParameter("name"); -// response.getWriter().write(name == null ? "Hello Resumes!" : "Hello " + name + "!"); + writer.write("
ИмяEmail
" + resume.getFullName() + "" + resume.getContact(ContactType.EMAIL) + "
\n" + + "
\n" + + "\n" + + "\n"); } } diff --git a/test/ru/javaops/webapp/storage/ResumeTestData.java b/test/ru/javaops/webapp/storage/ResumeTestData.java index 50612395..d301395a 100644 --- a/test/ru/javaops/webapp/storage/ResumeTestData.java +++ b/test/ru/javaops/webapp/storage/ResumeTestData.java @@ -34,7 +34,7 @@ public static Resume getResume2() { resume1.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); -/* resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( + resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( new Organisation("Yandex", "yandex.ru", new Organisation.Position(2008, Month.MAY, "Синьйор", null) ), @@ -48,7 +48,7 @@ public static Resume getResume2() { new Organisation("Study 1", "urlStudy1", new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", "Was a student") ) - ));*/ + )); resume2.addContact(ContactType.PHONE, "+79999999999"); resume2.addContact(ContactType.MOBILE_PHONE, "+79119999991"); @@ -66,7 +66,7 @@ public static Resume getResume2() { resume2.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); resume2.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); -/* resume2.addSection(SectionType.EXPERIENCE, new OrganisationSection( + resume2.addSection(SectionType.EXPERIENCE, new OrganisationSection( new Organisation("Google", "google.com", new Organisation.Position(2009, Month.MAY, "Старший уборщик", "Работаю старшим уборщиком") ), @@ -80,6 +80,6 @@ public static Resume getResume2() { new Organisation("Study 2", "urlStudy2", new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", null) ) - ));*/ + )); } } From dcc6b6f99c0c83254931c4f28c5af4df96316bbd Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 19 Dec 2018 22:17:35 +0300 Subject: [PATCH 207/220] HW16, For implementation --- src/ru/javaops/webapp/model/ContactType.java | 51 +++++++++++-- src/ru/javaops/webapp/model/Resume.java | 5 ++ src/ru/javaops/webapp/web/ResumeServlet.java | 76 +++++++++++--------- web/WEB-INF/jsp/edit.jsp | 45 ++++++++++++ web/WEB-INF/jsp/fragments/footer.jsp | 12 ++++ web/WEB-INF/jsp/fragments/header.jsp | 10 +++ web/WEB-INF/jsp/list.jsp | 41 +++++++++++ web/WEB-INF/jsp/view.jsp | 31 ++++++++ web/css/style.css | 58 +++++++++++++++ web/index.html | 11 +-- 10 files changed, 293 insertions(+), 47 deletions(-) create mode 100644 web/WEB-INF/jsp/edit.jsp create mode 100644 web/WEB-INF/jsp/fragments/footer.jsp create mode 100644 web/WEB-INF/jsp/fragments/header.jsp create mode 100644 web/WEB-INF/jsp/list.jsp create mode 100644 web/WEB-INF/jsp/view.jsp diff --git a/src/ru/javaops/webapp/model/ContactType.java b/src/ru/javaops/webapp/model/ContactType.java index 80e11a09..5a9ba1f5 100644 --- a/src/ru/javaops/webapp/model/ContactType.java +++ b/src/ru/javaops/webapp/model/ContactType.java @@ -3,13 +3,38 @@ public enum ContactType { PHONE("Тел."), MOBILE_PHONE("Мобильный тел."), - EMAIL("E-mail"), + EMAIL("E-mail"){ + @Override + public String toHtml0(String value) { + return getTitle() + ": " + toLink("mailto:" + value, value); + } + }, TELEGRAM("Telegram"), - SKYPE("Skype"), - LINKEDIN("LinkedIn"), + SKYPE("Skype"){ + @Override + public String toHtml0(String value) { + return getTitle() + ": " + toLink("skype:" + value, value); + } + }, + LINKEDIN("LinkedIn"){ + @Override + public String toHtml0(String value) { + return toLink(value); + } + }, GITHUB("GitHub"), - STACKOVERFLOW("Stackoverflow"), - HOME_PAGE("Домашняя страница"); + STACKOVERFLOW("Stackoverflow"){ + @Override + public String toHtml0(String value) { + return toLink(value); + } + }, + HOME_PAGE("Домашняя страница"){ + @Override + public String toHtml0(String value) { + return toLink(value); + } + }; private String title; @@ -20,4 +45,20 @@ public enum ContactType { public String getTitle() { return title; } + + protected String toHtml0(String value) { + return title + ": " + value; + } + + public String toHtml(String value) { + return (value == null) ? "" : toHtml0(value); + } + + public String toLink(String href) { + return toLink(href, title); + } + + public static String toLink(String href, String title) { + return "" + title + ""; + } } diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 9fbc5d41..d6dda6ed 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -63,6 +63,10 @@ public String getFullName() { return fullName; } + public void setFullName(String fullName){ + this.fullName = fullName; + } + public String getContact(ContactType type) { return contacts.get(type); } @@ -91,4 +95,5 @@ public Map getSections() { public String toString() { return uuid + " (" + fullName + ")"; } + } diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 6b3c747c..a9ee286d 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -11,10 +11,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.io.Writer; public class ResumeServlet extends HttpServlet { - IStorage storage; + + private IStorage storage; @Override public void init(ServletConfig config) throws ServletException { @@ -22,40 +22,48 @@ public void init(ServletConfig config) throws ServletException { storage = Config.getInstance().getStorage(); } - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { + request.setCharacterEncoding("UTF-8"); + String uuid = request.getParameter("uuid"); + String fullName = request.getParameter("fullName"); + Resume r = storage.get(uuid); + r.setFullName(fullName); + for (ContactType type : ContactType.values()) { + String value = request.getParameter(type.name()); + if (value != null && value.trim().length() != 0) { + r.addContact(type, value); + } else { + r.getContacts().remove(type); + } + } + storage.update(r); + response.sendRedirect("resume"); } - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - request.setCharacterEncoding("UTF-8"); - response.setCharacterEncoding("UTF-8"); -// response.setHeader("Content-Type", "text/html; charset=UTF-8"); - response.setContentType("text/html; charset=UTF-8"); - Writer writer = response.getWriter(); - writer.write( - "\n" + - "\n" + - " \n" + - " \n" + - " Список всех резюме\n" + - "\n" + - "\n" + - "
\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n"); - for (Resume resume : storage.getAllSorted()) { - writer.write( - "\n" + - " \n" + - " \n" + - "\n"); + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { + String uuid = request.getParameter("uuid"); + String action = request.getParameter("action"); + if (action == null) { + request.setAttribute("resumes", storage.getAllSorted()); + request.getRequestDispatcher("/WEB-INF/jsp/list.jsp").forward(request, response); + return; + } + Resume r; + switch (action) { + case "delete": + storage.delete(uuid); + response.sendRedirect("resume"); + return; + case "view": + case "edit": + r = storage.get(uuid); + break; + default: + throw new IllegalArgumentException("Action " + action + " is illegal"); } - writer.write("
ИмяEmail
" + resume.getFullName() + "" + resume.getContact(ContactType.EMAIL) + "
\n" + - "
\n" + - "\n" + - "\n"); + request.setAttribute("resume", r); + request.getRequestDispatcher( + ("view".equals(action) ? "/WEB-INF/jsp/view.jsp" : "/WEB-INF/jsp/edit.jsp") + ).forward(request, response); } } diff --git a/web/WEB-INF/jsp/edit.jsp b/web/WEB-INF/jsp/edit.jsp new file mode 100644 index 00000000..0cb18036 --- /dev/null +++ b/web/WEB-INF/jsp/edit.jsp @@ -0,0 +1,45 @@ +<%-- + Created by IntelliJ IDEA. + User: nick + Date: 19.12.2018 + Time: 21:36 + To change this template use File | Settings | File Templates. +--%> +<%@ page import="ru.javaops.webapp.model.ContactType" %> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + Резюме ${resume.fullName} + + + +
+
+ +
+
Имя:
+
+
+

Контакты:

+ +
+
${type.title}
+
+
+
+

Секции:

+
+
+
+
+ + +
+
+ + + diff --git a/web/WEB-INF/jsp/fragments/footer.jsp b/web/WEB-INF/jsp/fragments/footer.jsp new file mode 100644 index 00000000..6de3697f --- /dev/null +++ b/web/WEB-INF/jsp/fragments/footer.jsp @@ -0,0 +1,12 @@ +<%-- + Created by IntelliJ IDEA. + User: nick + Date: 19.12.2018 + Time: 19:20 + To change this template use File | Settings | File Templates. +--%> +<%@page contentType="text/html" pageEncoding="UTF-8" %> +
+ diff --git a/web/WEB-INF/jsp/fragments/header.jsp b/web/WEB-INF/jsp/fragments/header.jsp new file mode 100644 index 00000000..218125b4 --- /dev/null +++ b/web/WEB-INF/jsp/fragments/header.jsp @@ -0,0 +1,10 @@ +<%-- + Created by IntelliJ IDEA. + User: nick + Date: 19.12.2018 + Time: 19:21 + To change this template use File | Settings | File Templates. +--%> +<%@page contentType="text/html" pageEncoding="UTF-8" %> +
Управление резюме
+
diff --git a/web/WEB-INF/jsp/list.jsp b/web/WEB-INF/jsp/list.jsp new file mode 100644 index 00000000..4ea9567d --- /dev/null +++ b/web/WEB-INF/jsp/list.jsp @@ -0,0 +1,41 @@ +<%-- + Created by IntelliJ IDEA. + User: nick + Date: 19.12.2018 + Time: 18:56 + To change this template use File | Settings | File Templates. +--%> +<%@ page import="ru.javaops.webapp.model.ContactType" %> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + Список всех резюме + + + +
+ + + + + + + + + + + + + + + + +
ИмяEmail
${resume.fullName}<%=ContactType.EMAIL.toHtml(resume.getContact(ContactType.EMAIL))%>
+
+ + + \ No newline at end of file diff --git a/web/WEB-INF/jsp/view.jsp b/web/WEB-INF/jsp/view.jsp new file mode 100644 index 00000000..235a9245 --- /dev/null +++ b/web/WEB-INF/jsp/view.jsp @@ -0,0 +1,31 @@ +<%-- + Created by IntelliJ IDEA. + User: nick + Date: 19.12.2018 + Time: 21:35 + To change this template use File | Settings | File Templates. +--%> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + Резюме ${resume.fullName} + + + +
+

${resume.fullName} 

+

+ + + <%=contactEntry.getKey().toHtml(contactEntry.getValue())%>
+
+

+

+ + + diff --git a/web/css/style.css b/web/css/style.css index 672cdf5a..90b58df8 100644 --- a/web/css/style.css +++ b/web/css/style.css @@ -1,8 +1,14 @@ +section { + width: 900px; + margin: auto; +} + header { background: none repeat scroll 0 0 #A6C9E2; color: #2E6E9E; font-size: 20px; padding: 5px 20px; + text-align: center; } footer { @@ -10,4 +16,56 @@ footer { color: #2E6E9E; font-size: 20px; padding: 5px 20px; + margin: 20px 0; + text-align: center; +} + +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; +} + +h2, h3 { + margin: 15px 0 5px; +} + +li { + margin: 15px 0; +} + +a[href^="skype:"] { + padding-left: 20px !important; + background: url(../img/skype.png) no-repeat center left; +} + +a[href^="mailto:"] { + padding-left: 20px !important; + background: url(../img/email.png) no-repeat center left; +} + +a[href^="https://stackoverflow.com"] { + padding-left: 20px !important; + background: url(../img/so.png) no-repeat center left; +} + +a[href^="https://www.linkedin.com"] { + padding-left: 20px !important; + background: url(../img/lin.png) no-repeat center left; +} + +a[href*="github."] { + padding-left: 20px !important; + background: url(../img/gh.png) no-repeat center left; +} \ No newline at end of file diff --git a/web/index.html b/web/index.html index 5ba20327..00a91dde 100644 --- a/web/index.html +++ b/web/index.html @@ -1,14 +1,9 @@ - - + - - Практика Java. Разработка Web приложения. + -
This is Header
-

Приложение вебинара Практика Java. Разработка Web - приложения."

-
This is Footer
+

Resume List

\ No newline at end of file From 79ac80d8a7bd59da20147b148845c26b3b1387e6 Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 16 Jan 2019 23:02:02 +0300 Subject: [PATCH 208/220] HW16, CRUD implementation for refactoring --- src/ru/javaops/webapp/web/ResumeServlet.java | 29 ++++++++++-- web/WEB-INF/jsp/add.jsp | 49 ++++++++++++++++++++ web/WEB-INF/jsp/edit.jsp | 11 +++-- web/WEB-INF/jsp/list.jsp | 7 +-- web/WEB-INF/jsp/view.jsp | 1 + 5 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 web/WEB-INF/jsp/add.jsp diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index a9ee286d..bbf5f684 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -1,8 +1,7 @@ package ru.javaops.webapp.web; import ru.javaops.webapp.Config; -import ru.javaops.webapp.model.ContactType; -import ru.javaops.webapp.model.Resume; +import ru.javaops.webapp.model.*; import ru.javaops.webapp.storage.IStorage; import javax.servlet.ServletConfig; @@ -25,9 +24,18 @@ public void init(ServletConfig config) throws ServletException { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { request.setCharacterEncoding("UTF-8"); String uuid = request.getParameter("uuid"); - String fullName = request.getParameter("fullName"); - Resume r = storage.get(uuid); - r.setFullName(fullName); + String fullName = request.getParameter("fullName").trim(); + Resume r; + if (uuid.equals("") && fullName.trim().equals("")) { + response.sendRedirect("resume"); + return; + } else if (uuid.equals("") && !fullName.equals("")) { + r = new Resume(fullName); + storage.save(r); + } else { + r = storage.get(uuid); + r.setFullName(fullName); + } for (ContactType type : ContactType.values()) { String value = request.getParameter(type.name()); if (value != null && value.trim().length() != 0) { @@ -36,6 +44,14 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) r.getContacts().remove(type); } } + for (SectionType type : SectionType.values()) { + String value = request.getParameter(type.name()); + if (value != null && value.trim().length() != 0) { + r.addSection(type, new TextSection(value)); + } else { + r.getSections().remove(type); + } + } storage.update(r); response.sendRedirect("resume"); } @@ -50,6 +66,9 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t } Resume r; switch (action) { + case "add": + request.getRequestDispatcher(("/WEB-INF/jsp/add.jsp")).forward(request, response); + return; case "delete": storage.delete(uuid); response.sendRedirect("resume"); diff --git a/web/WEB-INF/jsp/add.jsp b/web/WEB-INF/jsp/add.jsp new file mode 100644 index 00000000..c7ceaf4f --- /dev/null +++ b/web/WEB-INF/jsp/add.jsp @@ -0,0 +1,49 @@ +<%-- + Created by IntelliJ IDEA. + User: nick + Date: 19.12.2018 + Time: 21:36 + To change this template use File | Settings | File Templates. +--%> +<%@ page import="ru.javaops.webapp.model.ContactType" %> +<%@ page import="ru.javaops.webapp.model.SectionType" %> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + + + Новое резюме + + + +
+
+ +
+
Имя:
+
+
+

Контакты:

+ +
+
${type.title}
+
+
+
+

Секции:

+ +
+
${type.title}
+
+
+
+
+ + +
+
+ + + diff --git a/web/WEB-INF/jsp/edit.jsp b/web/WEB-INF/jsp/edit.jsp index 0cb18036..b4b7d328 100644 --- a/web/WEB-INF/jsp/edit.jsp +++ b/web/WEB-INF/jsp/edit.jsp @@ -6,11 +6,13 @@ To change this template use File | Settings | File Templates. --%> <%@ page import="ru.javaops.webapp.model.ContactType" %> +<%@ page import="ru.javaops.webapp.model.SectionType" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + Резюме ${resume.fullName} @@ -32,9 +34,12 @@

Секции:

-
-
-
+ +
+
${type.title}
+
+
+

diff --git a/web/WEB-INF/jsp/list.jsp b/web/WEB-INF/jsp/list.jsp index 4ea9567d..35cf4677 100644 --- a/web/WEB-INF/jsp/list.jsp +++ b/web/WEB-INF/jsp/list.jsp @@ -12,6 +12,7 @@ + Список всех резюме @@ -23,15 +24,15 @@ Имя Email - + Add ${resume.fullName} <%=ContactType.EMAIL.toHtml(resume.getContact(ContactType.EMAIL))%> - - + Delete + Edit diff --git a/web/WEB-INF/jsp/view.jsp b/web/WEB-INF/jsp/view.jsp index 235a9245..ce8a503f 100644 --- a/web/WEB-INF/jsp/view.jsp +++ b/web/WEB-INF/jsp/view.jsp @@ -10,6 +10,7 @@ + Резюме ${resume.fullName} From e144bd8f5274ab61072176cf2f260472727c4b80 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Thu, 17 Jan 2019 17:47:14 +0300 Subject: [PATCH 209/220] HW16, ContactType, SectionType, CSS - refactoring --- src/ru/javaops/webapp/model/ContactType.java | 20 +++++-- src/ru/javaops/webapp/model/SectionType.java | 58 ++++++++++++++++++-- web/WEB-INF/jsp/view.jsp | 8 +++ web/css/style.css | 11 +++- 4 files changed, 83 insertions(+), 14 deletions(-) diff --git a/src/ru/javaops/webapp/model/ContactType.java b/src/ru/javaops/webapp/model/ContactType.java index 5a9ba1f5..6d7a5627 100644 --- a/src/ru/javaops/webapp/model/ContactType.java +++ b/src/ru/javaops/webapp/model/ContactType.java @@ -9,7 +9,12 @@ public String toHtml0(String value) { return getTitle() + ": " + toLink("mailto:" + value, value); } }, - TELEGRAM("Telegram"), + TELEGRAM("Telegram"){ + @Override + public String toHtml0(String value) { + return getTitle() + ": " + toLink("tg://resolve?domain=" + value, value); + } + }, SKYPE("Skype"){ @Override public String toHtml0(String value) { @@ -19,20 +24,25 @@ public String toHtml0(String value) { LINKEDIN("LinkedIn"){ @Override public String toHtml0(String value) { - return toLink(value); + return getTitle() + ": " + toLink("https://linkedin.com/" + value, value); + } + }, + GITHUB("GitHub"){ + @Override + public String toHtml0(String value) { + return getTitle() + ": " + toLink("https://github.com/" + value, value); } }, - GITHUB("GitHub"), STACKOVERFLOW("Stackoverflow"){ @Override public String toHtml0(String value) { - return toLink(value); + return getTitle() + ": " + toLink("https://stackoverflow.com/" + value, value); } }, HOME_PAGE("Домашняя страница"){ @Override public String toHtml0(String value) { - return toLink(value); + return getTitle() + ": " + toLink("https://" + value, value); } }; diff --git a/src/ru/javaops/webapp/model/SectionType.java b/src/ru/javaops/webapp/model/SectionType.java index 6acf51da..426f027d 100644 --- a/src/ru/javaops/webapp/model/SectionType.java +++ b/src/ru/javaops/webapp/model/SectionType.java @@ -1,12 +1,42 @@ package ru.javaops.webapp.model; public enum SectionType { - PERSONAL("Личные качества"), - OBJECTIVE("Позиция"), - ACHIEVEMENT("Достижения"), - QUALIFICATIONS("Квалификация"), - EXPERIENCE("Опыт работы"), - EDUCATION("Образование"); + PERSONAL("Личные качества"){ + @Override + public String toHtml0(String value) { + return value; + } + }, + OBJECTIVE("Позиция"){ + @Override + public String toHtml0(String value) { + return value; + } + }, + ACHIEVEMENT("Достижения"){ + @Override + public String toHtml0(String value) { + return value; + } + }, + QUALIFICATIONS("Квалификация"){ + @Override + public String toHtml0(String value) { + return value; + } + }, + EXPERIENCE("Опыт работы"){ + @Override + public String toHtml0(String value) { + return value; + } + }, + EDUCATION("Образование"){ + @Override + public String toHtml0(String value) { + return value; + } + }; private String title; @@ -17,4 +47,20 @@ public enum SectionType { public String getTitle() { return title; } + + public String toHtml(String value) { + return (value == null) ? "" : toHtml0(value); + } + + public String toHtml(TextSection value) { + return (value == null) ? "" : toHtml0(value.getText()); + } + + public String toHtml(OrganisationSection value) { + return (value == null) ? "" : toHtml0(value.toString()); + } + + protected String toHtml0(String value) { + return title + ": " + value; + } } diff --git a/web/WEB-INF/jsp/view.jsp b/web/WEB-INF/jsp/view.jsp index ce8a503f..ee8eac60 100644 --- a/web/WEB-INF/jsp/view.jsp +++ b/web/WEB-INF/jsp/view.jsp @@ -5,6 +5,8 @@ Time: 21:35 To change this template use File | Settings | File Templates. --%> +<%@ page import="ru.javaops.webapp.model.SectionType" %> + <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> @@ -25,6 +27,12 @@ type="java.util.Map.Entry"/> <%=contactEntry.getKey().toHtml(contactEntry.getValue())%>
+ +
+
${type.title}
+
${resume.getSection(type)}
+
+

diff --git a/web/css/style.css b/web/css/style.css index 90b58df8..77850167 100644 --- a/web/css/style.css +++ b/web/css/style.css @@ -46,8 +46,13 @@ li { } a[href^="skype:"] { + padding-left: 20px !important; + background: url(../img/skype.png) no-repeat center left; +} + +a[href^="tg:"] { padding-left: 20px !important; - background: url(../img/skype.png) no-repeat center left; + background: url(../img/telegram.png) no-repeat center left; } a[href^="mailto:"] { @@ -60,12 +65,12 @@ a[href^="https://stackoverflow.com"] { background: url(../img/so.png) no-repeat center left; } -a[href^="https://www.linkedin.com"] { +a[href^="https://linkedin.com"] { padding-left: 20px !important; background: url(../img/lin.png) no-repeat center left; } -a[href*="github."] { +a[href*="https://github.com"] { padding-left: 20px !important; background: url(../img/gh.png) no-repeat center left; } \ No newline at end of file From 9b71124b1021db761de3ae9e3bc8bde5cc8b69d1 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 22 Jan 2019 17:46:53 +0300 Subject: [PATCH 210/220] HW16, model toString refactoring --- src/ru/javaops/webapp/model/ListSection.java | 7 ++++--- src/ru/javaops/webapp/model/Organisation.java | 16 ++++++++-------- .../webapp/model/OrganisationSection.java | 7 ++++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/ru/javaops/webapp/model/ListSection.java b/src/ru/javaops/webapp/model/ListSection.java index 76b3358d..5db0f2d3 100644 --- a/src/ru/javaops/webapp/model/ListSection.java +++ b/src/ru/javaops/webapp/model/ListSection.java @@ -40,8 +40,9 @@ public int hashCode() { @Override public String toString() { - return "ListSection{" + - "items=" + items + - '}'; + return items.toString(); +// return "ListSection{" + +// "items=" + items + +// '}'; } } diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 74ed1f00..038b5927 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -66,11 +66,12 @@ public int hashCode() { @Override public String toString() { - return "Organisation{" + - "name='" + name + '\'' + - ", url='" + url + '\'' + - ", positions=" + positions + - '}'; + return "Organisation: " + name + " (" + url + ", " + positions + ")"; +// return "Organisation{" + +// "name='" + name + '\'' + +// ", url='" + url + '\'' + +// ", positions=" + positions + +// '}'; } @XmlAccessorType(XmlAccessType.FIELD) @@ -138,12 +139,11 @@ public int hashCode() { @Override public String toString() { - return "Position{" + + return "Position: " + "startDate=" + startDate + ", endDate=" + endDate + ", head='" + head + '\'' + - ", description='" + description + '\'' + - '}'; + ", description='" + description + '\''; } } } diff --git a/src/ru/javaops/webapp/model/OrganisationSection.java b/src/ru/javaops/webapp/model/OrganisationSection.java index f6a69aee..a7c5efe1 100644 --- a/src/ru/javaops/webapp/model/OrganisationSection.java +++ b/src/ru/javaops/webapp/model/OrganisationSection.java @@ -40,8 +40,9 @@ public int hashCode() { @Override public String toString() { - return "OrganisationSection{" + - "organisations=" + organisations + - '}'; + return organisations.toString(); +// return "OrganisationSection{" + +// "organisations=" + organisations + +// '}'; } } From 4a546525618b2279fff3253c9699fdaf6a5aa11a Mon Sep 17 00:00:00 2001 From: nickbeam Date: Fri, 25 Jan 2019 17:26:08 +0300 Subject: [PATCH 211/220] HW16, view.jsp refactoring --- src/ru/javaops/webapp/util/DateUtil.java | 7 +++ src/ru/javaops/webapp/util/HtmlUtil.java | 15 +++++ web/WEB-INF/jsp/view.jsp | 77 ++++++++++++++++++++++-- 3 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 src/ru/javaops/webapp/util/HtmlUtil.java diff --git a/src/ru/javaops/webapp/util/DateUtil.java b/src/ru/javaops/webapp/util/DateUtil.java index af5c0352..a753f960 100644 --- a/src/ru/javaops/webapp/util/DateUtil.java +++ b/src/ru/javaops/webapp/util/DateUtil.java @@ -2,6 +2,7 @@ import java.time.LocalDate; import java.time.Month; +import java.time.format.DateTimeFormatter; public class DateUtil { public static LocalDate of(int year, Month month){ @@ -9,4 +10,10 @@ public static LocalDate of(int year, Month month){ } public static final LocalDate NOW = LocalDate.of(3000, 1, 1); + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("MM/yyyy"); + + public static String format(LocalDate date) { + if (date == null) return ""; + return date.equals(NOW) ? "Сейчас" : date.format(DATE_FORMATTER); + } } diff --git a/src/ru/javaops/webapp/util/HtmlUtil.java b/src/ru/javaops/webapp/util/HtmlUtil.java new file mode 100644 index 00000000..b85ff0f1 --- /dev/null +++ b/src/ru/javaops/webapp/util/HtmlUtil.java @@ -0,0 +1,15 @@ +package ru.javaops.webapp.util; + +import ru.javaops.webapp.model.Organisation; + +public class HtmlUtil { + + public static boolean isEmpty(String str) { + return str == null || str.trim().length() == 0; + } + + public static String formatDates(Organisation.Position position) { + return DateUtil.format(position.getStartDate()) + " - " + DateUtil.format(position.getEndDate()); + } + +} diff --git a/web/WEB-INF/jsp/view.jsp b/web/WEB-INF/jsp/view.jsp index ee8eac60..2e517f77 100644 --- a/web/WEB-INF/jsp/view.jsp +++ b/web/WEB-INF/jsp/view.jsp @@ -6,6 +6,10 @@ To change this template use File | Settings | File Templates. --%> <%@ page import="ru.javaops.webapp.model.SectionType" %> +<%@ page import="ru.javaops.webapp.model.ListSection" %> +<%@ page import="ru.javaops.webapp.model.TextSection" %> +<%@ page import="ru.javaops.webapp.model.OrganisationSection" %> +<%@ page import="ru.javaops.webapp.util.HtmlUtil" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> @@ -25,13 +29,74 @@ - <%=contactEntry.getKey().toHtml(contactEntry.getValue())%>
+ + + <%=contactEntry.getKey().toHtml(contactEntry.getValue())%>
+ +
- -

-
${type.title}
-
${resume.getSection(type)}
-
+ + + + + + + +

${type.title}

+ + + + + +

<%=((TextSection) section).getText()%>

+ + +
+ + + + <%=((TextSection) section).getText()%> + + + + + + +
    + +
  • ${item}
  • +
    +
+ + +
+ + + + + + +

${org.url}

+
+ +

${org.name}

+
+
+ + + + + + <%=HtmlUtil.formatDates(position)%> + + ${position.head}
${position.description} + +
+
+
+
+

From 82cb8fe343c57817ac302099a6bfc41bf72124aa Mon Sep 17 00:00:00 2001 From: nick Date: Sun, 27 Jan 2019 21:56:03 +0300 Subject: [PATCH 212/220] HW16, edit.jsp refactoring --- web/WEB-INF/jsp/edit.jsp | 41 +++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/web/WEB-INF/jsp/edit.jsp b/web/WEB-INF/jsp/edit.jsp index b4b7d328..9c09079a 100644 --- a/web/WEB-INF/jsp/edit.jsp +++ b/web/WEB-INF/jsp/edit.jsp @@ -5,8 +5,7 @@ Time: 21:36 To change this template use File | Settings | File Templates. --%> -<%@ page import="ru.javaops.webapp.model.ContactType" %> -<%@ page import="ru.javaops.webapp.model.SectionType" %> +<%@ page import="ru.javaops.webapp.model.*" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> @@ -34,11 +33,39 @@

Секции:

- -
-
${type.title}
-
-
+ <%----%> + <%--
--%> + <%--
${type.title}
--%> + <%--
--%> + <%--
--%> + <%--
--%> + + + + + +

${type.title}

+ + + + + + + + + + + + + + +

From 05543d25fe08880e0a87e2164f3cb59ffcb8a379 Mon Sep 17 00:00:00 2001 From: nickbeam Date: Mon, 28 Jan 2019 17:54:39 +0300 Subject: [PATCH 213/220] HW16, edit.jsp refactoring, not complete --- src/ru/javaops/webapp/web/ResumeServlet.java | 31 +++++++++++++++++- web/WEB-INF/jsp/edit.jsp | 34 ++++++++++++++------ web/css/style.css | 4 +++ 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index bbf5f684..88912cd1 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -47,7 +47,36 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) for (SectionType type : SectionType.values()) { String value = request.getParameter(type.name()); if (value != null && value.trim().length() != 0) { - r.addSection(type, new TextSection(value)); + switch (type) { + case PERSONAL: { + r.addSection(type, new TextSection(value)); + break; + } + case OBJECTIVE: { + r.addSection(type, new TextSection(value)); + break; + } + case ACHIEVEMENT: { + r.addSection(type, new ListSection(value)); + break; + } + case QUALIFICATIONS: { + r.addSection(type, new ListSection(value)); + break; + } + case EXPERIENCE: { + System.out.println("1"); + //r.addSection(type, new OrganisationSection(new Organisation(value))); + break; + } + case EDUCATION: { + break; + } + default: { + break; + } + } + } else { r.getSections().remove(type); } diff --git a/web/WEB-INF/jsp/edit.jsp b/web/WEB-INF/jsp/edit.jsp index 9c09079a..f342ff3b 100644 --- a/web/WEB-INF/jsp/edit.jsp +++ b/web/WEB-INF/jsp/edit.jsp @@ -6,6 +6,8 @@ To change this template use File | Settings | File Templates. --%> <%@ page import="ru.javaops.webapp.model.*" %> +<%@ page import="java.time.LocalDate" %> +<%@ page import="ru.javaops.webapp.util.DateUtil" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> @@ -48,21 +50,33 @@ - - - +

- - + +

${organisation.name}

+ + <%----%> + + + +
+ + + <%--
--%> +
diff --git a/web/css/style.css b/web/css/style.css index 77850167..2480db3b 100644 --- a/web/css/style.css +++ b/web/css/style.css @@ -41,6 +41,10 @@ h2, h3 { margin: 15px 0 5px; } +p { + line-height: 1.5; +} + li { margin: 15px 0; } From efb6719a9498caa7ea490cfaed194f1f181e6d68 Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 28 Jan 2019 22:23:26 +0300 Subject: [PATCH 214/220] HW16, edit.jsp refactoring 2 --- src/ru/javaops/webapp/web/ResumeServlet.java | 22 ++++++++------------ web/WEB-INF/jsp/edit.jsp | 15 ++++++++----- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 88912cd1..5ce43aa0 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.Map; public class ResumeServlet extends HttpServlet { @@ -48,28 +49,23 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) String value = request.getParameter(type.name()); if (value != null && value.trim().length() != 0) { switch (type) { - case PERSONAL: { - r.addSection(type, new TextSection(value)); - break; - } + case PERSONAL: case OBJECTIVE: { r.addSection(type, new TextSection(value)); break; } - case ACHIEVEMENT: { - r.addSection(type, new ListSection(value)); - break; - } + case ACHIEVEMENT: case QUALIFICATIONS: { r.addSection(type, new ListSection(value)); break; } - case EXPERIENCE: { - System.out.println("1"); - //r.addSection(type, new OrganisationSection(new Organisation(value))); - break; - } + case EXPERIENCE: case EDUCATION: { + Map requestParameterMap = request.getParameterMap(); + requestParameterMap.forEach((key, value1) -> { + System.out.println(key + value1); + }); + //r.addSection(type, new OrganisationSection(new Organisation())); break; } default: { diff --git a/web/WEB-INF/jsp/edit.jsp b/web/WEB-INF/jsp/edit.jsp index f342ff3b..c0787c23 100644 --- a/web/WEB-INF/jsp/edit.jsp +++ b/web/WEB-INF/jsp/edit.jsp @@ -61,20 +61,25 @@

${organisation.name}

+

Название организации:

+ +

Сайт организации:

+
+ - <%----%> + - -
- + <%--
--%>
From c2e98b8c396893e0f4e6448d4466231b2ac361f4 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 29 Jan 2019 22:48:45 +0300 Subject: [PATCH 215/220] HW16, add.jsp, edit.jsp, ResumeServlet.java, DateUtil.java refactoring --- src/ru/javaops/webapp/util/DateUtil.java | 4 + src/ru/javaops/webapp/web/ResumeServlet.java | 35 +++++-- web/WEB-INF/jsp/add.jsp | 105 ++++++++++++++++++- web/WEB-INF/jsp/edit.jsp | 66 ++++++------ 4 files changed, 164 insertions(+), 46 deletions(-) diff --git a/src/ru/javaops/webapp/util/DateUtil.java b/src/ru/javaops/webapp/util/DateUtil.java index a753f960..899326f8 100644 --- a/src/ru/javaops/webapp/util/DateUtil.java +++ b/src/ru/javaops/webapp/util/DateUtil.java @@ -16,4 +16,8 @@ public static String format(LocalDate date) { if (date == null) return ""; return date.equals(NOW) ? "Сейчас" : date.format(DATE_FORMATTER); } + + public static LocalDate parse(String date) { + return LocalDate.parse(date); + } } diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 5ce43aa0..4ba6629f 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -3,6 +3,8 @@ import ru.javaops.webapp.Config; import ru.javaops.webapp.model.*; import ru.javaops.webapp.storage.IStorage; +import ru.javaops.webapp.util.DateUtil; +import ru.javaops.webapp.util.HtmlUtil; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -10,7 +12,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; public class ResumeServlet extends HttpServlet { @@ -47,6 +50,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) } for (SectionType type : SectionType.values()) { String value = request.getParameter(type.name()); + String[] values = request.getParameterValues(type.name()); if (value != null && value.trim().length() != 0) { switch (type) { case PERSONAL: @@ -61,18 +65,29 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) } case EXPERIENCE: case EDUCATION: { - Map requestParameterMap = request.getParameterMap(); - requestParameterMap.forEach((key, value1) -> { - System.out.println(key + value1); - }); - //r.addSection(type, new OrganisationSection(new Organisation())); - break; - } - default: { + List orgs = new ArrayList<>(); + String[] urls = request.getParameterValues(type.name() + "url"); + for (int i = 0; i < values.length; i++) { + String name = values[i]; + if (!HtmlUtil.isEmpty(name)) { + List positions = new ArrayList<>(); + String pfx = type.name() + i; + String[] startDates = request.getParameterValues(pfx + "startDate"); + String[] endDates = request.getParameterValues(pfx + "endDate"); + String[] heads = request.getParameterValues(pfx + "head"); + String[] descriptions = request.getParameterValues(pfx + "description"); + for (int j = 0; j < heads.length; j++) { + if (!HtmlUtil.isEmpty(heads[j])) { + positions.add(new Organisation.Position(DateUtil.parse(startDates[j]), DateUtil.parse(endDates[j]), heads[j], descriptions[j])); + } + } + orgs.add(new Organisation(name, urls[i], positions)); + } + } + r.addSection(type, new OrganisationSection(orgs)); break; } } - } else { r.getSections().remove(type); } diff --git a/web/WEB-INF/jsp/add.jsp b/web/WEB-INF/jsp/add.jsp index c7ceaf4f..ee4ce0cf 100644 --- a/web/WEB-INF/jsp/add.jsp +++ b/web/WEB-INF/jsp/add.jsp @@ -7,6 +7,7 @@ --%> <%@ page import="ru.javaops.webapp.model.ContactType" %> <%@ page import="ru.javaops.webapp.model.SectionType" %> +<%@ page import="java.time.LocalDate" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> @@ -21,6 +22,7 @@
+
Имя:
@@ -32,13 +34,106 @@
-

Секции:

+ -
-
${type.title}
-
-
+ + +

Личные качества:

+
+ +
+
+ +

Позиция:

+
+ +
+
+ +

Достижения:

+
+ +
+
+ +

Квалификация:

+
+ +
+
+ +

Опыт работы

+
+
Название организации:
+
+
+ +
+
Сайт организации:
+
+
+ + <%----%> +
+
с:
+
+
+ +
+
по:
+
+
+ +
+
Должность:
+
+
+ +
+
Описание:
+

+
+
+ +

Образование

+
+
Название организации:
+
+
+ +
+
Сайт организации:
+
+
+ + <%----%> +
+
с:
+
+
+ +
+
по:
+
+
+ +
+
Должность:
+
+
+ +
+
Описание:
+

+
+
+
+
diff --git a/web/WEB-INF/jsp/edit.jsp b/web/WEB-INF/jsp/edit.jsp index c0787c23..5ab11601 100644 --- a/web/WEB-INF/jsp/edit.jsp +++ b/web/WEB-INF/jsp/edit.jsp @@ -34,13 +34,7 @@
-

Секции:

- <%----%> - <%--
--%> - <%--
${type.title}
--%> - <%--
--%> - <%--
--%> - <%--
--%> + @@ -49,38 +43,48 @@

${type.title}

- + -

+
-

${organisation.name}

-

Название организации:

- -

Сайт организации:

-
+
+
Название организации:
+
+
+ +
+
Сайт организации:
+
+
- - - -
- - - <%--
--%> +
+
с:
+
+
+ +
+
по:
+
+
+ +
+
Должность:
+
+
+ +
+
Описание:
+

+
From ae5d4e5a55aac61a8d9e513421786a88b8ca33bf Mon Sep 17 00:00:00 2001 From: nickbeam Date: Tue, 5 Feb 2019 16:53:39 +0300 Subject: [PATCH 216/220] HW16, view.jsp ResumeServlet refactoring, not complete --- src/ru/javaops/webapp/web/ResumeServlet.java | 2 +- web/WEB-INF/jsp/list.jsp | 2 +- web/WEB-INF/jsp/view.jsp | 124 +++++++++---------- 3 files changed, 63 insertions(+), 65 deletions(-) diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 4ba6629f..3c435be8 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -60,7 +60,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) } case ACHIEVEMENT: case QUALIFICATIONS: { - r.addSection(type, new ListSection(value)); + r.addSection(type, new ListSection(value.split("\\n"))); break; } case EXPERIENCE: diff --git a/web/WEB-INF/jsp/list.jsp b/web/WEB-INF/jsp/list.jsp index 35cf4677..3249d6f4 100644 --- a/web/WEB-INF/jsp/list.jsp +++ b/web/WEB-INF/jsp/list.jsp @@ -19,7 +19,7 @@
- +
diff --git a/web/WEB-INF/jsp/view.jsp b/web/WEB-INF/jsp/view.jsp index 2e517f77..432e5911 100644 --- a/web/WEB-INF/jsp/view.jsp +++ b/web/WEB-INF/jsp/view.jsp @@ -5,7 +5,6 @@ Time: 21:35 To change this template use File | Settings | File Templates. --%> -<%@ page import="ru.javaops.webapp.model.SectionType" %> <%@ page import="ru.javaops.webapp.model.ListSection" %> <%@ page import="ru.javaops.webapp.model.TextSection" %> <%@ page import="ru.javaops.webapp.model.OrganisationSection" %> @@ -29,74 +28,73 @@ - - - + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

From 80e0c2ca47eef6b68d838cd57954ea5af27393c7 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 5 Feb 2019 20:44:46 +0300 Subject: [PATCH 217/220] HW16, add.jsp, view.jsp refactoring --- web/WEB-INF/jsp/add.jsp | 2 +- web/WEB-INF/jsp/view.jsp | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/web/WEB-INF/jsp/add.jsp b/web/WEB-INF/jsp/add.jsp index ee4ce0cf..9a44644f 100644 --- a/web/WEB-INF/jsp/add.jsp +++ b/web/WEB-INF/jsp/add.jsp @@ -22,7 +22,7 @@

- +
Имя:
diff --git a/web/WEB-INF/jsp/view.jsp b/web/WEB-INF/jsp/view.jsp index 432e5911..b2c07b5d 100644 --- a/web/WEB-INF/jsp/view.jsp +++ b/web/WEB-INF/jsp/view.jsp @@ -86,16 +86,19 @@ +
Имя Email
- <%=contactEntry.getKey().toHtml(contactEntry.getValue())%>
-
+ <%=contactEntry.getKey().toHtml(contactEntry.getValue())%>
+

${type.title}

-

<%=((TextSection) section).getText()%>

-
- <%=((TextSection) section).getText()%> -
-
    - -
  • ${item}
  • -
    -
-
- - -

${org.url}

-
- -

${org.name}

-
-
-
<%=HtmlUtil.formatDates(position)%> - ${position.head}
${position.description}

${type.title}

+ <%=((TextSection) section).getText()%> +
+ <%=((TextSection) section).getText()%> +
+
    + +
  • ${item}
  • +
    +
+
+ + +

${org.url}

+
+ +

${org.name}

+
+
+
<%=HtmlUtil.formatDates(position)%> + ${position.head}
${position.description}
- - + - - - - - + + + +
<%=HtmlUtil.formatDates(position)%> - ${position.head}
${position.description}
<%=HtmlUtil.formatDates(position)%>${position.head}
${position.description}
+ + + + +

From 49c112c84eee157e7e7c9716c140b41e5f5dadb9 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 5 Feb 2019 23:16:41 +0300 Subject: [PATCH 218/220] HW16, Organisation, Resume, SectionType refactoring, not complete --- src/ru/javaops/webapp/model/Organisation.java | 10 ++ src/ru/javaops/webapp/model/Resume.java | 4 +- src/ru/javaops/webapp/model/SectionType.java | 4 +- src/ru/javaops/webapp/storage/SqlStorage.java | 4 +- .../serialize/DataStreamSerializer.java | 4 +- src/ru/javaops/webapp/web/ResumeServlet.java | 24 +++- .../webapp/storage/AbstractStorageTest.java | 6 +- .../webapp/storage/ResumeTestData.java | 60 ++++----- web/WEB-INF/jsp/view.jsp | 124 +++++++++--------- 9 files changed, 134 insertions(+), 106 deletions(-) diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 038b5927..1b5c9b22 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -19,6 +19,8 @@ public class Organisation implements Serializable { private static final long serialVersionUID = 1L; + public static final Organisation EMPTY = new Organisation("", "", Position.EMPTY); + private String name; private String url; private List positions; @@ -37,6 +39,12 @@ public Organisation(String name, String url, List positions){ this.positions = positions; } + public Organisation(String url, List positions){ + this.name = "Введите название организации"; + this.url = url == null ? "" : url; + this.positions = positions; + } + public String getName() { return name; } @@ -78,6 +86,8 @@ public String toString() { public static class Position implements Serializable { private static final long serialVersionUID = 1L; + public static final Position EMPTY = new Position(); + @XmlJavaTypeAdapter(LocalDateAdapter.class) private LocalDate startDate; @XmlJavaTypeAdapter(LocalDateAdapter.class) diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index d6dda6ed..49dad073 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -75,11 +75,11 @@ public Section getSection(SectionType type) { return sections.get(type); } - public void addContact(ContactType type, String value) { + public void setContact(ContactType type, String value) { this.contacts.put(type, value); } - public void addSection(SectionType type, Section value) { + public void setSection(SectionType type, Section value) { this.sections.put(type, value); } diff --git a/src/ru/javaops/webapp/model/SectionType.java b/src/ru/javaops/webapp/model/SectionType.java index 426f027d..9e790ee3 100644 --- a/src/ru/javaops/webapp/model/SectionType.java +++ b/src/ru/javaops/webapp/model/SectionType.java @@ -1,13 +1,13 @@ package ru.javaops.webapp.model; public enum SectionType { - PERSONAL("Личные качества"){ + OBJECTIVE("Позиция"){ @Override public String toHtml0(String value) { return value; } }, - OBJECTIVE("Позиция"){ + PERSONAL("Личные качества"){ @Override public String toHtml0(String value) { return value; diff --git a/src/ru/javaops/webapp/storage/SqlStorage.java b/src/ru/javaops/webapp/storage/SqlStorage.java index 0b2c36ff..521165c2 100644 --- a/src/ru/javaops/webapp/storage/SqlStorage.java +++ b/src/ru/javaops/webapp/storage/SqlStorage.java @@ -124,7 +124,7 @@ public int size() { private void addContact(ResultSet rs, Resume resume) throws SQLException { String value = rs.getString("value"); if (rs.getString("value") != null) { - resume.addContact(ContactType.valueOf(rs.getString("type")), value); + resume.setContact(ContactType.valueOf(rs.getString("type")), value); } } @@ -132,7 +132,7 @@ private void addSection(ResultSet rs, Resume resume) throws SQLException { String value = rs.getString("value"); if (value != null) { SectionType type = SectionType.valueOf(rs.getString("type")); - resume.addSection(type, JsonParser.read(value, Section.class)); + resume.setSection(type, JsonParser.read(value, Section.class)); } } diff --git a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java index 919e17d1..8d5b7890 100644 --- a/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java +++ b/src/ru/javaops/webapp/storage/serialize/DataStreamSerializer.java @@ -67,10 +67,10 @@ public Resume doRead(InputStream is) throws IOException { String uuid = dis.readUTF(); String fullName = dis.readUTF(); Resume resume = new Resume(uuid, fullName); - readCollection(dis, () -> resume.addContact(ContactType.valueOf(dis.readUTF()), dis.readUTF())); + readCollection(dis, () -> resume.setContact(ContactType.valueOf(dis.readUTF()), dis.readUTF())); readCollection(dis, () -> { SectionType currentSection = SectionType.valueOf(dis.readUTF()); - resume.addSection(currentSection, readSection(dis, currentSection)); + resume.setSection(currentSection, readSection(dis, currentSection)); }); return resume; } diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 3c435be8..9a6d2956 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -43,7 +43,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) for (ContactType type : ContactType.values()) { String value = request.getParameter(type.name()); if (value != null && value.trim().length() != 0) { - r.addContact(type, value); + r.setContact(type, value); } else { r.getContacts().remove(type); } @@ -55,12 +55,12 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) switch (type) { case PERSONAL: case OBJECTIVE: { - r.addSection(type, new TextSection(value)); + r.setSection(type, new TextSection(value)); break; } case ACHIEVEMENT: case QUALIFICATIONS: { - r.addSection(type, new ListSection(value.split("\\n"))); + r.setSection(type, new ListSection(value.split("\\n"))); break; } case EXPERIENCE: @@ -84,7 +84,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) orgs.add(new Organisation(name, urls[i], positions)); } } - r.addSection(type, new OrganisationSection(orgs)); + r.setSection(type, new OrganisationSection(orgs)); break; } } @@ -114,8 +114,24 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t response.sendRedirect("resume"); return; case "view": + r = storage.get(uuid); + break; case "edit": r = storage.get(uuid); + for (SectionType type : new SectionType[]{SectionType.EXPERIENCE, SectionType.EDUCATION}) { + OrganisationSection section = (OrganisationSection) r.getSection(type); + List emptyFirstOrganisations = new ArrayList<>(); + emptyFirstOrganisations.add(Organisation.EMPTY); + if (section != null) { + for (Organisation org : section.getOrganisations()) { + List emptyFirstPositions = new ArrayList<>(); + emptyFirstPositions.add(Organisation.Position.EMPTY); + emptyFirstPositions.addAll(org.getPositions()); + emptyFirstOrganisations.add(new Organisation(org.getUrl(), emptyFirstPositions)); + } + } + r.setSection(type, new OrganisationSection(emptyFirstOrganisations)); + } break; default: throw new IllegalArgumentException("Action " + action + " is illegal"); diff --git a/test/ru/javaops/webapp/storage/AbstractStorageTest.java b/test/ru/javaops/webapp/storage/AbstractStorageTest.java index 096204f9..42e313d7 100644 --- a/test/ru/javaops/webapp/storage/AbstractStorageTest.java +++ b/test/ru/javaops/webapp/storage/AbstractStorageTest.java @@ -59,9 +59,9 @@ public void getAllSorted() { @Test public void update() { Resume resume = storage.get(UUID_3); - resume3.addContact(ContactType.PHONE, "+79898989898"); - resume3.addContact(ContactType.MOBILE_PHONE, "+7555444554"); - resume3.addContact(ContactType.EMAIL, "name33@mail.ru"); + resume3.setContact(ContactType.PHONE, "+79898989898"); + resume3.setContact(ContactType.MOBILE_PHONE, "+7555444554"); + resume3.setContact(ContactType.EMAIL, "name33@mail.ru"); storage.update(resume); compareSize(3); compareResume(resume); diff --git a/test/ru/javaops/webapp/storage/ResumeTestData.java b/test/ru/javaops/webapp/storage/ResumeTestData.java index d301395a..6f45d3e3 100644 --- a/test/ru/javaops/webapp/storage/ResumeTestData.java +++ b/test/ru/javaops/webapp/storage/ResumeTestData.java @@ -18,23 +18,23 @@ public static Resume getResume2() { } static { - resume1.addContact(ContactType.PHONE, "+71231231212"); - resume1.addContact(ContactType.MOBILE_PHONE, "+79217340000"); - resume1.addContact(ContactType.EMAIL, "name1@mail.ru"); - resume1.addContact(ContactType.TELEGRAM, "telegram1"); - resume1.addContact(ContactType.SKYPE, "skype1"); - resume1.addContact(ContactType.LINKEDIN, "LinkedIn/name1"); - resume1.addContact(ContactType.GITHUB, "GitHub/name1"); - resume1.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name1"); - resume1.addContact(ContactType.HOME_PAGE, "homepage/name1"); + resume1.setContact(ContactType.PHONE, "+71231231212"); + resume1.setContact(ContactType.MOBILE_PHONE, "+79217340000"); + resume1.setContact(ContactType.EMAIL, "name1@mail.ru"); + resume1.setContact(ContactType.TELEGRAM, "telegram1"); + resume1.setContact(ContactType.SKYPE, "skype1"); + resume1.setContact(ContactType.LINKEDIN, "LinkedIn/name1"); + resume1.setContact(ContactType.GITHUB, "GitHub/name1"); + resume1.setContact(ContactType.STACKOVERFLOW, "Stackoverflow/name1"); + resume1.setContact(ContactType.HOME_PAGE, "homepage/name1"); - resume1.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); - resume1.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 1")); + resume1.setSection(SectionType.PERSONAL, new TextSection("Личные качества resume 1")); + resume1.setSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 1")); - resume1.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); - resume1.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); + resume1.setSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); + resume1.setSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); - resume1.addSection(SectionType.EXPERIENCE, new OrganisationSection( + resume1.setSection(SectionType.EXPERIENCE, new OrganisationSection( new Organisation("Yandex", "yandex.ru", new Organisation.Position(2008, Month.MAY, "Синьйор", null) ), @@ -44,29 +44,29 @@ public static Resume getResume2() { ) )); - resume1.addSection(SectionType.EDUCATION, new OrganisationSection( + resume1.setSection(SectionType.EDUCATION, new OrganisationSection( new Organisation("Study 1", "urlStudy1", new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", "Was a student") ) )); - resume2.addContact(ContactType.PHONE, "+79999999999"); - resume2.addContact(ContactType.MOBILE_PHONE, "+79119999991"); - resume2.addContact(ContactType.EMAIL, "name2@mail.ru"); - resume2.addContact(ContactType.TELEGRAM, "telegram2"); - resume2.addContact(ContactType.SKYPE, "skype2"); - resume2.addContact(ContactType.LINKEDIN, "LinkedIn/name2"); - resume2.addContact(ContactType.GITHUB, "GitHub/name2"); - resume2.addContact(ContactType.STACKOVERFLOW, "Stackoverflow/name2"); - resume2.addContact(ContactType.HOME_PAGE, "homepage/name2"); + resume2.setContact(ContactType.PHONE, "+79999999999"); + resume2.setContact(ContactType.MOBILE_PHONE, "+79119999991"); + resume2.setContact(ContactType.EMAIL, "name2@mail.ru"); + resume2.setContact(ContactType.TELEGRAM, "telegram2"); + resume2.setContact(ContactType.SKYPE, "skype2"); + resume2.setContact(ContactType.LINKEDIN, "LinkedIn/name2"); + resume2.setContact(ContactType.GITHUB, "GitHub/name2"); + resume2.setContact(ContactType.STACKOVERFLOW, "Stackoverflow/name2"); + resume2.setContact(ContactType.HOME_PAGE, "homepage/name2"); - resume2.addSection(SectionType.PERSONAL, new TextSection("Личные качества resume 2")); - resume2.addSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 2")); + resume2.setSection(SectionType.PERSONAL, new TextSection("Личные качества resume 2")); + resume2.setSection(SectionType.OBJECTIVE, new TextSection("Позиция для resume 2")); - resume2.addSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); - resume2.addSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); + resume2.setSection(SectionType.ACHIEVEMENT, new ListSection(Arrays.asList("achievment 1", "achievment 2", "achievment 3"))); + resume2.setSection(SectionType.QUALIFICATIONS, new ListSection(Arrays.asList("qualification 1", "qualification 2", "qualification 3"))); - resume2.addSection(SectionType.EXPERIENCE, new OrganisationSection( + resume2.setSection(SectionType.EXPERIENCE, new OrganisationSection( new Organisation("Google", "google.com", new Organisation.Position(2009, Month.MAY, "Старший уборщик", "Работаю старшим уборщиком") ), @@ -76,7 +76,7 @@ public static Resume getResume2() { ) )); - resume2.addSection(SectionType.EDUCATION, new OrganisationSection( + resume2.setSection(SectionType.EDUCATION, new OrganisationSection( new Organisation("Study 2", "urlStudy2", new Organisation.Position(2000, Month.SEPTEMBER, 2004, Month.JUNE, "Student", null) ) diff --git a/web/WEB-INF/jsp/view.jsp b/web/WEB-INF/jsp/view.jsp index b2c07b5d..518f05f2 100644 --- a/web/WEB-INF/jsp/view.jsp +++ b/web/WEB-INF/jsp/view.jsp @@ -25,14 +25,15 @@

${resume.fullName} 

+ - - - + + + @@ -41,64 +42,65 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - -
- <%=contactEntry.getKey().toHtml(contactEntry.getValue())%>
-
+ <%=contactEntry.getKey().toHtml(contactEntry.getValue())%>
+

${type.title}

- <%=((TextSection) section).getText()%> -
- <%=((TextSection) section).getText()%> -
-
    - -
  • ${item}
  • +

${type.title}

+ <%=((TextSection) section).getText()%> +
+ <%=((TextSection) section).getText()%> +
+
    + +
  • ${item}
  • +
    +
+
+ + +

${org.url}

+
+ +

${org.name}

+
+
+
<%=HtmlUtil.formatDates(position)%> + ${position.head}
${position.description}
- - -

${org.url}

-
- -

${org.name}

-
-
-
- - - - - - + + +
<%=HtmlUtil.formatDates(position)%>${position.head}
${position.description}
- - - - -

From 65921f32ce494019be0ede4bf215d71865fb432b Mon Sep 17 00:00:00 2001 From: nick Date: Wed, 6 Feb 2019 22:26:46 +0300 Subject: [PATCH 219/220] HW16, prepare to deploy heroku --- config/resumes.properties | 9 ++- src/ru/javaops/webapp/Config.java | 22 +++--- src/ru/javaops/webapp/model/ListSection.java | 2 + src/ru/javaops/webapp/model/Organisation.java | 6 -- src/ru/javaops/webapp/model/Resume.java | 11 +++ src/ru/javaops/webapp/model/TextSection.java | 2 + src/ru/javaops/webapp/web/ResumeServlet.java | 72 ++++++++++++------- web/WEB-INF/jsp/edit.jsp | 60 +++++++++------- web/WEB-INF/jsp/list.jsp | 2 +- web/css/style.css | 4 ++ 10 files changed, 117 insertions(+), 73 deletions(-) diff --git a/config/resumes.properties b/config/resumes.properties index b3cd9ba2..abeec497 100644 --- a/config/resumes.properties +++ b/config/resumes.properties @@ -1,4 +1,7 @@ storage.dir=storage -db.url=jdbc:postgresql://localhost:5432/resumes -db.user=postgres -db.password=postgres +db.url=jdbc:postgresql://ec2-79-125-6-250.eu-west-1.compute.amazonaws.com:5432/d76l4kfs5it914 +db.user=tqcuhhawowqmzx +db.password=a5d3358e731c4e8bc1b34ec5494213f866b088123429223e1c120d3309d986a5 +#db.url=jdbc:postgresql://localhost:5432/resumes +#db.user=postgres +#db.password=postgres diff --git a/src/ru/javaops/webapp/Config.java b/src/ru/javaops/webapp/Config.java index 6692f133..8c75b7b0 100644 --- a/src/ru/javaops/webapp/Config.java +++ b/src/ru/javaops/webapp/Config.java @@ -8,7 +8,7 @@ import java.util.Properties; public class Config { - private final static File PROPS = new File(getHomeDir(), "config/resumes.properties"); + private final static String PROPS = "/resumes.properties"; private static final Config INSTANCE = new Config(); private final File storageDir; @@ -19,13 +19,13 @@ public static Config getInstance() { } private Config() { - try (InputStream is = new FileInputStream(PROPS)) { + try (InputStream is = Config.class.getResourceAsStream(PROPS)) { Properties prop = new Properties(); prop.load(is); storageDir = new File(prop.getProperty("storage.dir")); storage = new SqlStorage(prop.getProperty("db.url"), prop.getProperty("db.user"), prop.getProperty("db.password")); } catch (IOException e) { - throw new IllegalStateException("Invalid config file " + PROPS.getAbsolutePath()); + throw new IllegalStateException("Invalid config file " + PROPS); } } @@ -37,12 +37,12 @@ public IStorage getStorage() { return storage; } - private static File getHomeDir(){ - String prop = System.getProperty("homeDir"); - File homeDir = new File(prop == null? "." : prop); - if (!homeDir.isDirectory()){ - throw new IllegalStateException(homeDir + " is not directory."); - } - return homeDir; - } +// private static File getHomeDir(){ +// String prop = System.getProperty("homeDir"); +// File homeDir = new File(prop == null? "." : prop); +// if (!homeDir.isDirectory()){ +// throw new IllegalStateException(homeDir + " is not directory."); +// } +// return homeDir; +// } } diff --git a/src/ru/javaops/webapp/model/ListSection.java b/src/ru/javaops/webapp/model/ListSection.java index 5db0f2d3..486aa90d 100644 --- a/src/ru/javaops/webapp/model/ListSection.java +++ b/src/ru/javaops/webapp/model/ListSection.java @@ -7,6 +7,8 @@ public class ListSection extends Section { private static final long serialVersionUID = 1L; + public static final ListSection EMPTY = new ListSection(""); + private List items; public ListSection() { diff --git a/src/ru/javaops/webapp/model/Organisation.java b/src/ru/javaops/webapp/model/Organisation.java index 1b5c9b22..9b6462da 100644 --- a/src/ru/javaops/webapp/model/Organisation.java +++ b/src/ru/javaops/webapp/model/Organisation.java @@ -39,12 +39,6 @@ public Organisation(String name, String url, List positions){ this.positions = positions; } - public Organisation(String url, List positions){ - this.name = "Введите название организации"; - this.url = url == null ? "" : url; - this.positions = positions; - } - public String getName() { return name; } diff --git a/src/ru/javaops/webapp/model/Resume.java b/src/ru/javaops/webapp/model/Resume.java index 49dad073..52fdd11d 100644 --- a/src/ru/javaops/webapp/model/Resume.java +++ b/src/ru/javaops/webapp/model/Resume.java @@ -11,6 +11,17 @@ public class Resume implements Comparable, Serializable { private static final long serialVersionUID = 1L; + public static final Resume EMPTY = new Resume(); + + static { + EMPTY.setSection(SectionType.OBJECTIVE, TextSection.EMPTY); + EMPTY.setSection(SectionType.PERSONAL, TextSection.EMPTY); + EMPTY.setSection(SectionType.ACHIEVEMENT, ListSection.EMPTY); + EMPTY.setSection(SectionType.QUALIFICATIONS, ListSection.EMPTY); + EMPTY.setSection(SectionType.EXPERIENCE, new OrganisationSection(Organisation.EMPTY)); + EMPTY.setSection(SectionType.EDUCATION, new OrganisationSection(Organisation.EMPTY)); + } + // Unique identifier private String uuid; diff --git a/src/ru/javaops/webapp/model/TextSection.java b/src/ru/javaops/webapp/model/TextSection.java index 28c3806c..d227f59d 100644 --- a/src/ru/javaops/webapp/model/TextSection.java +++ b/src/ru/javaops/webapp/model/TextSection.java @@ -5,6 +5,8 @@ public class TextSection extends Section { private static final long serialVersionUID = 1L; + public static final TextSection EMPTY = new TextSection(""); + private String text; public TextSection() { diff --git a/src/ru/javaops/webapp/web/ResumeServlet.java b/src/ru/javaops/webapp/web/ResumeServlet.java index 9a6d2956..befcc2b6 100644 --- a/src/ru/javaops/webapp/web/ResumeServlet.java +++ b/src/ru/javaops/webapp/web/ResumeServlet.java @@ -51,7 +51,10 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) for (SectionType type : SectionType.values()) { String value = request.getParameter(type.name()); String[] values = request.getParameterValues(type.name()); - if (value != null && value.trim().length() != 0) { + //if (value != null && value.trim().length() != 0) { + if (HtmlUtil.isEmpty(value) && values.length < 2) { + r.getSections().remove(type); + } else { switch (type) { case PERSONAL: case OBJECTIVE: { @@ -65,31 +68,29 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) } case EXPERIENCE: case EDUCATION: { - List orgs = new ArrayList<>(); + List organisations = new ArrayList<>(); String[] urls = request.getParameterValues(type.name() + "url"); for (int i = 0; i < values.length; i++) { String name = values[i]; if (!HtmlUtil.isEmpty(name)) { List positions = new ArrayList<>(); - String pfx = type.name() + i; - String[] startDates = request.getParameterValues(pfx + "startDate"); - String[] endDates = request.getParameterValues(pfx + "endDate"); - String[] heads = request.getParameterValues(pfx + "head"); - String[] descriptions = request.getParameterValues(pfx + "description"); + String prefix = type.name() + i; + String[] startDates = request.getParameterValues(prefix + "startDate"); + String[] endDates = request.getParameterValues(prefix + "endDate"); + String[] heads = request.getParameterValues(prefix + "head"); + String[] descriptions = request.getParameterValues(prefix + "description"); for (int j = 0; j < heads.length; j++) { if (!HtmlUtil.isEmpty(heads[j])) { positions.add(new Organisation.Position(DateUtil.parse(startDates[j]), DateUtil.parse(endDates[j]), heads[j], descriptions[j])); } } - orgs.add(new Organisation(name, urls[i], positions)); + organisations.add(new Organisation(name, urls[i], positions)); } } - r.setSection(type, new OrganisationSection(orgs)); + r.setSection(type, new OrganisationSection(organisations)); break; } } - } else { - r.getSections().remove(type); } } storage.update(r); @@ -107,8 +108,10 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t Resume r; switch (action) { case "add": - request.getRequestDispatcher(("/WEB-INF/jsp/add.jsp")).forward(request, response); - return; + r = Resume.EMPTY; + break; +// request.getRequestDispatcher(("/WEB-INF/jsp/add.jsp")).forward(request, response); +// return; case "delete": storage.delete(uuid); response.sendRedirect("resume"); @@ -118,19 +121,38 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t break; case "edit": r = storage.get(uuid); - for (SectionType type : new SectionType[]{SectionType.EXPERIENCE, SectionType.EDUCATION}) { - OrganisationSection section = (OrganisationSection) r.getSection(type); - List emptyFirstOrganisations = new ArrayList<>(); - emptyFirstOrganisations.add(Organisation.EMPTY); - if (section != null) { - for (Organisation org : section.getOrganisations()) { - List emptyFirstPositions = new ArrayList<>(); - emptyFirstPositions.add(Organisation.Position.EMPTY); - emptyFirstPositions.addAll(org.getPositions()); - emptyFirstOrganisations.add(new Organisation(org.getUrl(), emptyFirstPositions)); - } + for (SectionType type : SectionType.values()) { + Section section = r.getSection(type); + switch (type) { + case OBJECTIVE: + case PERSONAL: + if (section == null) { + section = TextSection.EMPTY; + } + break; + case ACHIEVEMENT: + case QUALIFICATIONS: + if (section == null) { + section = ListSection.EMPTY; + } + break; + case EXPERIENCE: + case EDUCATION: + OrganisationSection orgSection = (OrganisationSection) section; + List emptyFirstOrganisations = new ArrayList<>(); + emptyFirstOrganisations.add(Organisation.EMPTY); + if (orgSection != null) { + for (Organisation organisation : orgSection.getOrganisations()) { + List emptyFirstPositions = new ArrayList<>(); + emptyFirstPositions.add(Organisation.Position.EMPTY); + emptyFirstPositions.addAll(organisation.getPositions()); + emptyFirstOrganisations.add(new Organisation(organisation.getName(), organisation.getUrl(), emptyFirstPositions)); + } + } + section = new OrganisationSection(emptyFirstOrganisations); + break; } - r.setSection(type, new OrganisationSection(emptyFirstOrganisations)); + r.setSection(type, section); } break; default: diff --git a/web/WEB-INF/jsp/edit.jsp b/web/WEB-INF/jsp/edit.jsp index 5ab11601..1dd750c6 100644 --- a/web/WEB-INF/jsp/edit.jsp +++ b/web/WEB-INF/jsp/edit.jsp @@ -36,7 +36,8 @@
- + @@ -46,10 +47,12 @@ - + - +
Название организации:
@@ -59,33 +62,36 @@
Сайт организации:
+
+ + +
+
с:
+
+
- - -
-
с:
-
-
+
+
по:
+
+
-
-
по:
-
-
+
+
Должность:
+
+
-
-
Должность:
-
-
- -
-
Описание:
-

-
-
+
+
Описание:
+

+
+
+
diff --git a/web/WEB-INF/jsp/list.jsp b/web/WEB-INF/jsp/list.jsp index 3249d6f4..b56532b6 100644 --- a/web/WEB-INF/jsp/list.jsp +++ b/web/WEB-INF/jsp/list.jsp @@ -24,7 +24,7 @@ Имя Email - Add + Add diff --git a/web/css/style.css b/web/css/style.css index 2480db3b..8bf09534 100644 --- a/web/css/style.css +++ b/web/css/style.css @@ -37,6 +37,10 @@ dd { vertical-align: top; } +.positions { + margin-left: 10%; +} + h2, h3 { margin: 15px 0 5px; } From bf7f0b6e4840cc5a001f37f6be00fcbb1616bb36 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 25 Feb 2021 22:43:53 +0300 Subject: [PATCH 220/220] Refactoring README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e288257e..e001b4da 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Разработка Web приложения "База данных резюме" - используем: Java 8, IntelliJ IDEA, - GitHib/Git, Сервлеты, JSP, JSTL, Tomcat, JUnit, PostgreSQL, GSON, JAXB + GitHub/Git, Сервлеты, JSP, JSTL, Tomcat, JUnit, PostgreSQL, GSON, JAXB - хранение резюме - в памяти на основе массива, отсортированного массива, списка и ассоциированного массива (Map) - в файловой системе (File API и Java 7 NIO File API)