diff --git a/docs/openapi.yaml b/docs/openapi.yaml
index a5e95a1..2dde410 100644
--- a/docs/openapi.yaml
+++ b/docs/openapi.yaml
@@ -1,7 +1,7 @@
openapi: 3.0.0
info:
title: "WebProg Lab1"
- version: 0.0.2
+ version: 0.1.0
description: |
Сервак из говна и палок
@@ -11,11 +11,11 @@ servers:
description: FastCGI API
paths:
- /:
+ /test:
get:
summary: Тест попадания в область
tags:
- - General
+ - Test hit
parameters:
- in: query
name: x
@@ -55,6 +55,58 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
+
+ /journal:
+ get:
+ summary: Получение истории
+ tags:
+ - Journal
+ responses:
+ 200:
+ description: Responce with data
+ content:
+ application/json:
+ schema:
+ type: array
+ description: Нужные для получения поля профиля пользователя
+ items:
+ type: object
+ properties:
+ timestamp:
+ type: integer
+ description: "Timestamp в милисекундах"
+ example: 1000000
+ elapsedTimeNs:
+ type: integer
+ description: "Затраченное на обработку время в наносекундах"
+ example: 100
+ x:
+ type: integer
+ example: 0
+ y:
+ type: integer
+ example: 0
+ r:
+ type: integer
+ example: 0
+ isInsideArea:
+ type: boolean
+ example: true
+ delete:
+ summary: Удаление истории
+ tags:
+ - Journal
+ responses:
+ 200:
+ description: Responce
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ result:
+ type: string
+ example: "Completed!"
components:
schemas:
x:
diff --git a/httpd/static/index.html b/httpd/static/index.html
index 6f4ebe2..eb91965 100644
--- a/httpd/static/index.html
+++ b/httpd/static/index.html
@@ -3,9 +3,14 @@
- Web lab1
-
+ Web lab1
+
+
+
+
+
+
@@ -671,167 +676,93 @@ История введенных данных
diff --git a/httpd/static/js/ajax.js b/httpd/static/js/ajax.js
deleted file mode 100644
index 9975aa8..0000000
--- a/httpd/static/js/ajax.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const sendAJAXGETRequest = (url, data, callback) => {
- // encode url
- const query = [];
- for (const key in data) {
- query.push(String(key) + '=' + String(data[key]));
- }
-
- // creating AJAX req object
- const xhr = new XMLHttpRequest();
- // enable CORS support
- xhr.withCredentials = true;
-
- xhr.open("GET", url+(query.length ? '?' + query.join('&') : ''));
-
- xhr.onreadystatechange = () => {
- if (xhr.readyState == 4) { // status of finished request
- callback(xhr.responseText)
- }
- };
-
- xhr.send(data)
-};
\ No newline at end of file
diff --git a/httpd/static/js/error.js b/httpd/static/js/error.js
new file mode 100644
index 0000000..d7384b2
--- /dev/null
+++ b/httpd/static/js/error.js
@@ -0,0 +1,31 @@
+class ErrorFactory {
+ #errorBlockClassName
+
+ constructor(errorBlockClassName){
+ this.#errorBlockClassName = errorBlockClassName;
+ }
+
+ #clearErrors(){
+ let existingErrors = document.querySelectorAll(this.#errorBlockClassName);
+ existingErrors.forEach(error => error.remove());
+ }
+
+ showError(message, showTimeMs = 5000){
+ this.#clearErrors();
+
+ // Слздаём элемент
+ const errorDiv = document.createElement('div');
+ errorDiv.className = this.#errorBlockClassName;
+ errorDiv.textContent = message;
+
+ // Вставка
+ document.body.appendChild(errorDiv);
+
+ // Убираем по прошествии времени
+ setTimeout(() => {
+ if (errorDiv.parentNode) {
+ errorDiv.parentNode.removeChild(errorDiv);
+ }
+ }, showTimeMs);
+ }
+}
\ No newline at end of file
diff --git a/httpd/static/js/historyTable.js b/httpd/static/js/historyTable.js
new file mode 100644
index 0000000..a43dd29
--- /dev/null
+++ b/httpd/static/js/historyTable.js
@@ -0,0 +1,47 @@
+class HistoryTable {
+ #tableElem;
+ #emptyHistoryElem;
+
+ constructor(tableId, emptyHistoryBlockId) {
+ this.#tableElem = document.getElementById(tableId);
+
+ this.#emptyHistoryElem = new EmptyBlock(emptyHistoryBlockId);
+ this.#emptyHistoryElem.setVisibility(true);
+ }
+
+ addHistoryItem(timestamp, elapsedTime, x, y, r, isHitted) {
+ this.#emptyHistoryElem.setVisibility(false);
+
+ const row = document.createElement('tr');
+
+ row.innerHTML = `
+ ${new Date(timestamp).toLocaleString('ru-RU')} |
+ ${elapsedTime} ns |
+ ${x} |
+ ${y} |
+ ${r} |
+ ${isHitted ? 'HIT' : 'MISS'} |
+ `;
+
+ this.#tableElem.prepend(row);
+ }
+
+ clear() {
+ this.#tableElem.querySelectorAll('tr').forEach((elem) => {
+ elem.remove();
+ });
+ this.#emptyHistoryElem.setVisibility(true);
+ }
+}
+
+class EmptyBlock {
+ #emptyHistoryElem;
+
+ constructor(emptyHistoryBlockId) {
+ this.#emptyHistoryElem = document.getElementById(emptyHistoryBlockId);
+ }
+
+ setVisibility(isVisible) {
+ emptyHistory.style.display = isVisible ? 'block' : 'none';
+ }
+}
\ No newline at end of file
diff --git a/httpd/static/js/net/ajax.js b/httpd/static/js/net/ajax.js
new file mode 100644
index 0000000..c326b6b
--- /dev/null
+++ b/httpd/static/js/net/ajax.js
@@ -0,0 +1,34 @@
+const sendAJAXRequest = (method, url, data) => {
+ return new Promise((resolve, reject) => {
+ // encode url
+ const query = [];
+ for (const key in data) {
+ query.push(String(key) + '=' + String(data[key]));
+ }
+
+ // creating AJAX req object
+ const xhr = new XMLHttpRequest();
+ // enable CORS support
+ xhr.withCredentials = true;
+
+ xhr.open(method, url + (query.length ? '?' + query.join('&') : ''));
+
+ xhr.onreadystatechange = () => {
+ if (xhr.readyState === 4) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ resolve({
+ status: xhr.status,
+ response: xhr.responseText
+ });
+ } else {
+ reject({
+ status: xhr.status,
+ response: xhr.responseText
+ });
+ }
+ }
+ };
+
+ xhr.send();
+ });
+};
\ No newline at end of file
diff --git a/httpd/static/js/plot.js b/httpd/static/js/plot.js
new file mode 100644
index 0000000..2206469
--- /dev/null
+++ b/httpd/static/js/plot.js
@@ -0,0 +1,37 @@
+const convertInputCordsToSvgCords = (
+ X, Y, R,
+ paddingX = 20,
+ paddingY = 20,
+ XAxisSize = 160,
+ YAxisSize = 160
+) => {
+ return [paddingX + (1 + X/R)*XAxisSize/2, paddingY + (1 - Y/R)*YAxisSize/2];
+}
+
+
+class Plot {
+ #svgNamespace = "http://www.w3.org/2000/svg";
+ #container;
+
+ constructor(svgId) {
+ this.#container = document.getElementById(svgId);
+ }
+
+ addPoint(cx, cy, radius, styleClass) {
+ const point = document.createElementNS(this.#svgNamespace, 'circle');
+
+ point.setAttributeNS(null, 'cx', cx);
+ point.setAttributeNS(null, 'cy', cy);
+ point.setAttributeNS(null, 'r', radius);
+ point.setAttributeNS(null, 'class', styleClass);
+
+ this.#container.appendChild(point);
+ }
+
+ clear() {
+ this.#container.querySelectorAll('circle').forEach((elem) => {
+ elem.remove();
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/server/.idea/runConfigurations/Main.xml b/server/.idea/runConfigurations/Application.xml
similarity index 72%
rename from server/.idea/runConfigurations/Main.xml
rename to server/.idea/runConfigurations/Application.xml
index 2e1a7a7..b9e984c 100644
--- a/server/.idea/runConfigurations/Main.xml
+++ b/server/.idea/runConfigurations/Application.xml
@@ -1,8 +1,8 @@
-
+
-
+
diff --git a/server/dependency-reduced-pom.xml b/server/dependency-reduced-pom.xml
index 9443a5f..f6bfa29 100644
--- a/server/dependency-reduced-pom.xml
+++ b/server/dependency-reduced-pom.xml
@@ -12,7 +12,7 @@
- org.web1.Main
+ org.web1.Application
true
diff --git a/server/pom.xml b/server/pom.xml
index 1962106..878b144 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -32,7 +32,7 @@
- org.web1.Main
+ org.web1.Application
true
diff --git a/server/src/main/java/org/web1/Application.java b/server/src/main/java/org/web1/Application.java
new file mode 100644
index 0000000..ca751a7
--- /dev/null
+++ b/server/src/main/java/org/web1/Application.java
@@ -0,0 +1,38 @@
+package org.web1;
+
+import java.util.HashMap;
+import java.util.function.Consumer;
+
+import org.web1.http.RequestContext;
+import org.web1.http.handler.journal.DeleteJournal;
+import org.web1.http.handler.journal.GetJournal;
+import org.web1.http.handler.journal.utils.Journal;
+import org.web1.http.routing.EndpointKey;
+import org.web1.http.routing.RestController;
+import org.web1.http.handler.tester.Tester;
+
+
+public class Application {
+ public static void main(String[] args) {
+ final HashMap> endpoints = new HashMap<>();
+
+ final Journal journal = new Journal();
+
+ endpoints.put(
+ new EndpointKey("GET", "/fcgi/test"),
+ new Tester(journal)
+ );
+ endpoints.put(
+ new EndpointKey("DELETE", "/fcgi/journal"),
+ new DeleteJournal(journal)
+ );
+ endpoints.put(
+ new EndpointKey("GET", "/fcgi/journal"),
+ new GetJournal(journal)
+ );
+
+ new RestController(
+ endpoints
+ ).start();
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/java/org/web1/Main.java b/server/src/main/java/org/web1/Main.java
deleted file mode 100644
index 2397c72..0000000
--- a/server/src/main/java/org/web1/Main.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.web1;
-
-import com.fastcgi.FCGIInterface;
-
-import java.util.HashMap;
-import java.util.function.Function;
-import java.util.logging.Logger;
-
-import org.validator.ValidatedRecordFactory;
-import org.validator.validation.exceptions.ValidationException;
-import org.web1.DTOs.RequestDTO;
-import org.web1.checkers.Checker;
-import org.web1.checkers.CheckerFunction;
-import org.web1.utils.SimpleLogger;
-import org.web1.utils.mappers.JsonBuilder;
-import org.web1.utils.mappers.QueryStringToHashmap;
-import org.web1.utils.responce.ResponseController;
-import org.web1.utils.responce.ResponseStatus;
-import org.web1.utils.timer.Timer;
-
-public class Main {
- private static final Function> parseQuery = new QueryStringToHashmap();
- private static final CheckerFunction checker = new Checker();
-
- public static void main(String[] args) {
- FCGIInterface fastCGI = new FCGIInterface();
- Timer timer = new Timer();
- Logger logger = SimpleLogger.create();
- ResponseController responseController = new ResponseController(logger);
-
- while (fastCGI.FCGIaccept() >= 0) {
- timer.start();
-
- final HashMap queryParams = parseQuery.apply(
- FCGIInterface.request.params.getProperty("QUERY_STRING")
- );
- logger.info("Received request with query: " + queryParams);
-
- try {
- RequestDTO requestData = ValidatedRecordFactory.create(
- RequestDTO.class,
- queryParams.get("x"),
- queryParams.get("r"),
- queryParams.get("y")
- );
-
- boolean checkResult = checker.test(
- Integer.parseInt(requestData.X()),
- Float.parseFloat(requestData.Y()),
- Float.parseFloat(requestData.R())
- );
-
-
- responseController.send(
- new JsonBuilder()
- .add("result", checkResult)
- .add("elapsedTimeNs", timer.stop()),
- ResponseStatus.OK
- );
- } catch (ValidationException e) {
- responseController.send(
- new JsonBuilder()
- .add("error", '"'+e.getMessage()+'"'),
- ResponseStatus.BAD_REQUEST
- );
- } catch (Exception e) {
- logger.severe("Failed to process request: " + e.getMessage());
- }
- }
- }
-}
\ No newline at end of file
diff --git a/server/src/main/java/org/web1/utils/mappers/QueryStringToHashmap.java b/server/src/main/java/org/web1/http/QueryStringParser.java
similarity index 82%
rename from server/src/main/java/org/web1/utils/mappers/QueryStringToHashmap.java
rename to server/src/main/java/org/web1/http/QueryStringParser.java
index 5bc2ada..45f31a9 100644
--- a/server/src/main/java/org/web1/utils/mappers/QueryStringToHashmap.java
+++ b/server/src/main/java/org/web1/http/QueryStringParser.java
@@ -1,9 +1,9 @@
-package org.web1.utils.mappers;
+package org.web1.http;
import java.util.HashMap;
import java.util.function.Function;
-public class QueryStringToHashmap implements Function> {
+public class QueryStringParser implements Function> {
public HashMap apply(final String jsonStr) {
HashMap params = new HashMap<>();
diff --git a/server/src/main/java/org/web1/http/RequestContext.java b/server/src/main/java/org/web1/http/RequestContext.java
new file mode 100644
index 0000000..948d029
--- /dev/null
+++ b/server/src/main/java/org/web1/http/RequestContext.java
@@ -0,0 +1,10 @@
+package org.web1.http;
+
+import org.web1.http.response.HttpResponseWriter;
+
+import java.util.HashMap;
+
+public record RequestContext(
+ HashMap queryParams,
+ HttpResponseWriter responseController
+) {}
diff --git a/server/src/main/java/org/web1/http/handler/journal/DeleteJournal.java b/server/src/main/java/org/web1/http/handler/journal/DeleteJournal.java
new file mode 100644
index 0000000..2c95a88
--- /dev/null
+++ b/server/src/main/java/org/web1/http/handler/journal/DeleteJournal.java
@@ -0,0 +1,27 @@
+package org.web1.http.handler.journal;
+
+import org.web1.http.RequestContext;
+import org.web1.http.handler.journal.utils.Journal;
+import org.web1.http.response.ResponseStatus;
+import org.web1.utils.json.JsonBuilder;
+
+import java.util.function.Consumer;
+
+public class DeleteJournal implements Consumer {
+ private final Journal journal;
+
+ public DeleteJournal(Journal journal) {
+ this.journal = journal;
+ }
+
+ @Override
+ public void accept(
+ final RequestContext endpointData
+ ) {
+ this.journal.clear();
+ endpointData.responseController().send(
+ new JsonBuilder().add("status", "\"Completed!\""),
+ ResponseStatus.OK
+ );
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/java/org/web1/http/handler/journal/GetJournal.java b/server/src/main/java/org/web1/http/handler/journal/GetJournal.java
new file mode 100644
index 0000000..e755648
--- /dev/null
+++ b/server/src/main/java/org/web1/http/handler/journal/GetJournal.java
@@ -0,0 +1,34 @@
+package org.web1.http.handler.journal;
+
+import org.web1.http.RequestContext;
+import org.web1.http.handler.journal.utils.Journal;
+import org.web1.http.handler.journal.utils.JournalItem;
+import org.web1.http.response.ResponseStatus;
+import org.web1.utils.json.JsonBuilder;
+
+import java.util.Arrays;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+public class GetJournal implements Consumer {
+ private final Journal journal;
+
+ public GetJournal(Journal journal) {
+ this.journal = journal;
+ }
+
+ @Override
+ public void accept(
+ final RequestContext endpointData
+ ) {
+ endpointData.responseController().send(
+ new JsonBuilder().add(
+ "result",
+ "[" + journal.get().stream()
+ .map(JournalItem::toString)
+ .collect(Collectors.joining(",")) + "]"
+ ),
+ ResponseStatus.OK
+ );
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/java/org/web1/http/handler/journal/utils/Journal.java b/server/src/main/java/org/web1/http/handler/journal/utils/Journal.java
new file mode 100644
index 0000000..7789266
--- /dev/null
+++ b/server/src/main/java/org/web1/http/handler/journal/utils/Journal.java
@@ -0,0 +1,19 @@
+package org.web1.http.handler.journal.utils;
+
+import java.util.ArrayList;
+
+public class Journal {
+ private final ArrayList journal = new ArrayList<>();
+
+ public ArrayList get() {
+ return journal;
+ }
+
+ public void append(JournalItem journalItem) {
+ journal.add(journalItem);
+ }
+
+ public void clear() {
+ journal.clear();
+ }
+}
\ No newline at end of file
diff --git a/server/src/main/java/org/web1/http/handler/journal/utils/JournalItem.java b/server/src/main/java/org/web1/http/handler/journal/utils/JournalItem.java
new file mode 100644
index 0000000..821d44e
--- /dev/null
+++ b/server/src/main/java/org/web1/http/handler/journal/utils/JournalItem.java
@@ -0,0 +1,24 @@
+package org.web1.http.handler.journal.utils;
+
+public record JournalItem(
+ long timestamp,
+ long elapsedTimeNs,
+ int x,
+ float y,
+ float r,
+ boolean isInsideArea
+) {
+ @Override
+ public String toString() {
+ return String.format("""
+ {
+ "timestamp": %s,
+ "elapsedTimeNs": %s,
+ "x": %s,
+ "y": %s,
+ "r": %s,
+ "isInsideArea": %s
+ }
+ """, timestamp, elapsedTimeNs, x, y, r, isInsideArea);
+ }
+}
diff --git a/server/src/main/java/org/web1/DTOs/RequestDTO.java b/server/src/main/java/org/web1/http/handler/tester/RequestDTO.java
similarity index 85%
rename from server/src/main/java/org/web1/DTOs/RequestDTO.java
rename to server/src/main/java/org/web1/http/handler/tester/RequestDTO.java
index d811ccd..30100c5 100644
--- a/server/src/main/java/org/web1/DTOs/RequestDTO.java
+++ b/server/src/main/java/org/web1/http/handler/tester/RequestDTO.java
@@ -1,4 +1,4 @@
-package org.web1.DTOs;
+package org.web1.http.handler.tester;
import org.validator.annotations.Number;
diff --git a/server/src/main/java/org/web1/http/handler/tester/Tester.java b/server/src/main/java/org/web1/http/handler/tester/Tester.java
new file mode 100644
index 0000000..e9ef8c8
--- /dev/null
+++ b/server/src/main/java/org/web1/http/handler/tester/Tester.java
@@ -0,0 +1,74 @@
+package org.web1.http.handler.tester;
+
+import org.validator.ValidatedRecordFactory;
+import org.validator.validation.exceptions.ValidationException;
+import org.web1.http.RequestContext;
+import org.web1.http.handler.journal.utils.Journal;
+import org.web1.http.handler.journal.utils.JournalItem;
+import org.web1.http.handler.tester.checkers.Checker;
+import org.web1.http.handler.tester.checkers.CheckerFunction;
+import org.web1.utils.json.JsonBuilder;
+import org.web1.http.response.ResponseStatus;
+import org.web1.utils.time.Stopwatch;
+
+import java.util.function.Consumer;
+
+public class Tester implements Consumer {
+ private static final Stopwatch timer = new Stopwatch();
+ private static final CheckerFunction checker = new Checker();
+
+ private final Journal journal;
+
+ public Tester(Journal journal) {
+ this.journal = journal;
+ }
+
+ @Override
+ public void accept(
+ final RequestContext endpointData
+ ) {
+ timer.start();
+
+ try {
+ RequestDTO requestData = ValidatedRecordFactory.create(
+ RequestDTO.class,
+ endpointData.queryParams().get("x"),
+ endpointData.queryParams().get("r"),
+ endpointData.queryParams().get("y")
+ );
+
+ boolean checkResult = checker.test(
+ Integer.parseInt(requestData.X()),
+ Float.parseFloat(requestData.Y()),
+ Float.parseFloat(requestData.R())
+ );
+
+ final long elapsedTime = timer.stop();
+
+ this.journal.append(
+ new JournalItem(
+ System.currentTimeMillis(),
+ elapsedTime,
+ Integer.parseInt(requestData.X()),
+ Float.parseFloat(requestData.Y()),
+ Float.parseFloat(requestData.R()),
+ checkResult
+ )
+ );
+
+ endpointData.responseController().send(
+ new JsonBuilder()
+ .add("result", checkResult)
+ .add("elapsedTimeNs", timer.stop()),
+ ResponseStatus.OK
+ );
+ } catch (ValidationException e) {
+ endpointData.responseController().send(
+ new JsonBuilder()
+ .add("error", '"' + e.getMessage() + '"'),
+ ResponseStatus.BAD_REQUEST
+ );
+ }
+
+ }
+}
diff --git a/server/src/main/java/org/web1/checkers/Checker.java b/server/src/main/java/org/web1/http/handler/tester/checkers/Checker.java
similarity index 85%
rename from server/src/main/java/org/web1/checkers/Checker.java
rename to server/src/main/java/org/web1/http/handler/tester/checkers/Checker.java
index e6a1745..02c116c 100644
--- a/server/src/main/java/org/web1/checkers/Checker.java
+++ b/server/src/main/java/org/web1/http/handler/tester/checkers/Checker.java
@@ -1,6 +1,6 @@
-package org.web1.checkers;
-import org.web1.checkers.utils.PlotQuarters;
-import org.web1.checkers.utils.PlotUtils;
+package org.web1.http.handler.tester.checkers;
+import org.web1.http.handler.tester.checkers.utils.PlotQuarters;
+import org.web1.http.handler.tester.checkers.utils.PlotUtils;
public class Checker implements CheckerFunction{
public boolean test(final int x, final float y, final float r) {
diff --git a/server/src/main/java/org/web1/checkers/CheckerFunction.java b/server/src/main/java/org/web1/http/handler/tester/checkers/CheckerFunction.java
similarity index 73%
rename from server/src/main/java/org/web1/checkers/CheckerFunction.java
rename to server/src/main/java/org/web1/http/handler/tester/checkers/CheckerFunction.java
index 6948e52..ede7b89 100644
--- a/server/src/main/java/org/web1/checkers/CheckerFunction.java
+++ b/server/src/main/java/org/web1/http/handler/tester/checkers/CheckerFunction.java
@@ -1,4 +1,4 @@
-package org.web1.checkers;
+package org.web1.http.handler.tester.checkers;
import java.util.HashMap;
diff --git a/server/src/main/java/org/web1/checkers/utils/PlotQuarters.java b/server/src/main/java/org/web1/http/handler/tester/checkers/utils/PlotQuarters.java
similarity index 67%
rename from server/src/main/java/org/web1/checkers/utils/PlotQuarters.java
rename to server/src/main/java/org/web1/http/handler/tester/checkers/utils/PlotQuarters.java
index ec90417..a04c2a7 100644
--- a/server/src/main/java/org/web1/checkers/utils/PlotQuarters.java
+++ b/server/src/main/java/org/web1/http/handler/tester/checkers/utils/PlotQuarters.java
@@ -1,4 +1,4 @@
-package org.web1.checkers.utils;
+package org.web1.http.handler.tester.checkers.utils;
public enum PlotQuarters {
FIRST_QUADRANT,
diff --git a/server/src/main/java/org/web1/checkers/utils/PlotUtils.java b/server/src/main/java/org/web1/http/handler/tester/checkers/utils/PlotUtils.java
similarity index 91%
rename from server/src/main/java/org/web1/checkers/utils/PlotUtils.java
rename to server/src/main/java/org/web1/http/handler/tester/checkers/utils/PlotUtils.java
index c0134be..2972510 100644
--- a/server/src/main/java/org/web1/checkers/utils/PlotUtils.java
+++ b/server/src/main/java/org/web1/http/handler/tester/checkers/utils/PlotUtils.java
@@ -1,4 +1,4 @@
-package org.web1.checkers.utils;
+package org.web1.http.handler.tester.checkers.utils;
public class PlotUtils {
public static PlotQuarters getQuarter(final int x, final float y) {
diff --git a/server/src/main/java/org/web1/utils/responce/ResponseController.java b/server/src/main/java/org/web1/http/response/HttpResponseWriter.java
similarity index 82%
rename from server/src/main/java/org/web1/utils/responce/ResponseController.java
rename to server/src/main/java/org/web1/http/response/HttpResponseWriter.java
index 005e7cb..81414cd 100644
--- a/server/src/main/java/org/web1/utils/responce/ResponseController.java
+++ b/server/src/main/java/org/web1/http/response/HttpResponseWriter.java
@@ -1,15 +1,12 @@
-package org.web1.utils.responce;
+package org.web1.http.response;
-import org.web1.utils.mappers.JsonBuilder;
+import org.web1.utils.json.JsonBuilder;
-import java.io.FileWriter;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
-import java.util.logging.Level;
import java.util.logging.Logger;
-public class ResponseController {
+public class HttpResponseWriter {
private static final String BASE_RESPONSE = """
Status: %s\r
Access-Control-Allow-Origin: *\r
@@ -27,7 +24,7 @@ public class ResponseController {
responseStatus.put(ResponseStatus.OK, "200");
}
- public ResponseController(Logger logger) {
+ public HttpResponseWriter(Logger logger) {
this.logger = logger;
}
diff --git a/server/src/main/java/org/web1/utils/responce/ResponseStatus.java b/server/src/main/java/org/web1/http/response/ResponseStatus.java
similarity index 62%
rename from server/src/main/java/org/web1/utils/responce/ResponseStatus.java
rename to server/src/main/java/org/web1/http/response/ResponseStatus.java
index 99752bf..3e2cfdc 100644
--- a/server/src/main/java/org/web1/utils/responce/ResponseStatus.java
+++ b/server/src/main/java/org/web1/http/response/ResponseStatus.java
@@ -1,4 +1,4 @@
-package org.web1.utils.responce;
+package org.web1.http.response;
public enum ResponseStatus {
BAD_REQUEST,
diff --git a/server/src/main/java/org/web1/http/routing/EndpointKey.java b/server/src/main/java/org/web1/http/routing/EndpointKey.java
new file mode 100644
index 0000000..0954049
--- /dev/null
+++ b/server/src/main/java/org/web1/http/routing/EndpointKey.java
@@ -0,0 +1,6 @@
+package org.web1.http.routing;
+
+public record EndpointKey(
+ String method,
+ String path
+) { }
diff --git a/server/src/main/java/org/web1/http/routing/RestController.java b/server/src/main/java/org/web1/http/routing/RestController.java
new file mode 100644
index 0000000..66631a9
--- /dev/null
+++ b/server/src/main/java/org/web1/http/routing/RestController.java
@@ -0,0 +1,48 @@
+package org.web1.http.routing;
+
+import com.fastcgi.FCGIInterface;
+import org.web1.http.RequestContext;
+import org.web1.utils.logging.SimpleLogger;
+import org.web1.http.QueryStringParser;
+import org.web1.http.response.HttpResponseWriter;
+
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.logging.Logger;
+
+public class RestController {
+ private static final Function> parseQuery = new QueryStringParser();
+ private static final FCGIInterface fastCGI = new FCGIInterface();
+ private static final Logger logger = SimpleLogger.create();
+ private final HashMap> endpoints;
+
+ public RestController(HashMap> endpoints) {
+ this.endpoints = endpoints;
+ }
+
+ public void start() {
+ HttpResponseWriter responseController = new HttpResponseWriter(logger);
+
+ while (fastCGI.FCGIaccept() >= 0) {
+ final Properties requestParams = FCGIInterface.request.params;
+
+ final EndpointKey requestInfo = new EndpointKey(
+ requestParams.getProperty("REQUEST_METHOD"),
+ requestParams.getProperty("DOCUMENT_URI")
+ );
+ final HashMap requestData = parseQuery.apply(
+ requestParams.getProperty("QUERY_STRING")
+ );
+
+ logger.info(requestInfo.method() + " " + requestInfo.path() + " " + requestData);
+
+ Consumer requestHandler = endpoints.get(requestInfo);
+
+ if (requestHandler != null) requestHandler.accept(
+ new RequestContext(requestData, responseController)
+ );
+ }
+ }
+}
diff --git a/server/src/main/java/org/web1/utils/mappers/JsonBuilder.java b/server/src/main/java/org/web1/utils/json/JsonBuilder.java
similarity index 94%
rename from server/src/main/java/org/web1/utils/mappers/JsonBuilder.java
rename to server/src/main/java/org/web1/utils/json/JsonBuilder.java
index 44c8141..94c0976 100644
--- a/server/src/main/java/org/web1/utils/mappers/JsonBuilder.java
+++ b/server/src/main/java/org/web1/utils/json/JsonBuilder.java
@@ -1,4 +1,4 @@
-package org.web1.utils.mappers;
+package org.web1.utils.json;
import java.util.HashMap;
diff --git a/server/src/main/java/org/web1/utils/SimpleLogger.java b/server/src/main/java/org/web1/utils/logging/SimpleLogger.java
similarity index 62%
rename from server/src/main/java/org/web1/utils/SimpleLogger.java
rename to server/src/main/java/org/web1/utils/logging/SimpleLogger.java
index a7dcd05..7d27fe0 100644
--- a/server/src/main/java/org/web1/utils/SimpleLogger.java
+++ b/server/src/main/java/org/web1/utils/logging/SimpleLogger.java
@@ -1,15 +1,17 @@
-package org.web1.utils;
+package org.web1.utils.logging;
import java.io.IOException;
import java.util.logging.*;
public class SimpleLogger {
- static Logger logger = Logger.getLogger(Logger.class.getName());
+ private static final Logger logger = Logger.getLogger(SimpleLogger.class.getName());
+ private static final Formatter SimpleLoggerFormatter = new SimpleLoggerFormatter();
public static Logger create(){
try {
Handler fileHandler = new FileHandler("log.log");
- fileHandler.setFormatter(fileHandler.getFormatter());
+
+ fileHandler.setFormatter(SimpleLoggerFormatter);
logger.addHandler(fileHandler);
logger.setLevel(Level.INFO);
diff --git a/server/src/main/java/org/web1/utils/logging/SimpleLoggerFormatter.java b/server/src/main/java/org/web1/utils/logging/SimpleLoggerFormatter.java
new file mode 100644
index 0000000..0c1b378
--- /dev/null
+++ b/server/src/main/java/org/web1/utils/logging/SimpleLoggerFormatter.java
@@ -0,0 +1,22 @@
+package org.web1.utils.logging;
+
+import java.util.Date;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+public class SimpleLoggerFormatter extends Formatter {
+ private final String logstringFormat = "%s - %s %s \t %s \n";
+
+ @Override
+ public String format(LogRecord record) {
+ return String.format(
+ logstringFormat,
+
+ new Date(record.getMillis()),
+ record.getSourceClassName(),
+ record.getSourceMethodName(),
+ record.getMessage()
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/server/src/main/java/org/web1/utils/timer/Timer.java b/server/src/main/java/org/web1/utils/time/Stopwatch.java
similarity index 77%
rename from server/src/main/java/org/web1/utils/timer/Timer.java
rename to server/src/main/java/org/web1/utils/time/Stopwatch.java
index 5e27275..7fcecee 100644
--- a/server/src/main/java/org/web1/utils/timer/Timer.java
+++ b/server/src/main/java/org/web1/utils/time/Stopwatch.java
@@ -1,6 +1,6 @@
-package org.web1.utils.timer;
+package org.web1.utils.time;
-public class Timer {
+public class Stopwatch {
private long startTime;
public void start() {
this.startTime = System.nanoTime();