dev #26
							
								
								
									
										3
									
								
								Backend-libXML/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Backend-libXML/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| .idea | ||||
| __pycache** | ||||
| venv | ||||
							
								
								
									
										8
									
								
								Backend-libXML/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Backend-libXML/Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -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/ | ||||
							
								
								
									
										69
									
								
								Backend-libXML/Parser.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								Backend-libXML/Parser.py
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||
							
								
								
									
										74
									
								
								Backend-libXML/main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								Backend-libXML/main.py
									
									
									
									
									
										Normal file
									
								
							| @@ -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() | ||||
							
								
								
									
										3
									
								
								Backend-libXML/requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Backend-libXML/requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| lxml | ||||
| flask | ||||
| flask_cors | ||||
							
								
								
									
										6
									
								
								Backend-libXML/sample/xpath/data.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Backend-libXML/sample/xpath/data.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|   "data": "<books><book id='1'><name>Hamlet</name><date>2001-05-04</date><authorId>1</authorId><availability>false</availability></book><book id='2'><name>Macbeth</name><date>2000-12-13</date><authorId>1</authorId><availability>false</availability></book><book id='3'><name>Harry Potter and the Sorcerer's Stone</name><date>2005-04-29</date><authorId>2</authorId><availability>true</availability></book><book id='4'><name>The Long Walk</name><date>2018-07-01</date><authorId>4</authorId><availability>true</availability></book><book id='5'><name>Misery</name><date>2018-01-31</date><authorId>4</authorId><availability>true</availability></book><book id='6'><name>Think and Grow Rich</name><date>2004-09-10</date><authorId>6</authorId><availability>true</availability></book><book id='7'><name>The Law of Success</name><date>1982-05-09</date><authorId>6</authorId><availability>false</availability></book><book id='8'><name>Patriot Games</name><date>1995-10-21</date><authorId>5</authorId><availability>false</availability></book><book id='9'><name>The Sum of All Fears</name><date>1992-09-19</date><authorId>5</authorId><availability>false</availability></book><book id='10'><name>The Alchemist</name><date>2017-02-20</date><authorId>3</authorId><availability>false</availability></book><book id='11'><name>Hamlet</name><date>1994-06-01</date><authorId>1</authorId><availability>false</availability></book><book id='12'><name>Measure for Measure</name><date>1990-03-23</date><authorId>1</authorId><availability>false</availability></book><book id='13'><name>Hamlet</name><date>1989-05-05</date><authorId>1</authorId><availability>true</availability></book><book id='14'><name>Hamlet</name><date>1999-05-30</date><authorId>1</authorId><availability>true</availability></book><book id='15'><name>The Law of Success</name><date>2004-11-26</date><authorId>6</authorId><availability>true</availability></book><book id='16'><name>Romeo and Juliet</name><date>1997-02-08</date><authorId>1</authorId><availability>true</availability></book><book id='17'><name>The Alchemist</name><date>2009-08-21</date><authorId>3</authorId><availability>true</availability></book></books>", | ||||
