diff --git a/.idea/libraries/gson_2_8_2.xml b/.idea/libraries/gson_2_8_2.xml
new file mode 100644
index 0000000..4b09acc
--- /dev/null
+++ b/.idea/libraries/gson_2_8_2.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/csvTaskFile.csv b/csvTaskFile.csv
new file mode 100644
index 0000000..97fdc8e
--- /dev/null
+++ b/csvTaskFile.csv
@@ -0,0 +1,5 @@
+id,type,name,status,description,epic
+1,Task,1,NEW,Task1
+2,Task,2,NEW,Task2
+3,Epic,3,NEW,Epic1
+4,SubTask,6,NEW,Sub 1,3
diff --git a/java-kanban.iml b/java-kanban.iml
index bc0c38b..45d53d1 100644
--- a/java-kanban.iml
+++ b/java-kanban.iml
@@ -71,5 +71,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/adapters/EpicAdapter.java b/src/adapters/EpicAdapter.java
new file mode 100644
index 0000000..b70874e
--- /dev/null
+++ b/src/adapters/EpicAdapter.java
@@ -0,0 +1,45 @@
+package adapters;
+
+import com.google.gson.*;
+import model.Epic;
+import model.Status;
+
+import java.lang.reflect.Type;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class EpicAdapter implements JsonSerializer, JsonDeserializer {
+
+ private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
+
+ @Override
+ public JsonElement serialize(Epic task, Type typeOfSrc, JsonSerializationContext context) {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("id", task.getId());
+ jsonObject.addProperty("taskName", task.getTaskName());
+ jsonObject.addProperty("status", task.getStatus().name());
+ jsonObject.addProperty("content", task.getContent());
+ jsonObject.addProperty("startTime", task.getStartTime().format(formatter));
+ jsonObject.addProperty("duration", task.getDuration().toMinutes());
+ jsonObject.addProperty("epicSubs", task.getEpicSubs().toString());
+
+ return jsonObject;
+ }
+
+ @Override
+ public Epic deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ JsonObject jsonObject = json.getAsJsonObject();
+
+ Integer id = jsonObject.get("id").getAsInt();
+ String taskName = jsonObject.get("taskName").getAsString();
+ Status status = Status.valueOf(jsonObject.get("status").getAsString());
+ String content = jsonObject.get("content").getAsString();
+
+ LocalDateTime startTime = LocalDateTime.parse(jsonObject.get("startTime").getAsString(), formatter);
+
+ Duration duration = Duration.ofMinutes(jsonObject.get("duration").getAsLong());
+
+ return new Epic(taskName, content, status, id, startTime, duration);
+ }
+}
diff --git a/src/adapters/SubTaskAdapter.java b/src/adapters/SubTaskAdapter.java
new file mode 100644
index 0000000..e57aa96
--- /dev/null
+++ b/src/adapters/SubTaskAdapter.java
@@ -0,0 +1,46 @@
+package adapters;
+
+import com.google.gson.*;
+import model.SubTask;
+import model.Status;
+
+import java.lang.reflect.Type;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class SubTaskAdapter implements JsonSerializer, JsonDeserializer {
+
+ private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
+
+ @Override
+ public JsonElement serialize(SubTask task, Type typeOfSrc, JsonSerializationContext context) {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("id", task.getId());
+ jsonObject.addProperty("taskName", task.getTaskName());
+ jsonObject.addProperty("status", task.getStatus().name());
+ jsonObject.addProperty("content", task.getContent());
+ jsonObject.addProperty("startTime", task.getStartTime().format(formatter));
+ jsonObject.addProperty("duration", task.getDuration().toMinutes());
+ jsonObject.addProperty("masterId", task.getMasterId());
+
+ return jsonObject;
+ }
+
+ @Override
+ public SubTask deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ JsonObject jsonObject = json.getAsJsonObject();
+
+ Integer id = jsonObject.get("id").getAsInt();
+ String taskName = jsonObject.get("taskName").getAsString();
+ Status status = Status.valueOf(jsonObject.get("status").getAsString());
+ String content = jsonObject.get("content").getAsString();
+ Integer masterId = jsonObject.get("masterId").getAsInt();
+
+ LocalDateTime startTime = LocalDateTime.parse(jsonObject.get("startTime").getAsString(), formatter);
+
+ Duration duration = Duration.ofMinutes(jsonObject.get("duration").getAsLong());
+
+ return new SubTask(taskName, content, status, masterId, id, startTime, duration);
+ }
+}
diff --git a/src/adapters/TaskAdapter.java b/src/adapters/TaskAdapter.java
new file mode 100644
index 0000000..e07f4e7
--- /dev/null
+++ b/src/adapters/TaskAdapter.java
@@ -0,0 +1,46 @@
+package adapters;
+
+import com.google.gson.*;
+import model.Task;
+import model.Status;
+
+import java.lang.reflect.Type;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class TaskAdapter implements JsonSerializer, JsonDeserializer {
+
+ private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
+
+ @Override
+ public JsonElement serialize(Task task, Type typeOfSrc, JsonSerializationContext context) {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("id", task.getId());
+ jsonObject.addProperty("taskName", task.getTaskName());
+ jsonObject.addProperty("status", task.getStatus().name());
+ jsonObject.addProperty("content", task.getContent());
+
+ jsonObject.addProperty("startTime", task.getStartTime().format(formatter));
+
+ jsonObject.addProperty("duration", task.getDuration().toMinutes());
+
+ return jsonObject;
+ }
+
+ @Override
+ public Task deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ JsonObject jsonObject = json.getAsJsonObject();
+
+ Integer id = jsonObject.get("id").getAsInt();
+ String taskName = jsonObject.get("taskName").getAsString();
+ Status status = Status.valueOf(jsonObject.get("status").getAsString());
+ String content = jsonObject.get("content").getAsString();
+
+ LocalDateTime startTime = LocalDateTime.parse(jsonObject.get("startTime").getAsString(), formatter);
+
+ Duration duration = Duration.ofMinutes(jsonObject.get("duration").getAsLong());
+
+ return new Task(taskName, content, status, id, startTime, duration);
+ }
+}
diff --git a/src/handlers/EpicHandler.java b/src/handlers/EpicHandler.java
new file mode 100644
index 0000000..61c3cc5
--- /dev/null
+++ b/src/handlers/EpicHandler.java
@@ -0,0 +1,93 @@
+package handlers;
+
+import adapters.EpicAdapter;
+import com.google.gson.GsonBuilder;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import manager.CrossingException;
+import manager.FileBackedTaskManager;
+import model.Epic;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+public class EpicHandler extends TaskHandler implements HttpHandler {
+
+
+ public EpicHandler(FileBackedTaskManager master) {
+ super(master);
+ }
+
+ @Override
+ public void get(HttpExchange exchange) throws IOException {
+ try {
+ List tasks = new ArrayList<>(master.getAllEpics());
+ String response = gson.toJson(tasks);
+ sendResponse(exchange, response, 200);
+ } catch (Exception e) {
+ e.getMessage();
+ }
+
+ }
+
+ @Override
+ public void post(HttpExchange exchange) throws IOException {
+ //Запускаем поток чтения тела запроса и создаём из него новый объект task, который отправляем в менеджер.
+ InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8);
+ Epic task = gson.fromJson(isr, Epic.class);
+ try {
+ master.addEpic(task);
+ String response = "Задача " + task.getId() + " успешно создана";
+ sendResponse(exchange, response, 201);
+ } catch (CrossingException e) {
+ String response = e.getMessage();
+ sendResponse(exchange, response, 406);
+ }
+ }
+
+ @Override
+ public void delete(HttpExchange exchange) throws IOException {
+ master.eraseEpicHashMap();
+ String response = "Все задачи удалены";
+ sendResponse(exchange, response, 200);
+ }
+
+ @Override
+ public void getId(Integer id, HttpExchange exchange) throws IOException {
+ try {
+ Epic task = master.getEpic(id);
+ String response = gson.toJson(task);
+ sendResponse(exchange, response, 200);
+ } catch (Exception e) {
+ String response = "Такой задачи не существует";
+ sendResponse(exchange, response, 404);
+ }
+ }
+
+ @Override
+ public void postId(Integer id, HttpExchange exchange) throws IOException {
+ InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8);
+ Epic task = gson.fromJson(isr, Epic.class);
+ task.setId(id);
+ master.updateEpic(task);
+ String response = "Задача " + task.getId() + " успешно обновлена";
+ sendResponse(exchange, response, 201);
+ }
+
+ @Override
+ public void deleteId(Integer id, HttpExchange exchange) throws IOException {
+ master.removeEpic(id);
+ String response = "Задача " + id + " удалена";
+ sendResponse(exchange, response, 200);
+ }
+
+ @Override
+ protected void gsonInitializator() {
+ GsonBuilder gsonBuilder = new GsonBuilder();
+ gsonBuilder.registerTypeAdapter(Epic.class, new EpicAdapter());
+ this.gson = gsonBuilder.create();
+ }
+}
diff --git a/src/handlers/HistoryHandler.java b/src/handlers/HistoryHandler.java
new file mode 100644
index 0000000..b76d740
--- /dev/null
+++ b/src/handlers/HistoryHandler.java
@@ -0,0 +1,54 @@
+package handlers;
+
+import com.google.gson.Gson;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import manager.FileBackedTaskManager;
+import model.Task;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class HistoryHandler implements HttpHandler {
+
+ Gson gson;
+ FileBackedTaskManager master;
+
+
+ public HistoryHandler(FileBackedTaskManager master) {
+ this.master = master;
+ }
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ String method = exchange.getRequestMethod();
+ if (method.toString().toLowerCase().equals("get")) {
+ get(exchange);
+ } else {
+ String response = "У нас пока нет таких методов";
+ sendResponse(exchange, response, 406);
+ }
+ }
+
+ public void get(HttpExchange exchange) throws IOException {
+ List tasks = new ArrayList<>(master.getHistory());
+ String response = tasks.toString();
+ sendResponse(exchange, response, 200);
+ }
+
+
+ public void sendResponse(HttpExchange httpExchange, String response, int statusCode) throws IOException {
+ httpExchange.getResponseHeaders().set("Content-Type", "application/json");
+ httpExchange.sendResponseHeaders(statusCode, response.getBytes().length);
+ OutputStream stream = httpExchange.getResponseBody();
+ stream.write(response.getBytes());
+ stream.close();
+ }
+
+ protected void gsonInitializator() {
+ this.gson = new Gson();
+ }
+}
diff --git a/src/handlers/PriorityHandler.java b/src/handlers/PriorityHandler.java
new file mode 100644
index 0000000..931d556
--- /dev/null
+++ b/src/handlers/PriorityHandler.java
@@ -0,0 +1,48 @@
+package handlers;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import manager.FileBackedTaskManager;
+import model.Task;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class PriorityHandler implements HttpHandler {
+
+ FileBackedTaskManager master;
+
+ public PriorityHandler(FileBackedTaskManager master) {
+ this.master = master;
+ }
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ String method = exchange.getRequestMethod();
+ if (method.toString().toLowerCase().equals("get")) {
+ get(exchange);
+ } else {
+ String response = "У нас пока нет таких методов";
+ sendResponse(exchange, response, 406);
+ }
+ }
+
+ public void get(HttpExchange exchange) throws IOException {
+ List tasks = new ArrayList<>(master.getPrioritizedTasks());
+ String response = tasks.toString();
+ sendResponse(exchange, response, 200);
+ }
+
+
+ public void sendResponse(HttpExchange httpExchange, String response, int statusCode) throws IOException {
+ httpExchange.getResponseHeaders().set("Content-Type", "application/json");
+ httpExchange.sendResponseHeaders(statusCode, response.getBytes().length);
+ OutputStream stream = httpExchange.getResponseBody();
+ stream.write(response.getBytes());
+ stream.close();
+ }
+
+}
diff --git a/src/handlers/SubHandler.java b/src/handlers/SubHandler.java
new file mode 100644
index 0000000..4325aae
--- /dev/null
+++ b/src/handlers/SubHandler.java
@@ -0,0 +1,94 @@
+package handlers;
+
+
+import adapters.SubTaskAdapter;
+import com.google.gson.GsonBuilder;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import manager.CrossingException;
+import manager.FileBackedTaskManager;
+import model.SubTask;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SubHandler extends TaskHandler implements HttpHandler {
+
+
+ public SubHandler(FileBackedTaskManager master) {
+ super(master);
+ }
+
+ @Override
+ public void get(HttpExchange exchange) throws IOException {
+ try {
+ List tasks = new ArrayList<>(master.getAllSubs());
+ String response = gson.toJson(tasks);
+ sendResponse(exchange, response, 200);
+ } catch (Exception e) {
+ e.getMessage();
+ }
+
+ }
+
+ @Override
+ public void post(HttpExchange exchange) throws IOException {
+ //Запускаем поток чтения тела запроса и создаём из него новый объект task, который отправляем в менеджер.
+ InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8);
+ SubTask task = gson.fromJson(isr, SubTask.class);
+ try {
+ master.addSub(task);
+ String response = "Задача " + task.getId() + " успешно создана";
+ sendResponse(exchange, response, 201);
+ } catch (CrossingException e) {
+ String response = e.getMessage();
+ sendResponse(exchange, response, 406);
+ }
+ }
+
+ @Override
+ public void delete(HttpExchange exchange) throws IOException {
+ master.eraseSubHashMap();
+ String response = "Все подзадачи удалены";
+ sendResponse(exchange, response, 200);
+ }
+
+ @Override
+ public void getId(Integer id, HttpExchange exchange) throws IOException {
+ try {
+ SubTask task = master.getSubtask(id);
+ String response = gson.toJson(task);
+ sendResponse(exchange, response, 200);
+ } catch (Exception e) {
+ String response = "Такой задачи не существует";
+ sendResponse(exchange, response, 404);
+ }
+ }
+
+ @Override
+ public void postId(Integer id, HttpExchange exchange) throws IOException {
+ InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8);
+ SubTask task = gson.fromJson(isr, SubTask.class);
+ task.setId(id);
+ master.updateSubTask(task);
+ String response = "Задача " + task.getId() + " успешно обновлена";
+ sendResponse(exchange, response, 201);
+ }
+
+ @Override
+ public void deleteId(Integer id, HttpExchange exchange) throws IOException {
+ master.removeSubTask(id);
+ String response = "Задача " + id + " удалена";
+ sendResponse(exchange, response, 200);
+ }
+
+ @Override
+ protected void gsonInitializator() {
+ GsonBuilder gsonBuilder = new GsonBuilder();
+ gsonBuilder.registerTypeAdapter(SubTask.class, new SubTaskAdapter());
+ this.gson = gsonBuilder.create();
+ }
+}
diff --git a/src/handlers/TaskHandler.java b/src/handlers/TaskHandler.java
new file mode 100644
index 0000000..a60f535
--- /dev/null
+++ b/src/handlers/TaskHandler.java
@@ -0,0 +1,163 @@
+package handlers;
+
+import adapters.TaskAdapter;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import manager.CrossingException;
+import manager.FileBackedTaskManager;
+import model.Task;
+
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+import java.io.IOException;
+
+
+public class TaskHandler implements HttpHandler {
+
+ Gson gson;
+ GsonBuilder gsonBuilder;
+ FileBackedTaskManager master;
+
+
+ public TaskHandler(FileBackedTaskManager master) {
+ this.master = master;
+ gsonInitializator();
+ }
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ Integer commandId = -1;
+ String path = exchange.getRequestURI().getPath();
+ String method = exchange.getRequestMethod();
+ String[] pathDeplete = path.split("/");
+ try {
+ commandId = Integer.parseInt(pathDeplete[2]);
+ } catch (Exception e) {
+ commandId = -1;
+ }
+
+ if (commandId < 0) {
+ noIdPath(method, exchange);
+
+ } else {
+ withIdPath(method, commandId, exchange);
+
+ }
+
+
+ }
+
+ public void get(HttpExchange exchange) throws IOException {
+ List tasks = new ArrayList<>(master.getAllTasks());
+ String response = gson.toJson(tasks);
+ sendResponse(exchange, response, 200);
+ }
+
+ public void post(HttpExchange exchange) throws IOException {
+ //Запускаем поток чтения тела запроса и создаём из него новый объект task, который отправляем в менеджер.
+ InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8);
+ Task task = gson.fromJson(isr, Task.class);
+ try {
+ master.addTask(task);
+ String response = "Задача " + task.getId() + " успешно создана";
+ sendResponse(exchange, response, 201);
+ } catch (CrossingException e) {
+ String response = e.getMessage();
+ sendResponse(exchange, response, 406);
+ }
+ //Высылаем ответ клиенту
+
+ }
+
+ public void delete(HttpExchange exchange) throws IOException {
+ master.eraseTaskHashMap();
+ String response = "Все задачи удалены";
+ sendResponse(exchange, response, 200);
+ }
+
+ public void getId(Integer id, HttpExchange exchange) throws IOException {
+ try {
+ Task task = master.getTask(id);
+ String response = gson.toJson(task);
+ sendResponse(exchange, response, 200);
+ } catch (Exception e) {
+ String response = "Такой задачи не существует";
+ sendResponse(exchange, response, 404);
+ }
+
+ }
+
+ public void postId(Integer id, HttpExchange exchange) throws IOException {
+ InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8);
+ Task task = gson.fromJson(isr, Task.class);
+ task.setId(id);
+ master.updateTask(task);
+ String response = "Задача " + task.getId() + " успешно обновлена";
+ sendResponse(exchange, response, 201);
+ }
+
+ public void deleteId(Integer id, HttpExchange exchange) throws IOException {
+ master.removeTask(id);
+ String response = "Задача " + id + " удалена";
+ sendResponse(exchange, response, 200);
+ }
+
+ public void dfM() {
+ String response = "Неизвестно как, но мы отправили неверный метод";
+ System.out.println(response);
+ }
+
+ public void noIdPath(String method, HttpExchange exchange) throws IOException {
+ switch (method.toLowerCase()) {
+ case "get":
+ get(exchange);
+ break;
+ case "post":
+ post(exchange);
+ break;
+ case "delete":
+ delete(exchange);
+ break;
+ default:
+ dfM();
+ break;
+ }
+ }
+
+ public void withIdPath(String method, Integer id, HttpExchange exchange) throws IOException {
+ switch (method.toLowerCase()) {
+ case "get":
+ getId(id, exchange);
+ break;
+ case "post":
+ postId(id, exchange);
+ break;
+ case "delete":
+ deleteId(id, exchange);
+ break;
+ default:
+ dfM();
+ break;
+ }
+ }
+
+ public void sendResponse(HttpExchange httpExchange, String response, int statusCode) throws IOException {
+ httpExchange.getResponseHeaders().set("Content-Type", "application/json");
+ httpExchange.sendResponseHeaders(statusCode, response.getBytes().length);
+ OutputStream stream = httpExchange.getResponseBody();
+ stream.write(response.getBytes());
+ stream.close();
+ }
+
+ protected void gsonInitializator() {
+ GsonBuilder gsonBuilder = new GsonBuilder();
+ gsonBuilder.registerTypeAdapter(Task.class, new TaskAdapter());
+ this.gson = gsonBuilder.create();
+ }
+}
diff --git a/src/manager/CrossingException.java b/src/manager/CrossingException.java
new file mode 100644
index 0000000..c9cb4a9
--- /dev/null
+++ b/src/manager/CrossingException.java
@@ -0,0 +1,7 @@
+package manager;
+
+public class CrossingException extends RuntimeException {
+ public CrossingException(String message) {
+ super(message);
+ }
+}
diff --git a/src/manager/FileBackedTaskManager.java b/src/manager/FileBackedTaskManager.java
new file mode 100644
index 0000000..13163f9
--- /dev/null
+++ b/src/manager/FileBackedTaskManager.java
@@ -0,0 +1,323 @@
+package manager;
+
+import model.Epic;
+import model.Status;
+import model.SubTask;
+import model.Task;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import static java.lang.Integer.parseInt;
+
+
+public class FileBackedTaskManager extends InMemoryTaskManager {
+
+ //Новые поля
+ private Path taskFile;
+
+
+ //Конструктор для тестов
+ public FileBackedTaskManager(String test) {
+
+ try {
+ createTempFile();
+ } catch (ManagerSaveException ex) {
+ System.out.println(ex.getMessage());
+ }
+ }
+
+
+ public FileBackedTaskManager() {
+ this.taskFile = Paths.get("csvTaskFile.csv");
+ try {
+ createFile();
+ } catch (ManagerSaveException ex) {
+ System.out.println(ex.getMessage());
+ }
+ }
+
+ //Начало переписанных методов
+ @Override
+ public void addTask(Task task) throws CrossingException {
+ boolean isCrossed = tasks.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || epics.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || subs.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+ if (isCrossed) {
+ throw new CrossingException("На данное время уже назначена задача");
+ } else {
+ taskId++;
+ tasks.put(taskId, task);
+ task.setId(taskId);
+ save();
+ }
+ }
+
+ @Override
+ public void addEpic(Epic task) throws CrossingException {
+ boolean isCrossed = tasks.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || epics.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || subs.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+ if (isCrossed) {
+ throw new CrossingException("На данное время уже назначена задача");
+ } else {
+ taskId++;
+ epics.put(taskId, task);
+ task.setId(taskId);
+ save();
+ }
+ }
+
+ @Override
+ public void addSub(SubTask task) throws CrossingException {
+ boolean isCrossed = tasks.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || epics.values().stream()
+ .filter(entry -> !entry.getId().equals(task.getMasterId()))
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || subs.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+ if (isCrossed) {
+ throw new CrossingException("На данное время уже назначена задача");
+ } else {
+ taskId++;
+ subs.put(taskId, task);
+ task.setId(taskId);
+ epics.get(task.getMasterId()).addSubTask(task);
+ epics.get(task.getMasterId()).statusUpdate();
+ save();
+ }
+ }
+
+ //Удаление по идентификатору
+ @Override
+ public void removeTask(Integer id) {
+ tasks.remove(id);
+ save();
+ }
+
+ //Удаление всех задач
+ @Override
+ public void eraseTaskHashMap() {
+ tasks.clear();
+ save();
+ }
+
+ //Обновление задачи
+ @Override
+ public void updateTask(Task task) {
+ tasks.put(task.getId(), task);
+ save();
+ }
+
+ //Удаление всех задач
+ @Override
+ public void eraseEpicHashMap() {
+ eraseSubHashMap();
+ epics.clear();
+ save();
+ }
+
+ //Обновление задачи
+ @Override
+ public void updateEpic(Epic task) {
+ epics.put(task.getId(), task);
+ save();
+ }
+
+ //Удаление по идентификатору
+ @Override
+ public void removeEpic(Integer id) {
+ epics.get(id).getEpicSubs().keySet().forEach(subs::remove);
+ epics.remove(id);
+ save();
+ }
+
+ //Удаление всех подзадач (без удаления эпиков. Эпики выставляются в статус NEW, так как подзадач нет.)
+ @Override
+ public void eraseSubHashMap() {
+ subs.clear();
+ epics.values().forEach(epic -> {
+ epic.clearSub();
+ epic.statusUpdate();
+ });
+ save();
+ }
+
+ //Обновление задачи
+ @Override
+ public void updateSubTask(SubTask task) {
+ subs.put(task.getId(), task);
+ epics.get(task.getMasterId()).addSubTask(task);
+ epics.get(task.getMasterId()).statusUpdate();
+ save();
+ }
+
+ //Удаление по идентификатору
+ @Override
+ public void removeSubTask(Integer id) {
+ subs.remove(id);
+ epics.values().forEach(epic -> {
+ if (epic.getEpicSubs().containsKey(id)) {
+ epic.getEpicSubs().remove(id);
+ epic.statusUpdate();
+ }
+ });
+ save();
+ }
+
+ //ДОПОЛНИТЕЛЬНЫЕ ОПЕРАЦИОННЫЕ МЕТОДЫ
+ //Метод автосохранения. Содержимое мапы uniMap переносится в файл CSV. И наполняется TreeSet
+ private void save() {
+ HashMap uniMap = createUniMap();
+ timeSortedTasks.clear();
+ StringBuilder sb = new StringBuilder("id,type,name,status,description,epic\n");
+ for (int i = 1; i <= taskId; i++) {
+ if (uniMap.containsKey(i)) {
+ sb.append(lineFormater(uniMap.get(i)) + "\n");
+ timeSortedTasks.add(uniMap.get(i));
+ }
+ }
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(String.valueOf(taskFile)))) {
+ writer.write(String.valueOf(sb));
+ } catch (IOException e) {
+ System.out.println("IOI save exception");
+ }
+ }
+
+ //Метод формирует хэш-мапу для автосохранения в файл
+ private HashMap createUniMap() {
+ HashMap uniMap = new HashMap<>();
+ for (int i = 1; i <= taskId; i++) {
+ if (tasks.containsKey(i)) {
+ uniMap.put(i, tasks.get(i));
+ } else if (epics.containsKey(i)) {
+ uniMap.put(i, epics.get(i));
+ } else if (subs.containsKey(i)) {
+ uniMap.put(i, subs.get(i));
+ }
+ }
+ return uniMap;
+ }
+
+ //Метод формирует линию для записи формата id,type,name,status,description,epic
+ private String lineFormater(Task task) {
+
+ if (task instanceof SubTask) {
+ SubTask subTask = (SubTask) task;
+
+ return subTask.getId() + "," + getTaskType(task) + "," + subTask.getTaskName() + "," + subTask.getStatus() + "," + subTask.getContent() + "," + subTask.getMasterId();
+ }
+ return task.getId() + "," + getTaskType(task) + "," + task.getTaskName() + "," + task.getStatus() + "," + task.getContent();
+ }
+
+ //Метод определяет тип задачи и возвращает в виде строки
+ private String getTaskType(Task task) {
+ Class> o = task.getClass();
+ return o.getSimpleName();
+ }
+
+ //Метод инициализирует содержимое CSV файла в память программы
+ private void loadFromFile() {
+ ArrayList data = new ArrayList<>();
+ try {
+ data = (ArrayList) Files.readAllLines(taskFile);
+ } catch (IOException e) {
+ System.out.println("Ошибка при чтении из файла");
+ }
+ data.removeFirst();
+ assert data != null;
+ for (String line : data) {
+ separateLines(line);
+ }
+
+ }
+
+ //Вспомогателльный метод readFromFile. Метод бьёт на строки id,type,name,status,description,epic
+ // 0 - ID, 1 - TYPE, 2 - NAME, 3 - STATUS, 4 - DESCRIPTION, 5 - EPIC, 6 - startTime, 7 - Duration
+ private void separateLines(String initialString) {
+ String[] lines = initialString.split(",");
+ int resId = parseInt(lines[0]);
+ String resType = lines[1];
+ String resTaskName = lines[2];
+ Status resTaskStatus = Status.valueOf(lines[3]);
+ String resContent = lines[4];
+ int resEpicNo = 0;
+ if (resType.equals("SubTask")) resEpicNo = parseInt(lines[5]);
+ switch (resType) {
+ case "Task":
+ Task task = new Task(resTaskName, resContent, resTaskStatus);
+ taskId = resId - 1;
+ addTask(task);
+ task.setId(resId);
+ taskId = resId;
+ break;
+ case "Epic":
+ Epic epic = new Epic(resTaskName, resContent, resTaskStatus);
+ taskId = resId - 1;
+ addEpic(epic);
+ epic.setId(resId);
+ taskId = resId;
+ break;
+ case "SubTask":
+ SubTask subTask = new SubTask(resTaskName, resContent, resTaskStatus, resEpicNo);
+ taskId = resId - 1;
+ addSub(subTask);
+ subTask.setId(resId);
+ taskId = resId;
+ break;
+ }
+ }
+
+ private void eraseFile() {
+ try {
+ Files.newBufferedWriter(taskFile).close();
+ } catch (IOException e) {
+ System.out.println("Ошибка при удалении данных");
+ }
+
+ }
+
+ private void createTempFile() throws ManagerSaveException {
+ try {
+ taskFile = Files.createTempFile("testFile", ".csv");
+ taskFile.toFile().deleteOnExit();
+ } catch (IOException ex) {
+ throw new ManagerSaveException("Ошибка при создании временного файла");
+ }
+ }
+
+ private void createFile() throws ManagerSaveException {
+
+ try {
+ if (!Files.exists(taskFile)) {
+ Files.createFile(taskFile);
+ }
+ } catch (IOException ex) {
+ throw new ManagerSaveException("Ошибка при создании постоянного CSV файла");
+ }
+ }
+
+ public Path getTaskFile() {
+ return taskFile;
+ }
+
+}
diff --git a/src/manager/HttpTaskServer.java b/src/manager/HttpTaskServer.java
new file mode 100644
index 0000000..c610d2d
--- /dev/null
+++ b/src/manager/HttpTaskServer.java
@@ -0,0 +1,63 @@
+package manager;
+
+import com.sun.net.httpserver.HttpServer;
+import handlers.*;
+import model.Epic;
+import model.Status;
+import model.SubTask;
+import model.Task;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.time.Duration;
+import java.time.LocalDateTime;
+
+public class HttpTaskServer {
+
+ private HttpServer server;
+ private final int applicationPort = 8080;
+ FileBackedTaskManager master = new FileBackedTaskManager();
+
+ public HttpTaskServer() throws IOException {
+ this.server = HttpServer.create(new InetSocketAddress(applicationPort), 0);
+ }
+
+ public void startServer() {
+ server.createContext("/tasks", new TaskHandler(master));
+ server.createContext("/epics", new EpicHandler(master));
+ server.createContext("/subtasks", new SubHandler(master));
+ server.createContext("/history", new HistoryHandler(master));
+ server.createContext("/prioritized", new PriorityHandler(master));
+ server.start();
+ System.out.println("Сервер запущен на порту: " + applicationPort);
+ }
+
+ public void stopServer() {
+ server.stop(10);
+ System.out.println("Сервер остановлен");
+ }
+
+ public void test() {
+ Task task1 = new Task("1", "Task1", Status.NEW);
+ Task task2 = new Task("2", "Task2", Status.NEW);
+ Epic epic1 = new Epic("3", "Epic1", Status.NEW);
+ SubTask sub1 = new SubTask("6", "Sub 1", Status.NEW, 3);
+ task1.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 0));
+ task1.setDuration(Duration.ofMinutes(10));
+ task2.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 10));
+ epic1.setDuration(Duration.ofMinutes(10));
+ epic1.setStartTime(LocalDateTime.of(1999, 1, 1, 0, 0));
+ task2.setDuration(Duration.ofMinutes(10));
+ sub1.setStartTime(LocalDateTime.of(1970, 1, 1, 0, 0));
+ sub1.setDuration(Duration.ofMinutes(10));
+ master.addTask(task1);
+ master.addTask(task2);
+ master.addEpic(epic1);
+ master.addSub(sub1);
+ }
+
+ public FileBackedTaskManager getMaster() {
+ return master;
+ }
+
+}
diff --git a/src/manager/InMemoryTaskManager.java b/src/manager/InMemoryTaskManager.java
index b2904c5..580a9fc 100644
--- a/src/manager/InMemoryTaskManager.java
+++ b/src/manager/InMemoryTaskManager.java
@@ -4,18 +4,15 @@
import model.SubTask;
import model.Task;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
+import java.util.*;
public class InMemoryTaskManager implements TaskManager {
- //Хранение всех типов
- private Integer taskId = 0;
-
- private final HashMap tasks = new HashMap<>();
- private final HashMap epics = new HashMap<>();
- private final HashMap subs = new HashMap<>();
+ protected Integer taskId = 0;
+ protected TreeSet timeSortedTasks = new TreeSet<>();
+ protected final HashMap tasks = new HashMap<>();
+ protected final HashMap epics = new HashMap<>();
+ protected final HashMap subs = new HashMap<>();
public HistoryManager historian = new InMemoryHistoryManager();
@@ -25,7 +22,6 @@ public Collection getAllTasks() {
return tasks.values();
}
- //Получение по идентификатору
@Override
public Task getTask(Integer id) {
historian.add(tasks.get(id));
@@ -40,10 +36,23 @@ public void eraseTaskHashMap() {
//Создание задачи
@Override
- public void addTask(Task task) {
- taskId++;
- tasks.put(taskId, task);
- task.setId(taskId);
+ public void addTask(Task task) throws CrossingException {
+ boolean isCrossed = tasks.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || epics.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || subs.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+ if (isCrossed) {
+ throw new CrossingException("На данное время уже назначена задача");
+ } else {
+ taskId++;
+ tasks.put(taskId, task);
+ task.setId(taskId);
+ timeSortedTasks.add(task);
+ }
}
//Обновление задачи
@@ -82,10 +91,23 @@ public void eraseEpicHashMap() {
//Создание задачи
@Override
- public void addEpic(Epic task) {
- taskId++;
- epics.put(taskId, task);
- task.setId(taskId);
+ public void addEpic(Epic task) throws CrossingException {
+ boolean isCrossed = tasks.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || epics.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || subs.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+ if (isCrossed) {
+ throw new CrossingException("На данное время уже назначена задача");
+ } else {
+ taskId++;
+ epics.put(taskId, task);
+ task.setId(taskId);
+ timeSortedTasks.add(task);
+ }
}
//Обновление задачи
@@ -129,12 +151,26 @@ public void eraseSubHashMap() {
//Создание задачи, добавление к существующей model.Epic
@Override
- public void addSub(SubTask task) {
- taskId++;
- subs.put(taskId, task);
- task.setId(taskId);
- epics.get(task.getMasterId()).addSubTask(task);
- epics.get(task.getMasterId()).statusUpdate();
+ public void addSub(SubTask task) throws CrossingException {
+ boolean isCrossed = tasks.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || epics.values().stream()
+ .filter(entry -> !entry.getId().equals(task.getMasterId()))
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+
+ isCrossed = isCrossed || subs.values().stream()
+ .anyMatch(existingTask -> existingTask.isTimeCrossed(task));
+ if (isCrossed) {
+ throw new CrossingException("На данное время уже назначена задача");
+ } else {
+ taskId++;
+ subs.put(taskId, task);
+ task.setId(taskId);
+ epics.get(task.getMasterId()).addSubTask(task);
+ epics.get(task.getMasterId()).statusUpdate();
+ timeSortedTasks.add(task);
+ }
}
//Обновление задачи
@@ -163,5 +199,9 @@ public ArrayList getHistory() {
return historian.getHistory();
}
+ @Override
+ public List getPrioritizedTasks() {
+ return new ArrayList<>(timeSortedTasks);
+ }
}
diff --git a/src/manager/ManagerSaveException.java b/src/manager/ManagerSaveException.java
new file mode 100644
index 0000000..c213c23
--- /dev/null
+++ b/src/manager/ManagerSaveException.java
@@ -0,0 +1,7 @@
+package manager;
+
+public class ManagerSaveException extends RuntimeException {
+ public ManagerSaveException(String message) {
+ super(message);
+ }
+}
diff --git a/src/manager/Managers.java b/src/manager/Managers.java
index e7cfae5..09de30e 100644
--- a/src/manager/Managers.java
+++ b/src/manager/Managers.java
@@ -1,8 +1,9 @@
package manager;
public class Managers {
+ //SP7 - класс изменён c InMemoryTaskManager на FileBackedTaskManager
public static TaskManager getDefault() {
- return new InMemoryTaskManager();
+ return new FileBackedTaskManager();
}
public static HistoryManager getDefaultHistory() {
diff --git a/src/manager/TaskManager.java b/src/manager/TaskManager.java
index 65879d1..2ccdd36 100644
--- a/src/manager/TaskManager.java
+++ b/src/manager/TaskManager.java
@@ -3,9 +3,9 @@
import model.Epic;
import model.SubTask;
import model.Task;
-
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
public interface TaskManager {
@@ -47,4 +47,6 @@ public interface TaskManager {
public ArrayList getHistory();
+ public List getPrioritizedTasks();
+
}
diff --git a/src/model/Epic.java b/src/model/Epic.java
index 0508d15..59b194a 100644
--- a/src/model/Epic.java
+++ b/src/model/Epic.java
@@ -1,5 +1,8 @@
package model;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.util.Comparator;
import java.util.HashMap;
public class Epic extends Task {
@@ -9,8 +12,28 @@ public Epic(String taskName, String content, Status status) {
super(taskName, content, status);
}
+ public Epic(String taskName, String content, Status status, Integer id, LocalDateTime startTime, Duration duration) {
+ super(taskName, content, status, id, startTime, duration);
+ }
+
public void addSubTask(SubTask subTask) {
epicSubs.put(subTask.getId(), subTask);
+ refreshTimeLimits();
+ }
+
+ private void refreshTimeLimits() {
+ LocalDateTime endTime;
+ Task firstTask = epicSubs.values()
+ .stream()
+ .min(Comparator.comparing(Task::getStartTime))
+ .orElse(null);
+ Task lastTask = epicSubs.values()
+ .stream()
+ .max(Comparator.comparing(Task::getStartTime))
+ .orElse(null);
+ startTime = firstTask.getStartTime();
+ endTime = lastTask.getEndTime();
+ duration = Duration.between(startTime,endTime);
}
void printAllEpicSubTasks() {
diff --git a/src/model/SubTask.java b/src/model/SubTask.java
index f17f3a4..1adf984 100644
--- a/src/model/SubTask.java
+++ b/src/model/SubTask.java
@@ -1,16 +1,26 @@
package model;
+import java.time.Duration;
+import java.time.LocalDateTime;
import java.util.ArrayList;
public class SubTask extends Task {
private final Integer masterId;
- ArrayList epicAssign = new ArrayList<>();
+ public ArrayList epicAssign = new ArrayList<>();
public SubTask(String taskName, String content, Status status, Integer masterId) {
super(taskName, content, status);
this.masterId = masterId;
}
+ public SubTask(String taskName, String content, Status status, Integer masterId, Integer id, LocalDateTime startTime, Duration duration) {
+ super(taskName, content, status);
+ this.masterId = masterId;
+ setId(id);
+ setStartTime(startTime);
+ setDuration(duration);
+ }
+
public Integer getMasterId() {
return masterId;
}
diff --git a/src/model/Task.java b/src/model/Task.java
index 0fefffc..2f192e5 100644
--- a/src/model/Task.java
+++ b/src/model/Task.java
@@ -1,21 +1,56 @@
package model;
+import java.time.Duration;
+import java.time.LocalDateTime;
import java.util.Objects;
-public class Task {
+public class Task implements Comparable {
private Integer id;//id задачи
private String taskName; // имя задачи
private Status status; // статус задачи
private String content; // содержимое задачи
-
- //Конструктор
+ protected LocalDateTime startTime;
+ protected Duration duration;
public Task(String taskName, String content, Status status) {
this.status = status;
this.taskName = taskName;
this.content = content;
+ }
+
+ public Task(String taskName, String content, Status status, Integer id, LocalDateTime startTime, Duration duration) {
+ this.status = status;
+ this.taskName = taskName;
+ this.content = content;
+ this.id = id;
+ this.startTime = startTime;
+ this.duration = duration;
+ }
+
+ public LocalDateTime getEndTime() {
+ if (startTime != null && duration != null) {
+ return startTime.plus(duration);
+ } else {
+ return LocalDateTime.MIN;
+ }
+ }
+
+ public Duration getDuration() {
+ if (duration != null) {
+ return duration;
+ } else {
+ return Duration.ofMinutes(0);
+ }
+ }
+
+ public LocalDateTime getStartTime() {
+ if (startTime != null) {
+ return startTime;
+ } else {
+ return LocalDateTime.MIN;
+ }
}
public Integer getId() {
@@ -72,4 +107,31 @@ public String toString() {
", content='" + content + '\'' +
'}';
}
+
+ @Override
+ public int compareTo(Task o) {
+ if (this.startTime == null && o.startTime == null) {
+ return 0;
+ }
+ if (this.startTime == null) {
+ return -1;
+ }
+ if (o.startTime == null) {
+ return 1;
+ }
+ return this.startTime.compareTo(o.startTime);
+ }
+
+ public boolean isTimeCrossed(Task task) {
+ return task.getStartTime().isBefore(this.getEndTime()) && task.getEndTime().isAfter(this.getStartTime());
+ }
+
+ public void setStartTime(LocalDateTime startTime) {
+ this.startTime = startTime;
+ }
+
+ public void setDuration(Duration duration) {
+ this.duration = duration;
+ }
+
}
diff --git a/test/FileBackedTaskManagerTest.java b/test/FileBackedTaskManagerTest.java
new file mode 100644
index 0000000..8840777
--- /dev/null
+++ b/test/FileBackedTaskManagerTest.java
@@ -0,0 +1,75 @@
+import manager.FileBackedTaskManager;
+import manager.HistoryManager;
+import manager.Managers;
+import model.Epic;
+import model.Status;
+import model.SubTask;
+import model.Task;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+
+public class FileBackedTaskManagerTest {
+
+ private static FileBackedTaskManager master;
+ private static HistoryManager historian;
+ private static Task task1;
+ private static Task task2;
+ private static Epic epic1;
+ private static SubTask sub1;
+
+ @BeforeEach
+ void managersCreationUtilityTest() {
+ master = new FileBackedTaskManager("true");
+ historian = Managers.getDefaultHistory();
+ task1 = new Task("1", "Task1", Status.NEW);
+ task2 = new Task("2", "Task2", Status.NEW);
+ epic1 = new Epic("3", "Epic1", Status.NEW);
+ sub1 = new SubTask("6", "Sub 1", Status.NEW, 3);
+ }
+
+ @Test
+ void checkFileReadAndWriteProcess() {
+ master.addTask(task1);
+ Assertions.assertEquals("1", master.getTask(1).getTaskName());
+ Assertions.assertEquals("Task1", master.getTask(1).getContent());
+ Assertions.assertEquals(Status.NEW, master.getTask(1).getStatus());
+ ArrayList data = new ArrayList<>();
+
+ try {
+ data = (ArrayList) Files.readAllLines(master.getTaskFile());
+ } catch (IOException e) {
+ System.out.println("Ошибка при чтении из файла");
+ }
+ Assertions.assertEquals("1,Task,1,NEW,Task1", data.get(1));
+ Assertions.assertNotEquals("Task,1,NEW,Task1", data.get(1));
+ }
+
+ @Test
+ void checkFileReadAndWriteProcessMore() {
+ master.addTask(task1);
+ master.addTask(task2);
+ master.addEpic(epic1);
+ master.addSub(sub1);
+ Assertions.assertEquals("1", master.getTask(1).getTaskName());
+ Assertions.assertEquals("Task1", master.getTask(1).getContent());
+ Assertions.assertEquals(Status.NEW, master.getTask(1).getStatus());
+ ArrayList data = new ArrayList<>();
+ master.removeTask(1);
+ task2 = new Task("2", "Task2", Status.DONE);
+ task2.setId(2);
+ master.updateTask(task2);
+
+ try {
+ data = (ArrayList) Files.readAllLines(master.getTaskFile());
+ } catch (IOException e) {
+ System.out.println("Ошибка при чтении из файла");
+ }
+ Assertions.assertEquals("2,Task,2,DONE,Task2", data.get(1));
+ Assertions.assertNotEquals("Task,1,NEW,Task1", data.get(1));
+ }
+
+}
diff --git a/test/HttpServerTest.java b/test/HttpServerTest.java
new file mode 100644
index 0000000..6e33e0e
--- /dev/null
+++ b/test/HttpServerTest.java
@@ -0,0 +1,154 @@
+import manager.*;
+import model.Epic;
+import model.Status;
+import model.SubTask;
+import model.Task;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.time.LocalDateTime;
+
+import static org.junit.Assert.assertEquals;
+
+class HttpServerTest {
+
+ private HttpTaskServer server;
+ private static Task task1;
+ private static Task task2;
+ private static Epic epic1;
+ private static SubTask sub1;
+ private static SubTask sub2;
+ private static SubTask sub3;
+ private static SubTask sub4;
+ private static Epic epic2;
+ private static SubTask sub5;
+ private static SubTask sub6;
+ private static SubTask sub7;
+ private static SubTask sub8;
+ private static Epic epic3;
+
+ @BeforeEach
+ void managersCreationUtilityTest() throws IOException {
+ server = new HttpTaskServer();
+ server.startServer();
+ task1 = new Task("1", "Task1", Status.NEW);
+ task2 = new Task("2", "Task2", Status.NEW);
+ epic1 = new Epic("3", "Epic1", Status.NEW);
+ sub1 = new SubTask("6", "Sub 1", Status.NEW, 3);
+ task1.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 0));
+ task1.setDuration(Duration.ofMinutes(10));
+ task2.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 10));
+ epic1.setDuration(Duration.ofMinutes(10));
+ epic1.setStartTime(LocalDateTime.of(1999, 1, 1, 0, 0));
+ task2.setDuration(Duration.ofMinutes(10));
+ sub1.setStartTime(LocalDateTime.of(1970, 1, 1, 0, 0));
+ sub1.setDuration(Duration.ofMinutes(10));
+ server.getMaster().addTask(task1);
+ server.getMaster().addTask(task2);
+ server.getMaster().addEpic(epic1);
+ server.getMaster().addSub(sub1);
+ }
+
+ @AfterEach
+ public void shutDown() {
+ server.stopServer();
+ }
+
+ @Test
+ void testGetAllTasksEpicsSubs() throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newHttpClient();
+ URI url = URI.create("http://localhost:8080/tasks");
+ HttpRequest request = HttpRequest.newBuilder().uri(url).GET().build();
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+ Assertions.assertEquals("[{\"id\":1,\"taskName\":\"1\",\"status\":\"NEW\",\"content\":\"Task1\",\"startTime\":\"2000-01-01T00:00:00\",\"duration\":10},{\"id\":2,\"taskName\":\"2\",\"status\":\"NEW\",\"content\":\"Task2\",\"startTime\":\"2000-01-01T00:10:00\",\"duration\":10}]", response.body());
+ url = URI.create("http://localhost:8080/epics");
+ request = HttpRequest.newBuilder().uri(url).GET().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+ url = URI.create("http://localhost:8080/subtasks");
+ request = HttpRequest.newBuilder().uri(url).GET().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+ }
+
+ @Test
+ void deletingTestForAllTypes() throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newHttpClient();
+ URI url = URI.create("http://localhost:8080/tasks/1");
+ HttpRequest request = HttpRequest.newBuilder().uri(url).DELETE().build();
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+ Assertions.assertEquals("Задача 1 удалена", response.body());
+ Assertions.assertEquals(1, server.getMaster().getAllTasks().size());
+ url = URI.create("http://localhost:8080/tasks");
+ request = HttpRequest.newBuilder().uri(url).DELETE().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+ Assertions.assertEquals("Все задачи удалены", response.body());
+ url = URI.create("http://localhost:8080/epics");
+ request = HttpRequest.newBuilder().uri(url).DELETE().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+ url = URI.create("http://localhost:8080/subtasks");
+ request = HttpRequest.newBuilder().uri(url).DELETE().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+ Assertions.assertEquals(0, server.getMaster().getAllTasks().size());
+ Assertions.assertEquals(0, server.getMaster().getAllEpics().size());
+ Assertions.assertEquals(0, server.getMaster().getAllSubs().size());
+ }
+
+ @Test
+ void notFoundTest() throws IOException, InterruptedException {
+ HttpClient client = HttpClient.newHttpClient();
+ URI url = URI.create("http://localhost:8080/tasks/5");
+ HttpRequest request = HttpRequest.newBuilder().uri(url).GET().build();
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(404, response.statusCode());
+ }
+
+ @Test
+ void testPostUpdateMethod () throws IOException, InterruptedException {
+ String inputJsonTask = "{"
+ + "\"id\": 1,"
+ + "\"taskName\": \"Updated\","
+ + "\"status\": \"NEW\","
+ + "\"content\": \"Updated task content.\","
+ + "\"startTime\": \"2000-01-01T00:00:00\","
+ + "\"duration\": 10"
+ + "}";
+ HttpClient client = HttpClient.newHttpClient();
+ URI url = URI.create("http://localhost:8080/tasks/1");
+ HttpRequest request = HttpRequest.newBuilder().uri(url).POST(HttpRequest.BodyPublishers.ofString(inputJsonTask, StandardCharsets.UTF_8)).build();
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(201, response.statusCode());
+ }
+
+ @Test
+ void testPostFailedTimeCrossingAddingMethod () throws IOException, InterruptedException {
+ String inputJsonTask = "{"
+ + "\"id\": 4,"
+ + "\"taskName\": \"Updated\","
+ + "\"status\": \"NEW\","
+ + "\"content\": \"Updated task content.\","
+ + "\"startTime\": \"2000-01-01T00:00:00\","
+ + "\"duration\": 10"
+ + "}";
+ HttpClient client = HttpClient.newHttpClient();
+ URI url = URI.create("http://localhost:8080/tasks");
+ HttpRequest request = HttpRequest.newBuilder().uri(url).POST(HttpRequest.BodyPublishers.ofString(inputJsonTask, StandardCharsets.UTF_8)).build();
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(406, response.statusCode());
+ }
+
+}
\ No newline at end of file
diff --git a/test/InMemoryTaskManagerTest.java b/test/InMemoryTaskManagerTest.java
index 3627204..e13ca06 100644
--- a/test/InMemoryTaskManagerTest.java
+++ b/test/InMemoryTaskManagerTest.java
@@ -6,10 +6,8 @@
import model.SubTask;
import model.Task;
import org.junit.jupiter.api.Assertions;
-
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-
import java.util.ArrayList;
class InMemoryTaskManagerTest {
diff --git a/test/OtherInterfacesTestSprint8.java b/test/OtherInterfacesTestSprint8.java
new file mode 100644
index 0000000..1638478
--- /dev/null
+++ b/test/OtherInterfacesTestSprint8.java
@@ -0,0 +1,117 @@
+import manager.CrossingException;
+import manager.FileBackedTaskManager;
+import manager.HistoryManager;
+import manager.Managers;
+import model.Epic;
+import model.Status;
+import model.SubTask;
+import model.Task;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import java.time.Duration;
+import java.time.LocalDateTime;
+
+public class OtherInterfacesTestSprint8 {
+
+ private static FileBackedTaskManager master;
+ private static HistoryManager historian;
+ private static Task task1;
+ private static Task task2;
+ private static Epic epic1;
+ private static SubTask sub1;
+ private static SubTask sub2;
+ private static SubTask sub3;
+
+ @BeforeEach
+ void managersCreationUtilityTest() {
+ master = new FileBackedTaskManager("true");
+ historian = Managers.getDefaultHistory();
+ task1 = new Task("1", "Task1", Status.NEW);
+ task2 = new Task("2", "Task2", Status.NEW);
+ epic1 = new Epic("3", "Epic1", Status.NEW);
+ sub1 = new SubTask("6", "Sub1", Status.NEW, 3);
+ sub2 = new SubTask("7", "Sub2", Status.NEW, 3);
+ sub3 = new SubTask("8", "Sub3", Status.NEW, 3);
+ }
+
+ @Test
+ void checkEpicStatusChanging() {
+ master.addTask(task1);
+ master.addTask(task2);
+ master.addEpic(epic1);
+ master.addSub(sub1);
+ Assertions.assertEquals(Status.NEW, master.getEpic(3).getStatus());
+ sub2.setStatus(Status.IN_PROGRESS);
+ master.addSub(sub2);
+ master.updateSubTask(new SubTask("7", "Sub2", Status.IN_PROGRESS, 3));
+ Assertions.assertEquals(Status.IN_PROGRESS, master.getEpic(3).getStatus());
+ master.addSub(sub3);
+ master.updateSubTask(new SubTask("6", "Sub1", Status.DONE, 3));
+ master.updateSubTask(new SubTask("7", "Sub2", Status.DONE, 3));
+ master.updateSubTask(new SubTask("8", "Sub3", Status.DONE, 3));
+ Assertions.assertEquals(Status.DONE, master.getEpic(3).getStatus());
+ }
+
+ @Test
+ void checkTimeManagerPriority() {
+ task1.setStartTime(LocalDateTime.of(2002, 1, 1, 0, 10));
+ task1.setDuration(Duration.ofMinutes(10));
+ task2.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 0));
+ task2.setDuration(Duration.ofMinutes(10));
+ epic1.setDuration(Duration.ofMinutes(10));
+ epic1.setStartTime(LocalDateTime.of(1990, 1, 1, 0, 0));
+ master.addTask(task2);
+ master.addTask(task1);
+ master.addEpic(epic1);
+ Assertions.assertEquals(master.getEpic(3), master.getPrioritizedTasks().get(0));
+ Assertions.assertEquals(master.getTask(2), master.getPrioritizedTasks().get(2));
+ Assertions.assertEquals(master.getTask(1), master.getPrioritizedTasks().get(1));
+ }
+
+ @Test
+ void checkCrossTimeTest() {
+ task1.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 10));
+ task1.setDuration(Duration.ofMinutes(10));
+ task2.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 10));
+ task2.setDuration(Duration.ofMinutes(10));
+ master.addTask(task1);
+ try {
+ master.addTask(task2);
+ } catch (CrossingException e){
+ System.out.println(e.getMessage());
+ }
+ task2.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 1));
+ task2.setDuration(Duration.ofMinutes(10));
+ try{
+ master.addTask(task2);
+ }catch (CrossingException e){
+ System.out.println(e.getMessage());
+ }
+ task2.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 19));
+ task2.setDuration(Duration.ofMinutes(10));
+ try{
+ master.addTask(task2);
+ }catch (CrossingException e){
+ System.out.println(e.getMessage());
+ }
+ Assertions.assertEquals(1, master.getAllTasks().size());
+ task2.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 20));
+ task2.setDuration(Duration.ofMinutes(10));
+ master.addTask(task2);
+ Assertions.assertEquals(2, master.getAllTasks().size());
+ }
+
+ void checkEpicTimeUpdate() {
+ master.addTask(task1);
+ master.addTask(task2);
+ epic1.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 10));
+ epic1.setDuration(Duration.ofMinutes(10));
+ master.addEpic(epic1);
+ Assertions.assertEquals(LocalDateTime.of(2000, 1, 1, 0, 10), epic1.getStartTime());
+ sub1.setStartTime(LocalDateTime.of(2000, 1, 1, 0, 0));
+ sub1.setDuration(Duration.ofMinutes(60));
+ Assertions.assertEquals(LocalDateTime.of(2000, 1, 1, 0, 0), epic1.getStartTime());
+ Assertions.assertEquals(LocalDateTime.of(2000, 1, 1, 0, 60), epic1.getEndTime());
+ }
+}