001package org.consensusj.jsonrpc;
002
003import com.fasterxml.jackson.annotation.JsonCreator;
004import com.fasterxml.jackson.annotation.JsonInclude;
005import com.fasterxml.jackson.annotation.JsonProperty;
006import com.fasterxml.jackson.databind.annotation.JsonSerialize;
007import com.fasterxml.jackson.databind.node.NullNode;
008import org.consensusj.jsonrpc.internal.NumberStringSerializer;
009import org.slf4j.Logger;
010import org.slf4j.LoggerFactory;
011
012/**
013 * JSON-RPC Response POJO
014 *
015 * Note that {@code result} is a parameterized type and can be used to directly map JSON-RPC results
016 * to the correct type for each method.
017 */
018public class JsonRpcResponse<RSLT> {
019    private static final Logger log = LoggerFactory.getLogger(JsonRpcResponse.class);
020    private final String          jsonrpc;   // version
021    private final String          id;
022    private final RSLT               result;
023    private final JsonRpcError    error;
024
025    @JsonCreator
026    public JsonRpcResponse(@JsonProperty("jsonrpc")  String jsonrpc,
027                            @JsonProperty("id")      String id,
028                            @JsonProperty("result")  RSLT result,
029                            @JsonProperty("error")   JsonRpcError error) {
030        if ((error == null && result == null) ||
031            (error != null && result != null && !(result instanceof NullNode))) {
032            log.warn("non-compliant response: (error, result) both null or both set.");
033        }
034        this.jsonrpc = jsonrpc;
035        this.id = id;
036        this.result = result;
037        this.error = error;
038    }
039
040    public JsonRpcResponse(JsonRpcRequest request,
041                           RSLT result) {
042        this.jsonrpc = request.getJsonrpc();
043        this.id = request.getId();
044        this.result = result;
045        this.error = null;
046    }
047
048    public JsonRpcResponse(JsonRpcRequest request,
049                           JsonRpcError error) {
050        this.jsonrpc = request.getJsonrpc();
051        this.id = request.getId();
052        this.error = error;
053        this.result = null;
054    }
055
056    @JsonInclude(JsonInclude.Include.NON_NULL)
057    public String getJsonrpc() {
058        return jsonrpc;
059    }
060
061    @JsonInclude(JsonInclude.Include.NON_NULL)
062    public RSLT getResult() {
063        return result;
064    }
065
066    @JsonInclude(JsonInclude.Include.NON_NULL)
067    public JsonRpcError getError() {
068        return error;
069    }
070
071    @JsonSerialize(using= NumberStringSerializer.class)
072    public String getId() {
073        return id;
074    }
075
076    // TODO: Add .toString() method for logging
077}