|   "process": "/books/book[name = 'The Law of Success']", | ||||
|   "processor": "saxon", | ||||
|   "version": "2.0" | ||||
| } | ||||
							
								
								
									
										6
									
								
								Backend-libXML/sample/xpath/dataNS.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Backend-libXML/sample/xpath/dataNS.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|   "data": "<b:books xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.demo.com' xmlns:b='http://www.book.com' xmlns:a='http://www.author.com'><b:book id='1'><b:name>Hamlet</b:name><b:date>2001-05-04</b:date><a:authorId>1</a:authorId><b:availability>false</b:availability></b:book><b:book id='2'><b:name>Macbeth</b:name><b:date>2000-12-13</b:date><a:authorId>1</a:authorId><b:availability>false</b:availability></b:book><b:book id='3'><b:name>Harry Potter and the Sorcerer's Stone</b:name><b:date>2005-04-29</b:date><a:authorId>2</a:authorId><b:availability>true</b:availability></b:book><b:book id='4'><b:name>The Long Walk</b:name><b:date>2018-07-01</b:date><a:authorId>4</a:authorId><b:availability>true</b:availability></b:book><b:book id='5'><b:name>Misery</b:name><b:date>2018-01-31</b:date><a:authorId>4</a:authorId><b:availability>true</b:availability></b:book><b:book id='6'><b:name>Think and Grow Rich</b:name><b:date>2004-09-10</b:date><a:authorId>6</a:authorId><b:availability>true</b:availability></b:book><b:book id='7'><b:name>The Law of Success</b:name><b:date>1982-05-09</b:date><a:authorId>6</a:authorId><b:availability>false</b:availability></b:book><b:book id='8'><b:name>Patriot Games</b:name><b:date>1995-10-21</b:date><a:authorId>5</a:authorId><b:availability>false</b:availability></b:book><b:book id='9'><b:name>The Sum of All Fears</b:name><b:date>1992-09-19</b:date><a:authorId>5</a:authorId><b:availability>false</b:availability></b:book><b:book id='10'><b:name>The Alchemist</b:name><b:date>2017-02-20</b:date><a:authorId>3</a:authorId><b:availability>false</b:availability></b:book><b:book id='11'><b:name>Hamlet</b:name><b:date>1994-06-01</b:date><a:authorId>1</a:authorId><b:availability>false</b:availability></b:book><b:book id='12'><b:name>Measure for Measure</b:name><b:date>1990-03-23</b:date><a:authorId>1</a:authorId><b:availability>false</b:availability></b:book><b:book id='13'><b:name>Hamlet</b:name><b:date>1989-05-05</b:date><a:authorId>1</a:authorId><b:availability>true</b:availability></b:book><b:book id='14'><b:name>Hamlet</b:name><b:date>1999-05-30</b:date><a:authorId>1</a:authorId><b:availability>true</b:availability></b:book><b:book id='15'><b:name>The Law of Success</b:name><b:date>2004-11-26</b:date><a:authorId>6</a:authorId><b:availability>true</b:availability></b:book><b:book id='16'><b:name>Romeo and Juliet</b:name><b:date>1997-02-08</b:date><a:authorId>1</a:authorId><b:availability>true</b:availability></b:book><b:book id='17'><b:name>The Alchemist</b:name><b:date>2009-08-21</b:date><a:authorId>3</a:authorId><b:availability>true</b:availability></b:book></b:books>", | ||||
|   "process": "/b:books/b:book[b:name = 'The Law of Success']", | ||||
|   "processor": "saxon", | ||||
|   "version": "2.0" | ||||
| } | ||||
							
								
								
									
										4
									
								
								Backend-libXML/sample/xpath/non-ns.curl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Backend-libXML/sample/xpath/non-ns.curl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #url = "localhost:8081/xpathpost" | ||||
| url = "localhost:5000/xpath" | ||||
| request = "POST" | ||||
| data = "@data.json" | ||||
							
								
								
									
										4
									
								
								Backend-libXML/sample/xpath/ns.curl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Backend-libXML/sample/xpath/ns.curl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #url = "localhost:8081/xpathpost" | ||||
| url = "localhost:5000/xpath" | ||||
| request = "POST" | ||||
| data = "@dataNS.json" | ||||
							
								
								
									
										4
									
								
								Backend-libXML/sample/xsd/xsd.curl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Backend-libXML/sample/xsd/xsd.curl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #url = "http://localhost:8082/xsd" | ||||
| url = "http://localhost:5000/xsd" | ||||
| data = "@xsd.json" | ||||
| request = POST | ||||
							
								
								
									
										6
									
								
								Backend-libXML/sample/xsd/xsd.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Backend-libXML/sample/xsd/xsd.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|     "data": "<ns0:values xmlns:ns0 = \"http://www.tibco.com/schemas/test/Test/Resources/Schema.xsd\"><ns0:value>Test</ns0:value><ns0:value>Test3</ns0:value></ns0:values>", | ||||
|     "process": "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://www.tibco.com/schemas/test/Test/Resources/Schema.xsd\" targetNamespace=\"http://www.tibco.com/schemas/test/Test/Resources/Schema.xsd\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\"> <xs:element name=\"values\"><xs:complexType><xs:sequence><xs:element name=\"value\" type=\"xs:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/></xs:sequence></xs:complexType></xs:element></xs:schema>", | ||||
|     "processor": "saxon", | ||||
|     "version": "1.0" | ||||
| } | ||||
							
								
								
									
										3
									
								
								Backend-libXML/sample/xslt/xslt.curl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Backend-libXML/sample/xslt/xslt.curl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| url = "http://localhost:5000/xslt" | ||||
