blob: 3f7e54e309acc8b0b8d6f0b1157ed779e0989b8a [file] [log] [blame]
package de.ids_mannheim.korap.response;
import java.util.*;
import java.io.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import de.ids_mannheim.korap.response.Notifications;
/**
* Base class for objects meant to be responded by the server.
*
* <p>
* <blockquote><pre>
* KorapResponse km = new KorapResponse();
* System.out.println(
* km.toJsonString()
* );
* </pre></blockquote>
*
* @author diewald
* @see Notifications
*/
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class KorapResponse extends Notifications {
ObjectMapper mapper = new ObjectMapper();
private String version, name, node, listener;
private long
totalResources = -2, // Not set
totalResults = -2; // Not set
private String benchmark;
private boolean timeExceeded = false;
/**
* Construct a new KorapResponse object.
*/
public KorapResponse () {};
/**
* Get string representation of the backend's version.
*
* @return String representation of the backend's version
*/
public String getVersion () {
return this.version;
};
/**
* Set the string representation of the backend's version.
*
* @param version The string representation of the backend's version
* @return KorapResponse object for chaining
*/
public KorapResponse setVersion (String fullVersion) {
int found = fullVersion.lastIndexOf('-');
// Is combined name and version
if (found > 0 && (found + 1 < fullVersion.length())) {
this.setName(fullVersion.substring(0, found));
this.version = fullVersion.substring(found + 1);
}
// Is only version number
else {
this.version = fullVersion;
};
return this;
};
/**
* Get string representation of the backend's name.
* All nodes in a cluster should have the same backend name.
*
* @return String representation of the backend's name
*/
public String getName () {
return this.name;
};
/**
* Set the string representation of the backend's name.
* All nodes in a cluster should have the same backend name.
*
* @param name The string representation of the backend's name
* @return KorapResponse object for chaining
*/
public KorapResponse setName (String name) {
this.name = name;
return this;
};
/**
* Get string representation of the node's name.
* Each node in a cluster has a unique name.
*
* @return String representation of the node's name
*/
public String getNode () {
return this.node;
};
/**
* Set the string representation of the node's name.
* Each node in a cluster has a unique name.
*
* @param version The string representation of the node's name
* @return KorapResponse object for chaining
*/
public KorapResponse setNode (String name) {
this.node = name;
return this;
};
/**
* Check if the response time was exceeded.
*
* @return <tt>true</tt> in case the response had a timeout,
* otherwise <tt>false</tt>
*/
@JsonIgnore
public boolean hasTimeExceeded () {
return this.timeExceeded;
};
/**
* Set to <tt>true</tt> if time is exceeded
* based on a timeout.
*
* <p>
* Will add a warning (682) to the output.
*
* @param timeout Either <tt>true</tt> or <tt>false</tt>,
* in case the response timed out
* @return KorapResponse object for chaining
*/
public KorapResponse setTimeExceeded (boolean timeout) {
if (timeout)
this.addWarning(682, "Response time exceeded");
this.timeExceeded = timeout;
return this;
};
/**
* Get the benchmark time as a string.
*
* @return String representation of the benchmark
* (including trailing time unit)
*/
public String getBenchmark () {
return this.benchmark;
};
/**
* Set the benchmark as timestamp differences.
*
* @param ts1 Starting time of the benchmark
* @param ts2 Ending time of the benchmark
* @return KorapResponse object for chaining
*/
@JsonIgnore
public KorapResponse setBenchmark (long ts1, long ts2) {
this.benchmark =
(ts2 - ts1) < 100_000_000 ?
// Store as miliseconds
(((double) (ts2 - ts1) * 1e-6) + " ms") :
// Store as seconds
(((double) (ts2 - ts1) / 1000000000.0) + " s");
return this;
};
/**
* Set the benchmark as a string representation.
*
* @param bm String representation of a benchmark
* (including trailing time unit)
* @return KorapResponse for chaining
*/
public KorapResponse setBenchmark (String bm) {
this.benchmark = bm;
return this;
};
/**
* Get the listener URI as a string.
*
* @return The listener URI as a string representation
*/
public String getListener () {
return this.listener;
};
/**
* Set the listener URI as a String. This is probably the localhost
* with an arbitrary port, like
*
* <p>
* <blockquote><pre>
* http://localhost:8080/
* </pre></blockquote>
*
* @param listener String representation of the listener URI
* @return KorapResponse object for chaining
*/
public KorapResponse setListener (String listener) {
this.listener = listener;
return this;
};
/**
* Get the total number of results.
*
* @return The total number of results.
*/
public long getTotalResults () {
if (this.totalResults == -2)
return (long) 0;
return this.totalResults;
};
/**
* Set the total number of results.
*
* @param results The total number of results.
* @return {link KorapResponse} object for chaining.
*/
public KorapResponse setTotalResults (long results) {
this.totalResults = results;
return this;
};
/**
* Increment the total number of results by a certain value.
*
* @param incr The number of results the total number should
* be incremented by.
* @return {@link KorapResponse} object for chaining.
*/
public KorapResponse incrTotalResults (int incr) {
if (this.totalResults < 0)
this.totalResults = incr;
else
this.totalResults += incr;
return this;
};
/**
* Get the total number of resources the total number of
* results occur in.
*
* @return The total number of resources the total number of
* results occur in.
*/
public long getTotalResources () {
if (this.totalResources == -2)
return (long) 0;
return this.totalResources;
};
/**
* Set the total number of resources the total number of
* results occur in.
*
* @param resources The total number of resources the total
* number of results occur in.
* @return {@link KorapResponse} object for chaining.
*/
public KorapResponse setTotalResources (long resources) {
this.totalResources = resources;
return this;
};
/**
* Increment the total number of resources the total number
* of results occur in by a certain value.
*
* @param incr The number of resources the total number of
* results occur in should be incremented by.
* (I don't care that this isn't English!)
* @return {@link KorapResponse} object for chaining.
*/
public KorapResponse incrTotalResources (int i) {
if (this.totalResources < 0)
this.totalResources = i;
else
this.totalResources += i;
return this;
};
/**
* Serialize response as a {@link JsonNode}.
*
* @return {@link JsonNode} representation of the response
*/
@Override
public JsonNode toJsonNode () {
// Get notifications json response
ObjectNode json = (ObjectNode) super.toJsonNode();
StringBuilder sb = new StringBuilder();
if (this.getName() != null) {
sb.append(this.getName());
if (this.getVersion() != null)
sb.append("-");
};
// No name but version is given
if (this.getVersion() != null)
sb.append(this.getVersion());
if (sb.length() > 0)
json.put("version", sb.toString());
if (this.timeExceeded)
json.put("timeExceeded", true);
if (this.getNode() != null)
json.put("node", this.getNode());
if (this.getListener() != null)
json.put("listener", this.getListener());
if (this.getBenchmark() != null)
json.put("benchmark", this.getBenchmark());
// totalTexts is set
if (this.totalResources != -2)
json.put("totalResources", this.totalResources);
// totalResults is set
if (this.totalResults != -2)
json.put("totalResults", this.totalResults);
return (JsonNode) json;
};
/**
* Serialize response as a JSON string.
* <p>
* <blockquote><pre>
* {
* "version" : "Lucene-Backend-0.49.1",
* "timeExceeded" : true,
* "node" : "Tanja",
* "listener" : "http://localhost:8080/",
* "benchmark" : "12.3s",
* "errors": [
* [123, "You are not allowed to serialize these messages"],
* [124, "Your request was invalid"]
* ],
* "messages" : [
* [125, "Class is deprecated", "Notifications"]
* ]
* }
* </pre></blockquote>
*
* @return String representation of the response
*/
public String toJsonString () {
String msg = "";
try {
return mapper.writeValueAsString(this.toJsonNode());
}
catch (Exception e) {
// Bad in case the message contains quotes!
msg = ", \"" + e.getLocalizedMessage() + "\"";
};
return
"{\"errors\":["+
"[620, " +
"\"Unable to generate JSON\"" + msg + "]" +
"]}";
};
};