| 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 + "]" + |
| "]}"; |
| }; |
| }; |