| data = "@xslt.json" | ||||
| request = POST | ||||
							
								
								
									
										6
									
								
								Backend-libXML/sample/xslt/xslt.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Backend-libXML/sample/xslt/xslt.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|     "data": "<b:books xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.demo.com' xmlns:b='http://www.book.com' xmlns:a='http://www.author.com'><b:book id='1'><b:name>Hamlet</b:name><b:date>2001-05-04</b:date><a:authorId>1</a:authorId><b:availability>false</b:availability></b:book><b:book id='2'><b:name>Macbeth</b:name><b:date>2000-12-13</b:date><a:authorId>1</a:authorId><b:availability>false</b:availability></b:book><b:book id='3'><b:name>Harry Potter and the Sorcerer's Stone</b:name><b:date>2005-04-29</b:date><a:authorId>2</a:authorId><b:availability>true</b:availability></b:book><b:book id='4'><b:name>The Long Walk</b:name><b:date>2018-07-01</b:date><a:authorId>4</a:authorId><b:availability>true</b:availability></b:book><b:book id='5'><b:name>Misery</b:name><b:date>2018-01-31</b:date><a:authorId>4</a:authorId><b:availability>true</b:availability></b:book><b:book id='6'><b:name>Think and Grow Rich</b:name><b:date>2004-09-10</b:date><a:authorId>6</a:authorId><b:availability>true</b:availability></b:book><b:book id='7'><b:name>The Law of Success</b:name><b:date>1982-05-09</b:date><a:authorId>6</a:authorId><b:availability>false</b:availability></b:book><b:book id='8'><b:name>Patriot Games</b:name><b:date>1995-10-21</b:date><a:authorId>5</a:authorId><b:availability>false</b:availability></b:book><b:book id='9'><b:name>The Sum of All Fears</b:name><b:date>1992-09-19</b:date><a:authorId>5</a:authorId><b:availability>false</b:availability></b:book><b:book id='10'><b:name>The Alchemist</b:name><b:date>2017-02-20</b:date><a:authorId>3</a:authorId><b:availability>false</b:availability></b:book><b:book id='11'><b:name>Hamlet</b:name><b:date>1994-06-01</b:date><a:authorId>1</a:authorId><b:availability>false</b:availability></b:book><b:book id='12'><b:name>Measure for Measure</b:name><b:date>1990-03-23</b:date><a:authorId>1</a:authorId><b:availability>false</b:availability></b:book><b:book id='13'><b:name>Hamlet</b:name><b:date>1989-05-05</b:date><a:authorId>1</a:authorId><b:availability>true</b:availability></b:book><b:book id='14'><b:name>Hamlet</b:name><b:date>1999-05-30</b:date><a:authorId>1</a:authorId><b:availability>true</b:availability></b:book><b:book id='15'><b:name>The Law of Success</b:name><b:date>2004-11-26</b:date><a:authorId>6</a:authorId><b:availability>true</b:availability></b:book><b:book id='16'><b:name>Romeo and Juliet</b:name><b:date>1997-02-08</b:date><a:authorId>1</a:authorId><b:availability>true</b:availability></b:book><b:book id='17'><b:name>The Alchemist</b:name><b:date>2009-08-21</b:date><a:authorId>3</a:authorId><b:availability>true</b:availability></b:book></b:books>", | ||||
