Refactored tools services endpoints system and fixed json formatter. #91
| @@ -96,23 +96,23 @@ def process_xml(request: request, type: str) -> str: | ||||
|         return json.dumps(response_json), code | ||||
|  | ||||
|  | ||||
| @app.route("/xpathpost", methods=["POST"]) | ||||
| @app.route("/xpath", methods=["POST"]) | ||||
| def xpath(): | ||||
|     return process_xml(request, "xpath") | ||||
|  | ||||
| @app.route("/xsdpost", methods=["POST"]) | ||||
| @app.route("/xsd", methods=["POST"]) | ||||
| def xsd(): | ||||
|     return process_xml(request, "xsd") | ||||
|  | ||||
| @app.route("/xsltpost", methods=["POST"]) | ||||
| @app.route("/xslt", methods=["POST"]) | ||||
| def xslt(): | ||||
|     return process_xml(request, "xslt") | ||||
|  | ||||
| @app.route("/prettifypost", methods=["POST"]) | ||||
| @app.route("/prettify", methods=["POST"]) | ||||
| def prettify(): | ||||
|     return process_xml(request, "prettify") | ||||
|  | ||||
| @app.route("/minimizepost", methods=["POST"]) | ||||
| @app.route("/minimize", methods=["POST"]) | ||||
| def minimize(): | ||||
|     return process_xml(request, "minimize") | ||||
|  | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
|   <packaging>pom</packaging> | ||||
|  | ||||
|   <modules> | ||||
|     <module>xslt-rest</module> | ||||
|     <module>tools-services</module> | ||||
|     <module>mocked-services</module> | ||||
|   </modules> | ||||
| </project> | ||||
| @@ -5,7 +5,7 @@ | ||||
|   <modelVersion>4.0.0</modelVersion> | ||||
| 
 | ||||
|   <groupId>com.r11.tools</groupId> | ||||
|   <artifactId>xslt-rest</artifactId> | ||||
|   <artifactId>tools-services</artifactId> | ||||
|   <version>1.0-SNAPSHOT</version> | ||||
| 
 | ||||
|   <properties> | ||||
| @@ -15,24 +15,11 @@ | ||||
|     <jackson.version>2.14.1</jackson.version> | ||||
|     <slf4j.version>2.0.6</slf4j.version> | ||||
|     <log4j.version>2.19.0</log4j.version> | ||||
|     <gson.version>2.10.1</gson.version> | ||||
|   </properties> | ||||
| 
 | ||||
|   <build> | ||||
|     <plugins> | ||||
|       <!--            <plugin>--> | ||||
|       <!--                <artifactId>maven-jar-plugin</artifactId>--> | ||||
|       <!--                <version>3.1.0</version>--> | ||||
|       <!--                <configuration>--> | ||||
|       <!--                    <archive>--> | ||||
|       <!--                        <manifest>--> | ||||
|       <!--                            <addClasspath>true</addClasspath>--> | ||||
|       <!--                            <classpathPrefix>lib/</classpathPrefix>--> | ||||
|       <!--                            <mainClass>com.r11.tools.xslt.Main</mainClass>--> | ||||
|       <!--                        </manifest>--> | ||||
|       <!--                    </archive>--> | ||||
|       <!--                </configuration>--> | ||||
|       <!--            </plugin>--> | ||||
| 
 | ||||
|       <plugin> | ||||
|         <artifactId>maven-compiler-plugin</artifactId> | ||||
|         <version>3.8.1</version> | ||||
| @@ -51,7 +38,7 @@ | ||||
|             <manifest> | ||||
|               <addClasspath>true</addClasspath> | ||||
|               <classpathPrefix>lib/</classpathPrefix> | ||||
|               <mainClass>com.r11.tools.xslt.Main</mainClass> | ||||
|               <mainClass>com.r11.tools.SparkInitializer</mainClass> | ||||
|             </manifest> | ||||
|           </archive> | ||||
|           <descriptorRefs> | ||||
| @@ -82,6 +69,11 @@ | ||||
|     </dependency> | ||||
| 
 | ||||
|     <!--    JSON    --> | ||||
|     <dependency> | ||||
|       <groupId>com.google.code.gson</groupId> | ||||
|       <artifactId>gson</artifactId> | ||||
|       <version>${gson.version}</version> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>com.fasterxml.jackson.core</groupId> | ||||
|       <artifactId>jackson-core</artifactId> | ||||
| @@ -142,7 +134,5 @@ | ||||
|       <artifactId>log4j-api</artifactId> | ||||
|       <version>${log4j.version}</version> | ||||
|     </dependency> | ||||
| 
 | ||||
| 
 | ||||
