LogoHomeIndexIndexGitHub </> No back No next Patch 3c58c015b4e9378126ec86c2d0ce3a81f42f61a4

Patch 3c58c015b4e9378126ec86c2d0ce3a81f42f61a4

Commit message: UI and REST added

diff --git a/code/groovy_console/pom.xml b/code/groovy_console/pom.xml
index 61d7737..d52393a 100644
--- a/code/groovy_console/pom.xml
+++ b/code/groovy_console/pom.xml
@@ -26,12 +26,15 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ </dependency>
</dependencies>

<build>
@@ -43,5 +46,4 @@
</plugin>
</plugins>
</build>
-
</project>
diff --git a/code/groovy_console/src/main/java/groovyconsole/Controller.java b/code/groovy_console/src/main/java/groovyconsole/Controller.java
new file mode 100644
index 0000000..cc15ab5
--- /dev/null
+++ b/code/groovy_console/src/main/java/groovyconsole/Controller.java
@@ -0,0 +1,30 @@
+package groovyconsole;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class Controller {
+
+ @Autowired
+ private State state;
+
+ @PostMapping("/console")
+ public Result console(@RequestBody String script) {
+ state.incrementConsoleRequestCount();
+ return script == null || script.isBlank() ?
+ Result.builder().error("The script is empty!").build() :
+ Result.builder()
+ .result("The script is: " + script)
+ .output("Fake output")
+ .build();
+ }
+
+ @GetMapping("/state")
+ public State state() {
+ return state;
+ }
+}
diff --git a/code/groovy_console/src/main/java/groovyconsole/MvcConfig.java b/code/groovy_console/src/main/java/groovyconsole/MvcConfig.java
new file mode 100644
index 0000000..62b94c6
--- /dev/null
+++ b/code/groovy_console/src/main/java/groovyconsole/MvcConfig.java
@@ -0,0 +1,14 @@
+package groovyconsole;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class MvcConfig implements WebMvcConfigurer {
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/").setViewName("console.html");
+ }
+}
diff --git a/code/groovy_console/src/main/java/groovyconsole/Result.java b/code/groovy_console/src/main/java/groovyconsole/Result.java
new file mode 100644
index 0000000..6c951ec
--- /dev/null
+++ b/code/groovy_console/src/main/java/groovyconsole/Result.java
@@ -0,0 +1,12 @@
+package groovyconsole;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class Result {
+ private String error;
+ private String result;
+ private String output;
+}
diff --git a/code/groovy_console/src/main/java/groovyconsole/State.java b/code/groovy_console/src/main/java/groovyconsole/State.java
new file mode 100644
index 0000000..e561e72
--- /dev/null
+++ b/code/groovy_console/src/main/java/groovyconsole/State.java
@@ -0,0 +1,15 @@
+package groovyconsole;
+
+import lombok.Data;
+import org.springframework.stereotype.Component;
+
+@Component
+@Data
+public class State {
+ private int consoleRequestCount = 0;
+ private String someProperty;
+
+ public void incrementConsoleRequestCount() {
+ ++consoleRequestCount;
+ }
+}
diff --git a/code/groovy_console/src/main/resources/static/console.html b/code/groovy_console/src/main/resources/static/console.html
new file mode 100644
index 0000000..1b1695d
--- /dev/null
+++ b/code/groovy_console/src/main/resources/static/console.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Groovy console</title>
+ <link rel="shortcut icon" type="image/png" href="favicon.png">
+</head>
+<body>
+<table>
+ <thead>
+ <tr><th>Script</th><th>Result</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><button type="button" onclick="execute();return false;">Execute</button></td>
+ <td><button type="button" onclick="clearResult();return false;">Clear</button></td>
+ </tr>
+ <tr>
+ <td><textarea id="script" rows="11" cols="50"
+ maxlength="500000">println "Hello world!"</textarea></td>
+ <td><textarea id="result" rows="11" cols="50"
+ maxlength="500000"></textarea></td>
+ </tr>
+ </tbody>
+</table>
+<h3>Application state</h3>
+<table>
+<tr><td><strong>consoleRequestCount:</strong></td><td id="consoleRequestCount"></td></tr>
+<tr><td><strong>someProperty:</strong></td><td id="someProperty"></td></tr>
+</table>
+
+<script>
+let scriptElement = document.getElementById("script")
+let resultElement = document.getElementById("result")
+let consoleRequestCountElement = document.getElementById("consoleRequestCount")
+let somePropertyElement = document.getElementById("someProperty")
+
+async function execute() {
+ let result = await sendRequest("console", "POST", scriptElement.value)
+ resultElement.value += "\n----------\n" +
+ (result.error ? "ERROR: " + result.error :
+ "RESULT: " + result.result) +
+ (result.output ? "\n" + "OUTPUT: " + result.output : "") + "\n"
+ updateState()
+}
+
+function clearResult() {
+ resultElement.value = ""
+}
+
+async function sendRequest(url, method, body) {
+ try {
+ const response = await fetch(url, {
+ method: method,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: body,
+ })
+ if (response.ok) {
+ return await response.json()
+ } else {
+ return {"error": "Request failed with status " + response.status +
+ " " + response.statusText}
+ }
+ } catch (error) {
+ return {"error": "REQUEST ERROR: " + error}
+ }
+}
+
+async function updateState() {
+ let result = await sendRequest("state", "GET")
+ consoleRequestCountElement.innerText = result.consoleRequestCount
+ somePropertyElement.innerText = result.someProperty
+}
+
+updateState()
+</script>
+</body>
+</html>
diff --git a/code/groovy_console/src/main/resources/static/favicon.png b/code/groovy_console/src/main/resources/static/favicon.png
new file mode 100644
index 0000000..9d0e13a
Binary files /dev/null and b/code/groovy_console/src/main/resources/static/favicon.png differ