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
4 changes: 2 additions & 2 deletions src/ru/practicum/task_tracker/CSVFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static String toString(Task task) {
public static Task taskFromString(String csvRow) {
String[] columns = csvRow.split(",");
return new Task(Integer.parseInt(columns[1]), columns[2], columns[3], getStatus(columns[4]),
Long.parseLong(columns[5]), LocalDateTime.parse(columns[6]));
Integer.parseInt(columns[5]), LocalDateTime.parse(columns[6]));
}

public static Epic epicFromString(String csvRow) {
Expand All @@ -39,7 +39,7 @@ public static Epic epicFromString(String csvRow) {
public static Subtask subtaskFromString(String csvRow) {
String[] columns = csvRow.split(",");
return new Subtask(Integer.parseInt(columns[7]), Integer.parseInt(columns[1]), columns[2],
columns[3], getStatus(columns[4]), Long.parseLong(columns[5]), LocalDateTime.parse(columns[6]));
columns[3], getStatus(columns[4]), Integer.parseInt(columns[5]), LocalDateTime.parse(columns[6]));
}

private static Status getStatus(String str) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.practicum.task_tracker.http.Exception;

public class BadRequestException extends RuntimeException {

public BadRequestException(String msg) {
super(msg);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ru.practicum.task_tracker.http.Exception;

public class NotAcceptableException extends RuntimeException {

public NotAcceptableException(String msg) {
super(msg);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.practicum.task_tracker.http.Exception;

public class NotFoundException extends RuntimeException {

public NotFoundException(String msg) {
super(msg);
}
}
54 changes: 54 additions & 0 deletions src/ru/practicum/task_tracker/http/HttpTaskServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package ru.practicum.task_tracker.http;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sun.net.httpserver.HttpServer;
import ru.practicum.task_tracker.Managers;
import ru.practicum.task_tracker.http.adapter.DurationAdapter;
import ru.practicum.task_tracker.http.adapter.LocalDateTimeAdapter;
import ru.practicum.task_tracker.http.handler.*;
import ru.practicum.task_tracker.manager.TaskManager;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.time.LocalDateTime;

public class HttpTaskServer {
public static final int PORT = 8080;

private final HttpServer httpServer;
private final TaskManager taskManager;

public HttpTaskServer(TaskManager taskManager) throws IOException {
this.taskManager = taskManager;
this.httpServer = HttpServer.create(new InetSocketAddress("localHost", PORT), 0);
this.httpServer.createContext("/tasks", new TaskHandler(taskManager));
this.httpServer.createContext("/subtasks", new SubtaskHandler(taskManager));
this.httpServer.createContext("/epics", new EpicHandler(taskManager));
this.httpServer.createContext("/history", new HistoryHandler(taskManager));
this.httpServer.createContext("/prioritized", new PrioritizedHandler(taskManager));
}

public void start() {
httpServer.start();
}

public void stop() {
httpServer.stop(0);
}

public static void main(String[] args) throws IOException {
TaskManager taskManager = Managers.getDefault();
HttpTaskServer httpTaskServer = new HttpTaskServer(taskManager);
httpTaskServer.start();
}

public static Gson getGson() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter());
gsonBuilder.registerTypeAdapter(Duration.class, new DurationAdapter());
return gsonBuilder.create();
}

}
24 changes: 24 additions & 0 deletions src/ru/practicum/task_tracker/http/adapter/DurationAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ru.practicum.task_tracker.http.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.Duration;

public class DurationAdapter extends TypeAdapter<Duration> {
@Override
public void write(JsonWriter jsonWriter, Duration duration) throws IOException {
if (duration == null) {
jsonWriter.value("null");
} else {
jsonWriter.value(duration.toMinutes());
}
}

@Override
public Duration read(JsonReader jsonReader) throws IOException {
return Duration.ofMinutes(jsonReader.nextInt());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ru.practicum.task_tracker.http.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 LocalDateTimeAdapter extends TypeAdapter<LocalDateTime> {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

@Override
public void write(JsonWriter jsonWriter, LocalDateTime localDateTime) throws IOException {
if (localDateTime == null) {
String str = "null";
jsonWriter.value(str);
} else {
jsonWriter.value(localDateTime.format(FORMATTER));
}
}

@Override
public LocalDateTime read(JsonReader jsonReader) throws IOException {
String str = jsonReader.nextString();
return LocalDateTime.parse(str, FORMATTER);
}
}
51 changes: 51 additions & 0 deletions src/ru/practicum/task_tracker/http/handler/BaseHttpHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package ru.practicum.task_tracker.http.handler;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sun.net.httpserver.HttpExchange;
import ru.practicum.task_tracker.task.Status;

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

public abstract class BaseHttpHandler {

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

protected static void sendException(HttpExchange h, String text, int statusCode) throws IOException {
byte[] resp = text.getBytes(StandardCharsets.UTF_8);
h.sendResponseHeaders(statusCode, resp.length);
h.getResponseHeaders().add("Content-Type", "application/json;charset=utf-8");
h.getResponseBody().write(resp);
h.close();
}


protected Integer jsonObjectGetId(String body) {
JsonObject jsonObject = JsonParser.parseString(body).getAsJsonObject();
return jsonObject.get("id") != null ? jsonObject.get("id").getAsInt() : null;
}

protected Status getStatus(String str) {
return switch (str) {
case "IN_PROGRESS" -> Status.IN_PROGRESS;
case "DONE" -> Status.DONE;
default -> Status.NEW;
};
}

protected Integer getIdFromPath(String path) {
String[] parts = path.split("/");
if (parts.length >= 3) {
return Integer.parseInt(parts[2]);
}
return null;
}

}
108 changes: 108 additions & 0 deletions src/ru/practicum/task_tracker/http/handler/EpicHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package ru.practicum.task_tracker.http.handler;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import ru.practicum.task_tracker.http.Exception.BadRequestException;
import ru.practicum.task_tracker.http.Exception.NotAcceptableException;
import ru.practicum.task_tracker.http.HttpTaskServer;
import ru.practicum.task_tracker.manager.TaskManager;
import ru.practicum.task_tracker.task.Epic;
import ru.practicum.task_tracker.task.Subtask;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class EpicHandler extends BaseHttpHandler implements HttpHandler {

private final TaskManager taskManager;

public EpicHandler(TaskManager taskManager) {
this.taskManager = taskManager;
}

@Override
public void handle(HttpExchange exchange) throws IOException {
try {
InputStream inputStream = exchange.getRequestBody();
String body = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
String path = exchange.getRequestURI().getPath();
Integer id = getIdFromPath(path);

switch (exchange.getRequestMethod()) {
case "GET":
if (id == null) {
List<Epic> epics = taskManager.getEpics();
String response = HttpTaskServer.getGson().toJson(epics);
sendText(exchange, response, 200);
} else {
Epic epic = taskManager.getByEpicId(id);
System.out.println(epic.getDuration());

if (booleanSubtasksPath(path)) {
List<Subtask> subtasks = epic.getSubtasks();
String response = HttpTaskServer.getGson().toJson(subtasks);
sendText(exchange, response, 200);
}
String response = HttpTaskServer.getGson().toJson(epic);
sendText(exchange, response, 200);
}
break;
case "POST":
Epic createdEpic = taskManager.createEpic(getNewEpic(body));
String responsePost = HttpTaskServer.getGson().toJson("Задача создана. id = " + createdEpic.getId());
sendText(exchange, responsePost, 201);
break;
case "DELETE":
if (id == null) {
throw new NotAcceptableException("Не передан id.");
}
taskManager.deleteEpic(id);
String response = HttpTaskServer.getGson().toJson("Задача удалена.");
sendText(exchange, response, 200);
break;
default:
throw new NotAcceptableException("Нет обработки текущей команды.");
}
} catch (Exception e) {
ErrorHandler.handleException(exchange, e);
} finally {
exchange.close();
}
}

private Epic getNewEpic(String body) {
JsonElement jsonElement = JsonParser.parseString(body);

if (jsonElement.isJsonNull()) {
throw new BadRequestException("Нет входных параметров");
}

JsonObject jsonObject = jsonElement.getAsJsonObject();

String name = jsonObject.get("name") != null ? jsonObject.get("name").getAsString() : null;
String description = jsonObject.get("description") != null ?
jsonObject.get("description").getAsString() : null;

if (name == null || description == null) {
throw new BadRequestException("От пользователя некорректно передана задача");
} else {
return new Epic(name, description);
}

}

protected Boolean booleanSubtasksPath(String path) {
String[] parts = path.split("/");
if (parts.length >= 4) {
return parts[3].equals("subtasks");
}
return false;

}

}
29 changes: 29 additions & 0 deletions src/ru/practicum/task_tracker/http/handler/ErrorHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package ru.practicum.task_tracker.http.handler;

import com.sun.net.httpserver.HttpExchange;
import ru.practicum.task_tracker.http.Exception.BadRequestException;
import ru.practicum.task_tracker.http.Exception.NotAcceptableException;
import ru.practicum.task_tracker.http.Exception.NotFoundException;

import java.io.IOException;


public class ErrorHandler extends BaseHttpHandler {

public static void handleException(HttpExchange h, Exception e) throws IOException {
int status;

try {
status = switch (e) {
case BadRequestException badRequestException -> 400;
case NotFoundException notFoundException -> 404;
case NotAcceptableException notAcceptableException -> 406;
case null, default -> throw e;
};
sendException(h, e.getMessage(), status);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}

}
37 changes: 37 additions & 0 deletions src/ru/practicum/task_tracker/http/handler/HistoryHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ru.practicum.task_tracker.http.handler;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import ru.practicum.task_tracker.http.Exception.NotAcceptableException;
import ru.practicum.task_tracker.http.HttpTaskServer;
import ru.practicum.task_tracker.manager.TaskManager;
import ru.practicum.task_tracker.task.Task;

import java.io.IOException;
import java.util.List;

public class HistoryHandler extends BaseHttpHandler implements HttpHandler {
private final TaskManager taskManager;

public HistoryHandler(TaskManager taskManager) {
this.taskManager = taskManager;
}

@Override
public void handle(HttpExchange exchange) throws IOException {

try {
if (exchange.getRequestMethod().equals("GET")) {
List<Task> history = taskManager.getHistory();
String response = HttpTaskServer.getGson().toJson(history);
sendText(exchange, response, 200);
} else {
throw new NotAcceptableException("Нет обработки текущей команды.");
}
} catch (Exception e) {
ErrorHandler.handleException(exchange, e);
} finally {
exchange.close();
}
}
}
Loading