diff --git a/src/main/java/ru/ewc/checklogic/LogicChecker.java b/src/main/java/ru/ewc/checklogic/LogicChecker.java index a786199..c9f4402 100644 --- a/src/main/java/ru/ewc/checklogic/LogicChecker.java +++ b/src/main/java/ru/ewc/checklogic/LogicChecker.java @@ -24,9 +24,6 @@ package ru.ewc.checklogic; -import com.renomad.minum.web.FullSystem; -import com.renomad.minum.web.RequestLine; -import com.renomad.minum.web.WebFramework; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -45,8 +42,7 @@ import org.assertj.core.api.Assertions; import org.assertj.core.api.SoftAssertions; import org.yaml.snakeyaml.Yaml; -import ru.ewc.checklogic.server.CommandPage; -import ru.ewc.checklogic.server.StatePage; +import ru.ewc.checklogic.server.WebServer; import ru.ewc.commands.CommandsFacade; import ru.ewc.decisions.api.DecitaFacade; import ru.ewc.decisions.api.Locators; @@ -72,7 +68,6 @@ private LogicChecker() { // Utility class } - // @todo #20 Implement a registry of pages and their endpoints public static void main(final String[] args) { if (args.length == 0) { throw new IllegalArgumentException("Please provide the path to the resources"); @@ -83,22 +78,16 @@ public static void main(final String[] args) { ".csv", ";" ); - final Computation initial = new Computation( + final Computation computation = new Computation( decisions, new CommandsFacade(Path.of(root, "commands").toUri(), decisions), stateFromAppConfig(Path.of(root, "application.yaml").toFile()) ); if (args.length > 1 && "server".equals(args[1])) { - final FullSystem minum = FullSystem.initialize(); - final WebFramework web = minum.getWebFramework(); - final StatePage state = new StatePage(initial); - web.registerPath(RequestLine.Method.GET, "", state::statePage); - final CommandPage command = new CommandPage(initial); - web.registerPath(RequestLine.Method.POST, "command", command::commandPage); - minum.block(); + new WebServer(computation).start(); } else { System.setProperty("sources", root); - readFileNames().forEach(test -> performTest(test, new SoftAssertions(), initial)); + readFileNames().forEach(test -> performTest(test, new SoftAssertions(), computation)); } } diff --git a/src/main/java/ru/ewc/checklogic/server/CommandPage.java b/src/main/java/ru/ewc/checklogic/server/CommandPage.java index 762464f..2e81b12 100644 --- a/src/main/java/ru/ewc/checklogic/server/CommandPage.java +++ b/src/main/java/ru/ewc/checklogic/server/CommandPage.java @@ -25,6 +25,7 @@ import com.renomad.minum.web.Request; import com.renomad.minum.web.Response; +import com.renomad.minum.web.WebFramework; import java.util.Map; import ru.ewc.checklogic.Computation; import ru.ewc.checklogic.Transition; @@ -35,7 +36,7 @@ * * @since 0.3.0 */ -public final class CommandPage { +public final class CommandPage implements Endpoints { /** * The computation to be used for the command processing. */ @@ -50,6 +51,11 @@ public CommandPage(final Computation computation) { this.computation = computation; } + @Override + public void register(final WebFramework web) { + web.registerPath(POST, "command", this::commandPage); + } + public Response commandPage(final Request request) { final String command = request.body().asString("command"); this.computation.perform(new Transition(command, new Locators(Map.of()))); diff --git a/src/main/java/ru/ewc/checklogic/server/Endpoints.java b/src/main/java/ru/ewc/checklogic/server/Endpoints.java new file mode 100644 index 0000000..5fef312 --- /dev/null +++ b/src/main/java/ru/ewc/checklogic/server/Endpoints.java @@ -0,0 +1,51 @@ +/* + * MIT License + * + * Copyright (c) 2024 Decision-Driven Development + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package ru.ewc.checklogic.server; + +import com.renomad.minum.web.RequestLine; +import com.renomad.minum.web.WebFramework; + +/** + * I am an interface for all the classes that define the endpoints for the web server. + * + * @since 0.3.0 + */ +interface Endpoints { + /** + * The shortcut to define an endpoint for a GET method. + */ + RequestLine.Method GET = RequestLine.Method.GET; + + /** + * The shortcut to define an endpoint for a POST method. + */ + RequestLine.Method POST = RequestLine.Method.POST; + + /** + * Register the endpoints with the web server. + * + * @param web The web framework to register endpoints in. + */ + void register(WebFramework web); +} diff --git a/src/main/java/ru/ewc/checklogic/server/StatePage.java b/src/main/java/ru/ewc/checklogic/server/StatePage.java index e94e2a9..6a823a3 100644 --- a/src/main/java/ru/ewc/checklogic/server/StatePage.java +++ b/src/main/java/ru/ewc/checklogic/server/StatePage.java @@ -26,6 +26,7 @@ import com.renomad.minum.templating.TemplateProcessor; import com.renomad.minum.web.Request; import com.renomad.minum.web.Response; +import com.renomad.minum.web.WebFramework; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -40,7 +41,7 @@ * * @since 0.3.0 */ -public final class StatePage { +public final class StatePage implements Endpoints { /** * The template processor for the State page. */ @@ -58,9 +59,13 @@ public StatePage(final Computation computation) { ); } + @Override + public void register(final WebFramework web) { + web.registerPath(GET, "", this::statePage); + } + // @todo #9 Output all the commands as buttons on the page // @todo #9 Get a modal with command description and parameters on button click - // @todo #9 Implement an endpoint to run a command public Response statePage(final Request request) { final StoredState stored = new StoredState(this.computation.storedState()); return Response.htmlOk(this.template.renderTemplate(Map.of("state", stored.asHtmlList()))); diff --git a/src/main/java/ru/ewc/checklogic/server/WebServer.java b/src/main/java/ru/ewc/checklogic/server/WebServer.java new file mode 100644 index 0000000..f1695e8 --- /dev/null +++ b/src/main/java/ru/ewc/checklogic/server/WebServer.java @@ -0,0 +1,62 @@ +/* + * MIT License + * + * Copyright (c) 2024 Decision-Driven Development + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package ru.ewc.checklogic.server; + +import com.renomad.minum.web.FullSystem; +import com.renomad.minum.web.WebFramework; +import ru.ewc.checklogic.Computation; + +/** + * I am the web server for the CheckLogic application. My main responsibility is to configure the + * routes, initialize and start the server. + * + * @since 0.3.0 + */ +public final class WebServer { + /** + * The computation to be used for the web server. + */ + private final Computation computation; + + /** + * Ctor. + * + * @param computation The computation to be used for the web server. + */ + public WebServer(final Computation computation) { + this.computation = computation; + } + + public void start() { + final FullSystem minum = FullSystem.initialize(); + final WebFramework web = minum.getWebFramework(); + registerEndpoints(web, new StatePage(this.computation)); + registerEndpoints(web, new CommandPage(this.computation)); + minum.block(); + } + + private static void registerEndpoints(final WebFramework web, final Endpoints endpoints) { + endpoints.register(web); + } +}