|     "process": "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:b='http://www.demo.com'><xsl:template match='b:books'><Library><BookCount><xsl:value-of select='count(b:book)' /></BookCount></Library></xsl:template></xsl:stylesheet>", | ||||
|     "processor": "saxon", | ||||
|     "version": "1.0" | ||||
| } | ||||
| @@ -3,12 +3,12 @@ | ||||
| <head> | ||||
|     <title>R11 MockedServices</title> | ||||
|     <meta charset="utf-8"> | ||||
|     <link rel="stylesheet" href="http://localhost:8086/assets/css/common/fontello.css" type="text/css"> | ||||
|     <link rel="stylesheet" href="http://localhost:8086/assets/css/mock-service/main.css" type="text/css"> | ||||
|     <link rel="stylesheet" href="../css/fontello.css" type="text/css"> | ||||
|     <link rel="stylesheet" href="../css/main.css" type="text/css"> | ||||
|     <!-- <link rel="stylesheet" href="css/common.css" type="text/css"> --> | ||||
|     <link rel="stylesheet" href="http://localhost:8086/assets/css/mock-service/common.css" type="text/css"> | ||||
|     <link rel="stylesheet" href="../css/common.css" type="text/css"> | ||||
|     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> | ||||
|     <script src="../js/dyn_host.js"></script> | ||||
|     <!-- <script src="../js/dyn_host.js"></script> --> | ||||
| </head> | ||||
| <body> | ||||
|     <div class="container"> | ||||
| @@ -37,15 +37,15 @@ | ||||
|                             <!-- status --> | ||||
|                             <div class="max-width  small-vertical-margin"> | ||||
|                                 <label for="httpStatus">Http Status</label> | ||||
|                                 <input id="httpStatus" class="bordered-field max-width data-field" type="text" value="200" list="httpStatusSuggestion"> | ||||
|                                 <datalist id="httpStatusSuggestion"> | ||||
|                                     <option value="200"> | ||||
|                                     <option value="300"> | ||||
|                                     <option value="400"> | ||||
|                                     <option value="403"> | ||||
|                                     <option value="404"> | ||||
|                                     <option value="500"> | ||||
|                                 </datalist> | ||||
|                                 <!-- <input id="httpStatus" class="bordered-field max-width data-field" type="text" value="200" list="httpStatusSuggestion"> --> | ||||
|                                 <select id="httpStatus" class="bordered-field max-width data-field" value="200"> | ||||
|                                     <option value="200">200</option> | ||||
|                                     <option value="300">300</option> | ||||
|                                     <option value="400">400</option> | ||||
|                                     <option value="403">403</option> | ||||
|                                     <option value="404">404</option> | ||||
|                                     <option value="500">500</option> | ||||
|                                 </select> | ||||
|                             </div> | ||||
|                             <!-- content type --> | ||||
|                             <div class="max-width  small-vertical-margin"> | ||||
|   | ||||
| @@ -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 | ||||
|     } | ||||
|      | ||||
| }); | ||||
|        | ||||
| @@ -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<String, String> 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<String, String> 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<String, String> jsonMap = new HashMap<>(); | ||||
|         Map<String, String> requestMap = new HashMap<>(); | ||||
|         Map<String, String> 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"; | ||||
|   | ||||
| @@ -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(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -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'); | ||||
| @@ -1,4 +0,0 @@ | ||||
| .overflowedTableContent { | ||||
|     max-height: 750px; | ||||
|     overflow: scroll; | ||||
| } | ||||
| @@ -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; | ||||
| } | ||||
| @@ -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; | ||||
| } | ||||
| @@ -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; | ||||
| } | ||||
| @@ -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%; | ||||
| } */ | ||||
| @@ -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%); | ||||
| } */ | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -24,13 +24,15 @@ | ||||
|                         <label for="processors">Select XPath processor:</label> | ||||
|                         <select name="processors" id="processors"> | ||||
|                             <option value="saxon">Saxon</option> | ||||
|                             <!-- <option value="xalan">Xalan</option> --> | ||||
|                             <option value="xalan">Xalan</option> | ||||
|                             <option value="libxml">libXML</option> | ||||
|                         </select> | ||||
|                         <label for="versions">XPath version:</label> | ||||
|                         <select name="versions" id="versions"> | ||||
|                             <option value="2.0">1.0/2.0</option> | ||||
|                             <option value="3.0">3.0</option> | ||||
|                             <option value="3.1">3.1</option> | ||||
|                             <option class="hideable libxml xalan"value="1.0">1.0</option> | ||||
|                             <option class="hideable saxon" value="2.0">2.0</option> | ||||
|                             <option class="hideable saxon" value="3.0">3.0</option> | ||||
|                             <option class="hideable saxon" value="3.1">3.1</option> | ||||
|                         </select> | ||||
|                     </div> | ||||
|                     <button class="action-button active" id="defaultXMLButton" style="padding: 3px 10px;" | ||||
| @@ -3066,6 +3068,31 @@ | ||||
|  | ||||
|  | ||||
|     <script> | ||||
|         function processVersionSelector() { | ||||
|             var processor = getProcessor(); | ||||
|             var hideableOptions = document.getElementsByClassName("hideable"); | ||||
|             for (let i = 0; i < hideableOptions.length; i++) { | ||||
|                hideableOptions[i].style = "display: none;"; | ||||
|             } | ||||
|             if (processor == "xalan" || processor == "libxml") { | ||||
|                 var xalanOptions = document.getElementsByClassName("xalan"); | ||||
|                 for (let i = 0; i < xalanOptions.length; i++) { | ||||
|                     xalanOptions[i].style = ""; | ||||
|                 } | ||||
|                 document.getElementById("versions").selectedIndex = 0; | ||||
|             } | ||||
|             else { | ||||
|                 var saxonOptions = document.getElementsByClassName("saxon"); | ||||
|                 for (let i = 0; i < saxonOptions.length; i++) { | ||||
|                     saxonOptions[i].style = ""; | ||||
|                 } | ||||
|                 document.getElementById("versions").selectedIndex = 3; | ||||
|                  | ||||
|             } | ||||
|             processTooltip(); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         function processTooltip() { | ||||
|             var filter = "collapse" + getVersion(); | ||||
|             var collList; | ||||
| @@ -3086,6 +3113,9 @@ | ||||
|                 hideList(document.getElementsByName("collapse30")); | ||||
|                 hideList(document.getElementsByName("collapse31")); | ||||
|             } | ||||
|  | ||||
|  | ||||
|  | ||||
|             // if (checkDefault(document.getElementById("xmlArea").value.trim()) || document.getElementById("xmlArea").value.trim() == "") { | ||||
|             //     document.getElementById("defaultXMLButton").classList.toggle("active", true); | ||||
|             // } else { | ||||
| @@ -3175,6 +3205,7 @@ | ||||
|             setDefaultContent(document.getElementById("transformArea"), 'Insert XPath expression here'); | ||||
|             console.log("init"); | ||||
|             processTooltip(); | ||||
|             processVersionSelector(); | ||||
|             tool.addEventListener('change', event => { | ||||
|                 //Check if script was called from textarea or selector | ||||
|                 var targetID = event.target.getAttribute('id'); | ||||
| @@ -3182,6 +3213,7 @@ | ||||
|                     return; | ||||
|                 } | ||||
|                 processTooltip(); | ||||
|                 processVersionSelector(); | ||||
|             }) | ||||
|             tool.addEventListener('click', event => { | ||||
|                 //Check if script was called from textarea or selector | ||||
| @@ -3190,6 +3222,7 @@ | ||||
|                     return; | ||||
|                 } | ||||
|                 processTooltip(); | ||||
|                 processVersionSelector(); | ||||
|             }) | ||||
|             tool.addEventListener('change', event => { | ||||
|                 //Check if script was called from textarea or selector | ||||
| @@ -3198,6 +3231,7 @@ | ||||
|                     return; | ||||
|                 } | ||||
|                 processTooltip(); | ||||
|                 processVersionSelector(); | ||||
|             }) | ||||
|         } | ||||
|     </script> | ||||
|   | ||||
| @@ -18,8 +18,8 @@ | ||||
|                 </div> | ||||
|                 <label for="processors">Select XSLT processor:</label> | ||||
|                 <select name="processors" id="processors"> | ||||
|                     <!-- <option value="saxon">Saxon</option> --> | ||||
|                     <option value="xalan">Xalan</option> | ||||
|                     <option value="libxml">libXML</option> | ||||
|                 </select> | ||||
|                 <!-- <span id="processorTooltipInfo">procInfo</span><br> --> | ||||
|                 <br> | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|                 <select name="processors" id="processors"> | ||||
|                     <option value="saxon">Saxon</option> | ||||
|                     <option value="xalan">Xalan</option> | ||||
|                     <option value="libxml">libXML</option> | ||||
|                 </select> | ||||
|                 <span id="processorTooltipInfo">procInfo</span><br> | ||||
|                 <br> | ||||
| @@ -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")); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user