diff --git a/Backend-libXML/.gitignore b/Backend-libXML/.gitignore
new file mode 100644
index 0000000..9ca9383
--- /dev/null
+++ b/Backend-libXML/.gitignore
@@ -0,0 +1,3 @@
+.idea
+__pycache**
+venv
diff --git a/Backend-libXML/Dockerfile b/Backend-libXML/Dockerfile
new file mode 100644
index 0000000..f3524b4
--- /dev/null
+++ b/Backend-libXML/Dockerfile
@@ -0,0 +1,8 @@
+FROM tiangolo/meinheld-gunicorn-flask:python3.9
+
+COPY ./requirements.txt /app/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
+
+COPY ./main.py /app/
+COPY ./Parser.py /app/
\ No newline at end of file
diff --git a/Backend-libXML/Parser.py b/Backend-libXML/Parser.py
new file mode 100644
index 0000000..c652212
--- /dev/null
+++ b/Backend-libXML/Parser.py
@@ -0,0 +1,69 @@
+from lxml import etree
+
+
+def xpath(source: str, xpath: str) -> str:
+ """
+ Method used to get nodes from XML string using XPath
+
+ :param source: XML string used for selection
+ :type source: str
+ :param xpath: XPath query used for selection
+ :type xpath: str
+ :return: Nodes selected using XPath
+ :rtype: str
+ """
+
+
+ root = etree.XML(source)
+ nsmap = root.nsmap
+
+ # LXML doesn't accept empty (None) namespace prefix,
+ # so it need to be deleted if exists
+ if None in nsmap:
+ nsmap.pop(None)
+
+ result = root.xpath(xpath, namespaces=nsmap)
+ result_string = ""
+ for e in result:
+ result_string += etree.tostring(e, pretty_print=True).decode() + "\n"
+ return result_string
+
+
+
+def xsd(source: str, xsd: str) -> bool:
+ """
+ Method used to validate XML string against XSD schema
+ :param source: XML string used for validation
+ :type source: str
+ :param xsd: XSD schema to validate XML against
+ :type xsd: str
+ :return: Message saying, if the validation was successful or not
+ :rtype: str
+ """
+ xml_schema = etree.XMLSchema(etree.XML(xsd))
+
+ xml = etree.XML(source)
+ if xml_schema.validate(xml):
+ return "XML is valid."
+ else:
+ return "XML is NOT valid."
+
+
+def xslt(source: str, xslt: str) -> str:
+ """
+ Method used to transformate XML string using XSLT
+
+ :param source: XML string to transform
+ :type source: str
+ :param xslt: XSLT string used to transformate XML
+ :type xslt: str
+ :return: Result of transformation
+ :rtype: str
+ """
+ xslt_transform = etree.XSLT(etree.XML(xslt))
+
+ xml = etree.XML(source)
+
+ transformated = xslt_transform(xml)
+ print(transformated)
+ return str(transformated)
\ No newline at end of file
diff --git a/Backend-libXML/main.py b/Backend-libXML/main.py
new file mode 100644
index 0000000..0869a00
--- /dev/null
+++ b/Backend-libXML/main.py
@@ -0,0 +1,74 @@
+from flask import Flask
+from flask_cors import CORS
+from flask import request
+from lxml import etree
+import json
+import time
+import Parser
+
+
+app = Flask(__name__)
+CORS(app)
+cors = CORS(app, resource={
+ r"/*":{
+ "origins":"*"
+ }
+})
+
+def process_xml(request: request, type: str) -> str:
+ """Function to process
+
+ :param request: Received request
+ :type request: request
+ :param type: Type of needed processing: xsd, xslt or xpath
+ :type type: str
+ :raises ValueError: is raised when type is different than those provided above
+ :return: response JSON converted to string and response code
+ :rtype: str, int
+ """
+ start = time.time_ns()
+ code = 200
+ response_json = dict()
+ try:
+ request_data = json.loads(request.get_data(as_text=True))
+ data = request_data['data']
+ process = request_data['process']
+ if (type == "xsd"):
+ response_json['result'] = Parser.xsd(data, process)
+ elif (type == "xslt"):
+ response_json['result'] = Parser.xslt(data, process)
+ elif (type == "xpath"):
+ response_json['result'] = Parser.xpath(data, process)
+ else:
+ raise ValueError("Valid operation types are: xsd, xslt, xpath")
+
+ response_json['status'] = "OK"
+ except KeyError as e:
+ response_json['result'] = "Missing key: " + str(e)
+ response_json['status'] = "ERR"
+ code = 400
+ except Exception as e:
+ response_json['result'] = str(e)
+ response_json['status'] = "ERR"
+ code = 400
+ finally:
+ exec_time = (time.time_ns() - start) / 10**6
+ response_json['time'] = f"{exec_time:.03f}"
+ response_json['processor'] = "libxml2 over lxml"
+ return json.dumps(response_json), code
+
+
+@app.route("/xpathpost", methods=["POST"])
+def xpath():
+ return process_xml(request, "xpath")
+
+@app.route("/xsdpost", methods=["POST"])
+def xsd():
+ return process_xml(request, "xsd")
+
+@app.route("/xsltpost", methods=["POST"])
+def xslt():
+ return process_xml(request, "xslt")
+
+if __name__ == "__main__":
+ app.run()
\ No newline at end of file
diff --git a/Backend-libXML/requirements.txt b/Backend-libXML/requirements.txt
new file mode 100644
index 0000000..7c41ff0
--- /dev/null
+++ b/Backend-libXML/requirements.txt
@@ -0,0 +1,3 @@
+lxml
+flask
+flask_cors
\ No newline at end of file
diff --git a/Backend-libXML/sample/xpath/data.json b/Backend-libXML/sample/xpath/data.json
new file mode 100644
index 0000000..2de1632
--- /dev/null
+++ b/Backend-libXML/sample/xpath/data.json
@@ -0,0 +1,6 @@
+{
+ "data": "Hamlet2001-05-041falseMacbeth2000-12-131falseHarry Potter and the Sorcerer's Stone2005-04-292trueThe Long Walk2018-07-014trueMisery2018-01-314trueThink and Grow Rich2004-09-106trueThe Law of Success1982-05-096falsePatriot Games1995-10-215falseThe Sum of All Fears1992-09-195falseThe Alchemist2017-02-203falseHamlet1994-06-011falseMeasure for Measure1990-03-231falseHamlet1989-05-051trueHamlet1999-05-301trueThe Law of Success2004-11-266trueRomeo and Juliet1997-02-081trueThe Alchemist2009-08-213true",
+ "process": "/books/book[name = 'The Law of Success']",
+ "processor": "saxon",
+ "version": "2.0"
+}
diff --git a/Backend-libXML/sample/xpath/dataNS.json b/Backend-libXML/sample/xpath/dataNS.json
new file mode 100644
index 0000000..ec5eb94
--- /dev/null
+++ b/Backend-libXML/sample/xpath/dataNS.json
@@ -0,0 +1,6 @@
+{
+ "data": "Hamlet2001-05-041falseMacbeth2000-12-131falseHarry Potter and the Sorcerer's Stone2005-04-292trueThe Long Walk2018-07-014trueMisery2018-01-314trueThink and Grow Rich2004-09-106trueThe Law of Success1982-05-096falsePatriot Games1995-10-215falseThe Sum of All Fears1992-09-195falseThe Alchemist2017-02-203falseHamlet1994-06-011falseMeasure for Measure1990-03-231falseHamlet1989-05-051trueHamlet1999-05-301trueThe Law of Success2004-11-266trueRomeo and Juliet1997-02-081trueThe Alchemist2009-08-213true",
+ "process": "/b:books/b:book[b:name = 'The Law of Success']",
+ "processor": "saxon",
+ "version": "2.0"
+}
diff --git a/Backend-libXML/sample/xpath/non-ns.curl b/Backend-libXML/sample/xpath/non-ns.curl
new file mode 100644
index 0000000..7d4219f
--- /dev/null
+++ b/Backend-libXML/sample/xpath/non-ns.curl
@@ -0,0 +1,4 @@
+#url = "localhost:8081/xpathpost"
+url = "localhost:5000/xpath"
+request = "POST"
+data = "@data.json"
diff --git a/Backend-libXML/sample/xpath/ns.curl b/Backend-libXML/sample/xpath/ns.curl
new file mode 100644
index 0000000..f439c0e
--- /dev/null
+++ b/Backend-libXML/sample/xpath/ns.curl
@@ -0,0 +1,4 @@
+#url = "localhost:8081/xpathpost"
+url = "localhost:5000/xpath"
+request = "POST"
+data = "@dataNS.json"
diff --git a/Backend-libXML/sample/xsd/xsd.curl b/Backend-libXML/sample/xsd/xsd.curl
new file mode 100644
index 0000000..2481c02
--- /dev/null
+++ b/Backend-libXML/sample/xsd/xsd.curl
@@ -0,0 +1,4 @@
+#url = "http://localhost:8082/xsd"
+url = "http://localhost:5000/xsd"
+data = "@xsd.json"
+request = POST
diff --git a/Backend-libXML/sample/xsd/xsd.json b/Backend-libXML/sample/xsd/xsd.json
new file mode 100644
index 0000000..91dd2f2
--- /dev/null
+++ b/Backend-libXML/sample/xsd/xsd.json
@@ -0,0 +1,6 @@
+{
+ "data": "TestTest3",
+ "process": " ",
+ "processor": "saxon",
+ "version": "1.0"
+}
diff --git a/Backend-libXML/sample/xslt/xslt.curl b/Backend-libXML/sample/xslt/xslt.curl
new file mode 100644
index 0000000..d50edd1
--- /dev/null
+++ b/Backend-libXML/sample/xslt/xslt.curl
@@ -0,0 +1,3 @@
+url = "http://localhost:5000/xslt"
+data = "@xslt.json"
+request = POST
diff --git a/Backend-libXML/sample/xslt/xslt.json b/Backend-libXML/sample/xslt/xslt.json
new file mode 100644
index 0000000..f833a40
--- /dev/null
+++ b/Backend-libXML/sample/xslt/xslt.json
@@ -0,0 +1,6 @@
+{
+ "data": "Hamlet2001-05-041falseMacbeth2000-12-131falseHarry Potter and the Sorcerer's Stone2005-04-292trueThe Long Walk2018-07-014trueMisery2018-01-314trueThink and Grow Rich2004-09-106trueThe Law of Success1982-05-096falsePatriot Games1995-10-215falseThe Sum of All Fears1992-09-195falseThe Alchemist2017-02-203falseHamlet1994-06-011falseMeasure for Measure1990-03-231falseHamlet1989-05-051trueHamlet1999-05-301trueThe Law of Success2004-11-266trueRomeo and Juliet1997-02-081trueThe Alchemist2009-08-213true",
+ "process": "",
+ "processor": "saxon",
+ "version": "1.0"
+}
diff --git a/Backend/mocked-services/src/main/resources/static/html/mock.html b/Backend/mocked-services/src/main/resources/static/html/mock.html
index f597720..8bedcb9 100644
--- a/Backend/mocked-services/src/main/resources/static/html/mock.html
+++ b/Backend/mocked-services/src/main/resources/static/html/mock.html
@@ -3,12 +3,12 @@
R11 MockedServices
-
-
+
+
-
+
-
+
@@ -37,15 +37,15 @@
-
-
+
+
diff --git a/Backend/mocked-services/src/main/resources/static/js/dyn_host.js b/Backend/mocked-services/src/main/resources/static/js/dyn_host.js
deleted file mode 100644
index b13a6e1..0000000
--- a/Backend/mocked-services/src/main/resources/static/js/dyn_host.js
+++ /dev/null
@@ -1,11 +0,0 @@
-$(document).ready( function() {
- console.log("Here")
- let links = document.getElementsByTagName("link")
- for (let i = 0; i < links.length; i++) {
- let oldStr = links[i].href.split("/")
- let endpoint = oldStr.slice(3).join("/")
- links[i].href = window.location.protocol + "//" + window.location.hostname + ":8086/" + endpoint
- }
-
-});
-
diff --git a/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/SparkInitializer.java b/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/SparkInitializer.java
index e17ad41..99a6133 100644
--- a/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/SparkInitializer.java
+++ b/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/SparkInitializer.java
@@ -1,5 +1,6 @@
package com.r11.tools.xslt;
+import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.r11.tools.xslt.processors.Saxon;
@@ -65,8 +66,15 @@ public class SparkInitializer {
Map responseMap = new HashMap<>();
try {
requestMap = mapper.readValue(body, Map.class);
- } catch (JsonMappingException ex) {
- ex.printStackTrace();
+ } catch (JsonMappingException | JsonParseException ex) {
+ LOG.error("Request JSON error. " + ex);
+ responseMap.put("result", ex.getMessage());
+ responseMap.put("processor", "N/A");
+ responseMap.put("status", "ERR");
+ responseMap.put("time", "N/A");
+ resp.status(400);
+ resp.body(mapper.writeValueAsString(responseMap));
+ return resp;
}
String data = requestMap.get("data");
@@ -103,8 +111,15 @@ public class SparkInitializer {
Map responseMap = new HashMap<>();
try {
requestMap = mapper.readValue(body, Map.class);
- } catch (JsonMappingException ex) {
- LOG.error("JSON mapping error. " + ex);
+ } catch (JsonMappingException | JsonParseException ex) {
+ LOG.error("Request JSON error. " + ex);
+ responseMap.put("result", ex.getMessage());
+ responseMap.put("processor", "N/A");
+ responseMap.put("status", "ERR");
+ responseMap.put("time", "N/A");
+ resp.status(400);
+ resp.body(mapper.writeValueAsString(responseMap));
+ return resp;
}
String data = requestMap.get("data");
@@ -158,7 +173,6 @@ public class SparkInitializer {
duration = System.currentTimeMillis() - timeStart;
LOG.info("Request: " + body + " processed in " + duration + " ms.");
responseMap.put("processor", Xalan.getVersion());
- responseMap.put("result", tmp);
responseMap.put("time", Long.toString(duration));
resp.body(mapper.writeValueAsString(responseMap));
return resp;
@@ -174,17 +188,24 @@ public class SparkInitializer {
private static final Route xsltHandler = (Request req, Response resp) -> {
String body = req.body();
ObjectMapper mapper = new ObjectMapper();
- Map jsonMap = new HashMap<>();
+ Map requestMap = new HashMap<>();
Map responseMap = new HashMap<>();
try {
- jsonMap = mapper.readValue(body, Map.class);
- } catch (JsonMappingException ex) {
- LOG.error("JSON mapping error. " + ex);
+ requestMap = mapper.readValue(body, Map.class);
+ } catch (JsonMappingException | JsonParseException ex) {
+ LOG.error("Request JSON error. " + ex);
+ responseMap.put("result", ex.getMessage());
+ responseMap.put("processor", "N/A");
+ responseMap.put("status", "ERR");
+ responseMap.put("time", "N/A");
+ resp.status(400);
+ resp.body(mapper.writeValueAsString(responseMap));
+ return resp;
}
- String data = jsonMap.get("data");
- String query = jsonMap.get("process");
- String processor = jsonMap.get("processor");
- String version = jsonMap.get("version");
+ String data = requestMap.get("data");
+ String query = requestMap.get("process");
+ String processor = requestMap.get("processor");
+ String version = requestMap.get("version");
if (processor == null) {
return "saxon, xalan";
diff --git a/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/processors/Xalan.java b/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/processors/Xalan.java
index 42db619..85fb7e7 100644
--- a/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/processors/Xalan.java
+++ b/Backend/xslt-rest/src/main/java/com/r11/tools/xslt/processors/Xalan.java
@@ -1,8 +1,12 @@
package com.r11.tools.xslt.processors;
+import net.sf.saxon.lib.RawResult;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.xpath.XPathAPI;
import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource;
import javax.xml.XMLConstants;
@@ -19,8 +23,7 @@ import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
-import java.io.StringReader;
-import java.io.StringWriter;
+import java.io.*;
/**
* Handler for Xalan engine
@@ -53,25 +56,55 @@ public class Xalan {
return sw.toString();
}
+ private static boolean isTextNode(Node n) {
+ if (n == null)
+ return false;
+ short nodeType = n.getNodeType();
+ return nodeType == Node.CDATA_SECTION_NODE || nodeType == Node.TEXT_NODE;
+ }
+
/**
* Process xpath and return either node or wrapped atomic value
- * @deprecated
- * Xalan needs assumption of the outcome, which is not implemented. Therefore method is deprecated
* @param data xml
* @param transform xpath
* @return xml processed using given xpath
* @throws Exception thrown on node building errors or invalid xpath
*/
- public static String processXPath(String data, String transform) throws Exception{
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
+ public static String processXPath(String data, String transform) throws Exception {
- XPath xpath = XPathFactory.newInstance().newXPath();
+ // Set up a DOM tree to query.
+ InputSource in = new InputSource(new StringReader(data));
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ dfactory.setNamespaceAware(true);
+ Document doc = dfactory.newDocumentBuilder().parse(in);
- xpath.setNamespaceContext(new XalanNamespaceResolver(builder.parse(new InputSource(new StringReader(data))), true));
- XPathExpression exp = xpath.compile(transform);
- exp.evaluate(new InputSource(new StringReader(data)), XPathConstants.NODESET);
- return exp.evaluate(new InputSource(new StringReader(data)));
+ // Set up an identity transformer to use as serializer.
+ Transformer serializer = TransformerFactory.newInstance().newTransformer();
+ serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+
+ // Use the simple XPath API to select a nodeIterator.
+ NodeIterator nl = XPathAPI.selectNodeIterator(doc, transform);
+
+ // Serialize the found nodes to result object.
+ StringBuilder result = new StringBuilder();
+ Node n;
+ while ((n = nl.nextNode())!= null) {
+ StringBuilder sb;
+ if (isTextNode(n)) {
+ // DOM may have more than one node corresponding to a
+ // single XPath text node. Coalesce all contiguous text nodes
+ // at this level
+ for (Node nn = n.getNextSibling(); isTextNode(nn); nn = nn.getNextSibling()) {
+ result.append(nn.getNodeValue());
+ }
+ } else {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ serializer.transform(new DOMSource(n), new StreamResult(new OutputStreamWriter(outputStream)));
+ result.append(outputStream);
+ }
+ result.append("\n");
+ }
+ return result.toString();
}
/**
diff --git a/Frontend/assets/css/mock-service/common.css b/Frontend/assets/css/mock-service/common.css
deleted file mode 100644
index 0c7e754..0000000
--- a/Frontend/assets/css/mock-service/common.css
+++ /dev/null
@@ -1,6 +0,0 @@
-@import url('https://necolas.github.io/normalize.css/8.0.1/normalize.css');
-@import url('r11addons.css');
-@import url('r11tables.css');
-@import url('r11tool.css');
-@import url('r11tooltip.css');
-@import url('r11modal.css');
diff --git a/Frontend/assets/css/mock-service/main.css b/Frontend/assets/css/mock-service/main.css
deleted file mode 100644
index 2f8c9ff..0000000
--- a/Frontend/assets/css/mock-service/main.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.overflowedTableContent {
- max-height: 750px;
- overflow: scroll;
-}
\ No newline at end of file
diff --git a/Frontend/assets/css/mock-service/r11addons.css b/Frontend/assets/css/mock-service/r11addons.css
deleted file mode 100644
index afb4425..0000000
--- a/Frontend/assets/css/mock-service/r11addons.css
+++ /dev/null
@@ -1,59 +0,0 @@
-.modification-button.btn-tile:hover {
- color: #ca1111;
-}
-
-.modification-button.btn-tile {
- width: 10%;
- margin: 20% 0 0 0;
- font-size: 14px;
- color: #00000020
-}
-
-.modification-button.btn-addtile {
- font-size: 38px;
- color: #00000030;
-}
-
-.modification-button.btn-addtile:hover {
- color: #58ac43;
-}
-
-.tile {
- width: 100%;
- padding-top: 40%;
- border: 1px solid gray;
- border-radius: 3px;
- position: relative;
- background: #f0f0f095;
- margin-bottom: 10px;
- cursor: default;
-}
-
-.tile:hover {
- filter: brightness(110%);
-}
-
-.tile.active {
- background: #00000070;
- color: white;
- filter: none;
-}
-
-.tile.active .btn-tile {
- opacity: 0;
-}
-
-.tile .content {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- right: 0;
- padding: 0 2% 0 7%;
- display: flex;
-}
-
-.content p {
- margin: 0;
- padding: 0;
-}
diff --git a/Frontend/assets/css/mock-service/r11modal.css b/Frontend/assets/css/mock-service/r11modal.css
deleted file mode 100644
index 7848a43..0000000
--- a/Frontend/assets/css/mock-service/r11modal.css
+++ /dev/null
@@ -1,104 +0,0 @@
-#overlay {
- position: fixed;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- opacity: 0;
- background: rgba(0, 0 , 0, 0.5);
- pointer-events: none;
-}
-
-#overlay.active {
- pointer-events: all;
- opacity: 1;
-}
-
-.modal {
- display: none;
- width: 390px;
- min-height: 71px;
- max-height: 700px;
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- background: white;
- padding: 5px;
- border: 1px solid #f0f0f0;
-}
-
-.modal.active {
- display: block;
-}
-
-.modal div.header {
- width: 384px;
- height: 24px;
- background: #2e3133;
- color: white;
- font-size: 24px;
- font-weight: 700;
- padding: 3px;
- margin-bottom: 5px;
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.modal div.header button {
- font-size: 100%;
- font-family: inherit;
- border: 0;
- padding: 0;
- background: 0;
- color: inherit;
- cursor: pointer;
-}
-
-.modal div.header button:hover {
- color: white;
- font-weight: 700;
-}
-
-.modal div.body {
- width: 370px;
- padding: 10px;
- background: #f0f0f0;
- color: #2e3133;
- min-height: 16px;
- text-align: justify;
- font-size: 16px;
-}
-
-.modal div.function {
- width: 385px;
- min-height: 30px;
- padding-top: 5px;
- display: flex;
- justify-content: space-evenly;
- background: inherit;
-}
-
-.modal div.function button {
- min-height: 22px;
- min-width: 34px;
- max-width: 74px;
- padding: 3px 20px;
- outline: none;
- border: 1px solid #f0f0f0;
- background: rgba(205,205,205,1);
- font-size: 16px;
- text-align: center;
- cursor: pointer;
-}
-
-.modal div.function button:hover {
- filter: brightness(110%);
-}
-
-.r-exclamation:before {
- content: '!';
- color: #3bc4f1;
- font-style: normal;
-}
diff --git a/Frontend/assets/css/mock-service/r11tables.css b/Frontend/assets/css/mock-service/r11tables.css
deleted file mode 100644
index 0a680ab..0000000
--- a/Frontend/assets/css/mock-service/r11tables.css
+++ /dev/null
@@ -1,71 +0,0 @@
-.table-map {
- width: 60%;
-}
-
-.table-map input{
- font-size: 16px;
- padding: 7px;
- border: 1px solid rgba(145, 146, 146, 0.849);
- border-radius: 5px;
-}
-
-.table-map input.key {
- background: #f0f0f0;
-}
-
-.modification-button.btn-add {
- font-size: 16px;
- color: #00000030;
- margin: auto 0 auto 0;
-}
-
-.modification-button.btn-add:hover {
- color:#58ac43;
-}
-
-.modification-button.btn-hashmap {
- font-size: 16px;
- color: #00000030;
- margin: auto 0 auto 0;
-}
-
-.modification-button.btn-hashmap:hover {
- color: #ca1111;
-}
-
-.table-default {
- width: 80%;
- border-collapse: collapse;
- border-spacing: 0;
-}
-
-.table-default tr {
- background: #f0f0f02d;
-}
-
-.table-default tr.bottom-border {
- border-bottom: 1px solid black;
-}
-
-.table-default th {
- background: #ffffff;
-}
-
-.table-default tr.even {
- background: #f0f0f0;
-}
-
-.table-doc td, .table-doc th{
- border-spacing: 0px;
- padding: 0px 10px;
-}
-
-.table-doc td {
- background-color: rgba(155, 165, 160, 0.342);
-}
-
-.table-doc th {
- background-color: #3bc4f1;
- text-align: left;
- color: white;
-}
\ No newline at end of file
diff --git a/Frontend/assets/css/mock-service/r11tool.css b/Frontend/assets/css/mock-service/r11tool.css
deleted file mode 100644
index 2243166..0000000
--- a/Frontend/assets/css/mock-service/r11tool.css
+++ /dev/null
@@ -1,300 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@300;400;700&display=swap');
-.hyperlink, .hyperlink:visited, .hyperlink:active {
- color: rgb(47, 125, 146);
- cursor: pointer;
-}
-
-.hyperlink:hover {
- filter: brightness(120%);
-}
-
-.bordered-field {
- border: 2px solid rgba(93, 99, 96, 0.705);
- border-radius: 5px;
- padding: 8px;
-
-}
-
-.bordered-field:focus {
- outline: none;
- box-shadow: 0 0 5px rgba(81, 203, 238);
- border: 2px solid #00000070;
-}
-
-.bordered-field:disabled {
- background: #eeeeeed2;
-}
-
-.vertically-resizeable {
- resize: vertical;
-}
-
-body {
- font-family: 'Nunito', sans-serif;
-}
-
-.container {
- display: flex;
- justify-content: left;
- width: 100%;
-}
-
-.tool {
- width: 55%;
- display: flex;
- justify-content: space-evenly;
-}
-
-.tool.extended {
- width: 65%;
-}
-
-.tool .tool-context {
- width: 90%;
-}
-
-.tool.extended .tool-context {
- width: 75%;
-}
-
-.tool.extended .tool-extention {
- width: 20%;
- padding-top: 2%;
- display: block;
-}
-
-.tool .tool-extention {
- display: none;
-}
-
-.tool-extention {
- opacity: 0;
- pointer-events: none;
-}
-
-.tool-extention.active {
- opacity: 100%;
- pointer-events: all;
-}
-
-.clickable-text {
- padding: 0;
- outline: none;
- background: none;
- border: none;
- font-weight: 300;
- cursor: pointer;
-}
-
-.clickable-text.highlight:hover {
- color: #3bc4f1;
-}
-
-.clickable-text.switch {
- font-size: 18px;
- font-weight: 700;
-}
-
-.clickable-text.switch span.toggleIndicator:before {
- content: '>';
-}
-
-.clickable-text.switch span.toggleIndicator.active:before {
- content: 'v';
-}
-
-.modification-button {
- padding: 0;
- outline: none;
- background: none;
- border: none;
- font-weight: 300;
-}
-
-.text-aligned-to-right {
- text-align: right;
-}
-
-.centered-vertically {
- margin-top: auto;
- margin-bottom: auto;
-}
-
-.display-space-between {
- width: 100%;
- display: flex;
- justify-content: space-between;
-}
-
-.display-space-evenly {
- display: flex;
- justify-content: space-evenly;
-}
-
-.float-left {
- display: flex;
- justify-content: left;
- width: 100%;
-}
-
-.version-span {
- font-size: 13px;
- font-weight: 400;
- color: rgba(85,85,85,0.555);
-}
-
-.block-display {
- display: block;
-}
-
-.block-label {
- display: block;
- margin: 0 0 0 5px;
-}
-
-.tabmenu {
- display: flex;
- flex-direction: row;
- text-align: center;
- border-bottom: 1px solid rgba(185, 185, 185, 0.5);
-}
-
-.tabitem {
- flex-grow: 1;
- cursor: pointer;
- padding: 5px 0;
-}
-
-.tabitem:hover {
- font-weight: 700;
-}
-
-.tabitem.active {
- background: rgba(33, 34, 34, 0.705);
- color: white;
- font-weight: 700;
- cursor:default;
- flex-grow: 1;
-}
-
-.big-font {
- font-size: 20px;
-}
-
-.action-button.active {
- background: #3bc4f1;
- border: 1px solid #7ed0eb;
- cursor: pointer;
-}
-
-.action-button.active:hover {
- filter: brightness(110%);
-}
-
-.action-button {
- background: rgba(155, 165, 160, 0.507);
- border:1px solid rgba(186, 197, 191, 0.507);
- color: white;
- padding: 10px 20px;
- font-weight: 700;
- margin: 3px 0;
-}
-
-.quater-width {
- width: 25%;
-}
-
-.half-width {
- width: 50%;
-}
-
-.tree-fourth-width {
- width: 75%;
-}
-
-.half-width.with-padding {
- width: 45%;
-}
-
-.max-width {
- width: 100%;
-}
-
-.max-width.with-padding {
- width: 94%;
-}
-
-.max-height {
- height: 100%;
-}
-
-.height-300 {
- height: 300px;
-}
-
-.max-height.with-padding {
- height: 90%;
-}
-
-.small-margins {
- margin: 3%;
-}
-
-.small-vertical-margin {
- margin-top: 10px;
- margin-bottom: 10px;
-}
-
-.medium-vertical-margin {
- margin-top: 30px;
- margin-bottom: 30px;
-}
-
-.large-vertical-margin {
- margin-top: 50px;
- margin-bottom: 50px;
-}
-
-.textarea-300 {
- height: 300px;
-}
-
-.centered-content {
- display: flex;
- justify-content: center;
-}
-
-
-.tabcontent {
- display: none;
-}
-
-.tabcontent.active {
- display: flex;
- justify-content: center;
-}
-
-.hiddable {
- display: none;
-}
-
-.hiddable.active {
- display: inherit;
-}
-
-/* In case of collision with classes that use 'active' */
-.hidden {
- display: none;
-}
-
-/* TODO: Add proper class */
-/* textarea {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
-} */
-
-/* TODO: Add proper class */
-/* code{
- line-height: 150%;
-} */
\ No newline at end of file
diff --git a/Frontend/assets/css/mock-service/r11tooltip.css b/Frontend/assets/css/mock-service/r11tooltip.css
deleted file mode 100644
index 34fcbfb..0000000
--- a/Frontend/assets/css/mock-service/r11tooltip.css
+++ /dev/null
@@ -1,77 +0,0 @@
-.tooltip-window {
- position: fixed;
- right: 0;
- filter: drop-shadow(-2px 0px 2px darkgray);
- background: #e8f3f7;
- padding: 15px 30px;
- font-family: 'Nunito', sans-serif;
- width: 40%;
- height: 100%;
- overflow: scroll;
-}
-
-.tooltip-window.lite {
- width: 30%;
-}
-
-.tip {
- display: none;
-}
-
-.tip.active {
- display: block;
-}
-
-/* TODO: Remove !important. It's bad practice and it can cause errors in future */
-.section-button {
- width: 100%;
- padding: 15px 0;
- font-size: 18px;
- background: #b4b4b4c5;
- cursor: pointer;
- border-bottom: darkgray 2px solid !important;
-}
-
-.section-button:hover {
- backdrop-filter: brightness(110%);
-}
-
-.section-button .active {
- background: #00000030;
-}
-
-.List .collapsibleContent {
- border-left: #bdc5c9 2px solid;
- overflow: hidden;
- background: #ffffff50;
-}
-
-/* TODO: .section class is to generic. It should be renamed */
-.section{
- padding: 10px 0px 20px 0px ;
-}
-
-/* TODO: content subclass already in use. Creating content class overrides the subclass.
-Make .content a subclass of .content */
-/* .content {
- padding: 0px 15px 0px 15px ;
- text-align: justify;
- overflow: hidden;
- transition: max-height .2s ease-out;
- max-height: 0px;
- border-left: #c0c2c3 2px solid;
-
-} */
-
-.collapsibleMini::before{
- content: "►";
-}
-
-.collapsibleMini.active::before{
- content: "▼";
-}
-
-/* TODO: Add proper class */
-/* button:hover{
- filter: brightness(110%);
-} */
\ No newline at end of file
diff --git a/Frontend/assets/scripts/tools/scripts.js b/Frontend/assets/scripts/tools/scripts.js
index 23818b3..085cd1a 100644
--- a/Frontend/assets/scripts/tools/scripts.js
+++ b/Frontend/assets/scripts/tools/scripts.js
@@ -105,8 +105,11 @@ function performRequest(text, checkXML, checkTransform){
//Form REST request, send, receive and display in resultArea
async function restRequest(text) {
const escapeChar = "specialEscapeChar";
- // const addr = "http://localhost:8081/" + text;
- const addr = window.location.protocol + "//" + window.location.hostname + ":8081/" + text;
+ var port = ":8081/"
+ if (getProcessor() == "libxml") {
+ port = ":8082/"
+ }
+ const addr = window.location.protocol + "//" + window.location.hostname + port + text;
var xmlData = document.getElementById("xmlArea").value.trim();
var transformData = document.getElementById("transformArea").value.trim();
diff --git a/Frontend/tools/xpath.html b/Frontend/tools/xpath.html
index 3d0a6b3..c7ed0a9 100644
--- a/Frontend/tools/xpath.html
+++ b/Frontend/tools/xpath.html
@@ -24,13 +24,15 @@
diff --git a/Frontend/tools/xslt.html b/Frontend/tools/xslt.html
index cc77f34..131fd3a 100644
--- a/Frontend/tools/xslt.html
+++ b/Frontend/tools/xslt.html
@@ -19,6 +19,7 @@
procInfo
@@ -1130,7 +1131,7 @@
console.log("processTooltip");
- if (getProcInfo() == "xalan") {
+ if (getProcInfo() == "xalan" || getProcInfo() == "libxml") {
document.getElementById("tooltipFunctionInfo").innerText = "XSLT 1.0 functions";
document.getElementById("processorTooltipInfo").innerText = "Supports XSLT 1.0";
hideList(document.getElementsByName("collapse30"));
diff --git a/docker-compose.yml b/docker-compose.yml
index 559be61..6524db5 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -19,6 +19,13 @@ services:
ports:
- 8081:8081
+ xmltools-libxml-backend:
+ build: ./Backend-libXML
+ container_name: xmltools-libxml-backend
+ image: xmltools-libxml-backend
+ ports:
+ - 8082:80
+
xmltools-mocked-services:
build:
context: ./Backend/mocked-services
diff --git a/readme.md b/readme.md
index d5600b6..c1a3e1b 100644
--- a/readme.md
+++ b/readme.md
@@ -17,6 +17,11 @@ openapi.yml
Rest API accepts xml documents, given querry and processor version to call requested xml engine to perform given
operation and finally returns outcome in response body.
+## Flask Python backend
+
+This is module providing support for processing XMLs using libxml library. It consumes same JSON as Java backend.
+
+
## Mocked services
MockedServices is a tool that allows developer to create, in easy and simple way, http server mocked endpoints for integration tests