summaryrefslogtreecommitdiff
path: root/src/main/java/seu/se/ApiController.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/seu/se/ApiController.java')
-rw-r--r--src/main/java/seu/se/ApiController.java370
1 files changed, 370 insertions, 0 deletions
diff --git a/src/main/java/seu/se/ApiController.java b/src/main/java/seu/se/ApiController.java
new file mode 100644
index 0000000..17a6702
--- /dev/null
+++ b/src/main/java/seu/se/ApiController.java
@@ -0,0 +1,370 @@
+package seu.se;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.util.HashSet;
+import java.util.List;
+
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+
+@RequestMapping("/api")
+@RestController
+public class ApiController {
+ public static abstract class DataObject {
+ public Boolean ok;
+ public String message;
+ public Object otherData;
+ }
+
+ public static abstract class ReturnObject {
+ public String status;
+ public DataObject dataObj;
+ }
+
+ @GetMapping(value = "/ping")
+ public String Ping() {
+ return "Pong!";
+ }
+
+ @RequestMapping("/api/user")
+ @RestController
+ static class UserController {
+ private final UserRepository uRepo;
+
+ UserController(UserRepository uRepo) {
+ this.uRepo = uRepo;
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Ok", content =
+ {@Content(mediaType = "application/json", schema =
+ @Schema(implementation = ReturnObject.class))}),
+ @ApiResponse(responseCode = "400", description = "Invalid userId supplied"),
+ @ApiResponse(responseCode = "500", description = "Internal server error")})
+ @PostMapping("/login")
+ public JsonNode Login(@RequestBody com.fasterxml.jackson.databind.JsonNode body) {
+ var id = body.get("userId").asInt();
+ var password = body.get("password").asText();
+ var user = uRepo.findById(id);
+ var retObj = new ObjectMapper().createObjectNode();
+ var dataObj = new ObjectMapper().createObjectNode();
+ String message;
+ Boolean ok;
+ if (user != null) {
+ if (password.equals(user.getPassword())) {
+ ok = true;
+ message = "Login Success";
+ // save session
+ ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
+ attr.getRequest().getSession(true).setAttribute("SESSION", user);
+
+ } else {
+ ok = false;
+ message = "Wrong password";
+ }
+ dataObj = new ObjectMapper().valueToTree(user);
+ } else {
+ ok = false;
+ message = "User not found";
+ }
+ dataObj.put("ok", ok);
+ dataObj.put("message", message);
+ retObj.set("data", dataObj);
+ retObj.put("status", "ok");
+ return retObj;
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Ok", content =
+ {@Content(mediaType = "application/json", schema =
+ @Schema(implementation = ReturnObject.class))}),
+ @ApiResponse(responseCode = "500", description = "Internal server error")})
+ @PostMapping("/register")
+ public JsonNode Register(@RequestBody com.fasterxml.jackson.databind.JsonNode body) {
+ var username = body.get("username").asText();
+ var password = body.get("password").asText();
+ String message;
+ Boolean ok;
+ var retObj = new ObjectMapper().createObjectNode();
+ var dataObj = new ObjectMapper().createObjectNode();
+ try {
+ var user = uRepo.save(new User(username, password));
+ ok = true;
+ message = "Registered";
+ dataObj = new ObjectMapper().valueToTree(user);
+ } catch (User.UserException ue) {
+ ok = false;
+ message = ue.getMessage();
+ }
+ dataObj.put("ok", ok);
+ dataObj.put("message", message);
+ retObj.set("data", dataObj);
+ retObj.put("status", "ok");
+ return retObj;
+ }
+ }
+
+ @RequestMapping("/api/node")
+ @RestController
+ static class TreeNodeController {
+ private final TreeNodeRepository tnRepo;
+
+ TreeNodeController(TreeNodeRepository tnRepo) {
+ this.tnRepo = tnRepo;
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Ok", content =
+ {@Content(mediaType = "application/json", schema =
+ @Schema(implementation = ReturnObject.class))}),
+ @ApiResponse(responseCode = "500", description = "Internal server error")})
+ @GetMapping("/content/{nodeId}")
+ public JsonNode getContent(@PathVariable String nodeId) {
+ String message;
+ Boolean ok;
+ var retObj = new ObjectMapper().createObjectNode();
+ var dataObj = new ObjectMapper().createObjectNode();
+ var treeNode = tnRepo.findByNodeId(nodeId);
+ if (treeNode != null) {
+ ok = true;
+ message = "Success";
+ dataObj.put("nodeId", treeNode.getNodeId());
+ dataObj.put("content", treeNode.getContent());
+ } else {
+ ok = false;
+ message = "Node not found";
+ }
+ dataObj.put("ok", ok);
+ dataObj.put("message", message);
+ retObj.set("data", dataObj);
+ retObj.put("status", "ok");
+ return retObj;
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Ok", content =
+ {@Content(mediaType = "application/json", schema =
+ @Schema(implementation = ReturnObject.class))}),
+ @ApiResponse(responseCode = "500", description = "Internal server error")})
+ @GetMapping("/exercises/{nodeId}")
+ public JsonNode getExercises(@PathVariable String nodeId) {
+ String message;
+ Boolean ok;
+ var retObj = new ObjectMapper().createObjectNode();
+ var dataObj = new ObjectMapper().createObjectNode();
+ var treeNode = tnRepo.findByNodeId(nodeId);
+ if (treeNode != null) {
+ ok = true;
+ message = "Success";
+ dataObj.put("nodeId", treeNode.getNodeId());
+ var exercisesObj = new ObjectMapper().createArrayNode();
+ for (var i : treeNode.getExercises()) {
+ var exerciseObj = new ObjectMapper().valueToTree(i);
+ exercisesObj.add(exerciseObj);
+ }
+ dataObj.set("exercises", exercisesObj);
+ } else {
+ ok = false;
+ message = "Node not found";
+ }
+ dataObj.put("ok", ok);
+ dataObj.put("message", message);
+ retObj.set("data", dataObj);
+ retObj.put("status", "ok");
+
+ ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
+ System.out.println(attr.getRequest().getSession(true).getAttribute("SESSION"));
+
+ return retObj;
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Ok", content =
+ {@Content(mediaType = "application/json", schema =
+ @Schema(implementation = ReturnObject.class))}),
+ @ApiResponse(responseCode = "500", description = "Internal server error")})
+ @PostMapping("/submit/{nodeId}")
+ public JsonNode Submit(@PathVariable String nodeId, @RequestBody com.fasterxml.jackson.databind.JsonNode body) {
+ String message;
+ Boolean ok;
+ var retObj = new ObjectMapper().createObjectNode();
+ var dataObj = new ObjectMapper().createObjectNode();
+ var treeNode = tnRepo.findByNodeId(nodeId);
+ ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
+ var user = (User) attr.getRequest().getSession(true).getAttribute("SESSION");
+ if (treeNode == null) {
+ ok = false;
+ message = "Node not found";
+ } else if (user == null) {
+ ok = false;
+ message = "Login first";
+ } else {
+ var score = body.get("score").asDouble();
+ var usp = treeNode.getUserScorePair(user.getId(), nodeId);
+ if (usp != null) {
+ usp.getScores().add(score);
+ } else {
+ treeNode.getUserScores().add(new TreeNode.UserScorePair(treeNode.getNodeId(), user.getId(), List.of(score)));
+ }
+ tnRepo.save(treeNode);
+ ok = true;
+ message = "Success";
+ dataObj.put("userId", user.getId());
+ dataObj.put("nodeId", nodeId);
+ }
+ dataObj.put("ok", ok);
+ dataObj.put("message", message);
+ retObj.set("data", dataObj);
+ retObj.put("status", "ok");
+ return retObj;
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Ok", content =
+ {@Content(mediaType = "application/json", schema =
+ @Schema(implementation = ReturnObject.class))}),
+ @ApiResponse(responseCode = "500", description = "Internal server error")})
+ @GetMapping("/history/{nodeId}")
+ public JsonNode History(@PathVariable String nodeId) {
+ String message;
+ Boolean ok;
+ var retObj = new ObjectMapper().createObjectNode();
+ var dataObj = new ObjectMapper().createObjectNode();
+ var treeNode = tnRepo.findByNodeId(nodeId);
+ ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
+ var user = (User) attr.getRequest().getSession(true).getAttribute("SESSION");
+ if (treeNode == null) {
+ ok = false;
+ message = "Node not found";
+ } else if (user == null) {
+ ok = false;
+ message = "Login first";
+ } else {
+ var usp = treeNode.getUserScorePair(user.getId(), nodeId);
+ if (usp != null) {
+ var uspObj = new ObjectMapper().valueToTree(usp);
+ ok = true;
+ message = "Success";
+ dataObj.set("historyScores", uspObj);
+ } else {
+ ok = false;
+ message = "No score found";
+ }
+ dataObj.put("userId", user.getId());
+ }
+ dataObj.put("ok", ok);
+ dataObj.put("message", message);
+ retObj.set("data", dataObj);
+ retObj.put("status", "ok");
+ return retObj;
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Ok", content =
+ {@Content(mediaType = "application/json", schema =
+ @Schema(implementation = ReturnObject.class))}),
+ @ApiResponse(responseCode = "500", description = "Internal server error")})
+ @GetMapping("/home")
+ public JsonNode Home() {
+ var retObj = new ObjectMapper().createObjectNode();
+ var dataObj = new ObjectMapper().createObjectNode();
+ String message;
+ Boolean ok;
+ var nodes = tnRepo.findAll();
+ var roots = new HashSet<TreeNode>();
+ for (var n : nodes) {
+ if (n.getLevel() == 1) roots.add(n);
+ }
+ if (roots.isEmpty()) {
+ ok = false;
+ message = "No root found";
+ } else {
+ class RecursiveHelper {
+ public final List<TreeNode> nodes;
+
+ public RecursiveHelper(List<TreeNode> nodes) {
+ this.nodes = nodes;
+ }
+
+ public ObjectNode RecursiveConstruct(TreeNode tn) {
+ ObjectNode graphNodesObj = new ObjectMapper().valueToTree(tn);
+ ArrayNode graphNodesIterateArr = new ObjectMapper().createArrayNode();
+ var children = tn.getChildren(nodes);
+ if (!children.isEmpty()) {
+ children.forEach(e -> {
+ graphNodesIterateArr.add(RecursiveConstruct(e));
+ });
+ graphNodesObj.set("children", graphNodesIterateArr);
+ }
+ return graphNodesObj;
+ }
+ }
+ ArrayNode graphNodesIterateArr = new ObjectMapper().createArrayNode();
+ for (var root : roots) {
+ graphNodesIterateArr.add(new RecursiveHelper(nodes).RecursiveConstruct(root));
+ }
+ dataObj.set("graphNodes", graphNodesIterateArr);
+ ok = true;
+ message = "Success";
+ }
+ dataObj.put("ok", ok);
+ dataObj.put("message", message);
+ retObj.set("data", dataObj);
+ retObj.put("status", "ok");
+ return retObj;
+ }
+
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Ok", content =
+ {@Content(mediaType = "application/json", schema =
+ @Schema(implementation = ReturnObject.class))}),
+ @ApiResponse(responseCode = "500", description = "Internal server error")})
+ @GetMapping("/review-suggestion")
+ public JsonNode ReviewSuggestion() {
+ String message;
+ Boolean ok;
+ var retObj = new ObjectMapper().createObjectNode();
+ var dataObj = new ObjectMapper().createObjectNode();
+ ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
+ var user = (User) attr.getRequest().getSession(true).getAttribute("SESSION");
+ if (user == null) {
+ ok = false;
+ message = "Login first";
+ } else {
+ var reviewSuggestionsArr = new ObjectMapper().createArrayNode();
+ var nodes = tnRepo.findAll();
+ for (var node : nodes) {
+ var usp = node.getUserScorePair(user.getId(), node.getNodeId());
+ if (usp == null) continue;
+ var msl = TreeNode.UserScorePair.MasteryLevel.getMasteryLevel(usp.getAverageScore());
+ if (msl.equals(TreeNode.UserScorePair.MasteryLevel.Average) || msl.equals(TreeNode.UserScorePair.MasteryLevel.Bad))
+ reviewSuggestionsArr.add(node.getNodeId());
+ }
+ ok = true;
+ message = "Success";
+ dataObj.put("userId", user.getId());
+ dataObj.set("reviewSuggestions", reviewSuggestionsArr);
+ }
+ dataObj.put("ok", ok);
+ dataObj.put("message", message);
+ retObj.set("data", dataObj);
+ retObj.put("status", "ok");
+ return retObj;
+ }
+ }
+}