Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/gson_2_9_0.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions java-kanban.iml
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="gson-2.9.0" level="project" />
</component>
</module>
2 changes: 1 addition & 1 deletion src/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

public class Main {

public static void main(String[] args) {
public static void main(String[] args) throws InterruptedException {
final long MINUTES_IN_DAY = 60 * 24;
final LocalDateTime TASK_START_TIME = LocalDateTime.now();
System.out.println("Поехали!");
Expand Down
23 changes: 23 additions & 0 deletions src/tracker/adapter/LocalDateAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package tracker.adapter;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateAdapter extends TypeAdapter<LocalDateTime> {
private static final DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

@Override
public void write(final JsonWriter jsonWriter, final LocalDateTime localDate) throws IOException {
jsonWriter.value(localDate.format(dtf));
}

@Override
public LocalDateTime read(final JsonReader jsonReader) throws IOException {
return LocalDateTime.parse(jsonReader.nextString(), dtf);
}
}
59 changes: 25 additions & 34 deletions src/tracker/controllers/InMemoryTaskManager.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package tracker.controllers;

import tracker.exceptions.OverlapsException;
import tracker.model.Epic;
import tracker.model.Status;
import tracker.model.Subtask;
Expand Down Expand Up @@ -134,26 +135,20 @@ public ArrayList<Subtask> getEpicsSubtasks(int epicId) {
// Создание. Сам объект должен передаваться в качестве параметра.
@Override
public void createTask(Task task) {
if (noIntersectionWithTasks(task)) {
tasks.put(taskId, task);
sortedTasks.add(task);
taskId++;
} else {
System.out.println("Пересечение с текущими задачами");
}
hasIntersectionWithTasks(task);
tasks.put(taskId, task);
sortedTasks.add(task);
taskId++;
}

@Override
public void createSubtask(Subtask task) {
if (noIntersectionWithTasks(task)) {
subtasks.put(taskId, task);
sortedTasks.add(task);
updateEpicStatus(task.getEpic());
updateEpicEndTimeAndDuration(task.getEpic());
taskId++;
} else {
System.out.println("Пересечение с текущими задачами.");
}
hasIntersectionWithTasks(task);
subtasks.put(taskId, task);
sortedTasks.add(task);
updateEpicStatus(task.getEpic());
updateEpicEndTimeAndDuration(task.getEpic());
taskId++;
}

@Override
Expand All @@ -169,13 +164,10 @@ public void updateTask(Task task) {
if (updatedTask == null) {
System.out.println("Задача с id = " + task.getId() + " не найдена");
}
if (noIntersectionWithTasks(task)) {
sortedTasks.remove(updatedTask);
tasks.put(task.getId(), task);
sortedTasks.add(task);
} else {
System.out.println("Пересечение с текущими задачами");
}
hasIntersectionWithTasks(task);
sortedTasks.remove(updatedTask);
tasks.put(task.getId(), task);
sortedTasks.add(task);
}

@Override
Expand All @@ -184,15 +176,12 @@ public void updateSubtask(Subtask task) {
if (updatedTask == null) {
System.out.println("Задача с id = " + task.getId() + " не найдена");
}
if (noIntersectionWithTasks(task)) {
sortedTasks.remove(updatedTask);
subtasks.put(task.getId(), task);
sortedTasks.add(task);
updateEpicStatus(task.getEpic());
updateEpicEndTimeAndDuration(task.getEpic());
} else {
System.out.println("Пересечение с текущими задачами");
}
hasIntersectionWithTasks(task);
sortedTasks.remove(updatedTask);
subtasks.put(task.getId(), task);
sortedTasks.add(task);
updateEpicStatus(task.getEpic());
updateEpicEndTimeAndDuration(task.getEpic());
}

@Override
Expand Down Expand Up @@ -303,12 +292,14 @@ private <T extends Task> boolean intersectionChecked(T task1, T task2) {
&& (endTime1.isAfter(endTime2) || endTime1.isEqual(endTime2));
}

private <T extends Task> boolean noIntersectionWithTasks(T task) {
private <T extends Task> void hasIntersectionWithTasks(T task) {
List<Task> intersectedTasks = sortedTasks.stream()
.filter(currentTask -> !currentTask.equals(task))
.filter(currentTask -> intersectionChecked(task, currentTask))
.toList();
return intersectedTasks.isEmpty();
if (!intersectedTasks.isEmpty()) {
throw new OverlapsException("Есть пересечение с текущими задачами");
}
}
}

7 changes: 7 additions & 0 deletions src/tracker/exceptions/OverlapsException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tracker.exceptions;

public class OverlapsException extends RuntimeException {
public OverlapsException(final String message) {
super(message);
}
}
44 changes: 44 additions & 0 deletions src/tracker/handler/BaseHttpHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package tracker.handler;

import com.google.gson.Gson;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import tracker.controllers.TaskManager;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public abstract class BaseHttpHandler implements HttpHandler {
protected final Gson gson;
protected final TaskManager taskManager;
protected final Charset charset = StandardCharsets.UTF_8;

public BaseHttpHandler(Gson gson, TaskManager taskManager) {
this.gson = gson;
this.taskManager = taskManager;
}

public static void sendText(HttpExchange httpExchange, String text, int code) throws IOException {
byte[] response = text.getBytes(StandardCharsets.UTF_8);
httpExchange.getResponseHeaders().add("Content-Type", "application/json;charset=utf-8");
httpExchange.sendResponseHeaders(code, response.length);
httpExchange.getResponseBody().write(response);
httpExchange.close();
}

public static void sendNotFound(HttpExchange httpExchange) throws IOException {
httpExchange.sendResponseHeaders(404, 0);
httpExchange.close();
}

public static void sendHasOverlaps(HttpExchange httpExchange) throws IOException {
httpExchange.sendResponseHeaders(406, 0);
httpExchange.close();
}

public static void sendServerError(HttpExchange httpExchange) throws IOException {
httpExchange.sendResponseHeaders(500, 0);
httpExchange.close();
}
}
82 changes: 82 additions & 0 deletions src/tracker/handler/EpicsHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package tracker.handler;

import com.google.gson.Gson;
import com.sun.net.httpserver.HttpExchange;
import tracker.controllers.TaskManager;
import tracker.model.Epic;

import java.io.IOException;
import java.io.InputStream;

public class EpicsHandler extends BaseHttpHandler {
public EpicsHandler(Gson gson, TaskManager taskManager) {
super(gson, taskManager);
}

@Override
public void handle(HttpExchange httpExchange) throws IOException {
String method = httpExchange.getRequestMethod();
String path = httpExchange.getRequestURI().getPath();
String[] partsOfPath = path.split("/");
switch (method) {
case "GET" -> {
if (partsOfPath.length == 2) {
BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getEpics()), 200);
return;
} else if (partsOfPath.length == 3) {
int id = Integer.parseInt(partsOfPath[2]);
Epic epic = taskManager.getEpicById(id);
if (epic == null) {
BaseHttpHandler.sendNotFound(httpExchange);
} else {
BaseHttpHandler.sendText(httpExchange, gson.toJson(epic), 200);
}
} else if (partsOfPath.length == 4 && partsOfPath[3].equals("subtasks")) {
int id = Integer.parseInt(partsOfPath[2]);
Epic epic = taskManager.getEpicById(id);
if (epic == null) {
BaseHttpHandler.sendNotFound(httpExchange);
} else {
BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getEpicsSubtasks(id)),
200);
}
} else {
BaseHttpHandler.sendServerError(httpExchange);
}
httpExchange.close();
}
case "POST" -> {
if (partsOfPath.length == 2) {
InputStream inputStream = httpExchange.getRequestBody();
String body = new String(inputStream.readAllBytes(), charset);
if (body.isEmpty()) {
BaseHttpHandler.sendServerError(httpExchange);
} else {
Epic epic = gson.fromJson(body, Epic.class);
taskManager.createEpic(epic);
BaseHttpHandler.sendText(httpExchange, gson.toJson(epic), 201);
}
} else {
BaseHttpHandler.sendServerError(httpExchange);
}
httpExchange.close();
}
case "DELETE" -> {
if (partsOfPath.length == 3) {
int id = Integer.parseInt(partsOfPath[2]);
Epic epic = taskManager.getEpicById(id);
if (epic == null) {
BaseHttpHandler.sendNotFound(httpExchange);
} else {
taskManager.deleteEpic(epic);
BaseHttpHandler.sendText(httpExchange, gson.toJson(epic), 200);
}
} else {
BaseHttpHandler.sendServerError(httpExchange);
}
httpExchange.close();
}
default -> BaseHttpHandler.sendServerError(httpExchange);
}
}
}
31 changes: 31 additions & 0 deletions src/tracker/handler/HistoryHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package tracker.handler;

