001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.bean.jsonrpc;
018
019import org.apache.juneau.marshall.*;
020
021/**
022 * JSON-RPC 2.0 success or error response envelope.
023 *
024 * <p>
025 * Exactly one of {@code result} or {@code error} should be present for a valid response.
026 *
027 * <p>
028 * This envelope is generic JSON-RPC 2.0 and carries no {@code _meta} property: MCP-specific per-result
029 * metadata belongs under {@code result._meta}, not beside the envelope. See the {@code 2026-07-28} v2 bean
030 * package ({@code org.apache.juneau.bean.mcp.v20260728}) for the typed nested carrier.
031 */
032@Marshalled
033public class JsonRpcResponse {
034
035   private String jsonrpc;
036   private Object id;
037   private Object result;
038   private JsonRpcError error;
039
040   /**
041    * JSON-RPC protocol version.
042    *
043    * @return The version token, or {@code null} if not set.
044    */
045   public String getJsonrpc() {
046      return jsonrpc;
047   }
048
049   /**
050    * Sets the JSON-RPC protocol version.
051    *
052    * @param value The new value.  Can be <jk>null</jk> to unset the property.
053    * @return This object (for method chaining).
054    */
055   public JsonRpcResponse setJsonrpc(String value) {
056      jsonrpc = value;
057      return this;
058   }
059
060   /**
061    * Correlates to the {@link JsonRpcRequest#getId() request id}.
062    *
063    * @return The id, or {@code null} if not set.
064    */
065   public Object getId() {
066      return id;
067   }
068
069   /**
070    * Sets the response id.
071    *
072    * @param value The new value.  Can be <jk>null</jk> to unset the property.
073    * @return This object (for method chaining).
074    */
075   public JsonRpcResponse setId(Object value) {
076      id = value;
077      return this;
078   }
079
080   /**
081    * Result payload on success.
082    *
083    * @return The result, or {@code null} if not set.
084    */
085   public Object getResult() {
086      return result;
087   }
088
089   /**
090    * Sets the result payload.
091    *
092    * @param value The new value.  Can be <jk>null</jk> to unset the property.
093    * @return This object (for method chaining).
094    */
095   public JsonRpcResponse setResult(Object value) {
096      result = value;
097      return this;
098   }
099
100   /**
101    * Error payload on failure.
102    *
103    * @return The error, or {@code null} if not set.
104    */
105   public JsonRpcError getError() {
106      return error;
107   }
108
109   /**
110    * Sets the error payload.
111    *
112    * @param value The new value.  Can be <jk>null</jk> to unset the property.
113    * @return This object (for method chaining).
114    */
115   public JsonRpcResponse setError(JsonRpcError value) {
116      error = value;
117      return this;
118   }
119
120   /**
121    * Tests whether a JSON-RPC id identifies a notification (a request that must not be answered).
122    *
123    * <p>
124    * A JSON-RPC request with no {@code id} is a notification; the server performs the work and returns
125    * no response body.
126    *
127    * @param id The request id. Can be <jk>null</jk>.
128    * @return <jk>true</jk> if the id is <jk>null</jk>.
129    */
130   public static boolean notification(Object id) {
131      return id == null;
132   }
133
134   /**
135    * Creates a JSON-RPC 2.0 success response.
136    *
137    * @param id The request id to correlate against. Can be <jk>null</jk>.
138    * @param result The result payload. Can be <jk>null</jk>.
139    * @return A new response object. Never <jk>null</jk>.
140    */
141   public static JsonRpcResponse ok(Object id, Object result) {
142      return new JsonRpcResponse()
143         .setJsonrpc("2.0")
144         .setId(id)
145         .setResult(result);
146   }
147
148   /**
149    * Creates a JSON-RPC 2.0 error response with no structured error data.
150    *
151    * @param id The request id to correlate against. Can be <jk>null</jk>.
152    * @param code The JSON-RPC error code.
153    * @param message The error message. Can be <jk>null</jk>.
154    * @return A new response object. Never <jk>null</jk>.
155    */
156   public static JsonRpcResponse errorResponse(Object id, int code, String message) {
157      return errorResponse(id, code, message, null);
158   }
159
160   /**
161    * Creates a JSON-RPC 2.0 error response.
162    *
163    * @param id The request id to correlate against. Can be <jk>null</jk>.
164    * @param code The JSON-RPC error code.
165    * @param message The error message. Can be <jk>null</jk>.
166    * @param data Optional structured error data. Can be <jk>null</jk> to leave the property unset.
167    * @return A new response object. Never <jk>null</jk>.
168    */
169   public static JsonRpcResponse errorResponse(Object id, int code, String message, Object data) {
170      return new JsonRpcResponse()
171         .setJsonrpc("2.0")
172         .setId(id)
173         .setError(new JsonRpcError().setCode(code).setMessage(message).setData(data));
174   }
175}