001    package com.thetransactioncompany.jsonrpc2;
002    
003    
004    import net.minidev.json.JSONObject;
005    
006    
007    /** 
008     * Represents a JSON-RPC 2.0 error that occurred during the processing of a 
009     * request. This class is immutable.
010     *
011     * <p>The protocol expects error objects to be structured like this:
012     *
013     * <ul>
014     *     <li>{@code code} An integer that indicates the error type.
015     *     <li>{@code message} A string providing a short description of the 
016     *         error. The message should be limited to a concise single sentence.
017     *     <li>{@code data} Additional information, which may be omitted. Its 
018     *         contents is entirely defined by the application.
019     * </ul>
020     * 
021     * <p>Note that the "Error" word in the class name was put there solely to
022     * comply with the parlance of the JSON-RPC spec. This class doesn't inherit 
023     * from {@code java.lang.Error}. It's a regular subclass of 
024     * {@code java.lang.Exception} and, if thrown, it's to indicate a condition 
025     * that a reasonable application might want to catch.
026     *
027     * <p>This class also includes convenient final static instances for all 
028     * standard JSON-RPC 2.0 errors:
029     *
030     * <ul>
031     *     <li>{@link #PARSE_ERROR} JSON parse error (-32700)
032     *     <li>{@link #INVALID_REQUEST} Invalid JSON-RPC 2.0 Request (-32600)
033     *     <li>{@link #METHOD_NOT_FOUND} Method not found (-32601)
034     *     <li>{@link #INVALID_PARAMS} Invalid parameters (-32602)
035     *     <li>{@link #INTERNAL_ERROR} Internal error (-32603)
036     * </ul>
037     *
038     * <p>Note that the range -32099..-32000 is reserved for additional server 
039     * errors.
040     *
041     * <p id="map">The mapping between JSON and Java entities (as defined by the 
042     * underlying JSON Smart library): 
043     * <pre>
044     *     true|false  <--->  java.lang.Boolean
045     *     number      <--->  java.lang.Number
046     *     string      <--->  java.lang.String
047     *     array       <--->  java.util.List
048     *     object      <--->  java.util.Map
049     *     null        <--->  null
050     * </pre>
051     *
052     * <p>The JSON-RPC 2.0 specification and user group forum can be found 
053     * <a href="http://groups.google.com/group/json-rpc">here</a>.
054     *
055     * @author Vladimir Dzhuvinov
056     * @version 1.34.3 (2012-11-28)
057     */
058    public class JSONRPC2Error extends Exception {
059            
060            
061            /**
062             * Serial version UID.
063             */
064            private static final long serialVersionUID = 4682571044532698806l;
065    
066    
067            /** 
068             * JSON parse error (-32700).
069             */
070            public static final JSONRPC2Error PARSE_ERROR = new JSONRPC2Error(-32700, "JSON parse error");
071            
072            
073            /** 
074             * Invalid JSON-RPC 2.0 request error (-32600).
075             */
076            public static final JSONRPC2Error INVALID_REQUEST = new JSONRPC2Error(-32600, "Invalid request");
077            
078            
079            /** 
080             * Method not found error (-32601). 
081             */
082            public static final JSONRPC2Error METHOD_NOT_FOUND = new JSONRPC2Error(-32601, "Method not found");
083            
084            
085            /** 
086             * Invalid parameters error (-32602).
087             */
088            public static final JSONRPC2Error INVALID_PARAMS = new JSONRPC2Error(-32602, "Invalid parameters");
089            
090            
091            /** 
092             * Internal JSON-RPC 2.0 error (-32603).
093             */
094            public static final JSONRPC2Error INTERNAL_ERROR = new JSONRPC2Error(-32603, "Internal error");
095            
096            
097            /**
098             * The error code.
099             */
100            private final int code;
101            
102            
103            /**
104             * The optional error data.
105             */
106            private final Object data;
107    
108    
109            /**
110             * Appends the specified string to the message of a JSON-RPC 2.0 error.
111             *
112             * @param err The JSON-RPC 2.0 error. Must not be {@code null}.
113             * @param apx The string to append to the original error message.
114             *
115             * @return A new JSON-RPC 2.0 error with the appended message.
116             */
117            public static JSONRPC2Error appendMessage(final JSONRPC2Error err, final String apx) {
118    
119                    return new JSONRPC2Error(err.getCode(), err.getMessage() + apx, err.getData());
120            }
121    
122    
123            /**
124             * Sets the specified data to a JSON-RPC 2.0 error.
125             *
126             * @param err  The JSON-RPC 2.0 error to have its data field set. Must
127             *             not be {@code null}.
128             * @param data Optional error data, must <a href="#map">map</a> to a 
129             *             valid JSON type.
130             *
131             * @return A new JSON-RPC 2.0 error with the set data.
132             */
133            public static JSONRPC2Error setData(final JSONRPC2Error err, final Object data) {
134    
135                    return new JSONRPC2Error(err.getCode(), err.getMessage(), data);
136            }
137            
138            
139            /** 
140             * Creates a new JSON-RPC 2.0 error with the specified code and 
141             * message. The optional data is omitted.
142             * 
143             * @param code    The error code (standard pre-defined or
144             *                application-specific).
145             * @param message The error message.
146             */
147            public JSONRPC2Error(int code, String message) {
148                    
149                    this(code, message, null);
150            }
151            
152            
153            /** 
154             * Creates a new JSON-RPC 2.0 error with the specified code,
155             * message and data.
156             * 
157             * @param code    The error code (standard pre-defined or
158             *                application-specific).
159             * @param message The error message.
160             * @param data    Optional error data, must <a href="#map">map</a>
161             *                to a valid JSON type.
162             */
163            public JSONRPC2Error(int code, String message, Object data) {
164                    
165                    super(message);
166                    this.code = code;
167                    this.data = data;
168            }
169            
170            
171            /** 
172             * Gets the JSON-RPC 2.0 error code.
173             *
174             * @return The error code.
175             */
176            public int getCode() {
177                    
178                    return code;
179            }
180            
181            
182            /**
183             * Gets the JSON-RPC 2.0 error data.
184             *
185             * @return The error data, {@code null} if none was specified.
186             */
187            public Object getData() {
188                    
189                    return data;    
190            }
191    
192    
193            /**
194             * Appends the specified string to the message of this JSON-RPC 2.0 
195             * error.
196             *
197             * @param apx The string to append to the original error message.
198             *
199             * @return A new JSON-RPC 2.0 error with the appended message.
200             */
201            public JSONRPC2Error appendMessage(final String apx) {
202    
203                    return new JSONRPC2Error(code, getMessage() + apx, data);
204            }
205            
206            
207            /** 
208             * @see #toJSONObject
209             */
210            @Deprecated
211            public JSONObject toJSON() {
212            
213                    return toJSONObject();
214            }
215            
216            
217            /** 
218             * Returns a JSON object representation of this JSON-RPC 2.0 error.
219             *
220             * @return A JSON object representing this error object.
221             */
222            public JSONObject toJSONObject() {
223            
224                    JSONObject out = new JSONObject();
225                    
226                    out.put("code", code);
227                    out.put("message", super.getMessage());
228                    if (data != null)
229                            out.put("data", data);
230                                    
231                    return out;
232            }
233            
234            
235            /** 
236             * Serialises the error object to a JSON string.
237             *
238             * @return A JSON-encoded string representing this error object.
239             */
240            @Override
241            public String toString() {
242                    
243                    return toJSON().toString();
244            }
245            
246            
247            /**
248             * Overrides {@code Object.equals()}.
249             *
250             * @param object The object to compare to.
251             *
252             * @return {@code true} if both objects are instances if this class and
253             *         their error codes are identical, {@code false} if not.
254             */
255            @Override
256            public boolean equals(Object object) {
257            
258                    return object instanceof JSONRPC2Error && code == ((JSONRPC2Error)object).getCode();
259            }
260    }