import com.google.gson.Gson;
import com.sun.net.httpserver.HttpExchange;
import tracker.controllers.TaskManager;

import java.io.IOException;

public class HistoryHandler extends BaseHttpHandler {
public HistoryHandler(Gson gson, TaskManager taskManager) {
super(gson, taskManager);
}

@Override
public void handle(HttpExchange httpExchange) throws IOException {
String method = httpExchange.getRequestMethod();
String path = httpExchange.getRequestURI().getPath();
String[] partsOfPath = path.split("/");
if (method.equals("GET")) {
if (partsOfPath.length == 2) {
BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getHistory()), 200);
return;
} else {
BaseHttpHandler.sendServerError(httpExchange);
}
httpExchange.close();
} else {
BaseHttpHandler.sendServerError(httpExchange);
}
}
}
31 changes: 31 additions & 0 deletions src/tracker/handler/PrioritizedHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package tracker.handler;

import com.google.gson.Gson;
import com.sun.net.httpserver.HttpExchange;
import tracker.controllers.TaskManager;

import java.io.IOException;

public class PrioritizedHandler extends BaseHttpHandler {
public PrioritizedHandler(Gson gson, TaskManager taskManager) {
super(gson, taskManager);
}

@Override
public void handle(HttpExchange httpExchange) throws IOException {
String method = httpExchange.getRequestMethod();
String path = httpExchange.getRequestURI().getPath();
String[] partsOfPath = path.split("/");
if (method.equals("GET")) {
if (partsOfPath.length == 2) {
BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getPrioritizedTasks()), 200);
return;
} else {
BaseHttpHandler.sendServerError(httpExchange);
}
httpExchange.close();
} else {
BaseHttpHandler.sendServerError(httpExchange);
}
}
}
Loading