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:
		
							
								
								
									
										21
									
								
								Backend/tools-services/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Backend/tools-services/Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| # Using maven image, based on java 8 | ||||
| FROM maven:3.6.3-jdk-8 as target | ||||
| WORKDIR build | ||||
| COPY ./ ./ | ||||
| RUN mvn -ntp package | ||||
|  | ||||
|  | ||||
| # Go to working directory in docker image | ||||
| # WORKDIR /usr/app/ | ||||
|  | ||||
| FROM openjdk:slim-buster | ||||
| COPY --from=target /build/target/*jar-with-dependencies.jar /app/REST_XSLT.jar | ||||
|  | ||||
| # Download dependencies during image build | ||||
| # (RUN - works on image creation) | ||||
| # (CMD - works on container start) | ||||
| # RUN mvn dependency:resolve | ||||
| # RUN mvn dependency:go-offline | ||||
|  | ||||
| # On container creation - run maven tests | ||||
| CMD exec java -jar /app/REST_XSLT.jar | ||||
							
								
								
									
										138
									
								
								Backend/tools-services/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								Backend/tools-services/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||
|   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|   <modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
|   <groupId>com.r11.tools</groupId> | ||||
|   <artifactId>tools-services</artifactId> | ||||
|   <version>1.0-SNAPSHOT</version> | ||||
|  | ||||
|   <properties> | ||||
|     <maven.compiler.source>11</maven.compiler.source> | ||||
|     <maven.compiler.target>11</maven.compiler.target> | ||||
|     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
|     <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-compiler-plugin</artifactId> | ||||
|         <version>3.8.1</version> | ||||
|         <configuration> | ||||
|           <source>1.8</source> | ||||
|           <target>1.8</target> | ||||
|         </configuration> | ||||
|       </plugin> | ||||
|  | ||||
|       <plugin> | ||||
|         <artifactId>maven-assembly-plugin</artifactId> | ||||
|         <version>3.3.0</version> | ||||
|  | ||||
|         <configuration> | ||||
|           <archive> | ||||
|             <manifest> | ||||
|               <addClasspath>true</addClasspath> | ||||
|               <classpathPrefix>lib/</classpathPrefix> | ||||
|               <mainClass>com.r11.tools.SparkInitializer</mainClass> | ||||
|             </manifest> | ||||
|           </archive> | ||||
|           <descriptorRefs> | ||||
|             <descriptorRef>jar-with-dependencies</descriptorRef> | ||||
|           </descriptorRefs> | ||||
|         </configuration> | ||||
|  | ||||
|         <executions> | ||||
|           <execution> | ||||
|             <id>make-assembly</id> | ||||
|             <phase>package</phase> | ||||
|             <goals> | ||||
|               <goal>single</goal> | ||||
|             </goals> | ||||
|           </execution> | ||||
|         </executions> | ||||
|  | ||||
|       </plugin> | ||||
|     </plugins> | ||||
|   </build> | ||||
|  | ||||
|   <dependencies> | ||||
|     <!--   Spark    --> | ||||
|     <dependency> | ||||
|       <groupId>com.sparkjava</groupId> | ||||
|       <artifactId>spark-core</artifactId> | ||||
|       <version>2.9.4</version> | ||||
|     </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> | ||||
|       <version>${jackson.version}</version> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>com.fasterxml.jackson.core</groupId> | ||||
|       <artifactId>jackson-databind</artifactId> | ||||
|       <version>${jackson.version}</version> | ||||
|     </dependency> | ||||
|  | ||||
|     <!--    XSLT    --> | ||||
|     <dependency> | ||||
|       <groupId>net.sf.saxon</groupId> | ||||
|       <artifactId>Saxon-HE</artifactId> | ||||
|       <version>11.4</version> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>xalan</groupId> | ||||
|       <artifactId>xalan</artifactId> | ||||
|       <version>2.7.2</version> | ||||
|     </dependency> | ||||
|  | ||||
|     <!-- Logging --> | ||||
|     <dependency> | ||||
|       <groupId>org.slf4j</groupId> | ||||
|       <artifactId>slf4j-simple</artifactId> | ||||
|       <version>${slf4j.version}</version> | ||||
|       <scope>test</scope> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>org.slf4j</groupId> | ||||
|       <artifactId>jcl-over-slf4j</artifactId> | ||||
|       <version>${slf4j.version}</version> | ||||
|       <scope>runtime</scope> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>org.slf4j</groupId> | ||||
|       <artifactId>slf4j-api</artifactId> | ||||
|       <version>${slf4j.version}</version> | ||||
|       <scope>runtime</scope> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>org.slf4j</groupId> | ||||
|       <artifactId>slf4j-log4j12</artifactId> | ||||
|       <version>${slf4j.version}</version> | ||||
|       <scope>runtime</scope> | ||||
|     </dependency> | ||||
|  | ||||
|     <dependency> | ||||
|       <groupId>org.apache.logging.log4j</groupId> | ||||
|       <artifactId>log4j-core</artifactId> | ||||
|       <version>${log4j.version}</version> | ||||
|     </dependency> | ||||
|  | ||||
|     <dependency> | ||||
|       <groupId>org.apache.logging.log4j</groupId> | ||||
|       <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; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,65 @@ | ||||
| package com.r11.tools.xml; | ||||
|  | ||||
| import net.sf.saxon.om.NamespaceMap; | ||||
| import net.sf.saxon.s9api.XPathCompiler; | ||||
| import net.sf.saxon.s9api.XdmNode; | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
|  | ||||
| /** | ||||
|  * Handler for saxon namespace scan engine. | ||||
|  * All found namespaces are stored within {@link #namespaceMap} | ||||
|  * @author Wojciech Czop | ||||
|  */ | ||||
| public class NewNamespaceResolver { | ||||
|     private static final Logger LOG = LogManager.getLogger("NewNamespaceResolver"); | ||||
|  | ||||
|     private NamespaceMap namespaceMap; | ||||
|  | ||||
|     /** | ||||
|      * Initializes {@link #namespaceMap} with namespace values | ||||
|      * @param doc dom structure object | ||||
|      * @return map of namespaces | ||||
|      */ | ||||
|  | ||||
|     // TODO: Closer inspection. Return value is never used according to IntelliJ | ||||
|     // | ||||
|     public NamespaceMap process(XdmNode doc) { | ||||
|         namespaceMap = NamespaceMap.emptyMap(); | ||||
|         //        TODO: remove | ||||
|         for (XdmNode tmp : doc.children()) { | ||||
|             extractNamespace(tmp); | ||||
|         } | ||||
| //        end | ||||
|         return namespaceMap; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Iterates through {@link #namespaceMap} and declares namespaces in {@link XPathCompiler} | ||||
|      * @param compiler compiler used to compile xpath statements | ||||
|      */ | ||||
|     public void exportNamespaces(XPathCompiler compiler){ | ||||
|         namespaceMap.forEach(namespaceBinding -> compiler.declareNamespace(namespaceBinding.getPrefix(), namespaceBinding.getURI())); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Uses recurrency to dive deep dom structure and appends {@link #namespaceMap} with every found namespace | ||||
|      * @param node dom structure object | ||||
|      */ | ||||
|     private void extractNamespace(XdmNode node) { | ||||
|         NamespaceMap tmp; | ||||
|         if ((tmp = node.getUnderlyingNode().getAllNamespaces()) != null) { | ||||
|             namespaceMap = namespaceMap.putAll(tmp); | ||||
|         } | ||||
|         if (node.children().iterator().hasNext()) { | ||||
|  | ||||
|             for (XdmNode rNode : node.children()) { | ||||
|                 if (rNode.getUnderlyingNode().getPrefix().isEmpty() && !rNode.getParent().getUnderlyingNode().getPrefix().isEmpty()) { | ||||
|                     LOG.warn("Missing prefix. Parent has " + rNode.getParent().getUnderlyingNode().getPrefix() + ", but child has none"); | ||||
|                 } | ||||
|  | ||||
|                 extractNamespace(rNode); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,75 @@ | ||||
| package com.r11.tools.xml; | ||||
|  | ||||
| import net.sf.saxon.s9api.*; | ||||
|  | ||||
| import javax.xml.transform.stream.StreamSource; | ||||
| import java.io.StringReader; | ||||
| import java.io.StringWriter; | ||||
|  | ||||
| /** | ||||
|  * Handler for Saxon engine | ||||
|  * @author Wojciech Czop | ||||
|  */ | ||||
| public class Saxon { | ||||
|  | ||||
|     /** | ||||
|      * Transforms string containing xml document via xslt | ||||
|      * @param data xml to be transformed | ||||
|      * @param transform xslt | ||||
|      * @return transformed xml | ||||
|      * @throws SaxonApiException thrown on stylesheet or transformation errors | ||||
|      */ | ||||
|     public static String processXSLT(String data, String transform) throws SaxonApiException { | ||||
|         Processor processor = new Processor(false); | ||||
|         XsltCompiler compiler = processor.newXsltCompiler(); | ||||
|         XsltExecutable stylesheet = compiler.compile(new StreamSource(new StringReader(transform))); | ||||
|         StringWriter sw = new StringWriter(); | ||||
|         Serializer out = processor.newSerializer(sw); | ||||
|         out.setOutputProperty(Serializer.Property.METHOD, "xml"); | ||||
|         out.setOutputProperty(Serializer.Property.INDENT, "yes"); | ||||
|  | ||||
|         Xslt30Transformer transformer = stylesheet.load30(); | ||||
|         transformer.transform(new StreamSource(new StringReader(data)), out); | ||||
|         return sw.toString(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Process xpath and return either node or wrapped atomic value | ||||
|      * @param data xml to be querried | ||||
|      * @param query xpath queryy | ||||
|      * @param version processor version | ||||
|      * @return string xml representation of the node | ||||
|      * @throws Exception thrown on node building errors or invalid xpath | ||||
|      */ | ||||
|     public static String processXPath(String data, String query, String version) throws Exception { | ||||
|         Processor p = new Processor(false); | ||||
|         XPathCompiler compiler = p.newXPathCompiler(); | ||||
|         DocumentBuilder builder = p.newDocumentBuilder(); | ||||
|         XdmNode doc = builder.build(new StreamSource(new StringReader(data))); | ||||
|  | ||||
|         compiler.setLanguageVersion(version); | ||||
|  | ||||
|         NewNamespaceResolver resolver = new NewNamespaceResolver(); | ||||
|  | ||||
|         resolver.process(doc); | ||||
|  | ||||
|         resolver.exportNamespaces(compiler); | ||||
|  | ||||
|         XdmValue result = compiler.evaluate(query, doc); | ||||
|         StringBuilder sb = new StringBuilder(); | ||||
|         for (XdmItem xdmItem : result) { | ||||
|             sb.append(xdmItem); | ||||
|             sb.append('\n'); | ||||
|         } | ||||
|         return sb.toString(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns version of the processor | ||||
|      * @return version of the processor | ||||
|      */ | ||||
|     public static String getVersion() { | ||||
|         return new Processor(false).getSaxonProductVersion(); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,128 @@ | ||||
| package com.r11.tools.xml; | ||||
|  | ||||
| import org.apache.xpath.XPathAPI; | ||||
| import org.w3c.dom.Document; | ||||
| import org.w3c.dom.Node; | ||||
| import org.w3c.dom.traversal.NodeIterator; | ||||
| import org.xml.sax.InputSource; | ||||
|  | ||||
| import javax.xml.XMLConstants; | ||||
| import javax.xml.parsers.DocumentBuilder; | ||||
| import javax.xml.parsers.DocumentBuilderFactory; | ||||
| import javax.xml.transform.*; | ||||
| import javax.xml.transform.dom.DOMSource; | ||||
| import javax.xml.transform.stream.StreamResult; | ||||
| import javax.xml.transform.stream.StreamSource; | ||||
| import javax.xml.validation.Schema; | ||||
| import javax.xml.validation.SchemaFactory; | ||||
| import javax.xml.validation.Validator; | ||||
| import java.io.*; | ||||
|  | ||||
| /** | ||||
|  * Handler for Xalan engine | ||||
|  * @author Wojciech Czop | ||||
|  */ | ||||
| public class Xalan { | ||||
|  | ||||
|     /** | ||||
|      * Transforms string containing xml document via xslt | ||||
|      * @param data xml to be transformed | ||||
|      * @param transform xslt | ||||
|      * @return transformed xml | ||||
|      * @throws Exception thrown on stylesheet or transformation errors | ||||
|      */ | ||||
|     public static String processXSLT(String data, String transform) throws Exception{ | ||||
|         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | ||||
|         DocumentBuilder builder = factory.newDocumentBuilder(); | ||||
|         Document document = builder.parse(new InputSource(new StringReader(data))); | ||||
|  | ||||
|         StreamSource stylesource = new StreamSource(new StringReader(transform)); | ||||
|         Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource); | ||||
|         transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); | ||||
|         transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | ||||
|  | ||||
|         Source source = new DOMSource(document); | ||||
|         StringWriter sw = new StringWriter(); | ||||
|         Result outputTarget = new StreamResult(sw); | ||||
|         transformer.transform(source, outputTarget); | ||||
|  | ||||
|         return sw.toString(); | ||||
|     } | ||||
|  | ||||
|     private static boolean isTextNode(Node n) { | ||||
|         if (n == null) | ||||
|             return false; | ||||
|         short nodeType = n.getNodeType(); | ||||
|         return nodeType == Node.CDATA_SECTION_NODE || nodeType == Node.TEXT_NODE; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Process xpath and return either node or wrapped atomic value | ||||
|      * @param data xml | ||||
|      * @param transform xpath | ||||
|      * @return xml processed using given xpath | ||||
|      * @throws Exception thrown on node building errors or invalid xpath | ||||
|      */ | ||||
|     public static String processXPath(String data, String transform) throws Exception { | ||||
|  | ||||
|         // Set up a DOM tree to query. | ||||
|         InputSource in = new InputSource(new StringReader(data)); | ||||
|         DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); | ||||
|         dfactory.setNamespaceAware(true); | ||||
|         Document doc = dfactory.newDocumentBuilder().parse(in); | ||||
|  | ||||
|         // Set up an identity transformer to use as serializer. | ||||
|         Transformer serializer = TransformerFactory.newInstance().newTransformer(); | ||||
|         serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); | ||||
|  | ||||
|         // Use the simple XPath API to select a nodeIterator. | ||||
|         NodeIterator nl = XPathAPI.selectNodeIterator(doc, transform); | ||||
|  | ||||
|         // Serialize the found nodes to result object. | ||||
|         StringBuilder result = new StringBuilder(); | ||||
|         Node n; | ||||
|         while ((n = nl.nextNode())!= null) { | ||||
|             StringBuilder sb; | ||||
|             if (isTextNode(n)) { | ||||
|                 // DOM may have more than one node corresponding to a | ||||
|                 // single XPath text node.  Coalesce all contiguous text nodes | ||||
|                 // at this level | ||||
|                 for (Node nn = n.getNextSibling(); isTextNode(nn); nn = nn.getNextSibling()) { | ||||
|                     result.append(nn.getNodeValue()); | ||||
|                 } | ||||
|             } else { | ||||
|                 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | ||||
|                 serializer.transform(new DOMSource(n), new StreamResult(new OutputStreamWriter(outputStream))); | ||||
|                 result.append(outputStream); | ||||
|             } | ||||
|             result.append("\n"); | ||||
|         } | ||||
|         return result.toString(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns version of the processor | ||||
|      * @return version of the processor | ||||
|      */ | ||||
|     public static String getVersion(){ | ||||
|         return org.apache.xalan.Version.getVersion(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Validates string representation of the xml document against xsd schema | ||||
|      * @param data xml document | ||||
|      * @param xsd xsd schema | ||||
|      * @return statement of validity | ||||
|      * @throws Exception thrown on invalid xsd schema or xml | ||||
|      */ | ||||
|     public static String validate(String data, String xsd) throws Exception{ | ||||
|         Source dataSource = new StreamSource(new StringReader(data)); | ||||
|         Source xsdSource = new StreamSource(new StringReader(xsd)); | ||||
|         SchemaFactory schemaFactory = SchemaFactory | ||||
|                 .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); | ||||
|         Schema schema = schemaFactory.newSchema(xsdSource); | ||||
|         Validator validator = schema.newValidator(); | ||||
|         validator.validate(dataSource); | ||||
|         return "XML file is valid"; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,132 @@ | ||||
| package com.r11.tools.xml; | ||||
|  | ||||
| import org.w3c.dom.*; | ||||
|  | ||||
| import javax.xml.XMLConstants; | ||||
| import javax.xml.namespace.NamespaceContext; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * Contains methods that scan document for namespaces and store them in map objects. | ||||
|  * @deprecated | ||||
|  * Class no longer in use. It has been replaced by {@link NewNamespaceResolver} | ||||
|  * @author Wojciech Czop | ||||
|  */ | ||||
| public class XalanNamespaceResolver implements NamespaceContext { | ||||
|     private static final String DEFAULT_NS = "DEFAULT"; | ||||
|     private Map<String, String> prefix2Uri = new HashMap<String, String>(); | ||||
|     private Map<String, String> uri2Prefix = new HashMap<String, String>(); | ||||
|  | ||||
|     /** | ||||
|      * This constructor parses the document and stores all namespaces it can | ||||
|      * find. If toplevelOnly is true, only namespaces in the root are used. | ||||
|      * | ||||
|      * @param document | ||||
|      *            source document | ||||
|      * @param toplevelOnly | ||||
|      *            restriction of the search to enhance performance | ||||
|      */ | ||||
|     public XalanNamespaceResolver(Document document, boolean toplevelOnly) { | ||||
|         examineNode(document.getFirstChild(), toplevelOnly); | ||||
|         System.out.println("The list of the cached namespaces:"); | ||||
|         for (String key : prefix2Uri.keySet()) { | ||||
|             System.out.println("prefix " + key + ": uri " + prefix2Uri.get(key)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * A single node is read, the namespace attributes are extracted and stored. | ||||
|      * | ||||
|      * @param node | ||||
|      *            to examine | ||||
|      * @param attributesOnly, | ||||
|      *            if true no recursion happens | ||||
|      */ | ||||
|     private void examineNode(Node node, boolean attributesOnly) { | ||||
|         NamedNodeMap attributes = node.getAttributes(); | ||||
|         for (int i = 0; i < attributes.getLength(); i++) { | ||||
|             Node attribute = attributes.item(i); | ||||
|             storeAttribute((Attr) attribute); | ||||
|         } | ||||
|  | ||||
|         if (!attributesOnly) { | ||||
|             NodeList chields = node.getChildNodes(); | ||||
|             for (int i = 0; i < chields.getLength(); i++) { | ||||
|                 Node chield = chields.item(i); | ||||
|                 if (chield.getNodeType() == Node.ELEMENT_NODE){ | ||||
|                     examineNode(chield, false); | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method looks at an attribute and stores it, if it is a namespace | ||||
|      * attribute. | ||||
|      * | ||||
|      * @param attribute | ||||
|      *            to examine | ||||
|      */ | ||||
|     private void storeAttribute(Attr attribute) { | ||||
|         // examine the attributes in namespace xmlns | ||||
|         String uri = attribute.getNamespaceURI(); | ||||
|         String name = attribute.getLocalName(); | ||||
|         String name2 = attribute.getName(); | ||||
|         String value = attribute.getNodeValue(); | ||||
|         if (attribute.getNodeValue() != null | ||||
|                 /*&& attribute.getNamespaceURI().equals( | ||||
|                 XMLConstants.XMLNS_ATTRIBUTE_NS_URI)*/) { | ||||
|             // Default namespace xmlns="uri goes here" | ||||
|             if (attribute.getNodeName().equals(XMLConstants.XMLNS_ATTRIBUTE)) { | ||||
|                 putInCache(DEFAULT_NS, attribute.getNodeValue()); | ||||
|             } else { | ||||
|                 // The defined prefixes are stored here | ||||
|                 putInCache(attribute.getName().replace("xmlns:", ""), attribute.getNodeValue()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Stores namespace prefix ass well as its uri in map | ||||
|      * @param prefix | ||||
|      * @param uri | ||||
|      */ | ||||
|     private void putInCache(String prefix, String uri) { | ||||
|         prefix2Uri.put(prefix, uri); | ||||
|         uri2Prefix.put(uri, prefix); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method is called by XPath. It returns the default namespace, if the | ||||
|      * prefix is null or "". | ||||
|      * | ||||
|      * @param prefix | ||||
|      *            to search for | ||||
|      * @return uri | ||||
|      */ | ||||
|     public String getNamespaceURI(String prefix) { | ||||
|         if (prefix == null || prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) { | ||||
|             return prefix2Uri.get(DEFAULT_NS); | ||||
|         } else { | ||||
|             return prefix2Uri.get(prefix); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method is not needed in this context, but can be implemented in a | ||||
|      * similar way. | ||||
|      */ | ||||
|     public String getPrefix(String namespaceURI) { | ||||
|         return uri2Prefix.get(namespaceURI); | ||||
|     } | ||||
|  | ||||
|     public Iterator getPrefixes(String namespaceURI) { | ||||
|         // Not implemented | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| # Set root logger level to DEBUG and its only appender to A1. | ||||
| log4j.rootLogger=ERROR, A1 | ||||
|  | ||||
| # A1 is set to be a ConsoleAppender. | ||||
| log4j.appender.A1=org.apache.log4j.ConsoleAppender | ||||
|  | ||||
| # A1 uses PatternLayout. | ||||
| log4j.appender.A1.layout=org.apache.log4j.PatternLayout | ||||
| log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n | ||||
							
								
								
									
										21
									
								
								Backend/tools-services/src/main/resources/log4j2.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Backend/tools-services/src/main/resources/log4j2.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Configuration status="WARN"> | ||||
| 	<Appenders> | ||||
| 		<Console name="Console" target="SYSTEM_OUT"> | ||||
| 			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%c] %-5level - %msg%n"/> | ||||
| 		</Console> | ||||
| 		<File name="File" fileName="/tmp/xml_tools_java_backend.log" append="true"> | ||||
| 			<PatternLayout> | ||||
| 				<Pattern>%d{HH:mm:ss.SSS} [%c] %-5level - %msg%n</Pattern> | ||||
| 			</PatternLayout> | ||||
| 		</File> | ||||
| 	</Appenders> | ||||
| 	<Loggers> | ||||
| 		<Logger name="com.r11.tools.SparkApplication" level="info" additivity="true"> | ||||
| 			<AppenderRef ref="Console"/> | ||||
| 		</Logger> | ||||
| 		<Root level="info"> | ||||
| 			<AppenderRef ref="File"/> | ||||
| 		</Root> | ||||
| 	</Loggers> | ||||
| </Configuration> | ||||
		Reference in New Issue
	
	Block a user