|   </dependencies> | ||||
| </project> | ||||
| @@ -0,0 +1,39 @@ | ||||
| package com.r11.tools; | ||||
|  | ||||
| import com.r11.tools.controller.JsonController; | ||||
| import com.r11.tools.controller.ProcessorInfoController; | ||||
| import com.r11.tools.controller.XPathController; | ||||
| import com.r11.tools.controller.XsdController; | ||||
| import com.r11.tools.controller.XsltController; | ||||
| import com.r11.tools.controller.internal.RestControllerRegistry; | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import spark.Spark; | ||||
|  | ||||
| public class SparkApplication { | ||||
|  | ||||
|     public static void run() { | ||||
|         // TODO: read port from config | ||||
|         Spark.port(8081); | ||||
|  | ||||
|         Spark.after((request, response) -> { | ||||
|             response.header("Access-Control-Allow-Origin", "*"); | ||||
|             response.header("access-control-allow-headers", "*"); | ||||
|             response.header("access-control-expose-headers", "*"); | ||||
|             response.header("Access-Control-Allow-Methods", "POST"); | ||||
|         }); | ||||
|  | ||||
|         Logger logger = LogManager.getLogger(SparkApplication.class); | ||||
|  | ||||
|         RestControllerRegistry registry = new RestControllerRegistry(); | ||||
|         registry.registerController(new ProcessorInfoController(logger)); | ||||
|         registry.registerController(new XsdController(logger)); | ||||
|         registry.registerController(new XPathController(logger)); | ||||
|         registry.registerController(new XsltController(logger)); | ||||
|         registry.registerController(new JsonController()); | ||||
|  | ||||
|         registry.register(); | ||||
|  | ||||
|         logger.info("Server is online at port: " + Spark.port()); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,7 @@ | ||||
| package com.r11.tools; | ||||
|  | ||||
| public class SparkInitializer { | ||||
|     public static void main(String[] args) { | ||||
|         SparkApplication.run(); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,58 @@ | ||||
| package com.r11.tools.controller; | ||||
|  | ||||
| import com.google.gson.Gson; | ||||
| import com.google.gson.GsonBuilder; | ||||
| import com.google.gson.JsonObject; | ||||
| import com.r11.tools.controller.internal.GlobalControllerManifest; | ||||
| import com.r11.tools.controller.internal.HandlerType; | ||||
| import com.r11.tools.controller.internal.RestController; | ||||
| import com.r11.tools.controller.internal.ScopedControllerManifest; | ||||
| import spark.Request; | ||||
| import spark.Response; | ||||
|  | ||||
| @GlobalControllerManifest(path = "/json") | ||||
| public class JsonController implements RestController { | ||||
|  | ||||
|     private final Gson prettyGson = new GsonBuilder() | ||||
|             .disableHtmlEscaping() | ||||
|             .setPrettyPrinting() | ||||
|             .create(); | ||||
|  | ||||
|     private final Gson gson = new GsonBuilder() | ||||
|             .disableHtmlEscaping() | ||||
|             .create(); | ||||
|  | ||||
|     @ScopedControllerManifest(method = HandlerType.POST, path = "/formatting") | ||||
|     public void formatting(Request request, Response response) { | ||||
|         try { | ||||
|             JsonObject jsonObject = this.gson.fromJson(request.body(), JsonObject.class); | ||||
|             response.status(200); | ||||
|             response.body(this.prettyGson.toJson(jsonObject)); | ||||
|         } catch (Exception e) { | ||||
|             response.status(500); | ||||
|             Throwable cause = e.getCause(); | ||||
|             if (cause == null) { | ||||
|                 response.body(e.getMessage()); | ||||
|             } else { | ||||
|                 response.body(cause.getMessage()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @ScopedControllerManifest(method = HandlerType.POST, path = "/minimize") | ||||
|     public void minimize(Request request, Response response) { | ||||
|         try { | ||||
|             JsonObject jsonObject = this.prettyGson.fromJson(request.body(), JsonObject.class); | ||||
|             response.status(200); | ||||
|             response.body(this.gson.toJson(jsonObject)); | ||||
|         } catch (Exception e) { | ||||
|             response.status(500); | ||||
|             Throwable cause = e.getCause(); | ||||
|             if (cause == null) { | ||||
|                 response.body(e.getMessage()); | ||||
|             } else { | ||||
|                 response.body(cause.getMessage()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,34 @@ | ||||
| package com.r11.tools.controller; | ||||
|  | ||||
| import com.r11.tools.controller.internal.GlobalControllerManifest; | ||||
| import com.r11.tools.controller.internal.HandlerType; | ||||
| import com.r11.tools.controller.internal.RestController; | ||||
| import com.r11.tools.controller.internal.ScopedControllerManifest; | ||||
| import com.r11.tools.xml.Saxon; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import spark.Request; | ||||
| import spark.Response; | ||||
|  | ||||
| @GlobalControllerManifest | ||||
| public class ProcessorInfoController implements RestController { | ||||
|  | ||||
|     private final Logger logger; | ||||
|  | ||||
|     public ProcessorInfoController(Logger logger) { | ||||
|         this.logger = logger; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handler that returns processor version | ||||
|      */ | ||||
|     @ScopedControllerManifest(method = HandlerType.GET, path = "/procinfo") | ||||
|     public void processorInfo(Request request, Response response) { | ||||
|         try { | ||||
|             response.header("processor", "Saxon " + Saxon.getVersion() + " over s9api"); | ||||
|             response.body(Saxon.getVersion()); | ||||
|         } catch (Exception ex) { | ||||
|             this.logger.error("Error on retrieving engine version. " + ex); | ||||
|             response.body(ex.getMessage()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,104 @@ | ||||
| package com.r11.tools.controller; | ||||
|  | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import com.r11.tools.controller.internal.GlobalControllerManifest; | ||||
| import com.r11.tools.controller.internal.HandlerType; | ||||
| import com.r11.tools.controller.internal.RestController; | ||||
| import com.r11.tools.controller.internal.ScopedControllerManifest; | ||||
| import com.r11.tools.xml.Saxon; | ||||
| import com.r11.tools.xml.Xalan; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import spark.Request; | ||||
| import spark.Response; | ||||
|  | ||||
| @GlobalControllerManifest | ||||
| public class XPathController implements RestController { | ||||
|  | ||||
|     private final Logger logger; | ||||
|  | ||||
|     public XPathController(Logger logger) { | ||||
|         this.logger = logger; | ||||
|     } | ||||
|  | ||||
|     @ScopedControllerManifest(method = HandlerType.POST, path = "/xpath") | ||||
|     public void transform(Request request, Response response) throws JsonProcessingException { | ||||
|         String body = request.body(); | ||||
|         ObjectMapper mapper = new ObjectMapper(); | ||||
|         Map<String, String> requestMap = new HashMap<>(); | ||||
|         Map<String, String> responseMap = new HashMap<>(); | ||||
|         try { | ||||
|             requestMap = mapper.readValue(body, Map.class); | ||||
|         } catch (JsonProcessingException ex) { | ||||
|             this.logger.error("Request JSON error. " + ex); | ||||
|             responseMap.put("result", ex.getMessage()); | ||||
|             responseMap.put("processor", "N/A"); | ||||
|             responseMap.put("status", "ERR"); | ||||
|             responseMap.put("time", "N/A"); | ||||
|             response.status(400); | ||||
|             response.body(mapper.writeValueAsString(responseMap)); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         String data = requestMap.get("data"); | ||||
|         String query = requestMap.get("process"); | ||||
|         String processor = requestMap.get("processor"); | ||||
|         String version = requestMap.get("version"); | ||||
|  | ||||
|  | ||||
|         String tmp = ""; | ||||
|         long timeStart; | ||||
|         long duration; | ||||
|  | ||||
|         if (processor == null) { | ||||
|             response.body("saxon, xalan"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         switch (processor) { | ||||
|             case "saxon": | ||||
|                 response.header("processor", "Saxon " + Saxon.getVersion() + " " + version + " over s9api"); | ||||
|                 timeStart = System.currentTimeMillis(); | ||||
|                 try { | ||||
|                     tmp = Saxon.processXPath(data, query, version).trim(); | ||||
|                     responseMap.put("result", tmp); | ||||
|                     responseMap.put("status", "OK"); | ||||
|                 } catch (Exception ex) { | ||||
|                     this.logger.error("Error on processing XPath using Saxon. " + ex); | ||||
|                     responseMap.put("result", ex.getMessage()); | ||||
|                     responseMap.put("status", "ERR"); | ||||
|                     response.status(400); | ||||
|                 } | ||||
|                 duration = System.currentTimeMillis() - timeStart; | ||||
|                 this.logger.info("Request" + body + " processed in " + duration + " ms."); | ||||
|                 responseMap.put("processor", "Saxon " + Saxon.getVersion() + " " + version + " over s9api"); | ||||
|                 responseMap.put("time", "" + duration); | ||||
|                 response.body(mapper.writeValueAsString(responseMap)); | ||||
|                 return; | ||||
|  | ||||
|             case "xalan": | ||||
|                 response.header("processor", Xalan.getVersion()); | ||||
|                 timeStart = System.currentTimeMillis(); | ||||
|                 try { | ||||
|                     tmp = Xalan.processXPath(data, query).trim(); | ||||
|                     responseMap.put("result", tmp); | ||||
|                     responseMap.put("status", "OK"); | ||||
|                 } catch (Exception ex) { | ||||
|                     this.logger.error("Error on processing XPath using Xalan. " + ex); | ||||
|                     responseMap.put("result", ex.getMessage()); | ||||
|                     responseMap.put("status", "ERR"); | ||||
|                     response.status(400); | ||||
|                 } | ||||
|                 duration = System.currentTimeMillis() - timeStart; | ||||
|                 this.logger.info("Request: " + body + " processed in " + duration + " ms."); | ||||
|                 responseMap.put("processor", Xalan.getVersion()); | ||||
|                 responseMap.put("time", Long.toString(duration)); | ||||
|                 response.body(mapper.writeValueAsString(responseMap)); | ||||
|                 return; | ||||
|             default: | ||||
|                 response.body("saxon, xalan"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,70 @@ | ||||
| package com.r11.tools.controller; | ||||
|  | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import com.r11.tools.controller.internal.GlobalControllerManifest; | ||||
| import com.r11.tools.controller.internal.HandlerType; | ||||
| import com.r11.tools.controller.internal.RestController; | ||||
| import com.r11.tools.controller.internal.ScopedControllerManifest; | ||||
| import com.r11.tools.xml.Xalan; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import spark.Request; | ||||
| import spark.Response; | ||||
|  | ||||
| @GlobalControllerManifest | ||||
| public class XsdController implements RestController { | ||||
|  | ||||
|     private final Logger logger; | ||||
|  | ||||
|     public XsdController(Logger logger) { | ||||
|         this.logger = logger; | ||||
|     } | ||||
|  | ||||
|     @ScopedControllerManifest(method = HandlerType.POST, path = "/xsd") | ||||
|     public Response transform(Request req, Response resp) throws JsonProcessingException { | ||||
|         String body = req.body(); | ||||
|  | ||||
|         ObjectMapper mapper = new ObjectMapper(); | ||||
|         Map<String, String> requestMap = new HashMap<>(); | ||||
|         Map<String, String> responseMap = new HashMap<>(); | ||||
|  | ||||
|         try { | ||||
|             requestMap = mapper.readValue(body, Map.class); | ||||
|         } catch (JsonProcessingException ex) { | ||||
|             this.logger.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"); | ||||
|         String xsd = requestMap.get("process"); | ||||
|  | ||||
|         resp.header("processor", Xalan.getVersion()); | ||||
|         long timeStart = System.currentTimeMillis(); | ||||
|         String tmp; | ||||
|         try { | ||||
|             tmp = Xalan.validate(data, xsd).trim(); | ||||
|             responseMap.put("result", tmp); | ||||
|             responseMap.put("status", "OK"); | ||||
|         } catch (Exception ex) { | ||||
|             this.logger.error("Error on validation against XSD using Xalan. " + ex); | ||||
|             responseMap.put("result", ex.getMessage()); | ||||
|             responseMap.put("status", "ERR"); | ||||
|             resp.status(400); | ||||
|         } | ||||
|  | ||||
|         long duration = System.currentTimeMillis() - timeStart; | ||||
|         this.logger.info("Request: " + body + " processed in " + duration + " ms."); | ||||
|         responseMap.put("processor", Xalan.getVersion()); | ||||
|         responseMap.put("time", "" + duration); | ||||
|         resp.body(mapper.writeValueAsString(responseMap)); | ||||
|         return resp; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,105 @@ | ||||
| package com.r11.tools.controller; | ||||
|  | ||||
| import com.fasterxml.jackson.core.JsonParseException; | ||||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||||
| import com.fasterxml.jackson.databind.JsonMappingException; | ||||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||||
| import com.r11.tools.controller.internal.GlobalControllerManifest; | ||||
| import com.r11.tools.controller.internal.HandlerType; | ||||
| import com.r11.tools.controller.internal.RestController; | ||||
| import com.r11.tools.controller.internal.ScopedControllerManifest; | ||||
| import com.r11.tools.xml.Saxon; | ||||
| import com.r11.tools.xml.Xalan; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import spark.Request; | ||||
| import spark.Response; | ||||
|  | ||||
| @GlobalControllerManifest | ||||
| public class XsltController implements RestController { | ||||
|  | ||||
|     private final Logger logger; | ||||
|  | ||||
|     public XsltController(Logger logger) { | ||||
|         this.logger = logger; | ||||
|     } | ||||
|  | ||||
|     @ScopedControllerManifest(method = HandlerType.POST, path = "/xslt") | ||||
|     public void transform(Request request, Response response) throws JsonProcessingException { | ||||
|         String body = request.body(); | ||||
|         ObjectMapper mapper = new ObjectMapper(); | ||||
|         Map<String, String> requestMap = new HashMap<>(); | ||||
|         Map<String, String> responseMap = new HashMap<>(); | ||||
|         try { | ||||
|             requestMap = mapper.readValue(body, Map.class); | ||||
|         } catch (JsonMappingException | JsonParseException ex) { | ||||
|             this.logger.error("Request JSON error. " + ex); | ||||
|             responseMap.put("result", ex.getMessage()); | ||||
|             responseMap.put("processor", "N/A"); | ||||
|             responseMap.put("status", "ERR"); | ||||
|             responseMap.put("time", "N/A"); | ||||
|             response.status(400); | ||||
|             response.body(mapper.writeValueAsString(responseMap)); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         String data = requestMap.get("data"); | ||||
|         String query = requestMap.get("process"); | ||||
|         String processor = requestMap.get("processor"); | ||||
|         String version = requestMap.get("version"); | ||||
|  | ||||
|         if (processor == null) { | ||||
|             response.body("saxon, xalan"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         String tmp; | ||||
|         long timeStart; | ||||
|         long duration; | ||||
|         switch (processor) { | ||||
|             case "saxon": | ||||
|                 timeStart = System.currentTimeMillis(); | ||||
|                 try { | ||||
|                     tmp = Saxon.processXSLT(data, query); | ||||
|                     responseMap.put("result", tmp); | ||||
|                     responseMap.put("status", "OK"); | ||||
|                 } catch (Exception ex) { | ||||
|                     this.logger.error("Error on processing XSLT using Saxon. " + ex); | ||||
|                     responseMap.put("result", ex.getMessage()); | ||||
|                     responseMap.put("status", "ERR"); | ||||
|                     response.status(400); | ||||
|                 } | ||||
|  | ||||
|                 duration = System.currentTimeMillis() - timeStart; | ||||
|                 this.logger.info("Request: " + body + " processed in " + duration + " ms."); | ||||
|                 responseMap.put("processor", "Saxon " + Saxon.getVersion() + " " + version); | ||||
|                 responseMap.put("time", Long.toString(duration)); | ||||
|                 response.body(mapper.writeValueAsString(responseMap)); | ||||
|                 return; | ||||
|  | ||||
|             case "xalan": | ||||
|                 timeStart = System.currentTimeMillis(); | ||||
|                 try { | ||||
|                     tmp = Xalan.processXSLT(data, query); | ||||
|                     responseMap.put("result", tmp); | ||||
|                     responseMap.put("status", "OK"); | ||||
|                 } catch (Exception ex) { | ||||
|                     this.logger.error("Error on processing XSLT using Xalan. " + ex); | ||||
|                     responseMap.put("result", ex.getMessage()); | ||||
|                     responseMap.put("status", "ERR"); | ||||
|                     response.status(400); | ||||
|                 } | ||||
|  | ||||
|                 duration = System.currentTimeMillis() - timeStart; | ||||
|                 this.logger.info("Request: " + body + " processed in " + duration + " ms."); | ||||
|                 responseMap.put("processor", Xalan.getVersion()); | ||||
|                 responseMap.put("time", Long.toString(duration)); | ||||
|                 response.body(mapper.writeValueAsString(responseMap)); | ||||
|                 return; | ||||
|  | ||||
|             default: | ||||
|                 response.body("saxon, xalan"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| package com.r11.tools.controller.internal; | ||||
|  | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
|  | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @Target(ElementType.TYPE) | ||||
| public @interface GlobalControllerManifest { | ||||
|  | ||||
|     String path() default ""; | ||||
| } | ||||
| @@ -0,0 +1,7 @@ | ||||
| package com.r11.tools.controller.internal; | ||||
|  | ||||
| public enum HandlerType { | ||||
|  | ||||
|     GET, POST, PUT, DELETE | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,5 @@ | ||||
| package com.r11.tools.controller.internal; | ||||
|  | ||||
| public interface RestController { | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,59 @@ | ||||
| package com.r11.tools.controller.internal; | ||||
|  | ||||
| import com.r11.tools.controller.internal.path.PathBuilder; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.HashSet; | ||||
| import java.util.Set; | ||||
| import spark.Spark; | ||||
|  | ||||
| public class RestControllerRegistry { | ||||
|  | ||||
|     private final Set<RestController> registeredControllers; | ||||
|  | ||||
|     public RestControllerRegistry() { | ||||
|         this.registeredControllers = new HashSet<>(); | ||||
|     } | ||||
|  | ||||
|     public void registerController(RestController restController) { | ||||
|         this.registeredControllers.add(restController); | ||||
|     } | ||||
|  | ||||
|     public void register() { | ||||
|         this.registeredControllers.forEach(controller -> { | ||||
|             if (controller.getClass().isAnnotationPresent(GlobalControllerManifest.class)) { | ||||
|                 for (Method method : controller.getClass().getMethods()) { | ||||
|                     this.registerAssignableHandlers(controller.getClass(), controller, method); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void registerAssignableHandlers(Class<? extends RestController> parent, RestController parentValue, Method method) { | ||||
|         if ( | ||||
|                 (parent.isAnnotationPresent(GlobalControllerManifest.class)) && | ||||
|                         (method.isAnnotationPresent(ScopedControllerManifest.class)) | ||||
|         ) { | ||||
|             HandlerType handlerType = method.getAnnotation(ScopedControllerManifest.class).method(); | ||||
|  | ||||
|             String path = PathBuilder.resolvePathOf( | ||||
|                     parent.getAnnotation(GlobalControllerManifest.class).path(), | ||||
|                     method.getAnnotation(ScopedControllerManifest.class).path() | ||||
|             ); | ||||
|  | ||||
|             switch (handlerType) { | ||||
|                 case GET: | ||||
|                     Spark.get(path, (request, response) -> method.invoke(parentValue, request, response)); | ||||
|                     break; | ||||
|                 case PUT: | ||||
|                     Spark.put(path, (request, response) -> method.invoke(parentValue, request, response)); | ||||
|                     break; | ||||
|                 case POST: | ||||
|                     Spark.post(path, (request, response) -> method.invoke(parentValue, request, response)); | ||||
|                     break; | ||||
|                 case DELETE: | ||||
|                     Spark.delete(path, (request, response) -> method.invoke(parentValue, request, response)); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,15 @@ | ||||
| package com.r11.tools.controller.internal; | ||||
|  | ||||
| import java.lang.annotation.ElementType; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
|  | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| @Target(ElementType.METHOD) | ||||
| public @interface ScopedControllerManifest { | ||||
|  | ||||
|     HandlerType method(); | ||||
|  | ||||
|     String path(); | ||||
| } | ||||
| @@ -0,0 +1,30 @@ | ||||
| package com.r11.tools.controller.internal.path; | ||||
|  | ||||
| public final class PathBuilder { | ||||
|  | ||||
|     private static final String PATH_SEPARATOR = "/"; | ||||
|  | ||||
|     private PathBuilder() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public static String resolvePathOf(String globalPath, String scopedPath) { | ||||
|         String resolvedPath = | ||||
|                 PathBuilder.removeTrailingPathSeparator(globalPath) + | ||||
|                         PathBuilder.removeTrailingPathSeparator(scopedPath); | ||||
|  | ||||
|         if (resolvedPath.endsWith(PATH_SEPARATOR)) { | ||||
|             resolvedPath = resolvedPath.substring(0, resolvedPath.length() - 1); | ||||
|         } | ||||
|  | ||||
|         return PATH_SEPARATOR + resolvedPath; | ||||
|     } | ||||
|  | ||||
|     private static String removeTrailingPathSeparator(String path) { | ||||
|         if (path.endsWith(PATH_SEPARATOR)) { | ||||
|             return path.substring(0, path.length() - 1); | ||||
|         } | ||||
|  | ||||
|         return path; | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| package com.r11.tools.xslt.processors; | ||||
| package com.r11.tools.xml; | ||||
| 
 | ||||
| import net.sf.saxon.om.NamespaceMap; | ||||
| import net.sf.saxon.s9api.XPathCompiler; | ||||
| @@ -1,8 +1,6 @@ | ||||
| package com.r11.tools.xslt.processors; | ||||
| package com.r11.tools.xml; | ||||
| 
 | ||||
| import net.sf.saxon.s9api.*; | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| 
 | ||||
| import javax.xml.transform.stream.StreamSource; | ||||
| import java.io.StringReader; | ||||
| @@ -1,8 +1,5 @@ | ||||
| package com.r11.tools.xslt.processors; | ||||
| package com.r11.tools.xml; | ||||
| 
 | ||||
| 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; | ||||
| @@ -19,10 +16,6 @@ import javax.xml.transform.stream.StreamSource; | ||||
| import javax.xml.validation.Schema; | ||||
| import javax.xml.validation.SchemaFactory; | ||||
| import javax.xml.validation.Validator; | ||||
| import javax.xml.xpath.XPath; | ||||
| import javax.xml.xpath.XPathConstants; | ||||
| import javax.xml.xpath.XPathExpression; | ||||
| import javax.xml.xpath.XPathFactory; | ||||
| import java.io.*; | ||||
| 
 | ||||
| /** | ||||
| @@ -1,4 +1,4 @@ | ||||
| package com.r11.tools.xslt.processors; | ||||
| package com.r11.tools.xml; | ||||
| 
 | ||||
| import org.w3c.dom.*; | ||||
| 
 | ||||
| @@ -11,7 +11,7 @@ | ||||
| 		</File> | ||||
| 	</Appenders> | ||||
| 	<Loggers> | ||||
| 		<Logger name="com.r11.tools.xslt.SparkInitializer" level="info" additivity="true"> | ||||
| 		<Logger name="com.r11.tools.SparkApplication" level="info" additivity="true"> | ||||
| 			<AppenderRef ref="Console"/> | ||||
| 		</Logger> | ||||
| 		<Root level="info"> | ||||
| @@ -1,15 +0,0 @@ | ||||
| package com.r11.tools.xslt; | ||||
|  | ||||
| /** | ||||
|  * Application initializer | ||||
|  * @author Wojciech Czop | ||||
|  */ | ||||
| public class Main { | ||||
|     /** | ||||
|      * Initializes the application | ||||
|      * @param args | ||||
|      */ | ||||
|     public static void main(String[] args) { | ||||
|         SparkInitializer.run(); | ||||
|     } | ||||
| } | ||||
| @@ -1,260 +0,0 @@ | ||||
| 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; | ||||
| import com.r11.tools.xslt.processors.Xalan; | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import spark.*; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * Class contains spark configuration and method initializing spark framework | ||||
|  * @author Wojciech Czop | ||||
|  */ | ||||
| public class SparkInitializer { | ||||
|  | ||||
|     private static final Logger LOG = LogManager.getLogger(SparkInitializer.class); | ||||
|  | ||||
|     /** | ||||
|      * Initializes spark framework | ||||
|      */ | ||||
|     public static void run(){ | ||||
| //        TODO: Port value as property | ||||
|         Spark.port(8081); | ||||
|  | ||||
|         Spark.after((request, response) -> { | ||||
|             response.header("Access-Control-Allow-Origin", "*"); | ||||
|             response.header("access-control-allow-headers", "*"); | ||||
|             response.header("access-control-expose-headers", "*"); | ||||
|             response.header("Access-Control-Allow-Methods", "POST"); | ||||
|         }); | ||||
|  | ||||
|         Spark.post("/xsltpost", xsltHandler); | ||||
|         Spark.post("/xpathpost", xpathHandler); | ||||
|         Spark.post("/xsdpost", xsdHandler); | ||||
|         Spark.get("/procinfo", procinfoHandler); | ||||
|  | ||||
|         LOG.info("Server is online at port: " + Spark.port()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handler that returns processor version | ||||
|      */ | ||||
|     private static final Route procinfoHandler = (Request req, Response resp) -> { | ||||
|         try { | ||||
|             resp.header("processor", "Saxon " + Saxon.getVersion() + " over s9api"); | ||||
|             return Saxon.getVersion(); | ||||
|         } catch (Exception ex) { | ||||
|             LOG.error("Error on retrieving engine version. " + ex); | ||||
|             return ex.getMessage(); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Handler that returns info if document is valid | ||||
|      * Also provides info about request time and processor | ||||
|      */ | ||||
|     private static final Route xsdHandler = (Request req, Response resp) -> { | ||||
|         String body = req.body(); | ||||
|         ObjectMapper mapper = new ObjectMapper(); | ||||
|         Map<String, String> requestMap = new HashMap<>(); | ||||
|         Map<String, String> responseMap = new HashMap<>(); | ||||
|         try { | ||||
|             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 = requestMap.get("data"); | ||||
|         String xsd = requestMap.get("process"); | ||||
|  | ||||
|         resp.header("processor", Xalan.getVersion()); | ||||
|         long timeStart = System.currentTimeMillis(); | ||||
|         String tmp; | ||||
|         try { | ||||
|             tmp = Xalan.validate(data, xsd).trim(); | ||||
|             responseMap.put("result", tmp); | ||||
|             responseMap.put("status", "OK"); | ||||
|         } catch (Exception ex) { | ||||
|             LOG.error("Error on validation against XSD using Xalan. " + ex); | ||||
|             responseMap.put("result", ex.getMessage()); | ||||
|             responseMap.put("status", "ERR"); | ||||
|             resp.status(400); | ||||
|         } | ||||
|         long duration = System.currentTimeMillis() - timeStart; | ||||
|         LOG.info("Request: " + body + " processed in " + duration + " ms."); | ||||
|         responseMap.put("processor", Xalan.getVersion()); | ||||
|         responseMap.put("time", "" + duration); | ||||
|         resp.body(mapper.writeValueAsString(responseMap)); | ||||
|         return resp; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Handler that returns output of xpath query and processor data | ||||
|      */ | ||||
|     private static final Route xpathHandler = (Request req, Response resp) -> { | ||||
|         String body = req.body(); | ||||
|         ObjectMapper mapper = new ObjectMapper(); | ||||
|         Map<String, String> requestMap = new HashMap<>(); | ||||
|         Map<String, String> responseMap = new HashMap<>(); | ||||
|         try { | ||||
|             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 = requestMap.get("data"); | ||||
|         String query = requestMap.get("process"); | ||||
|         String processor = requestMap.get("processor"); | ||||
|         String version = requestMap.get("version"); | ||||
|  | ||||
|  | ||||
|         String tmp = ""; | ||||
|         long timeStart; | ||||
|         long duration; | ||||
|  | ||||
|         if (processor == null) { | ||||
|             return "saxon, xalan"; | ||||
|         } | ||||
|  | ||||
|         switch (processor) { | ||||
|             case "saxon": | ||||
|                 resp.header("processor", "Saxon " + Saxon.getVersion() + " " + version + " over s9api"); | ||||
|                 timeStart = System.currentTimeMillis(); | ||||
|                 try { | ||||
|                     tmp = Saxon.processXPath(data, query, version).trim(); | ||||
|                     responseMap.put("result", tmp); | ||||
|                     responseMap.put("status", "OK"); | ||||
|                 } catch (Exception ex) { | ||||
|                     LOG.error("Error on processing XPath using Saxon. " + ex); | ||||
|                     responseMap.put("result", ex.getMessage()); | ||||
|                     responseMap.put("status", "ERR"); | ||||
|                     resp.status(400); | ||||
|                 } | ||||
|                 duration = System.currentTimeMillis() - timeStart; | ||||
|                 LOG.info("Request" + body + " processed in " + duration + " ms."); | ||||
|                 responseMap.put("processor", "Saxon " + Saxon.getVersion() + " " + version + " over s9api"); | ||||
|                 responseMap.put("time", "" + duration); | ||||
|                 resp.body(mapper.writeValueAsString(responseMap)); | ||||
|                 return resp; | ||||
|  | ||||
|             case "xalan": | ||||
|                 resp.header("processor", Xalan.getVersion()); | ||||
|                 timeStart = System.currentTimeMillis(); | ||||
|                 try { | ||||
|                     tmp = Xalan.processXPath(data, query).trim(); | ||||
|                     responseMap.put("result", tmp); | ||||
|                     responseMap.put("status", "OK"); | ||||
|                 } catch (Exception ex) { | ||||
|                     LOG.error("Error on processing XPath using Xalan. " + ex); | ||||
|                     responseMap.put("result", ex.getMessage()); | ||||
|                     responseMap.put("status", "ERR"); | ||||
|                     resp.status(400); | ||||
|                 } | ||||
|                 duration = System.currentTimeMillis() - timeStart; | ||||
|                 LOG.info("Request: " + body + " processed in " + duration + " ms."); | ||||
|                 responseMap.put("processor", Xalan.getVersion()); | ||||
|                 responseMap.put("time", Long.toString(duration)); | ||||
|                 resp.body(mapper.writeValueAsString(responseMap)); | ||||
|                 return resp; | ||||
|  | ||||
|             default: | ||||
|                 return "saxon, xalan"; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Handler that returns outcome of xslt transformation and processor data | ||||
|      */ | ||||
|     private static final Route xsltHandler = (Request req, Response resp) -> { | ||||
|         String body = req.body(); | ||||
|         ObjectMapper mapper = new ObjectMapper(); | ||||
|         Map<String, String> requestMap = new HashMap<>(); | ||||
|         Map<String, String> responseMap = new HashMap<>(); | ||||
|         try { | ||||
|             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 = requestMap.get("data"); | ||||
|         String query = requestMap.get("process"); | ||||
|         String processor = requestMap.get("processor"); | ||||
|         String version = requestMap.get("version"); | ||||
|  | ||||
|         if (processor == null) { | ||||
|             return "saxon, xalan"; | ||||
|         } | ||||
|  | ||||
|         String tmp; | ||||
|         long timeStart; | ||||
|         long duration; | ||||
|         switch (processor) { | ||||
|             case "saxon": | ||||
|                 timeStart = System.currentTimeMillis(); | ||||
|                 try { | ||||
|                     tmp = Saxon.processXSLT(data, query); | ||||
|                     responseMap.put("result", tmp); | ||||
|                     responseMap.put("status", "OK"); | ||||
|                 } catch (Exception ex) { | ||||
|                     LOG.error("Error on processing XSLT using Saxon. " + ex); | ||||
|                     responseMap.put("result", ex.getMessage()); | ||||
|                     responseMap.put("status", "ERR"); | ||||
|                     resp.status(400); | ||||
|                 } | ||||
|                 duration = System.currentTimeMillis() - timeStart; | ||||
|                 LOG.info("Request: " + body + " processed in " + duration + " ms."); | ||||
|                 responseMap.put("processor", "Saxon " + Saxon.getVersion() + " " + version); | ||||
|                 responseMap.put("time", Long.toString(duration)); | ||||
|                 resp.body(mapper.writeValueAsString(responseMap)); | ||||
|                 return resp; | ||||
|  | ||||
|             case "xalan": | ||||
|                 timeStart = System.currentTimeMillis(); | ||||
|                 try { | ||||
|                     tmp = Xalan.processXSLT(data, query); | ||||
|                     responseMap.put("result", tmp); | ||||
|                     responseMap.put("status", "OK"); | ||||
|                 } catch (Exception ex) { | ||||
|                     LOG.error("Error on processing XSLT using Xalan. " + ex); | ||||
|                     responseMap.put("result", ex.getMessage()); | ||||
|                     responseMap.put("status", "ERR"); | ||||
|                     resp.status(400); | ||||
|                 } | ||||
|                 duration = System.currentTimeMillis() - timeStart; | ||||
|                 LOG.info("Request: " + body + " processed in " + duration + " ms."); | ||||
|                 responseMap.put("processor", Xalan.getVersion()); | ||||
|                 responseMap.put("time", Long.toString(duration)); | ||||
|                 resp.body(mapper.writeValueAsString(responseMap)); | ||||
|                 return resp; | ||||
|  | ||||
|             default: | ||||
|                 return "saxon, xalan"; | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,39 +1,63 @@ | ||||
| function formatAndValidateJson(errorElement) { | ||||
|   const input = document.querySelector('#jsonBlock'); | ||||
|   const processInfo = document.getElementById(errorElement); | ||||
|   const start = new Date(); | ||||
|  | ||||
|   try { | ||||
|     const start = new Date(); | ||||
|   const address = window.location.protocol + "//" + window.location.hostname + ":" + 8081 + "/json/formatting" | ||||
|  | ||||
|     const obj = JSON.parse(input.textContent); | ||||
|     input.innerHTML = JSON.stringify(obj, null, 2); | ||||
|   fetch(address, { | ||||
|     method: 'POST', | ||||
|     body: input.textContent | ||||
|   }) | ||||
|   .then(async (response) => { | ||||
|     if (!response.ok) { | ||||
|       throw Error(await response.text()); | ||||
|     } | ||||
|  | ||||
|     return response.text(); | ||||
|   }) | ||||
|   .then((data) => { | ||||
|     input.innerText = data; | ||||
|     processInfo.innerText = ""; | ||||
|     hljs.highlightElement(input); | ||||
|  | ||||
|     const end = new Date(); | ||||
|     processInfo.innerHTML = "<b style='color: black'>Validation and formatting time:</b> <span style='color: green'>" + (end.getMilliseconds() - start.getMilliseconds()) + "ms</span>"; | ||||
|   } catch (error) { | ||||
|   }) | ||||
|   .catch((error) => { | ||||
|     processInfo.innerHTML = "<b style='color: red'>" + error + "</b>"; | ||||
|     console.error("Error: ", error) | ||||
|   } | ||||
|     console.error('Error:', error); | ||||
|   }); | ||||
| } | ||||
|  | ||||
| function minimizeJson(errorElement) { | ||||
|   const input = document.querySelector('#jsonBlock'); | ||||
|   const processInfo = document.getElementById(errorElement); | ||||
|  | ||||
|   try { | ||||
|     const start = new Date(); | ||||
|   const start = new Date(); | ||||
|   const address = window.location.protocol + "//" + window.location.hostname + ":" + 8081 + "/json/minimize" | ||||
|  | ||||
|     const obj = JSON.parse(input.textContent); | ||||
|     input.innerHTML = JSON.stringify(obj); | ||||
|   fetch(address, { | ||||
|     method: 'POST', | ||||
|     body: input.textContent | ||||
|   }) | ||||
|   .then(async (response) => { | ||||
|     if (!response.ok) { | ||||
|       throw Error(await response.text()); | ||||
|     } | ||||
|  | ||||
|     return response.text(); | ||||
|   }) | ||||
|   .then((data) => { | ||||
|     input.innerText = data; | ||||
|     processInfo.innerText = ""; | ||||
|     hljs.highlightElement(input); | ||||
|  | ||||
|     const end = new Date(); | ||||
|     processInfo.innerHTML = "<b style='color: black'>Validation and formatting time:</b> <span style='color: green'>" + (end.getMilliseconds() - start.getMilliseconds()) + "ms</span>"; | ||||
|   } catch (error) { | ||||
|   }) | ||||
|   .catch((error) => { | ||||
|     processInfo.innerHTML = "<b style='color: red'>" + error + "</b>"; | ||||
|     console.error("Error: ", error) | ||||
|   } | ||||
|     console.error('Error:', error); | ||||
|   }); | ||||
| } | ||||
| @@ -1,54 +1,251 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|   <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|   <meta charset="utf-8" /> | ||||
|   <head> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <meta charset="utf-8" /> | ||||
|  | ||||
|   <link rel="stylesheet" href="../assets/css/tools/r11form.css"> | ||||
|   <link rel="stylesheet" href="../assets/css/json.css"> | ||||
|   <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css"> | ||||
|   <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script> | ||||
|   <script src="../assets/scripts/tools/scripts.js"></script> | ||||
|   <script src="../assets/scripts/tools/json.js"></script> | ||||
|   <script>hljs.highlightAll();</script> | ||||
| </head> | ||||
|     <link rel="stylesheet" href="../assets/css/tools/r11form.css"> | ||||
|     <link rel="stylesheet" href="../assets/css/json.css"> | ||||
|     <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css"> | ||||
|     <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script> | ||||
|     <script src="../assets/scripts/tools/scripts.js"></script> | ||||
|     <script src="../assets/scripts/tools/json.js"></script> | ||||
|     <script>hljs.highlightAll();</script> | ||||
|   </head> | ||||
|  | ||||
| <body> | ||||
|   <div class="container"> | ||||
|     <div id="tool" class="tool rwd-expandable"> | ||||
|       <div class="tool-context"> | ||||
|         <div class="headline"> | ||||
|           <h1>Online JSON Formatter</h1> | ||||
|   <body> | ||||
|     <div class="container"> | ||||
|       <div id="tool" class="tool rwd-expandable"> | ||||
|         <div class="tool-context"> | ||||
|           <div class="headline"> | ||||
|             <h1>Online JSON Formatter</h1> | ||||
|           </div> | ||||
|  | ||||
|           <p style="margin-bottom: -30px" id="processInfo"></p> | ||||
|  | ||||
|           <pre> | ||||
|             <code class="hightlight-json json-block" id="jsonBlock" contenteditable="True">{"enter": "your", "json": "here"}</code> | ||||
|           </pre> | ||||
|  | ||||
|           <button style="margin-top: 20px" | ||||
|                   class="max-width block-label action-button active" | ||||
|                   onclick="formatAndValidateJson('processInfo')" | ||||
|           >Prettify JSON</button> | ||||
|  | ||||
|           <button class="max-width block-label action-button active" | ||||
|                   onclick="minimizeJson('processInfo')" | ||||
|           >Minimize JSON</button> | ||||
|         </div> | ||||
|  | ||||
|         <p style="margin-bottom: -30px" id="processInfo"></p> | ||||
|  | ||||
|         <pre> | ||||
|           <code class="hightlight-json json-block" id="jsonBlock" contenteditable="True">{"enter": "your", "json": "here"}</code> | ||||
|         </pre> | ||||
|  | ||||
|         <button style="margin-top: 20px" | ||||
|                 class="max-width block-label action-button active" | ||||
|                 onclick="formatAndValidateJson('processInfo')" | ||||
|         >Prettify JSON</button> | ||||
|  | ||||
|         <button class="max-width block-label action-button active" | ||||
|                 onclick="minimizeJson('processInfo')" | ||||
|         >Minimize JSON</button> | ||||
|       </div> | ||||
|  | ||||
|       <div class="tooltip-window rwd-hideable"> | ||||
|         <h2>What is this?</h2> | ||||
|         <p>This tool has 2 main functions: | ||||
|         <ul> | ||||
|           <li><strong>Prettify JSON</strong> to make it human-readable (add indentation etc.)</li> | ||||
|           <li><strong>Minimize JSON</strong> to make it more compact (exactly opposite to above)</li> | ||||
|         </ul> | ||||
|         </p> | ||||
|       </div> | ||||
|  | ||||
|     </div> | ||||
|  | ||||
|     <div class="tooltip-window rwd-hideable"> | ||||
|       <h2>What is this?</h2> | ||||
|       <p>This tool has 2 main functions: | ||||
|       <ul> | ||||
|         <li><strong>Prettify JSON</strong> to make it human-readable (add indentation etc.)</li> | ||||
|         <li><strong>Minimize JSON</strong> to make it more compact (exactly opposite to above)</li> | ||||
|       </ul> | ||||
|       </p> | ||||
|     </div> | ||||
|     <script> | ||||
|       const mergeHTMLPlugin = (function () { | ||||
|         'use strict'; | ||||
|  | ||||
|   </div> | ||||
| </body> | ||||
|         var originalStream; | ||||
|  | ||||
|         /** | ||||
|          * @param {string} value | ||||
|          * @returns {string} | ||||
|          */ | ||||
|         function escapeHTML(value) { | ||||
|           return value | ||||
|           .replace(/&/g, '&') | ||||
|           .replace(/</g, '<') | ||||
|           .replace(/>/g, '>') | ||||
|           .replace(/"/g, '"') | ||||
|           .replace(/'/g, '''); | ||||
|         } | ||||
|  | ||||
|         /* plugin itself */ | ||||
|  | ||||
|         /** @type {HLJSPlugin} */ | ||||
|         const mergeHTMLPlugin = { | ||||
|           // preserve the original HTML token stream | ||||
|           "before:highlightElement": ({el}) => { | ||||
|             originalStream = nodeStream(el); | ||||
|           }, | ||||
|           // merge it afterwards with the highlighted token stream | ||||
|           "after:highlightElement": ({el, result, text}) => { | ||||
|             if (!originalStream.length) { | ||||
|               return; | ||||
|             } | ||||
|  | ||||
|             const resultNode = document.createElement('div'); | ||||
|             resultNode.innerHTML = result.value; | ||||
|             result.value = mergeStreams(originalStream, nodeStream(resultNode), text); | ||||
|             el.innerHTML = result.value; | ||||
|           } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * @param {Node} node | ||||
|          */ | ||||
|         function tag(node) { | ||||
|           return node.nodeName.toLowerCase(); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * @param {Node} node | ||||
|          */ | ||||
|         function nodeStream(node) { | ||||
|           /** @type Event[] */ | ||||
|           const result = []; | ||||
|           (function _nodeStream(node, offset) { | ||||
|             for (let child = node.firstChild; child; child = child.nextSibling) { | ||||
|               if (child.nodeType === 3) { | ||||
|                 offset += child.nodeValue.length; | ||||
|               } else if (child.nodeType === 1) { | ||||
|                 result.push({ | ||||
|                   event: 'start', | ||||
|                   offset: offset, | ||||
|                   node: child | ||||
|                 }); | ||||
|                 offset = _nodeStream(child, offset); | ||||
|  | ||||
|                 if (!tag(child).match(/br|hr|img|input/)) { | ||||
|                   result.push({ | ||||
|                     event: 'stop', | ||||
|                     offset: offset, | ||||
|                     node: child | ||||
|                   }); | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|             return offset; | ||||
|           })(node, 0); | ||||
|           return result; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * @param {any} original - the original stream | ||||
|          * @param {any} highlighted - stream of the highlighted source | ||||
|          * @param {string} value - the original source itself | ||||
|          */ | ||||
|         function mergeStreams(original, highlighted, value) { | ||||
|           let processed = 0; | ||||
|           let result = ''; | ||||
|           const nodeStack = []; | ||||
|  | ||||
|           function selectStream() { | ||||
|             if (!original.length || !highlighted.length) { | ||||
|               return original.length ? original : highlighted; | ||||
|             } | ||||
|             if (original[0].offset !== highlighted[0].offset) { | ||||
|               return (original[0].offset < highlighted[0].offset) ? original : highlighted; | ||||
|             } | ||||
|  | ||||
|             return highlighted[0].event === 'start' ? original : highlighted; | ||||
|           } | ||||
|  | ||||
|           /** | ||||
|            * @param {Node} node | ||||
|            */ | ||||
|           function open(node) { | ||||
|             /** @param {Attr} attr */ | ||||
|             function attributeString(attr) { | ||||
|               return ' ' + attr.nodeName + '="' + escapeHTML(attr.value) + '"'; | ||||
|             } | ||||
|  | ||||
|             // @ts-ignore | ||||
|             result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('') | ||||
|                 + '>'; | ||||
|           } | ||||
|  | ||||
|           /** | ||||
|            * @param {Node} node | ||||
|            */ | ||||
|           function close(node) { | ||||
|             result += '</' + tag(node) + '>'; | ||||
|           } | ||||
|  | ||||
|           /** | ||||
|            * @param {Event} event | ||||
|            */ | ||||
|           function render(event) { | ||||
|             (event.event === 'start' ? open : close)(event.node); | ||||
|           } | ||||
|  | ||||
|           while (original.length || highlighted.length) { | ||||
|             let stream = selectStream(); | ||||
|             result += escapeHTML(value.substring(processed, stream[0].offset)); | ||||
|             processed = stream[0].offset; | ||||
|             if (stream === original) { | ||||
|               /* | ||||
|               On any opening or closing tag of the original markup we first close | ||||
|               the entire highlighted node stack, then render the original tag along | ||||
|               with all the following original tags at the same offset and then | ||||
|               reopen all the tags on the highlighted stack. | ||||
|               */ | ||||
|               nodeStack.reverse().forEach(close); | ||||
|               do { | ||||
|                 render(stream.splice(0, 1)[0]); | ||||
|                 stream = selectStream(); | ||||
|               } while (stream === original && stream.length && stream[0].offset === processed); | ||||
|               nodeStack.reverse().forEach(open); | ||||
|             } else { | ||||
|               if (stream[0].event === 'start') { | ||||
|                 nodeStack.push(stream[0].node); | ||||
|               } else { | ||||
|                 nodeStack.pop(); | ||||
|               } | ||||
|               render(stream.splice(0, 1)[0]); | ||||
|             } | ||||
|           } | ||||
|           return result + escapeHTML(value.substr(processed)); | ||||
|         } | ||||
|  | ||||
|         return mergeHTMLPlugin; | ||||
|  | ||||
|       }()); | ||||
|  | ||||
|       hljs.addPlugin(mergeHTMLPlugin); | ||||
|  | ||||
|       const editorEle = document.getElementById('jsonBlock'); | ||||
|  | ||||
|       // Handle the `paste` event | ||||
|       editorEle.addEventListener('paste', function (e) { | ||||
|         // Prevent the default action | ||||
|         e.preventDefault(); | ||||
|  | ||||
|         // Get the copied text from the clipboard | ||||
|         const text = e.clipboardData | ||||
|             ? (e.originalEvent || e).clipboardData.getData('text/plain') | ||||
|             : // For IE | ||||
|             window.clipboardData | ||||
|                 ? window.clipboardData.getData('Text') | ||||
|                 : ''; | ||||
|  | ||||
|         if (document.queryCommandSupported('insertText')) { | ||||
|           document.execCommand('insertText', false, text); | ||||
|         } else { | ||||
|           // Insert text at the current position of caret | ||||
|           const range = document.getSelection().getRangeAt(0); | ||||
|           range.deleteContents(); | ||||
|  | ||||
|           const textNode = document.createTextNode(text); | ||||
|           range.insertNode(textNode); | ||||
|           range.selectNodeContents(textNode); | ||||
|           range.collapse(false); | ||||
|  | ||||
|           const selection = window.getSelection(); | ||||
|           selection.removeAllRanges(); | ||||
|           selection.addRange(range); | ||||
|         } | ||||
|       }); | ||||
|     </script> | ||||
|   </body> | ||||
| </html> | ||||
|   | ||||
| @@ -1,79 +1,79 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|     <!-- <link rel="stylesheet" href="styles.css"> --> | ||||
|     <link rel="stylesheet" href="../assets/css/tools/r11form.css"> | ||||
|     <script src="../assets/scripts/tools/scripts.js"></script> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <meta charset="utf-8" /> | ||||
| </head> | ||||
|     <head> | ||||
|         <!-- <link rel="stylesheet" href="styles.css"> --> | ||||
|         <link rel="stylesheet" href="../assets/css/tools/r11form.css"> | ||||
|         <script src="../assets/scripts/tools/scripts.js"></script> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|         <meta charset="utf-8" /> | ||||
|     </head> | ||||
|  | ||||
| <body onload="init();"> | ||||
|     <div class="container"> | ||||
|         <div id="tool" class="tool rwd-expandable"> | ||||
|             <div class="tool-context"> | ||||
|                 <div class="headline"> | ||||
|                     <h1>Online XML Formatter</h1> | ||||
|                 </div> | ||||
|                 <select name="processors" id="processors" class="hidden"> | ||||
|                     <option value="libxml">libXML</option> | ||||
|                 </select> | ||||
|  | ||||
|                 <div class="display-space-between"> | ||||
|                     <div> | ||||
|                         <b><span id="formatinfo"></span></b><br> | ||||
|                         <label for="xmlArea"><b>Insert your XML:</b></label> | ||||
|     <body onload="init();"> | ||||
|         <div class="container"> | ||||
|             <div id="tool" class="tool rwd-expandable"> | ||||
|                 <div class="tool-context"> | ||||
|                     <div class="headline"> | ||||
|                         <h1>Online XML Formatter</h1> | ||||
|                     </div> | ||||
|                     <div> | ||||
|                         <button class="action-button active" id="clearXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="clearDataField()">Clear</button> | ||||
|                         <button class="action-button active" id="defaultXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="fillDefaultXML(this)">Insert default XML</button> | ||||
|                     <select name="processors" id="processors" class="hidden"> | ||||
|                         <option value="libxml">libXML</option> | ||||
|                     </select> | ||||
|  | ||||
|                     <div class="display-space-between"> | ||||
|                         <div> | ||||
|                             <b><span id="formatinfo"></span></b><br> | ||||
|                             <label for="xmlArea"><b>Insert your XML:</b></label> | ||||
|                         </div> | ||||
|                         <div> | ||||
|                             <button class="action-button active" id="clearXMLButton" style="padding: 3px 10px;" | ||||
|                                 onclick="clearDataField()">Clear</button> | ||||
|                             <button class="action-button active" id="defaultXMLButton" style="padding: 3px 10px;" | ||||
|                                 onclick="fillDefaultXML(this)">Insert default XML</button> | ||||
|                         </div> | ||||
|  | ||||
|                     </div> | ||||
|  | ||||
|                     <textarea id="xmlArea" name="xmlArea" rows="15" | ||||
|                         class="textarea-700 bordered-field vertically-resizeable max-width" | ||||
|                         onblur="setDefaultContent(this, 'Insert XML here');" | ||||
|                         onfocus="clearDefaultContent(this, 'Insert XML here');"></textarea> | ||||
|                     <br><br> | ||||
|                     <button id="prettifyButton" class="max-width block-label action-button active" | ||||
|                         onclick="performFormatRequest('prettify', true, 'xmlArea', 'xmlArea')">Prettify XML</button> | ||||
|                     <button id="minimizeButton" class="max-width block-label action-button active" | ||||
|                         onclick="performFormatRequest('minimize', true, 'xmlArea', 'xmlArea')">Minimize XML</button> | ||||
|  | ||||
|                 </div> | ||||
|                  | ||||
|                 <textarea id="xmlArea" name="xmlArea" rows="15" | ||||
|                     class="textarea-700 bordered-field vertically-resizeable max-width" | ||||
|                     onblur="setDefaultContent(this, 'Insert XML here');" | ||||
|                     onfocus="clearDefaultContent(this, 'Insert XML here');"></textarea> | ||||
|                 <br><br> | ||||
|                 <button id="prettifyButton" class="max-width block-label action-button active" | ||||
|                     onclick="performFormatRequest('prettifypost', true, 'xmlArea', 'xmlArea')">Prettify XML</button> | ||||
|                 <button id="minimizeButton" class="max-width block-label action-button active" | ||||
|                     onclick="performFormatRequest('minimizepost', true, 'xmlArea', 'xmlArea')">Minimize XML</button> | ||||
|                  | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="tooltip-window rwd-hideable"> | ||||
|             <h2>What is this?</h2> | ||||
|             <p>This tool has 2 main functions:  | ||||
|                 <ul> | ||||
|                     <li><strong>Prettify XML</strong> to make it human-readable (add indentation etc.)</li> | ||||
|                     <li><strong>Minimize XML</strong> to make it more compact (exactly opposite to above)</li> | ||||
|                 </ul> | ||||
|             </p> | ||||
|             <div class="tooltip-window rwd-hideable"> | ||||
|                 <h2>What is this?</h2> | ||||
|                 <p>This tool has 2 main functions: | ||||
|                     <ul> | ||||
|                         <li><strong>Prettify XML</strong> to make it human-readable (add indentation etc.)</li> | ||||
|                         <li><strong>Minimize XML</strong> to make it more compact (exactly opposite to above)</li> | ||||
|                     </ul> | ||||
|                 </p> | ||||
|             </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|         </div> | ||||
|  | ||||
|         <script> | ||||
|             function getProcessor() { | ||||
|                 return "libxml"; | ||||
|             } | ||||
|  | ||||
|             function getVersion() { | ||||
|                 return "1.0" | ||||
|             } | ||||
|  | ||||
|     </div> | ||||
|             function init() { | ||||
|                 setDefaultContent(document.getElementById("xmlArea"), 'Insert XML here'); | ||||
|             } | ||||
|         </script> | ||||
|  | ||||
|     <script> | ||||
|         function getProcessor() { | ||||
|             return "libxml"; | ||||
|         } | ||||
|  | ||||
|         function getVersion() { | ||||
|             return "1.0" | ||||
|         } | ||||
|  | ||||
|         function init() { | ||||
|             setDefaultContent(document.getElementById("xmlArea"), 'Insert XML here'); | ||||
|         } | ||||
|     </script> | ||||
|  | ||||
| </body> | ||||
|     </body> | ||||
|  | ||||
| </html> | ||||
|   | ||||
| @@ -40,7 +40,7 @@ | ||||
|                         <button class="action-button active" id="clearXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="clearDataField()">Clear</button> | ||||
|                         <button class="action-button active" id="prettyXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="performFormatRequest('prettifypost', true, 'xmlArea', 'xmlArea')">Format XML</button> | ||||
|                             onclick="performFormatRequest('prettify', true, 'xmlArea', 'xmlArea')">Format XML</button> | ||||
|                         <button class="action-button active" id="defaultXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="fillDefaultXML(this)">Insert default XML</button> | ||||
|                     </div> | ||||
| @@ -59,7 +59,7 @@ | ||||
|                     onfocus="clearDefaultContent(this,  'Insert XPath expression here');"></textarea> | ||||
|                 <br> | ||||
|                 <button id="requestButton" class="max-width block-label action-button active" | ||||
|                     onclick="performRequest('xpathpost', false, true)">Execute XPath | ||||
|                     onclick="performRequest('xpath', false, true)">Execute XPath | ||||
|                     expression</button> | ||||
|                 <br><br> | ||||
|                 <label for="resultArea"><b>Transform result:<span id="procinfo"></span></b></label> | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
|                         <button class="action-button active" id="clearXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="clearDataField()">Clear</button> | ||||
|                         <button class="action-button active" id="prettyXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="performFormatRequest('prettifypost', true, 'xmlArea', 'xmlArea')">Format XML</button> | ||||
|                             onclick="performFormatRequest('prettify', true, 'xmlArea', 'xmlArea')">Format XML</button> | ||||
|                         <button class="action-button active" id="defaultXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="fillDefaultXML(this)">Insert default XML</button> | ||||
|                     </div> | ||||
| @@ -50,7 +50,7 @@ | ||||
|                     onfocus="clearDefaultContent(this, 'Insert XSD here');"></textarea> | ||||
|                 <br> | ||||
|                 <button id="requestButton" class="max-width block-label action-button active" | ||||
|                     onclick="performRequest('xsdpost', true, true)">Verify XSD</button> | ||||
|                     onclick="performRequest('xsd', true, true)">Verify XSD</button> | ||||
|                 <br><br> | ||||
|  | ||||
|                 <label for="resultArea"><b>Result:<span id="procinfo"></span></b></label> | ||||
|   | ||||
| @@ -29,7 +29,7 @@ | ||||
|                         <button class="action-button active" id="clearXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="clearDataField()">Clear</button> | ||||
|                         <button class="action-button active" id="prettyXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="performFormatRequest('prettifypost', true, 'xmlArea', 'xmlArea')">Format XML</button> | ||||
|                             onclick="performFormatRequest('prettify', true, 'xmlArea', 'xmlArea')">Format XML</button> | ||||
|                         <button class="action-button active" id="defaultXMLButton" style="padding: 3px 10px;" | ||||
|                             onclick="fillDefaultXML(this)">Insert default XML</button> | ||||
|                     </div> | ||||
| @@ -52,7 +52,7 @@ | ||||
|                     onfocus="clearDefaultContent(this, 'Insert XSLT here');"></textarea> | ||||
|                 <br> | ||||
|                 <button id="requestButton" class="max-width block-label action-button active" | ||||
|                     onclick="performRequest('xsltpost', true, true)">Execute XSLT transform</button> | ||||
|                     onclick="performRequest('xslt', true, true)">Execute XSLT transform</button> | ||||
|                 <br><br> | ||||
|  | ||||
|                 <label for="resultArea"><b>Transform result:<span id="procinfo"></span></b></label> | ||||
|   | ||||
| @@ -423,7 +423,89 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/xpathpost": { | ||||
|     "/json/formatting": { | ||||
|       "post": { | ||||
|         "tags": [ | ||||
|           "JSON" | ||||
|         ], | ||||
|         "summary": "Json validation and formatting.", | ||||
|         "description": "", | ||||
|         "operationId": "json", | ||||
|         "consumes": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "in": "body", | ||||
|             "name": "request", | ||||
|             "description": "A transform that is to be performed", | ||||
|             "required": true, | ||||
|             "schema": { | ||||
|               "example": "{'a': 'b', 'c': 'd'}" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "200": { | ||||
|             "description": "Formatted JSON", | ||||
|             "schema": { | ||||
|               "type": "string" | ||||
|             } | ||||
|           }, | ||||
|           "500": { | ||||
|             "description": "Error message from json formatting.", | ||||
|             "schema": { | ||||
|               "type": "string" | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/json/minimize": { | ||||
|       "post": { | ||||
|         "tags": [ | ||||
|           "JSON" | ||||
|         ], | ||||
|         "summary": "Json validation and minimize formatting.", | ||||
|         "description": "", | ||||
|         "operationId": "json", | ||||
|         "consumes": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "in": "body", | ||||
|             "name": "request", | ||||
|             "description": "A transform that is to be performed", | ||||
|             "required": true, | ||||
|             "schema": { | ||||
|               "example": "{'a': 'b', 'c': 'd'}" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "200": { | ||||
|             "description": "Formatted JSON", | ||||
|             "schema": { | ||||
|               "type": "string" | ||||
|             } | ||||
|           }, | ||||
|           "500": { | ||||
|             "description": "Error message from json formatting.", | ||||
|             "schema": { | ||||
|               "type": "string" | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/xpath": { | ||||
|       "post": { | ||||
|         "tags": [ | ||||
|           "XPath" | ||||
| @@ -470,7 +552,7 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/xsltpost": { | ||||
|     "/xslt": { | ||||
|       "post": { | ||||
|         "tags": [ | ||||
|           "XSLT" | ||||
| @@ -517,7 +599,7 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/xsdpost": { | ||||
|     "/xsd": { | ||||
|       "post": { | ||||
|         "tags": [ | ||||
|           "XSD" | ||||
|   | ||||
| @@ -13,7 +13,7 @@ services: | ||||
|         - 8086:80 | ||||
|  | ||||
|     xmltools-backend: | ||||
|         build: ./Backend/xslt-rest | ||||
|         build: ./Backend/tools-services | ||||
|         container_name: xmltools-backend | ||||
|         image: xmltools-backend | ||||
|         ports: | ||||
|   | ||||
| @@ -11,7 +11,7 @@ Service is split into three microservices. | ||||
| Main page is hosted on port 8086. | ||||
|  | ||||
| ## API Documentation | ||||
| API documentation is available on port 8080/swagger/ | ||||
| API documentation is available on port 8000/swagger/ | ||||
|  | ||||
| ## JavaSpark backend | ||||
| Backend is hosted by default on port 8081. Rest api documentation is contained in OpenApi document | ||||
|   | ||||
		Reference in New Issue
	
	Block a user