diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..9a5a1c9c2
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,12 @@
+version: 2
+updates:
+ - package-ecosystem: "maven"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ groups:
+ minor-and-patch:
+ applies-to: version-updates
+ update-types:
+ - "patch"
+ - "minor"
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 044d8e67b..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-arch: amd64
-os: linux
-dist: trusty
-language: java
-script: mvn clean verify
-jdk:
-- oraclejdk8
-- openjdk8
-notifications:
- slack:
- secure: WZMfOBd4zX7SOjeIzCpXGu2vCXwrBQBK3mXkPfn8VaAhwQkAiL7VnonDS19YVMfSm0eG5S9uZKT1wSzZFKvTmw7KEeDkD1rLfdqjbmIzT9W0iwG31mY+Q8gKBN1Dg9dSrCtwC3LkhXhvv4UjzVZ+FnJlrMzEVT+QUrHcQHSqt+uM5Mxz83pj+ZM8eqviODVxSzTwWD4Lqromvq7nplUO45MOrAIhY0Jau0sst2ysAiQXayqSXI33YC2xUJkPcNdypLGOsZ0bWIs68yXfxTMgDVB1+acRw9AFPDMapHUiiueqkJgZ/Itn643iAG4wftGza4OMnTPHpe3hQGp5kM4cqcqvuVmz29wQUWjpOUCqX4e6AoQfV+9jAC81tzbEX89HyyKUf/tAgxe/BefjduSSwT+hlV0WPXOdp4YIyA9YykAPdWlAceYJPipG9sJOWEKekfxojIiRpH2Ha/aV3T0ZgaHlWeoxIwDYgMZeIZxTvRoOwK3SxQzP5cPqh3yj0brJ9d1Z090Vo8qX1/tRt0OXT966Z/yC4MEurhJDNPBbSuBTQpqH+ayhObLnIxXpinPQSEA0fF5votVgZU20ZQDW8SOLPLyP+ZJ5qfUxbvhkLEk7GlO0rlD5xhXjG288u5vEwsWKYXDQ2TVdJdBXIflLxvPhIk8fo/JClnosTlbc9eg=
diff --git a/CI.Jenkinsfile b/CI.Jenkinsfile
new file mode 100644
index 000000000..6d669cfba
--- /dev/null
+++ b/CI.Jenkinsfile
@@ -0,0 +1,60 @@
+node ("docker-light") {
+ def sourceDir = pwd()
+ try {
+ env.JAVA_HOME = "${tool 'java21'}"
+ env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}"
+ def mavenLocalRepo = "$JENKINS_HOME/maven-local-repositories/executor-$EXECUTOR_NUMBER"
+ stage("Clean up") {
+ step([$class: 'WsCleanup'])
+ sh "rm -rf $mavenLocalRepo"
+ }
+ stage("Checkout Code") {
+ checkout scm
+ }
+ stage("Build") {
+ withMaven(maven: "Basis",
+ mavenLocalRepo: mavenLocalRepo,
+ publisherStrategy: "EXPLICIT") {
+ sh "mvn clean verify"
+ }
+
+ }
+ stage("Test with Docker") {
+ withSonarQubeEnv {
+ mySonarOpts="-Dsonar.login=${env.SONAR_AUTH_TOKEN} -Dsonar.host.url=${env.SONAR_HOST_URL}"
+ if ("${env.CHANGE_BRANCH}" != "null") {
+ mySonarOpts="$mySonarOpts -Dsonar.pullrequest.key=${env.CHANGE_ID} -Dsonar.pullrequest.base=${env.CHANGE_TARGET} -Dsonar.pullrequest.branch=${env.CHANGE_BRANCH}"
+ }
+ echo("Sonar Options are: $mySonarOpts")
+ sh "docker run --rm \
+ --pull always \
+ --volume ${sourceDir}:/source \
+ --volume /opt/maven-basis:/opt/maven-basis \
+ eclipse-temurin:21-jdk-noble \
+ bash -c \"apt-get update && \
+ apt-get install -y git && \
+ pushd /source && \
+ git config --global --add safe.directory /source && \
+ /opt/maven-basis/bin/mvn --batch-mode clean install sonar:sonar $mySonarOpts; \
+ maven_ret=\\\$?; \
+ echo && \
+ echo [INFO] Set file permissions to UID and GID of jenkins user for cleanup. && \
+ chown -R 9960:9960 /source && \
+ exit \\\$maven_ret\""
+ }
+ }
+ postToTeams(true)
+ } catch (e) {
+ currentBuild.result = "FAILED"
+ postToTeams(false)
+ throw e
+ }
+}
+
+def postToTeams(boolean success) {
+ def webhookUrl = "${env.TEAMS_PNC_JENKINS_WEBHOOK_URL}"
+ def color = success ? "#00FF00" : "#FF0000"
+ def status = success ? "SUCCESSFUL" : "FAILED"
+ def message = "*" + status + ":* '${env.JOB_NAME}' - [${env.BUILD_NUMBER}] - ${env.BUILD_URL}"
+ office365ConnectorSend(webhookUrl: webhookUrl, color: color, message: message, status: status)
+}
diff --git a/DEVELOPER.md b/DEVELOPER.md
index 26ea73292..e733bfd8e 100644
--- a/DEVELOPER.md
+++ b/DEVELOPER.md
@@ -1,28 +1,18 @@
## Developer Notes
+#### Deprecation Strategies
+If we remove a field via deprecation, the field can still be passed in, but we will no longer deserialize it. As an example see [PR 204](https://github.com/rosette-api/java/pull/204).
+
#### Building and Releasing
To be updated..
#### Internal Releasing
-TBD..
-
-#### Old Stuff
-[Docker](examples/docker) bits for running examples. Maybe just remove?
-
-A duplicate copy of the examples docker notes is below...
-
-Docker files can be found [here](https://github.com/rosette-api/java/tree/master/examples/docker)
-
-To simplify the running of the Java examples, the Dockerfile will build an image and install the rosette-api library from the *published source*.
-
-Build the docker image, e.g. `docker build --rm -t basistech/java:1.1 .`
-
-Run an example as `docker run --rm -e API_KEY=api-key -v "path-to-java-dir:/source" basistech/java:1.1`
-
-To test against a specific source file, add `-e FILENAME=filename` before the `-v`.
-To test against an alternate url, add `-e ALT_URL=alternate_url`.
-#### TODOs
-...
+To perform an internal release, execute the following commands:
+```
+$ mvn release:clean
+$ mvn release:prepare
+$ mvn release:perform -Drelease-profile=internal-release
+```
diff --git a/Jenkinsfile b/Jenkinsfile
index e91e88593..5777d9641 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,30 +1,43 @@
node ("docker-light") {
def SOURCEDIR = pwd()
try {
+ env.JAVA_HOME = "${tool 'java21'}"
+ env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}"
+ def mavenLocalRepo = "$JENKINS_HOME/maven-local-repositories/executor-$EXECUTOR_NUMBER"
stage("Clean up") {
step([$class: 'WsCleanup'])
+ sh "rm -rf $mavenLocalRepo"
}
stage("Checkout Code") {
checkout scm
}
+ stage("Build") {
+ withMaven(maven: "Basis",
+ mavenLocalRepo: mavenLocalRepo,
+ publisherStrategy: "EXPLICIT") {
+ sh "mvn clean verify"
+ }
+
+ }
stage("Test with Docker") {
echo "${env.ALT_URL}"
def useUrl = ("${env.ALT_URL}" == "null") ? "${env.BINDING_TEST_URL}" : "${env.ALT_URL}"
withEnv(["API_KEY=${env.ROSETTE_API_KEY}", "ALT_URL=${useUrl}"]) {
- sh "docker run --rm -e API_KEY=${API_KEY} -e ALT_URL=${ALT_URL} -v ${SOURCEDIR}:/source rosetteapi/docker-java"
+ sh "docker run --rm -e API_KEY=${API_KEY} -e ALT_URL=${ALT_URL} -v ${SOURCEDIR}:/source rosette/docker-java"
}
}
- slack(true)
+ postToTeams(true)
} catch (e) {
currentBuild.result = "FAILED"
- slack(false)
+ postToTeams(false)
throw e
}
}
-def slack(boolean success) {
+def postToTeams(boolean success) {
+ def webhookUrl = "${env.TEAMS_PNC_JENKINS_WEBHOOK_URL}"
def color = success ? "#00FF00" : "#FF0000"
def status = success ? "SUCCESSFUL" : "FAILED"
- def message = status + ": Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})"
- slackSend(color: color, channel: "#p-n-c_jenkins", message: message)
+ def message = "*" + status + ":* '${env.JOB_NAME}' - [${env.BUILD_NUMBER}] - ${env.BUILD_URL}"
+ office365ConnectorSend(webhookUrl: webhookUrl, color: color, message: message, status: status)
}
diff --git a/Jenkinsfile.examples b/Jenkinsfile.examples
index 2c600f9d9..fad51cfde 100644
--- a/Jenkinsfile.examples
+++ b/Jenkinsfile.examples
@@ -22,17 +22,18 @@ node {
sh "docker run --rm -e API_KEY=${API_KEY} -e ALT_URL=${ALT_URL} -e VERSION=${PUBLISHED_VERSION} -v ${SOURCEDIR}:/source ${TEST_CONTAINER}"
}
}
- slack(true)
+ postToTeams(true)
} catch (e) {
currentBuild.result = "FAILED"
- slack(false)
+ postToTeams(false)
throw e
}
}
-def slack(boolean success) {
+def postToTeams(boolean success) {
+ def webhookUrl = "${env.TEAMS_PNC_JENKINS_WEBHOOK_URL}"
def color = success ? "#00FF00" : "#FF0000"
def status = success ? "SUCCESSFUL" : "FAILED"
- def message = status + ": Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})"
- slackSend(color: color, channel: "#p-n-c_jenkins", message: message)
+ def message = "*" + status + ":* '${env.JOB_NAME}' - [${env.BUILD_NUMBER}] - ${env.BUILD_URL}"
+ office365ConnectorSend(webhookUrl: webhookUrl, color: color, message: message, status: status)
}
diff --git a/README.md b/README.md
index bb65eff24..a15ed7735 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,32 @@
-
+
+
+
+
+
+
+
+
+# Analytics by Babel Street
---
-[](https://travis-ci.org/rosette-api/java)
[](https://maven-badges.herokuapp.com/maven-central/com.basistech.rosette/rosette-api-java-binding)
-## Rosette API
-The Rosette Text Analytics Platform uses natural language processing, statistical modeling, and machine learning to
-analyze unstructured and semi-structured text across 364 language-encoding-script combinations, revealing valuable
-information and actionable data. Rosette provides endpoints for extracting entities and relationships, translating and
-comparing the similarity of names, categorizing and adding linguistic tags to text and more.
+Our product is a full text processing pipeline from data preparation to extracting the most relevant information and
+analysis utilizing precise, focused AI that has built-in human understanding. Text Analytics provides foundational
+linguistic analysis for identifying languages and relating words. The result is enriched and normalized text for
+high-speed search and processing without translation.
+
+Text Analytics extracts events and entities — people, organizations, and places — from unstructured text and adds the
+structure of associating those entities into events that deliver only the necessary information for near real-time
+decision making. Accompanying tools shorten the process of training AI models to recognize domain-specific events.
-## Rosette API Access
-- Rosette Cloud [Sign Up](https://developer.rosette.com/signup)
-- Rosette Enterprise [Evaluation](https://www.rosette.com/product-eval/)
+The product delivers a multitude of ways to sharpen and expand search results. Semantic similarity expands search
+beyond keywords to words with the same meaning, even in other languages. Sentiment analysis and topic extraction help
+filter results to what’s relevant.
+## Analytics API Access
+- Analytics Cloud [Sign Up](https://developer.babelstreet.com/signup)
## Quick Start
#### Maven
@@ -31,19 +43,18 @@ in the Maven Central badge at the top of this page.
#### Test Releases
Versions, of the form `x.y.z`, where `z` is greater than or equal to `100`, are internal testing versions. Do not use
-them without consultation with Basis Technology Corp.
+them without consultation with Babel Street.
#### Examples
-View small example programs for each Rosette endpoint in the
+View small example programs for each Analytics endpoint in the
[examples](examples/src/main/java/com/basistech/rosette/examples) directory.
#### Documentation & Support
- [Binding API](https://rosette-api.github.io/java/)
-- [Rosette Platform API](https://developer.rosette.com/features-and-functions)
+- [Analytics Platform API](https://docs.babelstreet.com/API/en/index-en.html)
- [Binding Release Notes](https://github.com/rosette-api/java/wiki/Release-Notes)
-- [Rosette Platform Release Notes](https://support.rosette.com/hc/en-us/articles/360018354971-Release-Notes)
-- [Binding/Rosette Platform Compatibility](https://developer.rosette.com/features-and-functions?java#)
-- [Support](https://support.rosette.com)
+- [Analytics Platform Release Notes](https://docs.babelstreet.com/Release/en/rosette-cloud.html)
+- [Support](https://babelstreet.my.site.com/support/s/)
- [Binding License: Apache 2.0](LICENSE.txt)
## Binding Developer Information
diff --git a/all/pom.xml b/all/pom.xml
new file mode 100644
index 000000000..430805806
--- /dev/null
+++ b/all/pom.xml
@@ -0,0 +1,109 @@
+
+
+
+ 4.0.0
+
+ com.basistech.rosette
+ rosette-api-java-binding
+ 1.36.1-SNAPSHOT
+
+ rosette-api-all
+ rosette-api-all
+ Babel Street Analytics API all modules combined
+
+
+ com.basistech
+ common-api
+
+
+ com.basistech.rosette
+ rosette-api
+ ${project.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.basistech
+ adm-json
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ add-source
+ package
+
+ add-source
+
+
+
+ ../model/target/delombok
+ ../api/src/main/java
+ ../annotations/src/main/java
+
+
+
+
+
+
+ maven-javadoc-plugin
+
+ ../model/target/delombok;../api/src/main/java
+
+
+ com.basistech.rosette
+ rosette-api-annotations
+ ${project.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+
+
+ shade
+
+ shade
+
+ package
+
+ true
+
+
+ com.basistech.*
+
+
+
+
+
+
+
+
+
diff --git a/annotations/bnd.bnd b/annotations/bnd.bnd
deleted file mode 100644
index 099e137e3..000000000
--- a/annotations/bnd.bnd
+++ /dev/null
@@ -1,2 +0,0 @@
-Bundle-Version: ${osgi-version}
-Export-Package: com.basistech.rosette.annotations
diff --git a/annotations/pom.xml b/annotations/pom.xml
index c3e00247c..4b06d860d 100644
--- a/annotations/pom.xml
+++ b/annotations/pom.xml
@@ -1,6 +1,6 @@
+
+ commons-codec
+ commons-codec
+ ${commons-codec.version}
+ org.apache.httpcomponentshttpclient
- ${http-components-version}
+ ${bt-httpclient-version}
+
+
+ commons-codec
+ commons-codec
+
+ org.apache.httpcomponentshttpmime
- ${http-components-version}
+ ${bt-httpmime-version}
+
+
+ org.apache.httpcomponents
+ httpclient
+
+ org.slf4jslf4j-api
- junit
- junit
-
-
- org.mock-server
- mockserver-client-java
- ${mockserver-version}
- test
-
-
- org.mock-server
- mockserver-core
- ${mockserver-version}
+ org.junit.jupiter
+ junit-jupiter
+ ${junit.version}testorg.mock-server
- mockserver-netty
- ${mockserver-version}
+ mockserver-junit-jupiter-no-dependencies
+ ${mockserver.version}test
@@ -95,70 +103,9 @@
-
- biz.aQute.bnd
- bnd-maven-plugin
-
-
- org.apache.maven.plugins
- maven-jar-plugin
-
-
- ${project.build.outputDirectory}/META-INF/MANIFEST.MF
-
-
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
- ${build-helper-maven-plugin.version}
-
-
- reserve-network-port
-
- reserve-network-port
-
- initialize
-
-
- mockServerClient.port
-
-
-
-
-
-
- org.mock-server
- mockserver-maven-plugin
- ${mockserver-version}
-
- ${mockServerClient.port}
- WARN
- ${skip-mockserver}
-
-
-
- process-test-classes
- process-test-classes
-
- runForked
-
-
-
- verify
- verify
-
- stopForked
-
-
-
- org.apache.maven.pluginsmaven-surefire-plugin
-
- -Xmx1024m
-
@@ -171,13 +118,6 @@
-
- src/test/resources
-
- **/*.property
-
- true
- src/test/resources
@@ -189,24 +129,4 @@
-
-
- skip-mockserver-tests
-
- true
-
-
-
-
-
- maven-surefire-plugin
-
- true
-
-
-
-
-
-
-
diff --git a/api/src/main/java/com/basistech/rosette/api/HttpRosetteAPI.java b/api/src/main/java/com/basistech/rosette/api/HttpRosetteAPI.java
index 2accdfe2d..b0e997b90 100644
--- a/api/src/main/java/com/basistech/rosette/api/HttpRosetteAPI.java
+++ b/api/src/main/java/com/basistech/rosette/api/HttpRosetteAPI.java
@@ -1,5 +1,5 @@
/*
-* Copyright 2017 Basis Technology Corp.
+* Copyright 2024 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -73,20 +73,24 @@
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Future;
+import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import static java.net.HttpURLConnection.HTTP_OK;
/**
- * Access to the RosetteAPI via HTTP.
+ * Access to the Analytics API via HTTP.
*/
public class HttpRosetteAPI extends AbstractRosetteAPI {
- public static final String DEFAULT_URL_BASE = "https://api.rosette.com/rest/v1";
- public static final String SERVICE_NAME = "RosetteAPI";
+ public static final String DEFAULT_URL_BASE = "https://analytics.babelstreet.com/rest/v1";
+ public static final String SERVICE_NAME = "Babel-Street-Analytics-API";
public static final String BINDING_VERSION = getVersion();
- public static final String USER_AGENT_STR = SERVICE_NAME + "-Java/" + BINDING_VERSION + "/" + System.getProperty("java.version");
+ public static final String USER_AGENT_STR = SERVICE_NAME + "-Java/" + BINDING_VERSION + "/"
+ + System.getProperty("java.version");
private static final Logger LOG = LoggerFactory.getLogger(HttpRosetteAPI.class);
+ private static final String IO_EXCEPTION_MESSAGE = "IO Exception communicating with the Babel Street Analytics API";
+ private static final Pattern TRAILING_SLASHES = Pattern.compile("/+$");
private String urlBase = DEFAULT_URL_BASE;
private int failureRetries = 1;
private ObjectMapper mapper;
@@ -100,23 +104,23 @@ private HttpRosetteAPI() {
}
/**
- * Constructs a Rosette API instance using the builder syntax.
+ * Constructs an Analytics API instance using the builder syntax.
*
- * @param key Rosette API key. This may be null for use with an on-premise deployment
- * of the Rosette API.
- * @param urlToCall Alternate Rosette API URL. {@code null} uses the default, public, URL.
+ * @param key Analytics API key. This may be null for use with an on-premise deployment
+ * of the Analytics API.
+ * @param urlToCall Alternate Analytics API URL. {@code null} uses the default, public, URL.
* @param failureRetries Number of times to retry in case of failure; {@code null} uses the
* default value: 1.
* @param connectionConcurrency Number of concurrent connections. Pass this if have subscribed
* to a plan that supports enhanced concurrency, or if you are using
- * an on-premise deployment of the Rosette API. {@code null} uses the
+ * an on-premise deployment of the Analytics API. {@code null} uses the
* default value: 2.
* @throws HttpRosetteAPIException Problem with the API request
*/
HttpRosetteAPI(String key, String urlToCall, Integer failureRetries,
CloseableHttpClient httpClient, List additionalHeaders,
Integer connectionConcurrency, boolean onlyAcceptKnownFields) throws HttpRosetteAPIException {
- urlBase = urlToCall == null ? urlBase : urlToCall.trim().replaceAll("/+$", "");
+ urlBase = urlToCall == null ? urlBase : TRAILING_SLASHES.matcher(urlToCall.trim()).replaceAll("");
if (failureRetries != null && failureRetries >= 1) {
this.failureRetries = failureRetries;
}
@@ -173,10 +177,12 @@ private static byte[] getBytes(InputStream is) throws IOException {
}
}
+ @SuppressWarnings("java:HttpClient_must_be_closed") // This library requires keeping the connection open.
private void initClient(String key, List additionalHeaders) {
HttpClientBuilder builder = HttpClients.custom();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(connectionConcurrency);
+ cm.setDefaultMaxPerRoute(connectionConcurrency);
builder.setConnectionManager(cm);
initHeaders(key, additionalHeaders);
@@ -191,7 +197,10 @@ private void initHeaders(String key, List additionalHeaders) {
this.additionalHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, USER_AGENT_STR));
this.additionalHeaders.add(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "gzip"));
if (key != null) {
- this.additionalHeaders.add(new BasicHeader("X-RosetteAPI-Key", key));
+ this.additionalHeaders.add(new BasicHeader("X-BabelStreetAPI-Key", key));
+ this.additionalHeaders.add(new BasicHeader("X-BabelStreetAPI-Binding", "java"));
+ this.additionalHeaders.add(new BasicHeader("X-BabelStreetAPI-Binding-Version", BINDING_VERSION));
+ // TODO: Remove in a future release.
this.additionalHeaders.add(new BasicHeader("X-RosetteAPI-Binding", "java"));
this.additionalHeaders.add(new BasicHeader("X-RosetteAPI-Binding-Version", BINDING_VERSION));
}
@@ -210,10 +219,10 @@ public int getFailureRetries() {
}
/**
- * Gets information about the Rosette API, returns name, version, build number and build time.
+ * Gets information about the Analytics API, returns name, version, build number and build time.
*
* @return InfoResponse
- * @throws HttpRosetteAPIException Rosette specific exception
+ * @throws HttpRosetteAPIException Analytics specific exception
* @throws IOException General IO exception
*/
public InfoResponse info() throws IOException, HttpRosetteAPIException {
@@ -221,10 +230,10 @@ public InfoResponse info() throws IOException, HttpRosetteAPIException {
}
/**
- * Pings the Rosette API for a response indicating that the service is available.
+ * Pings the Analytics API for a response indicating that the service is available.
*
* @return PingResponse
- * @throws HttpRosetteAPIException Rosette specific exception
+ * @throws HttpRosetteAPIException Analytics specific exception
* @throws IOException General IO exception
*/
public PingResponse ping() throws IOException, HttpRosetteAPIException {
@@ -232,32 +241,34 @@ public PingResponse ping() throws IOException, HttpRosetteAPIException {
}
/**
- * Gets the set of language and script codes supported by the specified Rosette API endpoint.
+ * Gets the set of language and script codes supported by the specified Analytics API endpoint.
*
* @return SupportedLanguagesResponse
- * @throws HttpRosetteAPIException for an error returned from the Rosette API.
+ * @throws HttpRosetteAPIException for an error returned from the Analytics API.
*/
@Override
public SupportedLanguagesResponse getSupportedLanguages(String endpoint) throws HttpRosetteAPIException {
if (DOC_ENDPOINTS.contains(endpoint) || NAME_DEDUPLICATION_SERVICE_PATH.equals(endpoint)) {
- return sendGetRequest(urlBase + endpoint + SUPPORTED_LANGUAGES_SUBPATH, SupportedLanguagesResponse.class);
+ return sendGetRequest(urlBase + endpoint + SUPPORTED_LANGUAGES_SUBPATH,
+ SupportedLanguagesResponse.class);
} else {
return null;
}
}
/**
- * Gets the set of language, script codes and transliteration scheme pairs supported by the specified Rosette API
+ * Gets the set of language, script codes and transliteration scheme pairs supported by the specified Analytics API
* endpoint.
*
- * @param endpoint Rosette API endpoint.
+ * @param endpoint Analytics API endpoint.
* @return SupportedLanguagePairsResponse
- * @throws HttpRosetteAPIException for an error returned from the Rosette API.
+ * @throws HttpRosetteAPIException for an error returned from the Analytics API.
*/
@Override
public SupportedLanguagePairsResponse getSupportedLanguagePairs(String endpoint) throws HttpRosetteAPIException {
if (NAMES_ENDPOINTS.contains(endpoint) && !NAME_DEDUPLICATION_SERVICE_PATH.equals(endpoint)) {
- return sendGetRequest(urlBase + endpoint + SUPPORTED_LANGUAGES_SUBPATH, SupportedLanguagePairsResponse.class);
+ return sendGetRequest(urlBase + endpoint + SUPPORTED_LANGUAGES_SUBPATH,
+ SupportedLanguagePairsResponse.class);
} else {
return null;
}
@@ -271,15 +282,16 @@ public SupportedLanguagePairsResponse getSupportedLanguagePairs(String endpoint)
* @param the type of the request object.
* @param the type of the response object.
* @return the response.
- * @throws HttpRosetteAPIException for an error returned from the Rosette API.
+ * @throws HttpRosetteAPIException for an error returned from the Analytics API.
* @throws RosetteRuntimeException for other errors, such as communications problems with HTTP.
*/
@Override
- public ResponseType perform(String endpoint, RequestType request, Class responseClass) throws HttpRosetteAPIException {
+ public ResponseType perform(String endpoint,
+ RequestType request, Class responseClass) throws HttpRosetteAPIException {
try {
return sendPostRequest(request, urlBase + endpoint, responseClass);
} catch (IOException e) {
- throw new RosetteRuntimeException("IO Exception communicating with the Rosette API", e);
+ throw new RosetteRuntimeException(IO_EXCEPTION_MESSAGE, e);
} catch (URISyntaxException e) {
throw new RosetteRuntimeException("Invalid URI", e);
}
@@ -291,15 +303,16 @@ public ResponseType
* @param request the data for the request.
* @param the type of the request object.
* @return the response, {@link com.basistech.rosette.dm.AnnotatedText}.
- * @throws HttpRosetteAPIException for an error returned from the Rosette API.
+ * @throws HttpRosetteAPIException for an error returned from the Analytics API.
* @throws RosetteRuntimeException for other errors, such as communications problems with HTTP.
*/
@Override
- public AnnotatedText perform(String endpoint, RequestType request) throws HttpRosetteAPIException {
+ public AnnotatedText perform(String endpoint, RequestType request)
+ throws HttpRosetteAPIException {
try {
return sendPostRequest(request, urlBase + endpoint, AnnotatedText.class);
} catch (IOException e) {
- throw new RosetteRuntimeException("IO Exception communicating with the Rosette API", e);
+ throw new RosetteRuntimeException(IO_EXCEPTION_MESSAGE, e);
} catch (URISyntaxException e) {
throw new RosetteRuntimeException("Invalid URI", e);
}
@@ -309,16 +322,18 @@ public AnnotatedText perform(String endpoint, Requ
* This method always throws UnsupportedOperationException.
*/
@Override
- public Future performAsync(String endpoint, RequestType request, Class responseClass) throws HttpRosetteAPIException {
+ public Future
+ performAsync(String endpoint, RequestType request, Class responseClass)
+ throws HttpRosetteAPIException {
throw new UnsupportedOperationException("Asynchronous operations are not yet supported");
}
/**
- * Sends a GET request to Rosette API.
+ * Sends a GET request to Analytics API.
*
* Returns a Response.
*
- * @param urlStr Rosette API end point.
+ * @param urlStr Analytics API end point.
* @param clazz Response class
* @return Response
* @throws HttpRosetteAPIException
@@ -334,21 +349,22 @@ private T sendGetRequest(String urlStr, Class clazz) thr
responseHeadersToExtendedInformation(resp, httpResponse);
return resp;
} catch (IOException e) {
- throw new RosetteRuntimeException("IO Exception communicating with the Rosette API", e);
+ throw new RosetteRuntimeException(IO_EXCEPTION_MESSAGE, e);
}
}
/**
- * Sends a POST request to Rosette API.
+ * Sends a POST request to Analytics API.
*
* Returns a Response.
*
- * @param urlStr Rosette API end point.
+ * @param urlStr Analytics API end point.
* @param clazz Response class
* @return Response
* @throws IOException
*/
- private T sendPostRequest(Object request, String urlStr, Class clazz) throws IOException, URISyntaxException {
+ private T sendPostRequest(Object request, String urlStr, Class clazz)
+ throws IOException, URISyntaxException {
ObjectWriter writer = mapper.writer().without(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
boolean notPlainText = false;
if (request instanceof DocumentRequest) {
@@ -388,9 +404,14 @@ private T sendPostRequest(Object request, String urlStr, Class clazz) thr
while (numRetries-- > 0) {
try (CloseableHttpResponse response = httpClient.execute(post)) {
T resp = getResponse(response, clazz);
+ // TODO: Remove in a future release
Header ridHeader = response.getFirstHeader("X-RosetteAPI-DocumentRequest-Id");
if (ridHeader != null && ridHeader.getValue() != null) {
- LOG.debug("DocumentRequest ID " + ridHeader.getValue());
+ LOG.debug("DocumentRequest ID {}", ridHeader.getValue());
+ }
+ Header bsidHeader = response.getFirstHeader("X-BabelStreetAPI-DocumentRequest-Id");
+ if (bsidHeader != null && bsidHeader.getValue() != null) {
+ LOG.debug("DocumentRequest ID {}", bsidHeader.getValue());
}
if (resp instanceof Response) {
responseHeadersToExtendedInformation((Response)resp, response);
@@ -417,7 +438,8 @@ private void responseHeadersToExtendedInformation(T resp, H
if (resp.getExtendedInformation().get(header.getName()) instanceof Set) {
currentSetValue = (Set
@@ -65,19 +78,6 @@
-
- biz.aQute.bnd
- bnd-maven-plugin
-
-
- org.apache.maven.plugins
- maven-jar-plugin
-
-
- ${project.build.outputDirectory}/META-INF/MANIFEST.MF
-
-
- org.codehaus.mojobuild-helper-maven-plugin
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/AddressMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/AddressMixin.java
index 9fbf02075..c1e21f2fa 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/AddressMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/AddressMixin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Basis Technology Corp.
+ * Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,6 +58,6 @@ protected AddressMixin() {
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class AddressBuilderMixin {
+ abstract static class AddressBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/AddressSimilarityRequestMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/AddressSimilarityRequestMixin.java
index 743d78908..bb391655f 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/AddressSimilarityRequestMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/AddressSimilarityRequestMixin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Basis Technology Corp.
+ * Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,11 +36,11 @@ protected AddressSimilarityRequestMixin(
@JsonProperty("address1") IAddress address1,
@JsonProperty("address2") IAddress address2,
@JsonProperty("parameters") Map parameters
- ) {
+ ) {
//
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class AddressSimilarityRequestBuilderMixin {
+ abstract static class AddressSimilarityRequestBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/AdmRequestMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/AdmRequestMixin.java
index 8ebbd1d1a..9d8cad03a 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/AdmRequestMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/AdmRequestMixin.java
@@ -1,5 +1,5 @@
/*
-* Copyright 2017 Basis Technology Corp.
+* Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,13 +36,12 @@ protected AdmRequestMixin(
@JsonProperty("profileId") String profileId,
@JsonProperty("text") AnnotatedText text,
@JsonProperty("options") Options options,
- @JsonProperty("genre") String genre,
@JsonProperty("language") LanguageCode language
) {
//
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class AdmRequestBuilderMixin {
+ abstract static class AdmRequestBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/ApiModelMixinModule.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/ApiModelMixinModule.java
index 76931c0cc..16d30a1f3 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/ApiModelMixinModule.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/ApiModelMixinModule.java
@@ -16,7 +16,6 @@
package com.basistech.rosette.apimodel.jackson;
-import com.basistech.rosette.apimodel.Address;
import com.basistech.rosette.apimodel.AddressSimilarityRequest;
import com.basistech.rosette.apimodel.AdmRequest;
import com.basistech.rosette.apimodel.ConfigurationRequest;
@@ -25,9 +24,19 @@
import com.basistech.rosette.apimodel.IAddress;
import com.basistech.rosette.apimodel.Name;
import com.basistech.rosette.apimodel.NameDeduplicationRequest;
+import com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers.AddressFieldDeserializer;
+import com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers.DateFieldDeserializer;
+import com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers.NameFieldDeserializer;
+import com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers.RecordSimilarityResponseDeserializer;
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityResponse;
+import com.basistech.rosette.apimodel.recordsimilarity.records.AddressField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.DateField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.NameField;
import com.basistech.rosette.apimodel.NameSimilarityRequest;
import com.basistech.rosette.apimodel.NameTranslationRequest;
import com.basistech.rosette.apimodel.UnfieldedAddress;
+import com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers.RecordSimilarityRequestDeserializer;
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityRequest;
import com.basistech.rosette.dm.jackson.AnnotatedDataModelModule;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.Module;
@@ -38,13 +47,13 @@
* Jackson module to configure Json serialization and deserialization for the
* Rosette API model.
*/
-@SuppressWarnings("deprecation")
public class ApiModelMixinModule extends AnnotatedDataModelModule {
public ApiModelMixinModule() {
super();
}
+ @Override
public void setupModule(Module.SetupContext context) {
super.setupModule(context);
@@ -52,26 +61,33 @@ public void setupModule(Module.SetupContext context) {
MixinUtil.addMixins(context);
context.setMixInAnnotations(DocumentRequest.class, DocumentRequestMixin.class);
- context.setMixInAnnotations(DocumentRequest.DocumentRequestBuilder.class, DocumentRequestMixin.DocumentRequestBuilderMixin.class);
+ context.setMixInAnnotations(DocumentRequest.DocumentRequestBuilder.class,
+ DocumentRequestMixin.DocumentRequestBuilderMixin.class);
context.setMixInAnnotations(AdmRequest.class, AdmRequestMixin.class);
context.setMixInAnnotations(AdmRequest.AdmRequestBuilder.class, AdmRequestMixin.AdmRequestBuilderMixin.class);
context.setMixInAnnotations(Name.class, NameMixin.class);
context.setMixInAnnotations(Name.NameBuilder.class, NameMixin.NameBuilderMixin.class);
context.setMixInAnnotations(NameSimilarityRequest.class, NameSimilarityRequestMixin.class);
- context.setMixInAnnotations(NameSimilarityRequest.NameSimilarityRequestBuilder.class, NameSimilarityRequestMixin.NameSimilarityRequestBuilderMixin.class);
+ context.setMixInAnnotations(NameSimilarityRequest.NameSimilarityRequestBuilder.class,
+ NameSimilarityRequestMixin.NameSimilarityRequestBuilderMixin.class);
context.setMixInAnnotations(NameTranslationRequest.class, NameTranslationRequestMixin.class);
- context.setMixInAnnotations(NameTranslationRequest.NameTranslationRequestBuilder.class, NameTranslationRequestMixin.NameTranslationRequestBuilderMixin.class);
+ context.setMixInAnnotations(NameTranslationRequest.NameTranslationRequestBuilder.class,
+ NameTranslationRequestMixin.NameTranslationRequestBuilderMixin.class);
context.setMixInAnnotations(NameDeduplicationRequest.class, NameDeduplicationRequestMixin.class);
- context.setMixInAnnotations(NameDeduplicationRequest.NameDeduplicationRequestBuilder.class, NameDeduplicationRequestMixin.NameDeduplicationRequestBuilderMixin.class);
- context.setMixInAnnotations(Address.class, AddressMixin.class);
- context.setMixInAnnotations(Address.AddressBuilder.class, AddressMixin.AddressBuilderMixin.class);
+ context.setMixInAnnotations(NameDeduplicationRequest.NameDeduplicationRequestBuilder.class,
+ NameDeduplicationRequestMixin.NameDeduplicationRequestBuilderMixin.class);
+
context.setMixInAnnotations(FieldedAddress.class, FieldedAddressMixin.class);
- context.setMixInAnnotations(FieldedAddress.FieldedAddressBuilder.class, FieldedAddressMixin.FieldedAddressBuilderMixin.class);
+ context.setMixInAnnotations(FieldedAddress.FieldedAddressBuilder.class,
+ FieldedAddressMixin.FieldedAddressBuilderMixin.class);
context.setMixInAnnotations(UnfieldedAddress.class, UnfieldedAddressMixin.class);
- context.setMixInAnnotations(UnfieldedAddress.UnfieldedAddressBuilder.class, UnfieldedAddressMixin.UnfieldedAddressBuilderMixin.class);
+ context.setMixInAnnotations(UnfieldedAddress.UnfieldedAddressBuilder.class,
+ UnfieldedAddressMixin.UnfieldedAddressBuilderMixin.class);
+
context.setMixInAnnotations(AddressSimilarityRequest.class, AddressSimilarityRequestMixin.class);
- context.setMixInAnnotations(AddressSimilarityRequest.AddressSimilarityRequestBuilder.class, AddressSimilarityRequestMixin.AddressSimilarityRequestBuilderMixin.class);
+ context.setMixInAnnotations(AddressSimilarityRequest.AddressSimilarityRequestBuilder.class,
+ AddressSimilarityRequestMixin.AddressSimilarityRequestBuilderMixin.class);
context.setMixInAnnotations(ConfigurationRequest.class, ConfigurationRequestMixin.class);
context.setMixInAnnotations(ConfigurationRequest.ConfigurationRequestBuilder.class,
ConfigurationRequestMixin.ConfigurationRequestBuilderMixin.class);
@@ -79,6 +95,11 @@ public void setupModule(Module.SetupContext context) {
// IAddresses require a custom deserializer
SimpleDeserializers deserializers = new SimpleDeserializers();
deserializers.addDeserializer(IAddress.class, new AddressDeserializer());
+ deserializers.addDeserializer(NameField.class, new NameFieldDeserializer());
+ deserializers.addDeserializer(DateField.class, new DateFieldDeserializer());
+ deserializers.addDeserializer(AddressField.class, new AddressFieldDeserializer());
+ deserializers.addDeserializer(RecordSimilarityRequest.class, new RecordSimilarityRequestDeserializer());
+ deserializers.addDeserializer(RecordSimilarityResponse.class, new RecordSimilarityResponseDeserializer());
context.addDeserializers(deserializers);
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/ConfigurationRequestMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/ConfigurationRequestMixin.java
index 683447876..09400fec8 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/ConfigurationRequestMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/ConfigurationRequestMixin.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2022 Basis Technology Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.basistech.rosette.apimodel.jackson;
import com.basistech.rosette.apimodel.Configuration;
@@ -21,6 +37,6 @@ protected ConfigurationRequestMixin(
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class ConfigurationRequestBuilderMixin {
+ abstract static class ConfigurationRequestBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/DocumentRequestMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/DocumentRequestMixin.java
index b02541510..5070277d1 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/DocumentRequestMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/DocumentRequestMixin.java
@@ -1,5 +1,5 @@
/*
-* Copyright 2017 Basis Technology Corp.
+* Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
import com.basistech.util.LanguageCode;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
@@ -30,6 +31,7 @@
//CHECKSTYLE:OFF
@JsonTypeName("DocumentRequest")
+@JsonIgnoreProperties({"genre"})
@JsonInclude(JsonInclude.Include.NON_NULL)
public abstract class DocumentRequestMixin {
@@ -47,14 +49,13 @@ protected DocumentRequestMixin(
@JsonProperty("content") Object content,
@JsonProperty("contentUri") String contentUri,
@JsonProperty("contentType") String contentType,
- @JsonProperty("genre") String genre,
@JsonProperty("options") Options options
) {
//
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class DocumentRequestBuilderMixin {
+ abstract static class DocumentRequestBuilderMixin {
}
@JsonIgnore
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/FieldedAddressMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/FieldedAddressMixin.java
index fed88957f..a288b7918 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/FieldedAddressMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/FieldedAddressMixin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 Basis Technology Corp.
+ * Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,6 +49,6 @@ protected FieldedAddressMixin(@JsonProperty("house") String house,
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class FieldedAddressBuilderMixin {
+ abstract static class FieldedAddressBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameDeduplicationRequestMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameDeduplicationRequestMixin.java
index 2afe774e3..0a07ca1f6 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameDeduplicationRequestMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameDeduplicationRequestMixin.java
@@ -1,5 +1,5 @@
/*
-* Copyright 2017 Basis Technology Corp.
+* Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,6 @@ protected NameDeduplicationRequestMixin(
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class NameDeduplicationRequestBuilderMixin {
+ abstract static class NameDeduplicationRequestBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameSimilarityRequestMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameSimilarityRequestMixin.java
index c778fd206..7dac7d791 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameSimilarityRequestMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameSimilarityRequestMixin.java
@@ -1,5 +1,5 @@
/*
-* Copyright 2017 Basis Technology Corp.
+* Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,6 +43,6 @@ protected NameSimilarityRequestMixin(
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class NameSimilarityRequestBuilderMixin {
+ abstract static class NameSimilarityRequestBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameTranslationRequestMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameTranslationRequestMixin.java
index 034341d66..90b0976bb 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameTranslationRequestMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/NameTranslationRequestMixin.java
@@ -1,5 +1,5 @@
/*
-* Copyright 2017 Basis Technology Corp.
+* Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,12 +41,13 @@ protected NameTranslationRequestMixin(
@JsonProperty("sourceLanguageOfUse") LanguageCode sourceLanguageOfUse,
@JsonProperty("targetLanguage") LanguageCode targetLanguage,
@JsonProperty("targetScript") ISO15924 targetScript,
- @JsonProperty("targetScheme") TransliterationScheme targetScheme
+ @JsonProperty("targetScheme") TransliterationScheme targetScheme,
+ @JsonProperty("maximumResults") Integer maximumResults
) {
//
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class NameTranslationRequestBuilderMixin {
+ abstract static class NameTranslationRequestBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/UnfieldedAddressMixin.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/UnfieldedAddressMixin.java
index 5e12de139..2a2bd6223 100644
--- a/json/src/main/java/com/basistech/rosette/apimodel/jackson/UnfieldedAddressMixin.java
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/UnfieldedAddressMixin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 Basis Technology Corp.
+ * Copyright 2022 Basis Technology Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,6 +33,6 @@ protected UnfieldedAddressMixin(@JsonProperty("address") String address) {
}
@JsonPOJOBuilder(withPrefix = "")
- abstract class UnfieldedAddressBuilderMixin {
+ abstract static class UnfieldedAddressBuilderMixin {
}
}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/AddressFieldDeserializer.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/AddressFieldDeserializer.java
new file mode 100644
index 000000000..b38c46217
--- /dev/null
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/AddressFieldDeserializer.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2024 Basis Technology Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers;
+
+import com.basistech.rosette.apimodel.recordsimilarity.records.AddressField;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+import java.io.IOException;
+
+public class AddressFieldDeserializer extends StdDeserializer {
+ public AddressFieldDeserializer() {
+ super(AddressField.class);
+ }
+
+ @Override
+ public AddressField deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
+ if (node.isObject()) {
+ return jsonParser.getCodec().treeToValue(node, AddressField.FieldedAddress.class);
+ } else if (node.isTextual()) {
+ return AddressField.UnfieldedAddress.builder().address(node.textValue()).build();
+ }
+ throw new IOException("Invalid JSON structure: unexpected node type");
+ }
+}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/DateFieldDeserializer.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/DateFieldDeserializer.java
new file mode 100644
index 000000000..422f34252
--- /dev/null
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/DateFieldDeserializer.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2024 Basis Technology Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers;
+
+import com.basistech.rosette.apimodel.recordsimilarity.records.DateField;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+import java.io.IOException;
+
+public class DateFieldDeserializer extends StdDeserializer {
+ public DateFieldDeserializer() {
+ super(DateField.class);
+ }
+
+ @Override
+ public DateField deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
+ if (node.isObject()) {
+ return jsonParser.getCodec().treeToValue(node, DateField.FieldedDate.class);
+ } else if (node.isTextual()) {
+ return DateField.UnfieldedDate.builder().date(node.textValue()).build();
+ }
+ throw new IOException("Invalid JSON structure: unexpected node type");
+ }
+}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/NameFieldDeserializer.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/NameFieldDeserializer.java
new file mode 100644
index 000000000..8fb372bc0
--- /dev/null
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/NameFieldDeserializer.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2024 Basis Technology Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers;
+
+import com.basistech.rosette.apimodel.recordsimilarity.records.NameField;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+import java.io.IOException;
+
+public class NameFieldDeserializer extends StdDeserializer {
+ public NameFieldDeserializer() {
+ super(NameField.class);
+ }
+
+ @Override
+ public NameField deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
+ if (node.isObject()) {
+ return jsonParser.getCodec().treeToValue(node, NameField.FieldedName.class);
+ } else if (node.isTextual()) {
+ return NameField.UnfieldedName.builder().text(node.textValue()).build();
+ }
+ throw new IOException("Invalid JSON structure: unexpected node type");
+ }
+}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/RecordSimilarityDeserializerUtilities.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/RecordSimilarityDeserializerUtilities.java
new file mode 100644
index 000000000..2618938e8
--- /dev/null
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/RecordSimilarityDeserializerUtilities.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2024 Basis Technology Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityExplainInfo;
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityResult;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.JsonNode;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityFieldInfo;
+import com.basistech.rosette.apimodel.recordsimilarity.records.AddressField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.BooleanField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.DateField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.NameField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.NumberField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.RecordFieldType;
+import com.basistech.rosette.apimodel.recordsimilarity.records.RecordSimilarityField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.StringField;
+import com.basistech.rosette.apimodel.recordsimilarity.records.UnknownField;
+
+final class RecordSimilarityDeserializerUtilities {
+
+ private RecordSimilarityDeserializerUtilities() {
+ }
+
+ public static RecordSimilarityResult parseResult(JsonNode node, JsonParser jsonParser) throws IOException {
+ final Double score = node.get("score") != null
+ ? node.get("score").traverse(jsonParser.getCodec()).readValueAs(Double.class)
+ : null;
+ final RecordSimilarityExplainInfo explainInfo = node.get("explainInfo") != null
+ ? node.get("explainInfo").traverse(jsonParser.getCodec()).readValueAs(RecordSimilarityExplainInfo.class)
+ : null;
+ final Map left = node.get("left") != null
+ ? parseRecordForResponse(node.get("left"), jsonParser)
+ : null;
+ final Map right = node.get("right") != null
+ ? parseRecordForResponse(node.get("right"), jsonParser)
+ : null;
+
+ List errorList = Optional.ofNullable(node.get("error"))
+ .map(jsonNode -> StreamSupport.stream(jsonNode.spliterator(), false)
+ .map(JsonNode::asText)
+ .collect(Collectors.toList()))
+ .orElse(null);
+ final List info = Optional.ofNullable(node.get("info"))
+ .map(jsonNode -> StreamSupport.stream(jsonNode.spliterator(), false)
+ .map(JsonNode::asText)
+ .collect(Collectors.toList()))
+ .orElse(null);
+ return RecordSimilarityResult.builder()
+ .score(score)
+ .left(left)
+ .right(right)
+ .explainInfo(explainInfo)
+ .error(errorList)
+ .info(info)
+ .build();
+ }
+
+ static Map parseRecordForResponse(JsonNode jsonNode, JsonParser jsonParser) {
+ final Map recordMap = new HashMap<>();
+ jsonNode.fields().forEachRemaining(entry -> {
+ String fieldName = entry.getKey();
+ try {
+ recordMap.put(fieldName, jsonNode.get(fieldName).traverse(jsonParser.getCodec())
+ .readValueAs(UnknownField.class));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ return recordMap;
+ }
+
+ static Map parseRecord(
+ JsonNode jsonNode,
+ JsonParser jsonParser,
+ @NotNull @Valid Map fields
+ ) throws IOException {
+ final Iterator> recordsIterator = jsonNode.fields();
+ final Map recordMap = new HashMap<>();
+ while (recordsIterator.hasNext()) {
+ final Map.Entry recordEntry = recordsIterator.next();
+ final String fieldName = recordEntry.getKey();
+ final JsonNode fieldValue = recordEntry.getValue();
+
+ final RecordSimilarityField fieldData;
+
+ if (fields.containsKey(fieldName)) {
+ final RecordSimilarityFieldInfo fieldInfo = fields.get(fieldName);
+ if (fieldInfo.getType() == null) {
+ throw new IllegalArgumentException("Unspecified field type for: " + fieldName);
+ }
+ switch (fieldInfo.getType().toLowerCase(Locale.ENGLISH)) {
+ case RecordFieldType.RNI_DATE:
+ fieldData = fieldValue.traverse(jsonParser.getCodec()).readValueAs(DateField.class);
+ break;
+ case RecordFieldType.RNI_NAME:
+ fieldData = fieldValue.traverse(jsonParser.getCodec()).readValueAs(NameField.class);
+ break;
+ case RecordFieldType.RNI_ADDRESS:
+ fieldData = fieldValue.traverse(jsonParser.getCodec()).readValueAs(AddressField.class);
+ break;
+ case RecordFieldType.RNI_STRING:
+ fieldData = StringField.builder().data(fieldValue.textValue()).build();
+ break;
+ case RecordFieldType.RNI_NUMBER:
+ fieldData = NumberField.builder().data(fieldValue.numberValue()).build();
+ break;
+ case RecordFieldType.RNI_BOOLEAN:
+ // Be sure not to accidentally convert non-boolean values to 'false'
+ fieldData = BooleanField.builder()
+ .data(fieldValue.isBoolean() ? fieldValue.booleanValue() : null)
+ .build();
+ break;
+ default:
+ fieldData = fieldValue.traverse(jsonParser.getCodec()).readValueAs(UnknownField.class);
+ }
+ } else {
+ //treat unmapped field as UnknownField so we can get to scoring,
+ //it won't be counted toward the score anyway
+ fieldData = fieldValue.traverse(jsonParser.getCodec()).readValueAs(UnknownField.class);
+ }
+ recordMap.put(fieldName, fieldData);
+ }
+ return recordMap;
+ }
+}
diff --git a/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/RecordSimilarityRequestDeserializer.java b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/RecordSimilarityRequestDeserializer.java
new file mode 100644
index 000000000..32b0fb6ab
--- /dev/null
+++ b/json/src/main/java/com/basistech/rosette/apimodel/jackson/recordsimilaritydeserializers/RecordSimilarityRequestDeserializer.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2024 Basis Technology Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.basistech.rosette.apimodel.jackson.recordsimilaritydeserializers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityFieldInfo;
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityProperties;
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityRecords;
+import com.basistech.rosette.apimodel.recordsimilarity.RecordSimilarityRequest;
+import com.basistech.rosette.apimodel.recordsimilarity.records.RecordSimilarityField;
+
+public class RecordSimilarityRequestDeserializer extends StdDeserializer {
+
+ public RecordSimilarityRequestDeserializer() {
+ super(RecordSimilarityRequest.class);
+ }
+
+ @Override
+ public RecordSimilarityRequest deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ try (jsonParser) {
+ final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
+ final Map fields = node.get("fields") != null ? node.get("fields").traverse(jsonParser.getCodec()).readValueAs(new TypeReference