Importing WformServices and GlemmServices
Change-Id: Ifa95576d69e0d3863f63d3fdedb48c2c21cf64bc
diff --git a/WformServices/.classpath b/WformServices/.classpath
new file mode 100644
index 0000000..ec33d97
--- /dev/null
+++ b/WformServices/.classpath
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" path="json"/>
+ <classpathentry kind="src" path="services"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v9.0">
+ <attributes>
+ <attribute name="owner.project.facets" value="jst.web"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry combineaccessrules="false" exported="true" kind="src" path="/JsonTraverse"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/GlemmClient"/>
+ <classpathentry kind="lib" path="C:/Users/Franck/.m2/repository/de/korap/json/JsonTraverse/0.1-SNAPSHOT/JsonTraverse-0.1-SNAPSHOT.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/utils"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/WformServices/.project b/WformServices/.project
new file mode 100644
index 0000000..856db24
--- /dev/null
+++ b/WformServices/.project
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>wformServices</name>
+ <comment></comment>
+ <projects>
+ <project>utils</project>
+ <project>JsonTraverse</project>
+ <project>GlemmClient</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+ </natures>
+ <linkedResources>
+ <link>
+ <name>json</name>
+ <type>2</type>
+ <location>C:/myIDS/Daten/KorAP/Services-branch-0.1/JsonTraverse/src/de/korap/json</location>
+ </link>
+ <link>
+ <name>services</name>
+ <type>2</type>
+ <location>C:/myIDS/Daten/KorAP/Services-branch-0.1/GlemmServices/src/de/korap/services</location>
+ </link>
+ <link>
+ <name>src-GlemmServices</name>
+ <type>2</type>
+ <location>C:/myIDS/Daten/KorAP/Services/GlemmServices/src</location>
+ </link>
+ </linkedResources>
+</projectDescription>
diff --git a/WformServices/.settings/.jsdtscope b/WformServices/.settings/.jsdtscope
new file mode 100644
index 0000000..92e666d
--- /dev/null
+++ b/WformServices/.settings/.jsdtscope
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry excluding="**/bower_components/*|**/node_modules/*|**/*.min.js" kind="src" path="WebContent"/>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
+ <attributes>
+ <attribute name="hide" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+ <classpathentry kind="output" path=""/>
+</classpath>
diff --git a/WformServices/.settings/org.eclipse.jdt.core.prefs b/WformServices/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..4e4a3ad
--- /dev/null
+++ b/WformServices/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/WformServices/.settings/org.eclipse.m2e.core.prefs b/WformServices/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/WformServices/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/WformServices/.settings/org.eclipse.wst.common.component b/WformServices/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..a48f70e
--- /dev/null
+++ b/WformServices/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="wformServices-0.1-SNAPSHOT">
+ <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
+ <wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
+ <wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
+ <wb-resource deploy-path="/WEB-INF/classes" source-path="/services"/>
+ <wb-resource deploy-path="/WEB-INF/classes" source-path="/json"/>
+ <dependent-module archiveName="utils-0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/utils/utils">
+ <dependency-type>uses</dependency-type>
+ </dependent-module>
+ <dependent-module archiveName="JsonTraverse-0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/JsonTraverse/JsonTraverse">
+ <dependency-type>uses</dependency-type>
+ </dependent-module>
+ <dependent-module archiveName="GlemmClient-0.2-Test.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/GlemmClient/GlemmClient">
+ <dependency-type>uses</dependency-type>
+ </dependent-module>
+ <property name="java-output-path" value="/wformServices/build/classes"/>
+ <property name="context-root" value="wformServices"/>
+ </wb-module>
+</project-modules>
diff --git a/WformServices/.settings/org.eclipse.wst.common.project.facet.core.xml b/WformServices/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000..24124f7
--- /dev/null
+++ b/WformServices/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <runtime name="Apache Tomcat v9.0"/>
+ <fixed facet="jst.web"/>
+ <fixed facet="wst.jsdt.web"/>
+ <fixed facet="java"/>
+ <installed facet="java" version="1.8"/>
+ <installed facet="jst.web" version="4.0"/>
+ <installed facet="wst.jsdt.web" version="1.0"/>
+</faceted-project>
diff --git a/WformServices/.settings/org.eclipse.wst.jsdt.ui.superType.container b/WformServices/.settings/org.eclipse.wst.jsdt.ui.superType.container
new file mode 100644
index 0000000..3bd5d0a
--- /dev/null
+++ b/WformServices/.settings/org.eclipse.wst.jsdt.ui.superType.container
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/WformServices/.settings/org.eclipse.wst.jsdt.ui.superType.name b/WformServices/.settings/org.eclipse.wst.jsdt.ui.superType.name
new file mode 100644
index 0000000..05bd71b
--- /dev/null
+++ b/WformServices/.settings/org.eclipse.wst.jsdt.ui.superType.name
@@ -0,0 +1 @@
+Window
\ No newline at end of file
diff --git a/WformServices/.settings/org.eclipse.wst.validation.prefs b/WformServices/.settings/org.eclipse.wst.validation.prefs
new file mode 100644
index 0000000..04cad8c
--- /dev/null
+++ b/WformServices/.settings/org.eclipse.wst.validation.prefs
@@ -0,0 +1,2 @@
+disabled=06target
+eclipse.preferences.version=1
diff --git a/WformServices/WebContent/META-INF/MANIFEST.MF b/WformServices/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..254272e
--- /dev/null
+++ b/WformServices/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/WformServices/WebContent/WEB-INF/WformServices.properties b/WformServices/WebContent/WEB-INF/WformServices.properties
new file mode 100644
index 0000000..8df4067
--- /dev/null
+++ b/WformServices/WebContent/WEB-INF/WformServices.properties
@@ -0,0 +1,22 @@
+# WordformServices properties:
+# expected in /WEB-INF/.
+
+## General properties:
+GS_WorkingPath = /home/bodmer/KorAP/GlemmServices/work-live
+
+## Loging:
+
+# fnameOut = GS_WorkingPath + "/WformmServices.log";
+#fnameOut = WformServices-t.log
+fnameOut = WformServices.log
+# fnameErr = GS_WorkingPath + "/WformServices.err";
+#fnameErr = WformServices-t.err
+fnameErr = WformServices.err
+
+## Communicating with the GlemmServices
+URLGlemmServer = http://c0r4ft
+GlemmPort = 40913
+#URLGlemmServices = GlemmServices-0.2-Test
+URLGlemmServices = GlemmServices
+LemmaRequestPath = index/info/lemma
+
\ No newline at end of file
diff --git a/WformServices/WebContent/WEB-INF/plugin.html b/WformServices/WebContent/WEB-INF/plugin.html
new file mode 100644
index 0000000..9936067
--- /dev/null
+++ b/WformServices/WebContent/WEB-INF/plugin.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Wordform Services (including Glemm Services)</title>
+ <!-- load client javascript library -->
+ <!-- live-version: script src="https://korap.ids-mannheim.de/js/korap-plugin-0.2.js"
+ data-server="https://korap.ids-mannheim.de/"></script -->
+ <!-- Testversion: -->
+ <script src="https://korap.ids-mannheim.de/instance/test/js/korap-plugin-0.2.js"
+ data-server="https://korap.ids-mannheim.de/instance/test"></script>
+ </head>
+ <body>
+ <script>
+ let data = {
+ 'action' : 'pipe',
+ <!-- KoralQuery mit POST Request an diesen service schicken; dahinter steht der Wordform Service, dahinter der Glemm Service. -->
+ <!-- ohne proxy: 'service' : 'http://c0r4ft.ids-mannheim.de:40913/wformServices-0.1-SNAPSHOT/wformServices/query' -->
+ <!-- mit proxy : 'service' : 'https://korap.ids-mannheim.de/proxy/c0r4ft/wformServices-0.1-SNAPSHOT/wformServices/query' -->
+ <!-- ab Version 0.2 der WformServices enthält die URL zu den Services keine Versionsnummer mehr: -->
+ 'service' : 'https://korap.ids-mannheim.de/proxy/c0r4ft/wformServices/wformServices/query'
+ };
+
+ function pluginit (p) {
+ p.onMessage = function(msg) {
+ if (msg.key == 'glemm') {
+ if (msg.value) {
+ data['job'] = 'add';
+ }
+ else {
+ data['job'] = 'del';
+ };
+ KorAPlugin.sendMsg(data);
+ };
+ };
+ };
+ </script>
+ </body>
+</html>
\ No newline at end of file
diff --git a/WformServices/WebContent/WEB-INF/web.xml b/WformServices/WebContent/WEB-INF/web.xml
new file mode 100644
index 0000000..1b3ae97
--- /dev/null
+++ b/WformServices/WebContent/WEB-INF/web.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- kopiert aus https://blog.dejavu.sk/registering-resources-and-providers-in-jersey-2/ , 09.12.19/FB -->
+
+<web-app version="2.5"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
+
+ <servlet>
+ <servlet-name>WordformServices mit Jersey REST</servlet-name>
+ <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+
+ <!-- Register JAX-RS Application, if needed. -->
+ <!-- init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>my.package.MyApplication</param-value>
+ </init-param -->
+
+ <!-- Register resources and providers under my.package. -->
+ <init-param>
+ <param-name>jersey.config.server.provider.packages</param-name>
+ <param-value>de.korap.services</param-value>
+ </init-param>
+
+ <!-- Register my custom provider (not needed if it's in my.package) AND LoggingFilter. -->
+ <init-param>
+ <param-name>jersey.config.server.provider.classnames</param-name>
+ <param-value>de.korap.services</param-value>
+ </init-param>
+
+ <!-- Enable Tracing support. -->
+ <init-param>
+ <param-name>jersey.config.server.tracing</param-name>
+ <param-value>ALL</param-value>
+ </init-param>
+
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>WordformServices mit Jersey REST</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file
diff --git a/WformServices/pom.xml b/WformServices/pom.xml
new file mode 100644
index 0000000..b3eb297
--- /dev/null
+++ b/WformServices/pom.xml
@@ -0,0 +1,83 @@
+<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>de.korap.services</groupId>
+ <artifactId>wformServices</artifactId>
+ <!-- version>0.2-Test</version-->
+ <version>0.2-live</version>
+ <name>wformServices</name>
+ <description>Wordform Services for Rewriting Wordform Queries and Handling Wordform Lists.</description>
+ <build>
+ <sourceDirectory>src</sourceDirectory>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.7.0</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>3.2.1</version>
+ <configuration>
+ <warSourceDirectory>WebContent</warSourceDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ </dependency>
+ <!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>2.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>2.9.6</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>2.9.6</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>de.korap.services</groupId>
+ <artifactId>utils</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>de.korap.json</groupId>
+ <artifactId>JsonTraverse</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>de.korap.services.glemm.client</groupId>
+ <artifactId>GlemmClient</artifactId>
+ <version>0.2-Test</version>
+ </dependency>
+ </dependencies>
+
+ <packaging>war</packaging>
+</project>
\ No newline at end of file
diff --git a/WformServices/src/de/korap/services/WordformRewrite.java b/WformServices/src/de/korap/services/WordformRewrite.java
new file mode 100644
index 0000000..b575f84
--- /dev/null
+++ b/WformServices/src/de/korap/services/WordformRewrite.java
@@ -0,0 +1,129 @@
+package de.korap.services;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Properties;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.korap.json.JsonTraverse;
+import de.korap.json.TraversedPath;
+import de.korap.services.glemm.client.GlemmClient;
+import de.korap.services.utils.Utils;
+import de.korap.services.LemmaResponse;
+
+public class WordformRewrite {
+
+
+ /*
+ * traverse_and_rewrite_KoralQuery:
+ * Parameters:
+ * query : JSON KoralQuery.
+ * props : wformServices.properties.
+ *
+ * Notes:
+ * -
+ * Returns : 0 = rewrite done. 1 = no rewrite needed. > 1: error!
+ * - rewriten new Query if rewritten done.
+ * - null + no exception: no rewriting needed.
+ * - null + exception : error.
+ * 04.03.20/FB 27.04.20/FB
+ */
+
+ public static String traverse_and_rewrite_KoralQuery(
+ String query,
+ Properties props,
+ PrintStream fout,
+ PrintStream ferr )
+
+ throws IOException
+
+ {
+ final String
+ func = "traverse_and_rewrite_KoralQuery";
+ ObjectMapper
+ objMapper = null;
+ JsonNode
+ jsonNode = null;
+ TraversedPath
+ tPath = null;
+ LemmaResponse
+ lemResp = null;
+ final boolean
+ bDebug = true;
+ int
+ mode = JsonTraverse.REWRITE_EXP; // rewrite lemma query by expansion list.
+
+ fout.printf("Debug: %s: ready for traversing query...\n", func);
+
+ objMapper = new ObjectMapper();
+
+ // get full query as a JsonNode tree:
+ try {
+ jsonNode = objMapper.readTree(query);
+
+ // traverse query and collect lemma subqueries in a TraversedPath object:
+ tPath = new TraversedPath(objMapper);
+ JsonTraverse.traverseJsonTree(jsonNode, tPath, JsonTraverse.COLLECT, fout, ferr);
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ throw e;
+ }
+
+ fout.printf("Debug: %s: query traversed.\n", func);
+
+ // Exit if no lemma subqueries found:
+ if( tPath == null || tPath.getLemmaCount() == 0 )
+ {
+ fout.printf("Info: %s: no lemma subquery found -> no rewrite needed.\n", func);
+ return null; // no rewrite.
+ }
+
+ /* - - - Call GlemmServices to resolve lemma-Subqueries - - -
+ *
+ * This returns for each lemma a reference to a list of wordform instantiations
+ * (= instantiation list).
+ */
+
+ GlemmClient
+ glemmClient = new GlemmClient(props, fout, ferr);
+
+ for(int i=0; i<tPath.getLemmaCount(); i++)
+ {
+ lemResp = glemmClient.sendQuery(tPath.getLemma(i));
+ tPath.addLemmaResponse(lemResp);
+
+ fout.printf("Debug: %s: lemma='%s': %d wfs found: %s.\n", func,
+ tPath.getLemma(i),
+ lemResp.head_nWfs,
+ lemResp.printPartialList());
+ }
+
+ // TODO glemmClient.close ?
+
+ /*
+ * - - - Rewriting KoralQuery with lists of wordforms:
+ *
+ * - Rewrite KoralQuery: use either JsonTraverse.REWRITE or .REWRITE_EXP:
+ * - REWRITE_EXP = rewrite with expansion lists.
+ */
+
+ JsonTraverse.traverseJsonTree(jsonNode, tPath, JsonTraverse.REWRITE_EXP, fout, ferr);
+
+ // OK: return newQuery formated in pretty json:
+ fout.printf("Debug: %s: returning OK with jsonNode as a String.\n", func);
+
+ return objMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
+
+ //System.out.printf("Debug: %s: returning OK and null String.\n", func);
+
+ //return null; // OK
+
+ } // traverse_and_rewrite_KoralQuery
+
+
+
+} // class WordformRewrite
+
diff --git a/WformServices/src/de/korap/services/WordformServices.java b/WformServices/src/de/korap/services/WordformServices.java
new file mode 100644
index 0000000..0a26350
--- /dev/null
+++ b/WformServices/src/de/korap/services/WordformServices.java
@@ -0,0 +1,284 @@
+package de.korap.services;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.charset.Charset;
+import java.time.LocalDateTime;
+import java.util.Locale;
+import java.util.Properties;
+
+import de.korap.services.WordformRewrite;
+import de.korap.services.utils.Utils;
+
+
+/*
+ * v-0.1: 29.06.20/FB: 1st version.
+ * v-0.1: 28.10.21/FB:
+ * - writes request time to log;
+ * - resets fnameOut/Err after call to GlemmServices.
+ * Notes:
+ * - When submitting a KoralQuery [UTF-8] to the WformServices (if redirected
+ * to the GlemmServices, only chars that may be translated to ISO8859-1 (=Lat1)
+ * will be processed correctly. Glemm behind the scene can only treat
+ * German words, so this restriction is OK.
+ */
+
+@Path("/wformServices")
+
+public class WordformServices {
+
+ final private static String versionDate = "28.10.21";
+ final private static String version = "0.2";
+ final private String fnameProps = "/WEB-INF/WformServices.properties";
+ private static String GS_WorkingPath = "/home/bodmer/KorAP/GlemmServices/Tests"; // linux
+ private static String fnameOut = GS_WorkingPath + "/wformServices-t.log";
+ private static String fnameErr = GS_WorkingPath + "/wformServices-t.err";
+ final private static String filename_pluginHTML = "WEB-INF/plugin.html";
+
+ @Context
+ private ServletContext servletContext;
+
+ Properties
+ props = null; // properties in WEB-INF/WformServices.properties
+
+ public static PrintStream fout = null;
+ public static PrintStream ferr = null;
+
+ /*
+ * log_Request:
+ *
+ * - write info about API Request.
+ * Parameters:
+ * requestPath : path of webapp addressed by the request.
+ * func : name of the function which implements the request.
+ *
+ * 19.10.21/FB
+ */
+
+ private void log_Request(String requestPath, String func)
+
+ {
+ // transform "dateTtime" -> "date time":
+
+ fout.printf("###\n");
+ fout.printf("### %s: %s : vers='%s', vdate='%s' request='%s'.\n", func, requestPath, version, versionDate,
+ LocalDateTime.now().toString().replace("T", " "));
+ fout.printf("###\n");
+ } // log_Request
+
+ /*
+ *
+ * - after loadProperties, sets the class variable with loaded property values.
+ *
+ * 15.10.21/FB
+ */
+
+ private void set_ConstantsFromProperties(Properties props)
+
+ {
+ GS_WorkingPath = Utils.getConstantFromProperties(props, "GS_WorkingPath", "/home/bodmer/KorAP/GlemmServices/Tests");
+ fnameOut = Utils.getConstantFromProperties(props, "fnameOut", "WformServices-t.log");
+ fnameOut = GS_WorkingPath + "/" + fnameOut;
+ fnameErr = Utils.getConstantFromProperties(props, "fnameErr", "WformServices-t.err");
+ fnameErr = GS_WorkingPath + "/" + fnameErr;
+
+ } // set_ConstantsFromProperties
+
+ /* init_and_log_Request
+ *
+ * - load GlemmServices.properties, sets GlemmServices constants
+ * and logs the request.
+ * - load properties and set constants before logging anything, because
+ * logging will be done into the last stdout/stderr opened in glassfish's JVM,
+ * e.g. in the log of another Service.
+ *
+ * 19.10.21/FB
+ */
+
+ private void init_and_log_Request(String func, String requestPath)
+
+ {
+ String
+ realPath = servletContext.getRealPath(fnameProps);
+
+ // load GlemmServices properties and log them (if last param = true):
+ props = Utils.loadProperties(servletContext.getResourceAsStream(fnameProps), fnameProps, realPath, false);
+
+ set_ConstantsFromProperties(props);
+
+ // Set Standard File output streams for GlemmServices:
+ // Utils.setStdFileStreams(fnameErr, fnameOut);
+
+ // open fout and ferr as replacement for stdout/stderr for use in GlemmServices.
+ // do not use or redirect System.out and System.err, as they will be redirected
+ // by other Services in the same glassfish JVM, e.g. by the WformServices.
+ fout = Utils.setLogStream(fnameOut);
+ ferr = Utils.setLogStream(fnameErr);
+
+ log_Request(requestPath, func);
+
+ } // init_and_log_Request
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * GET: /wformServices/status/
+ *
+ * returns status of Wordform Services in HTML.
+ *
+ * Parameters:
+ * -
+ * Notes:
+ * -
+ * 12.06.20/FB
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ @Path("status")
+ @GET
+ @Produces("text/html")
+
+ public String doGET_status()
+
+ {
+ final String func = "doGET_status";
+ String
+ status;
+
+ init_and_log_Request(func, "/wformServices/status/");
+
+ status = String.format( "<html>\n" +
+ " <h3>Wordform Services</h3>\n" +
+ " <p><b>Version</b> : %s</p>" +
+ " <p><b>Date </b> : %s</p>" +
+ " <p><b>status</b> : ready.</p>" +
+ " <p><b>Request time</b>: %s</p>" +
+ " <p><b>properties</b>: %s </p>" +
+ "</html>",
+ version,
+ versionDate,
+ LocalDateTime.now().toString().replace("T", " "),
+ servletContext.getResourceAsStream(fnameProps) == null ? "not found" :
+ props.isEmpty() ? "empty" : "loaded");
+
+ fout.printf("Debug: %s: done.\n", func);
+
+ return status;
+
+ } // doGET_status
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * GET: /wformServices/plugin.html
+ *
+ * returns plugin.html file for registration in Kalamar.
+ *
+ * Parameters:
+ * -
+ * Notes:
+ * -
+ * 29.06.20/FB
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ @Path("plugin.html")
+ @GET
+ @Produces("text/html")
+
+ public String doGET_pluginHTML(@Context ServletContext servletContext)
+
+ {
+ final String func = "doGET_pluginHTML";
+ String
+ pluginHTML;
+ String
+ webAppRoot;
+
+ init_and_log_Request(func, "/wformServices/plugin.html");
+
+ webAppRoot = servletContext.getRealPath("/");
+
+ fout.printf("Debug: %s: Root Path of webApp = '%s'.\n", func, webAppRoot);
+ fout.printf("Debug: %s: loading = '%s'.\n", func, webAppRoot + filename_pluginHTML);
+
+ try {
+ pluginHTML = Utils.readFromInputStream(webAppRoot + filename_pluginHTML);
+ fout.printf("Debug: %s: loading plugin.html: OK'.\n", func);
+ fout.printf("Debug: %s: plugin.html = '%s'.\n", func, pluginHTML);
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ pluginHTML = String.format("<html>\n<body><h3>wformServices Error: cannot load plugin.html!</h3></body></html>\n");
+ fout.printf("Debug: %s: loading plugin.html: failed!\n", func);
+ }
+
+ fout.printf("Debug: %s: done.\n", func);
+ return pluginHTML;
+
+ } // doGET_pluginHTML
+
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * POST: /wformServices/query/: application/json.
+ * submits a Koral Query which might contain 1 or more lemma subqueries [UTF-8].
+ * Each subquery is searched in the Glemm DB and the resulting wordform list rewrites
+ * the original subquery.
+ * Parameters:
+ * query : content of POST body: full KoralQuery in Json.
+ * Notes:
+ * - HTTP POST Body can be read once only. Probably Jersey reads it once and
+ * passes it to the POST method, i.e. String query.
+ * - if we try to read the POST Body by either HttpServletRequest.getReader()
+ * or HttpServletRequest.getInputStream(), we get an exception, as this
+ * would be the 2nd access to the body data.
+ * 17.02.20/FB
+ * 20.02.20/FB Body Data access by parameter query.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+ @Path("query")
+ @POST
+ @Consumes("application/json")
+ @Produces("application/json")
+
+ public String doPOST_handleWordformQueries(String query)
+
+ {
+ final String
+ func = "doPOST_handleWordformQueries";
+ String
+ newQuery = "";
+
+ init_and_log_Request(func, "/wformServices/query/");
+
+ try {
+ newQuery = WordformRewrite.traverse_and_rewrite_KoralQuery(query, props, fout, ferr);
+ if( newQuery == null )
+ {
+ fout.printf("Debug: %s: ending time: %s.\n", func, LocalDateTime.now().toString().replace("T", " "));
+ fout.printf("Debug: %s: nothing to rewrite.\n", func);
+ return query; // nothing to rewrite, return original query.
+ }
+ }
+ catch( Exception e)
+ {
+ e.printStackTrace();
+ fout.printf("Debug: %s: ending time: %s.\n", func, LocalDateTime.now().toString().replace("T", " "));
+ fout.printf("Debug: %s: Exception occured: returning unrewritten query!\n", func);
+ return query; // error occured, but returning original, unrewritten query.
+ }
+
+ fout.printf("Debug: %s: ending time: %s.\n", func, LocalDateTime.now().toString().replace("T", " "));
+ fout.printf("Debug: %s: returning rewritten query: size=%d chars.\n", func, newQuery.length());
+
+ return newQuery;
+
+ } // doPOST_handleWordformQueries
+
+}