diff options
author | Magdalena GrodziĆska <mag.grodzinska@gmail.com> | 2019-11-21 10:46:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-21 10:46:21 +0100 |
commit | d683a761b2710a252b0bfb1b3f0879a60247bb50 (patch) | |
tree | 06a0ccf7e2df0b8736f3f3889da039b39b617534 /src | |
parent | 79c8f56efcf76e7916597c0ef0e554d9fb91f8f4 (diff) | |
parent | 02f98aed224580d05deb4b40eac4a11c36d39498 (diff) |
Merge pull request #25 from m-chrzan/extend_frontend
Extend frontend
Diffstat (limited to 'src')
6 files changed, 218 insertions, 24 deletions
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/Attribute.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/Attribute.java new file mode 100644 index 0000000..abaa02a --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/Attribute.java @@ -0,0 +1,51 @@ +package pl.edu.mimuw.cloudatlas.client; + +import pl.edu.mimuw.cloudatlas.model.Value; + +public class Attribute { + private String zoneName; + private String attributeName; + private String valueString; + private String attributeType; + private Value value; + + public String getZoneName() { + return zoneName; + } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + public String getAttributeName() { + return attributeName; + } + + public void setAttributeName(String attributeName) { + this.attributeName = attributeName; + } + + public String getValueString() { + return valueString; + } + + public void setValueString(String valueString) { + this.valueString = valueString; + } + + public Value getValue() { + return value; + } + + public void setValue(Value value) { + this.value = value; + } + + public String getAttributeType() { + return attributeType; + } + + public void setAttributeType(String attributeType) { + this.attributeType = attributeType; + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index 31d1c06..022c665 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -5,8 +5,7 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; import pl.edu.mimuw.cloudatlas.api.Api; -import pl.edu.mimuw.cloudatlas.model.PathName; -import pl.edu.mimuw.cloudatlas.model.ValueContact; +import pl.edu.mimuw.cloudatlas.model.*; import java.net.InetAddress; import java.net.UnknownHostException; @@ -85,26 +84,34 @@ public class ClientController { return "contactsForm"; } - @PostMapping("/contacts") - public String contactPage(@ModelAttribute ContactsString contactsObject, Model model) { - boolean success = true; + private Set<ValueContact> parseContactsString(ContactsString contactsInput) throws Exception { Gson gson = new Gson(); - Map<String, ArrayList> contactStrings = gson.fromJson(contactsObject.getString(), Map.class); + Map<String, ArrayList> contactStrings = gson.fromJson(contactsInput.getString(), Map.class); Set<ValueContact> contactObjects = new HashSet<ValueContact>(); ArrayList<Double> cAddr; byte[] inetArray = new byte[4]; - try { - for (Map.Entry<String, ArrayList> cursor : contactStrings.entrySet()) { - cAddr = cursor.getValue(); // gson always reads numerical values as doubles - for (int i = 0; i < 4; i++) { - inetArray[i] = (byte) cAddr.get(i).doubleValue(); - } - contactObjects.add(new ValueContact( - new PathName(cursor.getKey()), - InetAddress.getByAddress(inetArray)) - ); + for (Map.Entry<String, ArrayList> cursor : contactStrings.entrySet()) { + cAddr = cursor.getValue(); // gson always reads numerical values as doubles + for (int i = 0; i < 4; i++) { + inetArray[i] = (byte) cAddr.get(i).doubleValue(); } + contactObjects.add(new ValueContact( + new PathName(cursor.getKey()), + InetAddress.getByAddress(inetArray)) + ); + } + + return contactObjects; + } + + @PostMapping("/contacts") + public String contactPage(@ModelAttribute ContactsString contactsObject, Model model) { + boolean success = true; + Set<ValueContact> contactObjects; + + try { + contactObjects = parseContactsString(contactsObject); this.api.setFallbackContacts(contactObjects); } catch (Exception e) { success = false; @@ -123,6 +130,78 @@ public class ClientController { @GetMapping("/attribs") public String attribPage(Model model) { + model.addAttribute("attributeObject", new Attribute()); + return "attribForm"; + } + + private Value parseAttributeValue(Attribute attributeObject) throws Exception { + Value attributeValue = null; + + switch (attributeObject.getAttributeType()) { + case "Boolean": + attributeValue = attributeObject.getValueString().toLowerCase().equals("true") ? + new ValueBoolean(true) : + new ValueBoolean(false); + break; + case "Double": + attributeValue = new ValueDouble(Double.parseDouble(attributeObject.getValueString())); + break; + case "Int": + attributeValue = new ValueInt(Long.parseLong(attributeObject.getValueString())); + break; + case "String": + attributeValue = new ValueString(attributeObject.getValueString()); + break; + case "Time": + attributeValue = new ValueTime(Long.parseLong(attributeObject.getValueString())); + break; + case "Duration": + attributeValue = new ValueDuration(attributeObject.getValueString()); + break; + case "Contact": + ContactsString contactsString = new ContactsString(); + contactsString.setString(attributeObject.getValueString()); + attributeValue = parseContactsString(contactsString).iterator().next(); + break; + case "Query": + attributeValue = new ValueQuery(attributeObject.getValueString()); + break; + default: + String errMsg = "Value type not supported: " + attributeObject.getAttributeType(); + throw new UnsupportedOperationException(errMsg); + } + + return attributeValue; + } + + @PostMapping("/attribs") + public String attribPage(@ModelAttribute Attribute attributeObject, Model model) { + boolean success = true; + Value attributeValue; + + try { + attributeValue = parseAttributeValue(attributeObject); + api.setAttributeValue( + attributeObject.getZoneName(), + attributeObject.getAttributeName(), + attributeValue); + } catch (Exception e) { + success = false; + System.err.println("Client exception:"); + e.printStackTrace(); + } + + if (success) { + model.addAttribute("homeMessage", "Attribute submitted successfully"); + } else { + model.addAttribute("homeMessage", "Attribute submission failed"); + } + + return "home"; + } + + @GetMapping("/values") + public String valuesPage(Model model) { return "attribChart"; } } diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java index a311c61..7f2f604 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/ZMI.java @@ -27,6 +27,7 @@ package pl.edu.mimuw.cloudatlas.model; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -40,7 +41,7 @@ import com.esotericsoftware.kryo.io.Output; * A zone management information object. This object is a single node in a zone hierarchy. It stores zone attributes as well as * references to its father and sons in the tree. */ -public class ZMI implements Cloneable { +public class ZMI implements Cloneable, Serializable { public class NoSuchZoneException extends Exception { public NoSuchZoneException(PathName path) { super("No such zone: " + path); diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribForm.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribForm.html new file mode 100644 index 0000000..0499bc8 --- /dev/null +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribForm.html @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html lang="en" xmlns:th="http://www.thymeleaf.org"> + +<head> + <meta charset="UTF-8"> + <title>Query form</title> + <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> +</head> + +<body> + +<div th:replace="fragments/navbar :: navbar"></div> +<div id="queryForm"> + <form action="#" th:action="@{/attribs}" th:object="${attributeObject}" method="post"> + <div class="form-group"> + <label for="ZoneName1">Enter zone name</label> + <input type="text" class="form-control" id="ZoneName1" rows="3" th:field="*{zoneName}"/> + </div> + <div class="form-group"> + <label for="AttributeName1">Enter attribute name</label> + <input type="text" class="form-control" id="AttributeName1" rows="3" th:field="*{attributeName}"/> + </div> + <div class="form-group"> + <label for="TypeSelect1">Enter attribute type</label> + <select class="form-control" id="TypeSelect1" th:field="*{attributeType}"> + <option th:value="Boolean" th:text="Boolean"></option> + <option th:value="Double" th:text="Double"></option> + <option th:value="Int" th:text="Int"></option> + <option th:value="String" th:text="String"></option> + <option th:value="Time" th:text="Time"></option> + <option th:value="Duration" th:text="Duration"></option> + <option th:value="Contact" th:text="Contact"></option> + <option th:value="Query" th:text="Query"></option> + </select> + </div> + <div class="form-group"> + <label for="Textarea1">Enter attribute value as a Json</label> + <textarea class="form-control" id="Textarea1" rows="3" th:field="*{valueString}"></textarea> + </div> + <button type="submit" class="btn btn-primary">Submit</button> + </form> +</div> + +<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> +<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> + +</body> + +</html> diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/fragments/navbar.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/fragments/navbar.html index c651f74..ca83cbb 100644 --- a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/fragments/navbar.html +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/fragments/navbar.html @@ -27,7 +27,10 @@ <a class="nav-link" href="/contacts">Contacts</a> </li> <li class="nav-item"> - <a class="nav-link" href="/attribs">Attribute values</a> + <a class="nav-link" href="/attribs">Attributes</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="/values">Values</a> </li> </ul> </div> diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/queryForm.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/queryForm.html index ac00645..08b4e89 100644 --- a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/queryForm.html +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/queryForm.html @@ -10,20 +10,30 @@ <body> <div th:replace="fragments/navbar :: navbar"></div> -<div id="queryForm"> +<div id="installQueryForm"> + <h2 class="display-7">Install query</h2> <form action="#" th:action="@{/query}" th:object="${queryObject}" method="post"> <div class="form-group"> - <label for="QueryName1">Enter query name</label> - <input type="text" class="form-control" id="QueryName1" rows="3" th:field="*{name}"/> + <label for="InstallQueryName1">Enter query name</label> + <input type="text" class="form-control" id="InstallQueryName1" rows="3" th:field="*{name}"/> </div> <div class="form-group"> - <label for="Textarea1">Enter query</label> - <textarea class="form-control" id="Textarea1" rows="3" th:field="*{value}"></textarea> + <label for="InstallTextarea1">Enter query</label> + <textarea class="form-control" id="InstallTextarea1" rows="3" th:field="*{value}"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> +</div> - <div id="response"><p th:text="${responseText}"/></div> +<div id="uninstallQueryForm"> + <h2 class="display-7">Uninstall query</h2> + <form action="#" th:action="@{/query}" th:object="${queryObject}" method="post"> + <div class="form-group"> + <label for="UninstallQueryName1">Enter query name</label> + <input type="text" class="form-control" id="UninstallQueryName1" rows="3" th:field="*{name}"/> + </div> + <button type="submit" class="btn btn-primary">Submit</button> + </form> </div> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> |