Refactored tools services endpoints system and fixed json formatter. (#91)
Co-authored-by: Artur Kołecki <koleckiartur@icloud.com> Co-authored-by: Adam Bem <adam.bem@zoho.eu> Reviewed-on: R11/release11-tools-web#91
This commit is contained in:
		| @@ -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"; | ||||
|         } | ||||
|     }; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user