Formatted .java files.
This commit is contained in:
@ -57,114 +57,114 @@ import org.json.simple.JSONObject;
|
||||
public class JSONRPC2Error extends Exception {
|
||||
|
||||
|
||||
/** JSON parse error (-32700) */
|
||||
public static final JSONRPC2Error PARSE_ERROR = new JSONRPC2Error(-32700, "JSON parse error");
|
||||
/** JSON parse error (-32700) */
|
||||
public static final JSONRPC2Error PARSE_ERROR = new JSONRPC2Error(-32700, "JSON parse error");
|
||||
|
||||
|
||||
/** Invalid JSON-RPC 2.0 request error (-32600) */
|
||||
public static final JSONRPC2Error INVALID_REQUEST = new JSONRPC2Error(-32600, "Invalid request");
|
||||
/** Invalid JSON-RPC 2.0 request error (-32600) */
|
||||
public static final JSONRPC2Error INVALID_REQUEST = new JSONRPC2Error(-32600, "Invalid request");
|
||||
|
||||
|
||||
/** Method not found error (-32601) */
|
||||
public static final JSONRPC2Error METHOD_NOT_FOUND = new JSONRPC2Error(-32601, "Method not found");
|
||||
/** Method not found error (-32601) */
|
||||
public static final JSONRPC2Error METHOD_NOT_FOUND = new JSONRPC2Error(-32601, "Method not found");
|
||||
|
||||
|
||||
/** Invalid parameters error (-32602) */
|
||||
public static final JSONRPC2Error INVALID_PARAMS = new JSONRPC2Error(-32602, "Invalid parameters");
|
||||
/** Invalid parameters error (-32602) */
|
||||
public static final JSONRPC2Error INVALID_PARAMS = new JSONRPC2Error(-32602, "Invalid parameters");
|
||||
|
||||
|
||||
/** Internal JSON-RPC 2.0 error (-32603) */
|
||||
public static final JSONRPC2Error INTERNAL_ERROR = new JSONRPC2Error(-32603, "Internal error");
|
||||
/** Internal JSON-RPC 2.0 error (-32603) */
|
||||
public static final JSONRPC2Error INTERNAL_ERROR = new JSONRPC2Error(-32603, "Internal error");
|
||||
|
||||
|
||||
/** The error code */
|
||||
protected int code;
|
||||
/** The error code */
|
||||
protected int code;
|
||||
|
||||
|
||||
/** The optional error data */
|
||||
protected Object data;
|
||||
/** The optional error data */
|
||||
protected Object data;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 error with the specified code and
|
||||
* message. The optional data is omitted.
|
||||
*
|
||||
* @param code The error code (standard pre-defined or
|
||||
* application-specific).
|
||||
* @param message The error message.
|
||||
*/
|
||||
public JSONRPC2Error(int code, String message) {
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 error with the specified code and
|
||||
* message. The optional data is omitted.
|
||||
*
|
||||
* @param code The error code (standard pre-defined or
|
||||
* application-specific).
|
||||
* @param message The error message.
|
||||
*/
|
||||
public JSONRPC2Error(int code, String message) {
|
||||
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 error with the specified code,
|
||||
* message and data.
|
||||
*
|
||||
* @param code The error code (standard pre-defined or
|
||||
* application-specific).
|
||||
* @param message The error message.
|
||||
* @param data Optional error data, must <a href="#map">map</a>
|
||||
* to a valid JSON type.
|
||||
*/
|
||||
public JSONRPC2Error(int code, String message, Object data) {
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 error with the specified code,
|
||||
* message and data.
|
||||
*
|
||||
* @param code The error code (standard pre-defined or
|
||||
* application-specific).
|
||||
* @param message The error message.
|
||||
* @param data Optional error data, must <a href="#map">map</a>
|
||||
* to a valid JSON type.
|
||||
*/
|
||||
public JSONRPC2Error(int code, String message, Object data) {
|
||||
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.data = data;
|
||||
}
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the JSON-RPC 2.0 error code.
|
||||
*
|
||||
* @return The error code.
|
||||
*/
|
||||
public int getCode() {
|
||||
/**
|
||||
* Gets the JSON-RPC 2.0 error code.
|
||||
*
|
||||
* @return The error code.
|
||||
*/
|
||||
public int getCode() {
|
||||
|
||||
return code;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the JSON-RPC 2.0 error data.
|
||||
*
|
||||
* @return The error data, {@code null} if none was specified.
|
||||
*/
|
||||
public Object getData() {
|
||||
/**
|
||||
* Gets the JSON-RPC 2.0 error data.
|
||||
*
|
||||
* @return The error data, {@code null} if none was specified.
|
||||
*/
|
||||
public Object getData() {
|
||||
|
||||
return data;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a JSON representation of the JSON-RPC 2.0 error.
|
||||
*
|
||||
* @return A JSON object representing this error object.
|
||||
*/
|
||||
public JSONObject toJSON() {
|
||||
/**
|
||||
* Gets a JSON representation of the JSON-RPC 2.0 error.
|
||||
*
|
||||
* @return A JSON object representing this error object.
|
||||
*/
|
||||
public JSONObject toJSON() {
|
||||
|
||||
JSONObject out = new JSONObject();
|
||||
JSONObject out = new JSONObject();
|
||||
|
||||
out.put("code", code);
|
||||
out.put("message", super.getMessage());
|
||||
if (data != null)
|
||||
out.put("data", data);
|
||||
out.put("code", code);
|
||||
out.put("message", super.getMessage());
|
||||
if (data != null)
|
||||
out.put("data", data);
|
||||
|
||||
return out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serialises the error object to a JSON string.
|
||||
*
|
||||
* @return A JSON-encoded string representing this error object.
|
||||
*/
|
||||
public String toString() {
|
||||
/**
|
||||
* Serialises the error object to a JSON string.
|
||||
*
|
||||
* @return A JSON-encoded string representing this error object.
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
return toJSON().toString();
|
||||
}
|
||||
return toJSON().toString();
|
||||
}
|
||||
}
|
||||
|
@ -55,92 +55,92 @@ import org.json.simple.JSONObject;
|
||||
public abstract class JSONRPC2Message {
|
||||
|
||||
|
||||
/**
|
||||
* Provides common parsing of JSON-RPC 2.0 requests, notifications
|
||||
* and responses. Use this method if you don't know which type of
|
||||
* JSON-RPC message the input string represents.
|
||||
*
|
||||
* <p>This method is thread-safe. Batched requests / notifications
|
||||
* are not supported.
|
||||
*
|
||||
* <p>If you are certain about the message type use the dedicated
|
||||
* {@link JSONRPC2Request#parse}, {@link JSONRPC2Notification#parse}
|
||||
* and {@link JSONRPC2Response#parse} methods. They are more efficient
|
||||
* and would provide you with more detailed parse error reporting.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the optional {@link
|
||||
* #parse(String,boolean,boolean)} method.
|
||||
*
|
||||
* @param jsonString A JSON string representing a JSON-RPC 2.0 request,
|
||||
* notification or response, UTF-8 encoded.
|
||||
*
|
||||
* @return An instance of {@link JSONRPC2Request},
|
||||
* {@link JSONRPC2Notification} or {@link JSONRPC2Response}.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Message parse(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
/**
|
||||
* Provides common parsing of JSON-RPC 2.0 requests, notifications
|
||||
* and responses. Use this method if you don't know which type of
|
||||
* JSON-RPC message the input string represents.
|
||||
*
|
||||
* <p>This method is thread-safe. Batched requests / notifications
|
||||
* are not supported.
|
||||
*
|
||||
* <p>If you are certain about the message type use the dedicated
|
||||
* {@link JSONRPC2Request#parse}, {@link JSONRPC2Notification#parse}
|
||||
* and {@link JSONRPC2Response#parse} methods. They are more efficient
|
||||
* and would provide you with more detailed parse error reporting.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the optional {@link
|
||||
* #parse(String,boolean,boolean)} method.
|
||||
*
|
||||
* @param jsonString A JSON string representing a JSON-RPC 2.0 request,
|
||||
* notification or response, UTF-8 encoded.
|
||||
*
|
||||
* @return An instance of {@link JSONRPC2Request},
|
||||
* {@link JSONRPC2Notification} or {@link JSONRPC2Response}.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Message parse(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
return parse(jsonString, false, false);
|
||||
}
|
||||
return parse(jsonString, false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides common parsing of JSON-RPC 2.0 requests, notifications
|
||||
* and responses. Use this method if you don't know which type of
|
||||
* JSON-RPC message the input string represents.
|
||||
*
|
||||
* <p>This method is thread-safe. Batched requests / notifications
|
||||
* are not supported.
|
||||
*
|
||||
* <p>If you are certain about the message type use the dedicated
|
||||
* {@link JSONRPC2Request#parse}, {@link JSONRPC2Notification#parse}
|
||||
* and {@link JSONRPC2Response#parse} methods. They are more efficient
|
||||
* and would provide you with more detailed parse error reporting.
|
||||
*
|
||||
* @param jsonString A JSON string representing a JSON-RPC 2.0
|
||||
* request, notification or response, UTF-8
|
||||
* encoded.
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in parameters and results will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*
|
||||
* @return An instance of {@link JSONRPC2Request},
|
||||
* {@link JSONRPC2Notification} or {@link JSONRPC2Response}.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Message parse(final String jsonString, final boolean preserveOrder, final boolean noStrict)
|
||||
throws JSONRPC2ParseException {
|
||||
/**
|
||||
* Provides common parsing of JSON-RPC 2.0 requests, notifications
|
||||
* and responses. Use this method if you don't know which type of
|
||||
* JSON-RPC message the input string represents.
|
||||
*
|
||||
* <p>This method is thread-safe. Batched requests / notifications
|
||||
* are not supported.
|
||||
*
|
||||
* <p>If you are certain about the message type use the dedicated
|
||||
* {@link JSONRPC2Request#parse}, {@link JSONRPC2Notification#parse}
|
||||
* and {@link JSONRPC2Response#parse} methods. They are more efficient
|
||||
* and would provide you with more detailed parse error reporting.
|
||||
*
|
||||
* @param jsonString A JSON string representing a JSON-RPC 2.0
|
||||
* request, notification or response, UTF-8
|
||||
* encoded.
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in parameters and results will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*
|
||||
* @return An instance of {@link JSONRPC2Request},
|
||||
* {@link JSONRPC2Notification} or {@link JSONRPC2Response}.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Message parse(final String jsonString, final boolean preserveOrder, final boolean noStrict)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
JSONRPC2Parser parser = new JSONRPC2Parser(preserveOrder, noStrict);
|
||||
JSONRPC2Parser parser = new JSONRPC2Parser(preserveOrder, noStrict);
|
||||
|
||||
return parser.parseJSONRPC2Message(jsonString);
|
||||
}
|
||||
return parser.parseJSONRPC2Message(jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a JSON object representing this message.
|
||||
*
|
||||
* @return A JSON object.
|
||||
*/
|
||||
public abstract JSONObject toJSON();
|
||||
/**
|
||||
* Gets a JSON object representing this message.
|
||||
*
|
||||
* @return A JSON object.
|
||||
*/
|
||||
public abstract JSONObject toJSON();
|
||||
|
||||
|
||||
/**
|
||||
* Serialises this message to a JSON string.
|
||||
*
|
||||
* @return A JSON-RPC 2.0 encoded string.
|
||||
*/
|
||||
public String toString() {
|
||||
/**
|
||||
* Serialises this message to a JSON string.
|
||||
*
|
||||
* @return A JSON-RPC 2.0 encoded string.
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
return toJSON().toString();
|
||||
}
|
||||
return toJSON().toString();
|
||||
}
|
||||
}
|
||||
|
@ -87,208 +87,208 @@ import java.util.Map;
|
||||
public class JSONRPC2Notification extends JSONRPC2Message {
|
||||
|
||||
|
||||
/**
|
||||
* The requested method name.
|
||||
*/
|
||||
private String method;
|
||||
/**
|
||||
* The requested method name.
|
||||
*/
|
||||
private String method;
|
||||
|
||||
|
||||
/**
|
||||
* The notification parameters.
|
||||
*/
|
||||
private Object params;
|
||||
/**
|
||||
* The notification parameters.
|
||||
*/
|
||||
private Object params;
|
||||
|
||||
|
||||
/**
|
||||
* The parameters type constant.
|
||||
*/
|
||||
private JSONRPC2ParamsType paramsType;
|
||||
/**
|
||||
* The parameters type constant.
|
||||
*/
|
||||
private JSONRPC2ParamsType paramsType;
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 notification string. This method is
|
||||
* thread-safe.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the optional {@link
|
||||
* #parse(String,boolean,boolean)} method.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 notification string, UTF-8
|
||||
* encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 notification object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Notification parse(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 notification string. This method is
|
||||
* thread-safe.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the optional {@link
|
||||
* #parse(String,boolean,boolean)} method.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 notification string, UTF-8
|
||||
* encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 notification object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Notification parse(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
return parse(jsonString, false, false);
|
||||
}
|
||||
return parse(jsonString, false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 notification string. This method is
|
||||
* thread-safe.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 notification string, UTF-8
|
||||
* encoded.
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in parameters will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 notification object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Notification parse(final String jsonString, final boolean preserveOrder, final boolean noStrict)
|
||||
throws JSONRPC2ParseException {
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 notification string. This method is
|
||||
* thread-safe.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 notification string, UTF-8
|
||||
* encoded.
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in parameters will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 notification object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Notification parse(final String jsonString, final boolean preserveOrder, final boolean noStrict)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
JSONRPC2Parser parser = new JSONRPC2Parser(preserveOrder, noStrict);
|
||||
JSONRPC2Parser parser = new JSONRPC2Parser(preserveOrder, noStrict);
|
||||
|
||||
return parser.parseJSONRPC2Notification(jsonString);
|
||||
}
|
||||
return parser.parseJSONRPC2Notification(jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 notification with no parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
*/
|
||||
public JSONRPC2Notification(final String method) {
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 notification with no parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
*/
|
||||
public JSONRPC2Notification(final String method) {
|
||||
|
||||
setMethod(method);
|
||||
setParams(null);
|
||||
}
|
||||
setMethod(method);
|
||||
setParams(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 notification with JSON array
|
||||
* parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param params The notification parameters packed as a JSON array
|
||||
* (<a href="#map">maps</a> to java.util.List).
|
||||
*/
|
||||
public JSONRPC2Notification(final String method, final List params) {
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 notification with JSON array
|
||||
* parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param params The notification parameters packed as a JSON array
|
||||
* (<a href="#map">maps</a> to java.util.List).
|
||||
*/
|
||||
public JSONRPC2Notification(final String method, final List params) {
|
||||
|
||||
setMethod(method);
|
||||
setParams(params);
|
||||
}
|
||||
setMethod(method);
|
||||
setParams(params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 notification JSON object parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param params The notification parameters packed as a JSON object
|
||||
* (<a href="#map">maps</a> to java.util.Map).
|
||||
*/
|
||||
public JSONRPC2Notification(final String method, final Map params) {
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 notification JSON object parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param params The notification parameters packed as a JSON object
|
||||
* (<a href="#map">maps</a> to java.util.Map).
|
||||
*/
|
||||
public JSONRPC2Notification(final String method, final Map params) {
|
||||
|
||||
setMethod(method);
|
||||
setParams(params);
|
||||
}
|
||||
setMethod(method);
|
||||
setParams(params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the name of the requested method.
|
||||
*
|
||||
* @return The method name.
|
||||
*/
|
||||
public String getMethod() {
|
||||
/**
|
||||
* Gets the name of the requested method.
|
||||
*
|
||||
* @return The method name.
|
||||
*/
|
||||
public String getMethod() {
|
||||
|
||||
return method;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the name of the requested method.
|
||||
*
|
||||
* @param method The method name.
|
||||
*/
|
||||
public void setMethod(final String method) {
|
||||
/**
|
||||
* Sets the name of the requested method.
|
||||
*
|
||||
* @param method The method name.
|
||||
*/
|
||||
public void setMethod(final String method) {
|
||||
|
||||
// The method name is mandatory
|
||||
if (method == null)
|
||||
throw new NullPointerException();
|
||||
// The method name is mandatory
|
||||
if (method == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
this.method = method;
|
||||
}
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the parameters type ({@link JSONRPC2ParamsType#ARRAY},
|
||||
* {@link JSONRPC2ParamsType#OBJECT} or
|
||||
* {@link JSONRPC2ParamsType#NO_PARAMS}).
|
||||
*
|
||||
* @return The parameters type.
|
||||
*/
|
||||
public JSONRPC2ParamsType getParamsType() {
|
||||
/**
|
||||
* Gets the parameters type ({@link JSONRPC2ParamsType#ARRAY},
|
||||
* {@link JSONRPC2ParamsType#OBJECT} or
|
||||
* {@link JSONRPC2ParamsType#NO_PARAMS}).
|
||||
*
|
||||
* @return The parameters type.
|
||||
*/
|
||||
public JSONRPC2ParamsType getParamsType() {
|
||||
|
||||
return paramsType;
|
||||
}
|
||||
return paramsType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the notification parameters.
|
||||
*
|
||||
* @return The parameters as {@code List} if JSON array, {@code Map}
|
||||
* if JSON object, or {@code null} if none.
|
||||
*/
|
||||
public Object getParams() {
|
||||
/**
|
||||
* Gets the notification parameters.
|
||||
*
|
||||
* @return The parameters as {@code List} if JSON array, {@code Map}
|
||||
* if JSON object, or {@code null} if none.
|
||||
*/
|
||||
public Object getParams() {
|
||||
|
||||
return params;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the notification parameters.
|
||||
*
|
||||
* @param params The parameters. For a JSON array type pass a
|
||||
* {@code List}. For a JSON object pass a {@code Map}.
|
||||
* If there are no parameters pass {@code null}.
|
||||
*/
|
||||
public void setParams(final Object params) {
|
||||
/**
|
||||
* Sets the notification parameters.
|
||||
*
|
||||
* @param params The parameters. For a JSON array type pass a
|
||||
* {@code List}. For a JSON object pass a {@code Map}.
|
||||
* If there are no parameters pass {@code null}.
|
||||
*/
|
||||
public void setParams(final Object params) {
|
||||
|
||||
if (params == null)
|
||||
paramsType = JSONRPC2ParamsType.NO_PARAMS;
|
||||
if (params == null)
|
||||
paramsType = JSONRPC2ParamsType.NO_PARAMS;
|
||||
|
||||
else if (params instanceof List)
|
||||
paramsType = JSONRPC2ParamsType.ARRAY;
|
||||
else if (params instanceof List)
|
||||
paramsType = JSONRPC2ParamsType.ARRAY;
|
||||
|
||||
else if (params instanceof Map)
|
||||
paramsType = JSONRPC2ParamsType.OBJECT;
|
||||
else if (params instanceof Map)
|
||||
paramsType = JSONRPC2ParamsType.OBJECT;
|
||||
|
||||
else
|
||||
throw new IllegalArgumentException("The notification parameters must be of type List, Map or null");
|
||||
else
|
||||
throw new IllegalArgumentException("The notification parameters must be of type List, Map or null");
|
||||
|
||||
this.params = params;
|
||||
}
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a JSON representation of this JSON-RPC 2.0 notification.
|
||||
*
|
||||
* @return A JSON object representing the notification.
|
||||
*/
|
||||
public JSONObject toJSON() {
|
||||
/**
|
||||
* Gets a JSON representation of this JSON-RPC 2.0 notification.
|
||||
*
|
||||
* @return A JSON object representing the notification.
|
||||
*/
|
||||
public JSONObject toJSON() {
|
||||
|
||||
JSONObject notf = new JSONObject();
|
||||
JSONObject notf = new JSONObject();
|
||||
|
||||
notf.put("method", method);
|
||||
notf.put("method", method);
|
||||
|
||||
// the params can be omitted if empty
|
||||
if (params != null && paramsType != JSONRPC2ParamsType.NO_PARAMS)
|
||||
notf.put("params", params);
|
||||
// the params can be omitted if empty
|
||||
if (params != null && paramsType != JSONRPC2ParamsType.NO_PARAMS)
|
||||
notf.put("params", params);
|
||||
|
||||
notf.put("jsonrpc", "2.0");
|
||||
notf.put("jsonrpc", "2.0");
|
||||
|
||||
return notf;
|
||||
}
|
||||
return notf;
|
||||
}
|
||||
}
|
||||
|
@ -21,146 +21,146 @@ package com.thetransactioncompany.jsonrpc2;
|
||||
*/
|
||||
public final class JSONRPC2ParamsType {
|
||||
|
||||
/** The integer value for this parameters type. */
|
||||
private final int intValue;
|
||||
/** The integer value for this parameters type. */
|
||||
private final int intValue;
|
||||
|
||||
|
||||
/** The name to use for this parameters type. */
|
||||
private final String name;
|
||||
/** The name to use for this parameters type. */
|
||||
private final String name;
|
||||
|
||||
|
||||
/**
|
||||
* The integer constant for the "NO_PARAMS" parameters type.
|
||||
*/
|
||||
public static final int NO_PARAMS_CONST = 0;
|
||||
/**
|
||||
* The integer constant for the "NO_PARAMS" parameters type.
|
||||
*/
|
||||
public static final int NO_PARAMS_CONST = 0;
|
||||
|
||||
|
||||
/**
|
||||
* No parameters.
|
||||
*/
|
||||
public static final JSONRPC2ParamsType NO_PARAMS =
|
||||
new JSONRPC2ParamsType("NO_PARAMS", NO_PARAMS_CONST);
|
||||
/**
|
||||
* No parameters.
|
||||
*/
|
||||
public static final JSONRPC2ParamsType NO_PARAMS =
|
||||
new JSONRPC2ParamsType("NO_PARAMS", NO_PARAMS_CONST);
|
||||
|
||||
|
||||
/**
|
||||
* The integer constant for the "ARRAY" parameters type.
|
||||
*/
|
||||
public static final int ARRAY_CONST = 1;
|
||||
/**
|
||||
* The integer constant for the "ARRAY" parameters type.
|
||||
*/
|
||||
public static final int ARRAY_CONST = 1;
|
||||
|
||||
|
||||
/**
|
||||
* The parameters are packed as a JSON array.
|
||||
*/
|
||||
public static final JSONRPC2ParamsType ARRAY =
|
||||
new JSONRPC2ParamsType("ARRAY", ARRAY_CONST);
|
||||
/**
|
||||
* The parameters are packed as a JSON array.
|
||||
*/
|
||||
public static final JSONRPC2ParamsType ARRAY =
|
||||
new JSONRPC2ParamsType("ARRAY", ARRAY_CONST);
|
||||
|
||||
|
||||
/**
|
||||
* The integer constant for the "OBJECT" parameters type.
|
||||
*/
|
||||
public static final int OBJECT_CONST = 2;
|
||||
/**
|
||||
* The integer constant for the "OBJECT" parameters type.
|
||||
*/
|
||||
public static final int OBJECT_CONST = 2;
|
||||
|
||||
|
||||
/**
|
||||
* The parameters are packed as a JSON object.
|
||||
*/
|
||||
public static final JSONRPC2ParamsType OBJECT =
|
||||
new JSONRPC2ParamsType("OBJECT", OBJECT_CONST);
|
||||
/**
|
||||
* The parameters are packed as a JSON object.
|
||||
*/
|
||||
public static final JSONRPC2ParamsType OBJECT =
|
||||
new JSONRPC2ParamsType("OBJECT", OBJECT_CONST);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new parameter type with the specified name and integer
|
||||
* value.
|
||||
*
|
||||
* @param name The name to use for this parameter type.
|
||||
* @param intValue The integer value to use for this parameter type.
|
||||
*/
|
||||
private JSONRPC2ParamsType(final String name, final int intValue) {
|
||||
/**
|
||||
* Creates a new parameter type with the specified name and integer
|
||||
* value.
|
||||
*
|
||||
* @param name The name to use for this parameter type.
|
||||
* @param intValue The integer value to use for this parameter type.
|
||||
*/
|
||||
private JSONRPC2ParamsType(final String name, final int intValue) {
|
||||
|
||||
this.name = name;
|
||||
this.intValue = intValue;
|
||||
}
|
||||
this.name = name;
|
||||
this.intValue = intValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the name for this parameters type.
|
||||
*
|
||||
* @return The parameters type name.
|
||||
*/
|
||||
public String getName() {
|
||||
/**
|
||||
* Retrieves the name for this parameters type.
|
||||
*
|
||||
* @return The parameters type name.
|
||||
*/
|
||||
public String getName() {
|
||||
|
||||
return name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the integer constant for this parameters type.
|
||||
*
|
||||
* @return The parameters integer constant.
|
||||
*/
|
||||
public int intValue() {
|
||||
/**
|
||||
* Retrieves the integer constant for this parameters type.
|
||||
*
|
||||
* @return The parameters integer constant.
|
||||
*/
|
||||
public int intValue() {
|
||||
|
||||
return intValue;
|
||||
}
|
||||
return intValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the parameters type with the specified integer constant.
|
||||
*
|
||||
* @param intValue The integer constant for which to retrieve the
|
||||
* corresponding parameters type.
|
||||
*
|
||||
* @return The parameters type or {@code null} if none matches.
|
||||
*/
|
||||
public static JSONRPC2ParamsType valueOf(final int intValue) {
|
||||
/**
|
||||
* Retrieves the parameters type with the specified integer constant.
|
||||
*
|
||||
* @param intValue The integer constant for which to retrieve the
|
||||
* corresponding parameters type.
|
||||
*
|
||||
* @return The parameters type or {@code null} if none matches.
|
||||
*/
|
||||
public static JSONRPC2ParamsType valueOf(final int intValue) {
|
||||
|
||||
switch (intValue) {
|
||||
switch (intValue) {
|
||||
|
||||
case 0:
|
||||
return NO_PARAMS;
|
||||
case 1:
|
||||
return ARRAY;
|
||||
case 2:
|
||||
return OBJECT;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
case 0:
|
||||
return NO_PARAMS;
|
||||
case 1:
|
||||
return ARRAY;
|
||||
case 2:
|
||||
return OBJECT;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates wheter the provided object is equal to this parameters type.
|
||||
*
|
||||
* @param o The object for which to make the comparison.
|
||||
*
|
||||
* @return {@code true} if the objects are equal, or {@code false} if
|
||||
* not.
|
||||
*/
|
||||
public boolean equals(final Object o) {
|
||||
/**
|
||||
* Indicates wheter the provided object is equal to this parameters type.
|
||||
*
|
||||
* @param o The object for which to make the comparison.
|
||||
*
|
||||
* @return {@code true} if the objects are equal, or {@code false} if
|
||||
* not.
|
||||
*/
|
||||
public boolean equals(final Object o) {
|
||||
|
||||
if (o == null)
|
||||
return false;
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
else if (o == this)
|
||||
return true;
|
||||
else if (o == this)
|
||||
return true;
|
||||
|
||||
else if (o instanceof JSONRPC2ParamsType)
|
||||
return (intValue == ((JSONRPC2ParamsType) o).intValue);
|
||||
else if (o instanceof JSONRPC2ParamsType)
|
||||
return (intValue == ((JSONRPC2ParamsType) o).intValue);
|
||||
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a string representing this parameters type.
|
||||
*
|
||||
* @return A string representing this parameters type.
|
||||
*/
|
||||
public String toString() {
|
||||
/**
|
||||
* Retrieves a string representing this parameters type.
|
||||
*
|
||||
* @return A string representing this parameters type.
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
return name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,98 +14,98 @@ package com.thetransactioncompany.jsonrpc2;
|
||||
public class JSONRPC2ParseException extends Exception {
|
||||
|
||||
|
||||
/**
|
||||
* Indicates a parse exception caused by a JSON message not conforming
|
||||
* to the JSON-RPC 2.0 protocol.
|
||||
*/
|
||||
public static int PROTOCOL = 0;
|
||||
/**
|
||||
* Indicates a parse exception caused by a JSON message not conforming
|
||||
* to the JSON-RPC 2.0 protocol.
|
||||
*/
|
||||
public static int PROTOCOL = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates a parse exception caused by invalid JSON.
|
||||
*/
|
||||
public static int JSON = 1;
|
||||
/**
|
||||
* Indicates a parse exception caused by invalid JSON.
|
||||
*/
|
||||
public static int JSON = 1;
|
||||
|
||||
|
||||
/**
|
||||
* The parse exception cause type. Default is {@link #PROTOCOL}.
|
||||
*/
|
||||
private int causeType = PROTOCOL;
|
||||
/**
|
||||
* The parse exception cause type. Default is {@link #PROTOCOL}.
|
||||
*/
|
||||
private int causeType = PROTOCOL;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The string that could't be parsed.
|
||||
*/
|
||||
private String unparsableString = null;
|
||||
/**
|
||||
* The string that could't be parsed.
|
||||
*/
|
||||
private String unparsableString = null;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new parse exception with the specified message. The cause
|
||||
* type is set to {@link #PROTOCOL}.
|
||||
*
|
||||
* @param message The exception message.
|
||||
*/
|
||||
public JSONRPC2ParseException(final String message) {
|
||||
/**
|
||||
* Creates a new parse exception with the specified message. The cause
|
||||
* type is set to {@link #PROTOCOL}.
|
||||
*
|
||||
* @param message The exception message.
|
||||
*/
|
||||
public JSONRPC2ParseException(final String message) {
|
||||
|
||||
super(message);
|
||||
}
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new parse exception with the specified message and the
|
||||
* original string that didn't parse. The cause type is set to
|
||||
* {@link #PROTOCOL}.
|
||||
*
|
||||
* @param message The exception message.
|
||||
* @param unparsableString The unparsable string.
|
||||
*/
|
||||
public JSONRPC2ParseException(final String message, final String unparsableString) {
|
||||
/**
|
||||
* Creates a new parse exception with the specified message and the
|
||||
* original string that didn't parse. The cause type is set to
|
||||
* {@link #PROTOCOL}.
|
||||
*
|
||||
* @param message The exception message.
|
||||
* @param unparsableString The unparsable string.
|
||||
*/
|
||||
public JSONRPC2ParseException(final String message, final String unparsableString) {
|
||||
|
||||
super(message);
|
||||
this.unparsableString = unparsableString;
|
||||
}
|
||||
super(message);
|
||||
this.unparsableString = unparsableString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new parse exception with the specified message, cause type
|
||||
* and the original string that didn't parse.
|
||||
*
|
||||
* @param message The exception message.
|
||||
* @param causeType The exception cause type, either
|
||||
* {@link #PROTOCOL} or {@link #JSON}.
|
||||
* @param unparsableString The unparsable string.
|
||||
*/
|
||||
public JSONRPC2ParseException(final String message, final int causeType, final String unparsableString) {
|
||||
/**
|
||||
* Creates a new parse exception with the specified message, cause type
|
||||
* and the original string that didn't parse.
|
||||
*
|
||||
* @param message The exception message.
|
||||
* @param causeType The exception cause type, either
|
||||
* {@link #PROTOCOL} or {@link #JSON}.
|
||||
* @param unparsableString The unparsable string.
|
||||
*/
|
||||
public JSONRPC2ParseException(final String message, final int causeType, final String unparsableString) {
|
||||
|
||||
super(message);
|
||||
super(message);
|
||||
|
||||
if (causeType != PROTOCOL && causeType != JSON)
|
||||
throw new IllegalArgumentException("Cause type must be either PROTOCOL or JSON");
|
||||
if (causeType != PROTOCOL && causeType != JSON)
|
||||
throw new IllegalArgumentException("Cause type must be either PROTOCOL or JSON");
|
||||
|
||||
this.causeType = causeType;
|
||||
this.unparsableString = unparsableString;
|
||||
}
|
||||
this.causeType = causeType;
|
||||
this.unparsableString = unparsableString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the parse exception cause type.
|
||||
*
|
||||
* @return The cause type, either {@link #PROTOCOL} or {@link #JSON}.
|
||||
*/
|
||||
public int getCauseType() {
|
||||
/**
|
||||
* Gets the parse exception cause type.
|
||||
*
|
||||
* @return The cause type, either {@link #PROTOCOL} or {@link #JSON}.
|
||||
*/
|
||||
public int getCauseType() {
|
||||
|
||||
return causeType;
|
||||
}
|
||||
return causeType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets original string that caused the parse exception (if specified).
|
||||
*
|
||||
* @return The string that didn't parse, {@code null} if none.
|
||||
*/
|
||||
public String getUnparsableString() {
|
||||
/**
|
||||
* Gets original string that caused the parse exception (if specified).
|
||||
*
|
||||
* @return The string that didn't parse, {@code null} if none.
|
||||
*/
|
||||
public String getUnparsableString() {
|
||||
|
||||
return unparsableString;
|
||||
}
|
||||
return unparsableString;
|
||||
}
|
||||
}
|
||||
|
@ -61,441 +61,441 @@ import java.util.Map;
|
||||
public class JSONRPC2Parser {
|
||||
|
||||
|
||||
/**
|
||||
* Reusable JSON parser.
|
||||
*/
|
||||
private JSONParser parser;
|
||||
|
||||
|
||||
/**
|
||||
* If {@code true} the order of the parsed JSON object members must be
|
||||
* preserved.
|
||||
*/
|
||||
private boolean preserveOrder;
|
||||
|
||||
|
||||
/**
|
||||
* If {@code true} the {@code "jsonrpc":"2.0"} version field in the
|
||||
* JSON-RPC 2.0 message must not be checked.
|
||||
*/
|
||||
private boolean noStrict;
|
||||
|
||||
|
||||
/**
|
||||
* Special container factory for constructing JSON objects in a way
|
||||
* that preserves their original member order.
|
||||
*/
|
||||
private static final ContainerFactory linkedContainerFactory = new ContainerFactory() {
|
||||
|
||||
// Yes, there is a typo here!
|
||||
public List creatArrayContainer() {
|
||||
return new LinkedList();
|
||||
}
|
||||
|
||||
public Map createObjectContainer() {
|
||||
return new LinkedHashMap();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 message parser.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the {@link
|
||||
* #JSONRPC2Parser(boolean,boolean) alternative constructor}.
|
||||
*/
|
||||
public JSONRPC2Parser() {
|
||||
|
||||
this(false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 message parser.
|
||||
*
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in parameters and results will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*/
|
||||
public JSONRPC2Parser(final boolean preserveOrder, final boolean noStrict) {
|
||||
|
||||
parser = new JSONParser();
|
||||
this.preserveOrder = preserveOrder;
|
||||
this.noStrict = noStrict;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON object string. Provides the initial parsing of JSON-RPC
|
||||
* 2.0 messages. The member order of JSON objects will be preserved if
|
||||
* {@link #preserveOrder} is set to {@code true}.
|
||||
*
|
||||
* @param jsonString The JSON string to parse.
|
||||
*
|
||||
* @return The parsed JSON object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if parsing
|
||||
* failed.
|
||||
*/
|
||||
private Map parseJSONObject(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
if (jsonString == null)
|
||||
throw new JSONRPC2ParseException("Null argument", JSONRPC2ParseException.JSON, null);
|
||||
|
||||
if (jsonString.trim().isEmpty())
|
||||
throw new JSONRPC2ParseException("Invalid JSON: Empty string", JSONRPC2ParseException.JSON, jsonString);
|
||||
|
||||
Object json;
|
||||
|
||||
// Parse the JSON string
|
||||
try {
|
||||
if (preserveOrder)
|
||||
json = parser.parse(jsonString, linkedContainerFactory);
|
||||
else
|
||||
json = parser.parse(jsonString);
|
||||
|
||||
} catch (ParseException e) {
|
||||
// JSON.simple provides no error message
|
||||
throw new JSONRPC2ParseException("Invalid JSON", JSONRPC2ParseException.JSON, jsonString);
|
||||
}
|
||||
|
||||
if (json instanceof List)
|
||||
throw new JSONRPC2ParseException("JSON-RPC 2.0 batch requests/notifications not supported", jsonString);
|
||||
|
||||
if (! (json instanceof Map))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 message: Message must be a JSON object", jsonString);
|
||||
|
||||
return (Map)json;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensures the specified parameter is a {@code String} object set to
|
||||
* "2.0". This method is intended to check the "jsonrpc" field during
|
||||
* parsing of JSON-RPC messages.
|
||||
*
|
||||
* @param version The version parameter.
|
||||
* @param jsonString The original JSON string.
|
||||
*
|
||||
* @throws JSONRPC2Exception If the parameter is not a string matching
|
||||
* "2.0".
|
||||
*/
|
||||
private static void ensureVersion2(final Object version, final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
if (version == null)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0: Version string missing", jsonString);
|
||||
|
||||
else if (! (version instanceof String))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0: Version not a JSON string", jsonString);
|
||||
|
||||
else if (! version.equals("2.0"))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0: Version must be \"2.0\"", jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides common parsing of JSON-RPC 2.0 requests, notifications
|
||||
* and responses. Use this method if you don't know which type of
|
||||
* JSON-RPC message the input string represents.
|
||||
*
|
||||
* <p>If you are certain about the message type use the dedicated
|
||||
* {@link #parseJSONRPC2Request}, {@link #parseJSONRPC2Notification}
|
||||
* and {@link #parseJSONRPC2Response} methods. They are more efficient
|
||||
* and would provide you with more detailed parse error reporting.
|
||||
*
|
||||
* @param jsonString A JSON string representing a JSON-RPC 2.0 request,
|
||||
* notification or response, UTF-8 encoded.
|
||||
*
|
||||
* @return An instance of {@link JSONRPC2Request},
|
||||
* {@link JSONRPC2Notification} or {@link JSONRPC2Response}.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public JSONRPC2Message parseJSONRPC2Message(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
// Try each of the parsers until one succeeds (or all fail)
|
||||
try {
|
||||
return parseJSONRPC2Request(jsonString);
|
||||
|
||||
} catch (JSONRPC2ParseException e) {
|
||||
|
||||
// throw on JSON error, ignore on protocol error
|
||||
if (e.getCauseType() == JSONRPC2ParseException.JSON)
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
return parseJSONRPC2Notification(jsonString);
|
||||
|
||||
} catch (JSONRPC2ParseException e) {
|
||||
|
||||
// throw on JSON error, ignore on protocol error
|
||||
if (e.getCauseType() == JSONRPC2ParseException.JSON)
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
return parseJSONRPC2Response(jsonString);
|
||||
|
||||
} catch (JSONRPC2ParseException e) {
|
||||
|
||||
// throw on JSON error, ignore on protocol error
|
||||
if (e.getCauseType() == JSONRPC2ParseException.JSON)
|
||||
throw e;
|
||||
}
|
||||
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 message", JSONRPC2ParseException.PROTOCOL, jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 request string.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 request string, UTF-8 encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 request object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public JSONRPC2Request parseJSONRPC2Request(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
// Initial JSON object parsing
|
||||
Map json = parseJSONObject(jsonString);
|
||||
|
||||
|
||||
// Check for JSON-RPC version "2.0"
|
||||
if (! noStrict) {
|
||||
Object version = json.get("jsonrpc");
|
||||
ensureVersion2(version, jsonString);
|
||||
}
|
||||
|
||||
|
||||
// Extract method name
|
||||
Object method = json.get("method");
|
||||
|
||||
if (method == null)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Method name missing", jsonString);
|
||||
else if (! (method instanceof String))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Method name not a JSON string", jsonString);
|
||||
else if (((String)method).length() == 0)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Method name is an empty string", jsonString);
|
||||
|
||||
|
||||
// Extract ID
|
||||
if (! json.containsKey("id"))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Missing identifier", jsonString);
|
||||
|
||||
Object id = json.get("id");
|
||||
|
||||
if ( id != null &&
|
||||
!(id instanceof Number ) &&
|
||||
!(id instanceof Boolean) &&
|
||||
!(id instanceof String ) )
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Identifier not a JSON scalar", jsonString);
|
||||
|
||||
|
||||
// Extract params
|
||||
Object params = json.get("params");
|
||||
|
||||
if (params == null)
|
||||
return new JSONRPC2Request((String)method, id);
|
||||
else if (params instanceof List)
|
||||
return new JSONRPC2Request((String)method, (List)params, id);
|
||||
else if (params instanceof Map)
|
||||
return new JSONRPC2Request((String)method, (Map)params, id);
|
||||
else
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Method parameters have unexpected JSON type", jsonString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable JSON parser.
|
||||
*/
|
||||
private JSONParser parser;
|
||||
|
||||
|
||||
/**
|
||||
* If {@code true} the order of the parsed JSON object members must be
|
||||
* preserved.
|
||||
*/
|
||||
private boolean preserveOrder;
|
||||
|
||||
|
||||
/**
|
||||
* If {@code true} the {@code "jsonrpc":"2.0"} version field in the
|
||||
* JSON-RPC 2.0 message must not be checked.
|
||||
*/
|
||||
private boolean noStrict;
|
||||
|
||||
|
||||
/**
|
||||
* Special container factory for constructing JSON objects in a way
|
||||
* that preserves their original member order.
|
||||
*/
|
||||
private static final ContainerFactory linkedContainerFactory = new ContainerFactory() {
|
||||
|
||||
// Yes, there is a typo here!
|
||||
public List creatArrayContainer() {
|
||||
return new LinkedList();
|
||||
}
|
||||
|
||||
public Map createObjectContainer() {
|
||||
return new LinkedHashMap();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 message parser.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the {@link
|
||||
* #JSONRPC2Parser(boolean,boolean) alternative constructor}.
|
||||
*/
|
||||
public JSONRPC2Parser() {
|
||||
|
||||
this(false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 message parser.
|
||||
*
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in parameters and results will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*/
|
||||
public JSONRPC2Parser(final boolean preserveOrder, final boolean noStrict) {
|
||||
|
||||
parser = new JSONParser();
|
||||
this.preserveOrder = preserveOrder;
|
||||
this.noStrict = noStrict;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON object string. Provides the initial parsing of JSON-RPC
|
||||
* 2.0 messages. The member order of JSON objects will be preserved if
|
||||
* {@link #preserveOrder} is set to {@code true}.
|
||||
*
|
||||
* @param jsonString The JSON string to parse.
|
||||
*
|
||||
* @return The parsed JSON object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if parsing
|
||||
* failed.
|
||||
*/
|
||||
private Map parseJSONObject(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
if (jsonString == null)
|
||||
throw new JSONRPC2ParseException("Null argument", JSONRPC2ParseException.JSON, null);
|
||||
|
||||
if (jsonString.trim().isEmpty())
|
||||
throw new JSONRPC2ParseException("Invalid JSON: Empty string", JSONRPC2ParseException.JSON, jsonString);
|
||||
|
||||
Object json;
|
||||
|
||||
// Parse the JSON string
|
||||
try {
|
||||
if (preserveOrder)
|
||||
json = parser.parse(jsonString, linkedContainerFactory);
|
||||
else
|
||||
json = parser.parse(jsonString);
|
||||
|
||||
} catch (ParseException e) {
|
||||
// JSON.simple provides no error message
|
||||
throw new JSONRPC2ParseException("Invalid JSON", JSONRPC2ParseException.JSON, jsonString);
|
||||
}
|
||||
|
||||
if (json instanceof List)
|
||||
throw new JSONRPC2ParseException("JSON-RPC 2.0 batch requests/notifications not supported", jsonString);
|
||||
|
||||
if (!(json instanceof Map))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 message: Message must be a JSON object", jsonString);
|
||||
|
||||
return (Map)json;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensures the specified parameter is a {@code String} object set to
|
||||
* "2.0". This method is intended to check the "jsonrpc" field during
|
||||
* parsing of JSON-RPC messages.
|
||||
*
|
||||
* @param version The version parameter.
|
||||
* @param jsonString The original JSON string.
|
||||
*
|
||||
* @throws JSONRPC2Exception If the parameter is not a string matching
|
||||
* "2.0".
|
||||
*/
|
||||
private static void ensureVersion2(final Object version, final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
if (version == null)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0: Version string missing", jsonString);
|
||||
|
||||
else if (!(version instanceof String))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0: Version not a JSON string", jsonString);
|
||||
|
||||
else if (! version.equals("2.0"))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0: Version must be \"2.0\"", jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides common parsing of JSON-RPC 2.0 requests, notifications
|
||||
* and responses. Use this method if you don't know which type of
|
||||
* JSON-RPC message the input string represents.
|
||||
*
|
||||
* <p>If you are certain about the message type use the dedicated
|
||||
* {@link #parseJSONRPC2Request}, {@link #parseJSONRPC2Notification}
|
||||
* and {@link #parseJSONRPC2Response} methods. They are more efficient
|
||||
* and would provide you with more detailed parse error reporting.
|
||||
*
|
||||
* @param jsonString A JSON string representing a JSON-RPC 2.0 request,
|
||||
* notification or response, UTF-8 encoded.
|
||||
*
|
||||
* @return An instance of {@link JSONRPC2Request},
|
||||
* {@link JSONRPC2Notification} or {@link JSONRPC2Response}.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public JSONRPC2Message parseJSONRPC2Message(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
// Try each of the parsers until one succeeds (or all fail)
|
||||
try {
|
||||
return parseJSONRPC2Request(jsonString);
|
||||
|
||||
} catch (JSONRPC2ParseException e) {
|
||||
|
||||
// throw on JSON error, ignore on protocol error
|
||||
if (e.getCauseType() == JSONRPC2ParseException.JSON)
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
return parseJSONRPC2Notification(jsonString);
|
||||
|
||||
} catch (JSONRPC2ParseException e) {
|
||||
|
||||
// throw on JSON error, ignore on protocol error
|
||||
if (e.getCauseType() == JSONRPC2ParseException.JSON)
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
return parseJSONRPC2Response(jsonString);
|
||||
|
||||
} catch (JSONRPC2ParseException e) {
|
||||
|
||||
// throw on JSON error, ignore on protocol error
|
||||
if (e.getCauseType() == JSONRPC2ParseException.JSON)
|
||||
throw e;
|
||||
}
|
||||
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 message", JSONRPC2ParseException.PROTOCOL, jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 request string.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 request string, UTF-8 encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 request object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public JSONRPC2Request parseJSONRPC2Request(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
// Initial JSON object parsing
|
||||
Map json = parseJSONObject(jsonString);
|
||||
|
||||
|
||||
// Check for JSON-RPC version "2.0"
|
||||
if (! noStrict) {
|
||||
Object version = json.get("jsonrpc");
|
||||
ensureVersion2(version, jsonString);
|
||||
}
|
||||
|
||||
|
||||
// Extract method name
|
||||
Object method = json.get("method");
|
||||
|
||||
if (method == null)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Method name missing", jsonString);
|
||||
else if (!(method instanceof String))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Method name not a JSON string", jsonString);
|
||||
else if (((String)method).length() == 0)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Method name is an empty string", jsonString);
|
||||
|
||||
|
||||
// Extract ID
|
||||
if (! json.containsKey("id"))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Missing identifier", jsonString);
|
||||
|
||||
Object id = json.get("id");
|
||||
|
||||
if (id != null &&
|
||||
!(id instanceof Number) &&
|
||||
!(id instanceof Boolean) &&
|
||||
!(id instanceof String))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Identifier not a JSON scalar", jsonString);
|
||||
|
||||
|
||||
// Extract params
|
||||
Object params = json.get("params");
|
||||
|
||||
if (params == null)
|
||||
return new JSONRPC2Request((String)method, id);
|
||||
else if (params instanceof List)
|
||||
return new JSONRPC2Request((String)method, (List)params, id);
|
||||
else if (params instanceof Map)
|
||||
return new JSONRPC2Request((String)method, (Map)params, id);
|
||||
else
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 request: Method parameters have unexpected JSON type", jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 notification string.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 notification string, UTF-8
|
||||
* encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 notification object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public JSONRPC2Notification parseJSONRPC2Notification(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
// Initial JSON object parsing
|
||||
Map json = parseJSONObject(jsonString);
|
||||
|
||||
|
||||
// Check for JSON-RPC version "2.0"
|
||||
if (! noStrict) {
|
||||
Object version = json.get("jsonrpc");
|
||||
ensureVersion2(version, jsonString);
|
||||
}
|
||||
|
||||
|
||||
// Extract method name
|
||||
Object method = json.get("method");
|
||||
|
||||
if (method == null)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 notification: Method name missing", jsonString);
|
||||
else if (! (method instanceof String))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 notification: Method name not a JSON string", jsonString);
|
||||
else if (((String)method).length() == 0)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 notification: Method name is an empty string", jsonString);
|
||||
|
||||
|
||||
// Extract params
|
||||
Object params = json.get("params");
|
||||
|
||||
if (params == null)
|
||||
return new JSONRPC2Notification((String)method);
|
||||
else if (params instanceof List)
|
||||
return new JSONRPC2Notification((String)method, (List)params);
|
||||
else if (params instanceof Map)
|
||||
return new JSONRPC2Notification((String)method, (Map)params);
|
||||
else
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 notification: Method parameters have unexpected JSON type", jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 response string.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 response string, UTF-8 encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 response object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public JSONRPC2Response parseJSONRPC2Response(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
// Initial JSON object parsing
|
||||
Map json = parseJSONObject(jsonString);
|
||||
|
||||
// Check for JSON-RPC version "2.0"
|
||||
if (! noStrict) {
|
||||
Object version = json.get("jsonrpc");
|
||||
ensureVersion2(version, jsonString);
|
||||
}
|
||||
|
||||
// Extract request ID
|
||||
Object id = json.get("id");
|
||||
|
||||
if ( id != null &&
|
||||
! (id instanceof Boolean) &&
|
||||
! (id instanceof Number ) &&
|
||||
! (id instanceof String ) )
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Identifier not a JSON scalar", jsonString);
|
||||
|
||||
|
||||
// Extract result/error and create response object
|
||||
// Note: result and error are mutually exclusive
|
||||
if (json.containsKey("result") && ! json.containsKey("error")) {
|
||||
|
||||
// Success
|
||||
Object res = json.get("result");
|
||||
|
||||
return new JSONRPC2Response(res, id);
|
||||
|
||||
}
|
||||
else if (! json.containsKey("result") && json.containsKey("error")) {
|
||||
|
||||
// Error
|
||||
Map errorJSON = (Map)json.get("error");
|
||||
|
||||
if (errorJSON == null)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Missing error object", jsonString);
|
||||
|
||||
int errorCode;
|
||||
try {
|
||||
errorCode = ((Long)errorJSON.get("code")).intValue();
|
||||
} catch (Exception e) {
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Error code missing or not an integer", jsonString);
|
||||
}
|
||||
|
||||
String errorMessage = null;
|
||||
try {
|
||||
errorMessage = (String)errorJSON.get("message");
|
||||
} catch (Exception e) {
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Error message missing or not a string", jsonString);
|
||||
}
|
||||
|
||||
Object errorData = errorJSON.get("data");
|
||||
|
||||
return new JSONRPC2Response(new JSONRPC2Error(errorCode, errorMessage, errorData), id);
|
||||
|
||||
}
|
||||
else if (json.containsKey("result") && json.containsKey("error")) {
|
||||
// Invalid response
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: You cannot have result and error at the same time", jsonString);
|
||||
}
|
||||
else if (! json.containsKey("result") && ! json.containsKey("error")){
|
||||
// Invalid response
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Neither result nor error specified", jsonString);
|
||||
}
|
||||
else {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Controls the preservation of JSON object member order in parsed
|
||||
* JSON-RPC 2.0 messages.
|
||||
*
|
||||
* @param preserveOrder {@code true} to preserve JSON object member,
|
||||
* else {@code false}.
|
||||
*/
|
||||
public void preserveOrder(final boolean preserveOrder) {
|
||||
|
||||
this.preserveOrder = preserveOrder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the order of JSON object members in parsed
|
||||
* JSON-RPC 2.0 messages is preserved, else {@code false}.
|
||||
*
|
||||
* @return {@code true} if order is preserved, else {@code false}.
|
||||
*/
|
||||
public boolean preservesOrder() {
|
||||
|
||||
return preserveOrder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the strictness of JSON-RPC 2.0 message parsing.
|
||||
*
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"} version
|
||||
* field in parsed JSON-RPC 2.0 messages must be
|
||||
* ignored.
|
||||
*/
|
||||
public void noStrict(final boolean noStrict) {
|
||||
|
||||
this.noStrict = noStrict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the strictness of JSON-RPC 2.0 message parsing.
|
||||
*
|
||||
* @return {@code true} if the {@code "jsonrpc":"2.0"} version field in
|
||||
* parsed JSON-RPC 2.0 messages is ignored, else {@code false}.
|
||||
*/
|
||||
public boolean isNoStrict() {
|
||||
|
||||
return noStrict;
|
||||
}
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 notification string.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 notification string, UTF-8
|
||||
* encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 notification object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public JSONRPC2Notification parseJSONRPC2Notification(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
// Initial JSON object parsing
|
||||
Map json = parseJSONObject(jsonString);
|
||||
|
||||
|
||||
// Check for JSON-RPC version "2.0"
|
||||
if (! noStrict) {
|
||||
Object version = json.get("jsonrpc");
|
||||
ensureVersion2(version, jsonString);
|
||||
}
|
||||
|
||||
|
||||
// Extract method name
|
||||
Object method = json.get("method");
|
||||
|
||||
if (method == null)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 notification: Method name missing", jsonString);
|
||||
else if (!(method instanceof String))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 notification: Method name not a JSON string", jsonString);
|
||||
else if (((String)method).length() == 0)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 notification: Method name is an empty string", jsonString);
|
||||
|
||||
|
||||
// Extract params
|
||||
Object params = json.get("params");
|
||||
|
||||
if (params == null)
|
||||
return new JSONRPC2Notification((String)method);
|
||||
else if (params instanceof List)
|
||||
return new JSONRPC2Notification((String)method, (List)params);
|
||||
else if (params instanceof Map)
|
||||
return new JSONRPC2Notification((String)method, (Map)params);
|
||||
else
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 notification: Method parameters have unexpected JSON type", jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 response string.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 response string, UTF-8 encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 response object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public JSONRPC2Response parseJSONRPC2Response(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
// Initial JSON object parsing
|
||||
Map json = parseJSONObject(jsonString);
|
||||
|
||||
// Check for JSON-RPC version "2.0"
|
||||
if (! noStrict) {
|
||||
Object version = json.get("jsonrpc");
|
||||
ensureVersion2(version, jsonString);
|
||||
}
|
||||
|
||||
// Extract request ID
|
||||
Object id = json.get("id");
|
||||
|
||||
if (id != null &&
|
||||
!(id instanceof Boolean) &&
|
||||
!(id instanceof Number) &&
|
||||
!(id instanceof String))
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Identifier not a JSON scalar", jsonString);
|
||||
|
||||
|
||||
// Extract result/error and create response object
|
||||
// Note: result and error are mutually exclusive
|
||||
if (json.containsKey("result") && ! json.containsKey("error")) {
|
||||
|
||||
// Success
|
||||
Object res = json.get("result");
|
||||
|
||||
return new JSONRPC2Response(res, id);
|
||||
|
||||
}
|
||||
else if (! json.containsKey("result") && json.containsKey("error")) {
|
||||
|
||||
// Error
|
||||
Map errorJSON = (Map)json.get("error");
|
||||
|
||||
if (errorJSON == null)
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Missing error object", jsonString);
|
||||
|
||||
int errorCode;
|
||||
try {
|
||||
errorCode = ((Long)errorJSON.get("code")).intValue();
|
||||
} catch (Exception e) {
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Error code missing or not an integer", jsonString);
|
||||
}
|
||||
|
||||
String errorMessage = null;
|
||||
try {
|
||||
errorMessage = (String)errorJSON.get("message");
|
||||
} catch (Exception e) {
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Error message missing or not a string", jsonString);
|
||||
}
|
||||
|
||||
Object errorData = errorJSON.get("data");
|
||||
|
||||
return new JSONRPC2Response(new JSONRPC2Error(errorCode, errorMessage, errorData), id);
|
||||
|
||||
}
|
||||
else if (json.containsKey("result") && json.containsKey("error")) {
|
||||
// Invalid response
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: You cannot have result and error at the same time", jsonString);
|
||||
}
|
||||
else if (! json.containsKey("result") && ! json.containsKey("error")) {
|
||||
// Invalid response
|
||||
throw new JSONRPC2ParseException("Invalid JSON-RPC 2.0 response: Neither result nor error specified", jsonString);
|
||||
}
|
||||
else {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Controls the preservation of JSON object member order in parsed
|
||||
* JSON-RPC 2.0 messages.
|
||||
*
|
||||
* @param preserveOrder {@code true} to preserve JSON object member,
|
||||
* else {@code false}.
|
||||
*/
|
||||
public void preserveOrder(final boolean preserveOrder) {
|
||||
|
||||
this.preserveOrder = preserveOrder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the order of JSON object members in parsed
|
||||
* JSON-RPC 2.0 messages is preserved, else {@code false}.
|
||||
*
|
||||
* @return {@code true} if order is preserved, else {@code false}.
|
||||
*/
|
||||
public boolean preservesOrder() {
|
||||
|
||||
return preserveOrder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the strictness of JSON-RPC 2.0 message parsing.
|
||||
*
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"} version
|
||||
* field in parsed JSON-RPC 2.0 messages must be
|
||||
* ignored.
|
||||
*/
|
||||
public void noStrict(final boolean noStrict) {
|
||||
|
||||
this.noStrict = noStrict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the strictness of JSON-RPC 2.0 message parsing.
|
||||
*
|
||||
* @return {@code true} if the {@code "jsonrpc":"2.0"} version field in
|
||||
* parsed JSON-RPC 2.0 messages is ignored, else {@code false}.
|
||||
*/
|
||||
public boolean isNoStrict() {
|
||||
|
||||
return noStrict;
|
||||
}
|
||||
}
|
||||
|
@ -90,257 +90,257 @@ import java.util.Map;
|
||||
public class JSONRPC2Request extends JSONRPC2Message {
|
||||
|
||||
|
||||
/**
|
||||
* The requested method name.
|
||||
*/
|
||||
private String method;
|
||||
/**
|
||||
* The requested method name.
|
||||
*/
|
||||
private String method;
|
||||
|
||||
|
||||
/**
|
||||
* The request parameters.
|
||||
*/
|
||||
private Object params;
|
||||
/**
|
||||
* The request parameters.
|
||||
*/
|
||||
private Object params;
|
||||
|
||||
|
||||
/**
|
||||
* The parameters type constant.
|
||||
*/
|
||||
private JSONRPC2ParamsType paramsType;
|
||||
/**
|
||||
* The parameters type constant.
|
||||
*/
|
||||
private JSONRPC2ParamsType paramsType;
|
||||
|
||||
|
||||
/**
|
||||
* The request identifier.
|
||||
*/
|
||||
private Object id;
|
||||
/**
|
||||
* The request identifier.
|
||||
*/
|
||||
private Object id;
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 request string. This method is thread-safe.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the optional {@link
|
||||
* #parse(String,boolean,boolean)} method.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 request string, UTF-8 encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 request object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Request parse(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 request string. This method is thread-safe.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the optional {@link
|
||||
* #parse(String,boolean,boolean)} method.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 request string, UTF-8 encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 request object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Request parse(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
return parse(jsonString, false, false);
|
||||
}
|
||||
return parse(jsonString, false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 request string. This method is thread-safe.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 request string, UTF-8 encoded.
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in parameters will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 request object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Request parse(final String jsonString, final boolean preserveOrder, final boolean noStrict)
|
||||
throws JSONRPC2ParseException {
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 request string. This method is thread-safe.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 request string, UTF-8 encoded.
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in parameters will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 request object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Request parse(final String jsonString, final boolean preserveOrder, final boolean noStrict)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
JSONRPC2Parser parser = new JSONRPC2Parser(preserveOrder, noStrict);
|
||||
JSONRPC2Parser parser = new JSONRPC2Parser(preserveOrder, noStrict);
|
||||
|
||||
return parser.parseJSONRPC2Request(jsonString);
|
||||
}
|
||||
return parser.parseJSONRPC2Request(jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 request with no parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* The value must <a href="#map">map</a> to a JSON
|
||||
* scalar ({@code null} and fractions, however, should
|
||||
* be avoided).
|
||||
*/
|
||||
public JSONRPC2Request(final String method, final Object id) {
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 request with no parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* The value must <a href="#map">map</a> to a JSON
|
||||
* scalar ({@code null} and fractions, however, should
|
||||
* be avoided).
|
||||
*/
|
||||
public JSONRPC2Request(final String method, final Object id) {
|
||||
|
||||
setMethod(method);
|
||||
setParams(null);
|
||||
setID(id);
|
||||
}
|
||||
setMethod(method);
|
||||
setParams(null);
|
||||
setID(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 request with JSON array parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param params The request parameters packed as a JSON array
|
||||
* (<a href="#map">maps</a> to java.util.List).
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* The value must <a href="#map">map</a> to a JSON
|
||||
* scalar ({@code null} and fractions, however, should
|
||||
* be avoided).
|
||||
*/
|
||||
public JSONRPC2Request(final String method, final List params, final Object id) {
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 request with JSON array parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param params The request parameters packed as a JSON array
|
||||
* (<a href="#map">maps</a> to java.util.List).
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* The value must <a href="#map">map</a> to a JSON
|
||||
* scalar ({@code null} and fractions, however, should
|
||||
* be avoided).
|
||||
*/
|
||||
public JSONRPC2Request(final String method, final List params, final Object id) {
|
||||
|
||||
setMethod(method);
|
||||
setParams(params);
|
||||
setID(id);
|
||||
}
|
||||
setMethod(method);
|
||||
setParams(params);
|
||||
setID(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 request with JSON object parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param params The request parameters packed as a JSON object
|
||||
* (<a href="#map">maps</a> to java.util.Map).
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* The value must <a href="#map">map</a> to a JSON
|
||||
* scalar ({@code null} and fractions, however, should
|
||||
* be avoided).
|
||||
*/
|
||||
public JSONRPC2Request(final String method, final Map params, final Object id) {
|
||||
/**
|
||||
* Constructs a new JSON-RPC 2.0 request with JSON object parameters.
|
||||
*
|
||||
* @param method The name of the requested method.
|
||||
* @param params The request parameters packed as a JSON object
|
||||
* (<a href="#map">maps</a> to java.util.Map).
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* The value must <a href="#map">map</a> to a JSON
|
||||
* scalar ({@code null} and fractions, however, should
|
||||
* be avoided).
|
||||
*/
|
||||
public JSONRPC2Request(final String method, final Map params, final Object id) {
|
||||
|
||||
setMethod(method);
|
||||
setParams(params);
|
||||
setID(id);
|
||||
}
|
||||
setMethod(method);
|
||||
setParams(params);
|
||||
setID(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the name of the requested method.
|
||||
*
|
||||
* @return The method name.
|
||||
*/
|
||||
public String getMethod() {
|
||||
/**
|
||||
* Gets the name of the requested method.
|
||||
*
|
||||
* @return The method name.
|
||||
*/
|
||||
public String getMethod() {
|
||||
|
||||
return method;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the name of the requested method.
|
||||
*
|
||||
* @param method The method name.
|
||||
*/
|
||||
public void setMethod(final String method) {
|
||||
/**
|
||||
* Sets the name of the requested method.
|
||||
*
|
||||
* @param method The method name.
|
||||
*/
|
||||
public void setMethod(final String method) {
|
||||
|
||||
// The method name is mandatory
|
||||
if (method == null)
|
||||
throw new NullPointerException();
|
||||
// The method name is mandatory
|
||||
if (method == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
this.method = method;
|
||||
}
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the parameters type ({@link JSONRPC2ParamsType#ARRAY},
|
||||
* {@link JSONRPC2ParamsType#OBJECT} or
|
||||
* {@link JSONRPC2ParamsType#NO_PARAMS}).
|
||||
*
|
||||
* @return The parameters type.
|
||||
*/
|
||||
public JSONRPC2ParamsType getParamsType() {
|
||||
/**
|
||||
* Gets the parameters type ({@link JSONRPC2ParamsType#ARRAY},
|
||||
* {@link JSONRPC2ParamsType#OBJECT} or
|
||||
* {@link JSONRPC2ParamsType#NO_PARAMS}).
|
||||
*
|
||||
* @return The parameters type.
|
||||
*/
|
||||
public JSONRPC2ParamsType getParamsType() {
|
||||
|
||||
return paramsType;
|
||||
}
|
||||
return paramsType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the request parameters.
|
||||
*
|
||||
* @return The parameters as {@code List} if JSON array, {@code Map}
|
||||
* if JSON object, or {@code null} if none.
|
||||
*/
|
||||
public Object getParams() {
|
||||
/**
|
||||
* Gets the request parameters.
|
||||
*
|
||||
* @return The parameters as {@code List} if JSON array, {@code Map}
|
||||
* if JSON object, or {@code null} if none.
|
||||
*/
|
||||
public Object getParams() {
|
||||
|
||||
return params;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the request parameters.
|
||||
*
|
||||
* @param params The parameters. For a JSON array type pass a
|
||||
* {@code List}. For a JSON object pass a {@code Map}.
|
||||
* If there are no parameters pass {@code null}.
|
||||
*/
|
||||
public void setParams(final Object params) {
|
||||
/**
|
||||
* Sets the request parameters.
|
||||
*
|
||||
* @param params The parameters. For a JSON array type pass a
|
||||
* {@code List}. For a JSON object pass a {@code Map}.
|
||||
* If there are no parameters pass {@code null}.
|
||||
*/
|
||||
public void setParams(final Object params) {
|
||||
|
||||
if (params == null)
|
||||
paramsType = JSONRPC2ParamsType.NO_PARAMS;
|
||||
if (params == null)
|
||||
paramsType = JSONRPC2ParamsType.NO_PARAMS;
|
||||
|
||||
else if (params instanceof List)
|
||||
paramsType = JSONRPC2ParamsType.ARRAY;
|
||||
else if (params instanceof List)
|
||||
paramsType = JSONRPC2ParamsType.ARRAY;
|
||||
|
||||
else if (params instanceof Map)
|
||||
paramsType = JSONRPC2ParamsType.OBJECT;
|
||||
else if (params instanceof Map)
|
||||
paramsType = JSONRPC2ParamsType.OBJECT;
|
||||
|
||||
else
|
||||
throw new IllegalArgumentException("The request parameters must be of type List, Map or null");
|
||||
else
|
||||
throw new IllegalArgumentException("The request parameters must be of type List, Map or null");
|
||||
|
||||
this.params = params;
|
||||
}
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the request identifier.
|
||||
*
|
||||
* @return The request identifier ({@code Number}, {@code Boolean},
|
||||
* {@code String}) or {@code null}.
|
||||
*/
|
||||
public Object getID() {
|
||||
/**
|
||||
* Gets the request identifier.
|
||||
*
|
||||
* @return The request identifier ({@code Number}, {@code Boolean},
|
||||
* {@code String}) or {@code null}.
|
||||
*/
|
||||
public Object getID() {
|
||||
|
||||
return id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the request identifier (ID).
|
||||
*
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* The value must <a href="#map">map</a> to a JSON
|
||||
* scalar ({@code null} and fractions, however, should
|
||||
* be avoided).
|
||||
*/
|
||||
public void setID(final Object id) {
|
||||
/**
|
||||
* Sets the request identifier (ID).
|
||||
*
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* The value must <a href="#map">map</a> to a JSON
|
||||
* scalar ({@code null} and fractions, however, should
|
||||
* be avoided).
|
||||
*/
|
||||
public void setID(final Object id) {
|
||||
|
||||
if ( id != null &&
|
||||
! (id instanceof Boolean) &&
|
||||
! (id instanceof Number ) &&
|
||||
! (id instanceof String ) )
|
||||
throw new IllegalArgumentException("The request identifier must map to a JSON scalar");
|
||||
this.id = id;
|
||||
}
|
||||
if (id != null &&
|
||||
!(id instanceof Boolean) &&
|
||||
!(id instanceof Number) &&
|
||||
!(id instanceof String))
|
||||
throw new IllegalArgumentException("The request identifier must map to a JSON scalar");
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a JSON representation of this JSON-RPC 2.0 request.
|
||||
*
|
||||
* @return A JSON object representing the request.
|
||||
*/
|
||||
public JSONObject toJSON() {
|
||||
/**
|
||||
* Gets a JSON representation of this JSON-RPC 2.0 request.
|
||||
*
|
||||
* @return A JSON object representing the request.
|
||||
*/
|
||||
public JSONObject toJSON() {
|
||||
|
||||
JSONObject req = new JSONObject();
|
||||
JSONObject req = new JSONObject();
|
||||
|
||||
req.put("method", method);
|
||||
req.put("method", method);
|
||||
|
||||
// the params can be omitted if empty
|
||||
if (params != null && paramsType != JSONRPC2ParamsType.NO_PARAMS)
|
||||
req.put("params", params);
|
||||
// the params can be omitted if empty
|
||||
if (params != null && paramsType != JSONRPC2ParamsType.NO_PARAMS)
|
||||
req.put("params", params);
|
||||
|
||||
req.put("id", id);
|
||||
req.put("id", id);
|
||||
|
||||
req.put("jsonrpc", "2.0");
|
||||
req.put("jsonrpc", "2.0");
|
||||
|
||||
return req;
|
||||
}
|
||||
return req;
|
||||
}
|
||||
}
|
||||
|
@ -116,243 +116,243 @@ import java.util.Map;
|
||||
public class JSONRPC2Response extends JSONRPC2Message {
|
||||
|
||||
|
||||
/**
|
||||
* The result.
|
||||
*/
|
||||
private Object result = null;
|
||||
/**
|
||||
* The result.
|
||||
*/
|
||||
private Object result = null;
|
||||
|
||||
|
||||
/**
|
||||
* The error object.
|
||||
*/
|
||||
private JSONRPC2Error error = null;
|
||||
/**
|
||||
* The error object.
|
||||
*/
|
||||
private JSONRPC2Error error = null;
|
||||
|
||||
|
||||
/**
|
||||
* The request identifier.
|
||||
*/
|
||||
private Object id = null;
|
||||
/**
|
||||
* The request identifier.
|
||||
*/
|
||||
private Object id = null;
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 response string. This method is thread-safe.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the optional {@link
|
||||
* #parse(String,boolean,boolean)} method.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 response string, UTF-8 encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 response object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Response parse(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 response string. This method is thread-safe.
|
||||
*
|
||||
* <p>The member order of parsed JSON objects will not be preserved
|
||||
* (for efficiency reasons) and the JSON-RPC 2.0 version field must be
|
||||
* set to "2.0". To change this behaviour check the optional {@link
|
||||
* #parse(String,boolean,boolean)} method.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 response string, UTF-8 encoded.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 response object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Response parse(final String jsonString)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
return parse(jsonString, false, false);
|
||||
}
|
||||
return parse(jsonString, false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 response string. This method is thread-safe.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 response string, UTF-8 encoded.
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in results will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 response object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Response parse(final String jsonString, final boolean preserveOrder, final boolean noStrict)
|
||||
throws JSONRPC2ParseException {
|
||||
/**
|
||||
* Parses a JSON-RPC 2.0 response string. This method is thread-safe.
|
||||
*
|
||||
* @param jsonString The JSON-RPC 2.0 response string, UTF-8 encoded.
|
||||
* @param preserveOrder If {@code true} the member order of JSON objects
|
||||
* in results will be preserved.
|
||||
* @param noStrict If {@code true} the {@code "jsonrpc":"2.0"}
|
||||
* version field in the JSON-RPC 2.0 message will
|
||||
* not be checked.
|
||||
*
|
||||
* @return The corresponding JSON-RPC 2.0 response object.
|
||||
*
|
||||
* @throws JSONRPC2ParseException With detailed message if the parsing
|
||||
* failed.
|
||||
*/
|
||||
public static JSONRPC2Response parse(final String jsonString, final boolean preserveOrder, final boolean noStrict)
|
||||
throws JSONRPC2ParseException {
|
||||
|
||||
JSONRPC2Parser parser = new JSONRPC2Parser(preserveOrder, noStrict);
|
||||
JSONRPC2Parser parser = new JSONRPC2Parser(preserveOrder, noStrict);
|
||||
|
||||
return parser.parseJSONRPC2Response(jsonString);
|
||||
}
|
||||
return parser.parseJSONRPC2Response(jsonString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 response to a successful request.
|
||||
*
|
||||
* @param result The result. The value can <a href="#map">map</a>
|
||||
* to any JSON type.
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
*/
|
||||
public JSONRPC2Response(final Object result, final Object id) {
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 response to a successful request.
|
||||
*
|
||||
* @param result The result. The value can <a href="#map">map</a>
|
||||
* to any JSON type.
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
*/
|
||||
public JSONRPC2Response(final Object result, final Object id) {
|
||||
|
||||
setResult(result);
|
||||
setID(id);
|
||||
}
|
||||
setResult(result);
|
||||
setID(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 response to a failed request.
|
||||
*
|
||||
* @param error A JSON-RPC 2.0 error instance indicating the
|
||||
* cause of the failure.
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* Pass a {@code null} if the request identifier couldn't
|
||||
* be determined (e.g. due to a parse error).
|
||||
*/
|
||||
public JSONRPC2Response(final JSONRPC2Error error, final Object id) {
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 response to a failed request.
|
||||
*
|
||||
* @param error A JSON-RPC 2.0 error instance indicating the
|
||||
* cause of the failure.
|
||||
* @param id The request identifier echoed back to the caller.
|
||||
* Pass a {@code null} if the request identifier couldn't
|
||||
* be determined (e.g. due to a parse error).
|
||||
*/
|
||||
public JSONRPC2Response(final JSONRPC2Error error, final Object id) {
|
||||
|
||||
setError(error);
|
||||
setID(id);
|
||||
}
|
||||
setError(error);
|
||||
setID(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates a successful JSON-RPC 2.0 request and sets the result.
|
||||
* Note that if the response was previously indicating failure this
|
||||
* will turn it into a response indicating success. Any previously set
|
||||
* error data will be invalidated.
|
||||
*
|
||||
* @param result The result. The value can <a href="#map">map</a> to
|
||||
* any JSON type.
|
||||
*/
|
||||
public void setResult(final Object result) {
|
||||
/**
|
||||
* Indicates a successful JSON-RPC 2.0 request and sets the result.
|
||||
* Note that if the response was previously indicating failure this
|
||||
* will turn it into a response indicating success. Any previously set
|
||||
* error data will be invalidated.
|
||||
*
|
||||
* @param result The result. The value can <a href="#map">map</a> to
|
||||
* any JSON type.
|
||||
*/
|
||||
public void setResult(final Object result) {
|
||||
|
||||
if ( result != null &&
|
||||
! (result instanceof Boolean) &&
|
||||
! (result instanceof Number ) &&
|
||||
! (result instanceof String ) &&
|
||||
! (result instanceof List ) &&
|
||||
! (result instanceof Map ) )
|
||||
throw new IllegalArgumentException("The result must map to a JSON type");
|
||||
if (result != null &&
|
||||
!(result instanceof Boolean) &&
|
||||
!(result instanceof Number) &&
|
||||
!(result instanceof String) &&
|
||||
!(result instanceof List) &&
|
||||
!(result instanceof Map))
|
||||
throw new IllegalArgumentException("The result must map to a JSON type");
|
||||
|
||||
// result and error are mutually exclusive
|
||||
this.result = result;
|
||||
this.error = null;
|
||||
}
|
||||
// result and error are mutually exclusive
|
||||
this.result = result;
|
||||
this.error = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the result of the request. The returned value has meaning
|
||||
* only if the request was successful. Use the {@link #getError getError}
|
||||
* method to check this.
|
||||
*
|
||||
* @return The result
|
||||
*/
|
||||
public Object getResult() {
|
||||
/**
|
||||
* Gets the result of the request. The returned value has meaning
|
||||
* only if the request was successful. Use the {@link #getError getError}
|
||||
* method to check this.
|
||||
*
|
||||
* @return The result
|
||||
*/
|
||||
public Object getResult() {
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates a failed JSON-RPC 2.0 request and sets the error details.
|
||||
* Note that if the response was previously indicating success this
|
||||
* will turn it into a response indicating failure. Any previously set
|
||||
* result data will be invalidated.
|
||||
*
|
||||
* @param error A JSON-RPC 2.0 error instance indicating the
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void setError(final JSONRPC2Error error) {
|
||||
/**
|
||||
* Indicates a failed JSON-RPC 2.0 request and sets the error details.
|
||||
* Note that if the response was previously indicating success this
|
||||
* will turn it into a response indicating failure. Any previously set
|
||||
* result data will be invalidated.
|
||||
*
|
||||
* @param error A JSON-RPC 2.0 error instance indicating the
|
||||
* cause of the failure.
|
||||
*/
|
||||
public void setError(final JSONRPC2Error error) {
|
||||
|
||||
if (error == null)
|
||||
throw new NullPointerException("The error object cannot be null");
|
||||
if (error == null)
|
||||
throw new NullPointerException("The error object cannot be null");
|
||||
|
||||
// result and error are mutually exclusive
|
||||
this.error = error;
|
||||
this.result = null;
|
||||
}
|
||||
// result and error are mutually exclusive
|
||||
this.error = error;
|
||||
this.result = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the error object indicating the cause of the request failure.
|
||||
* If a {@code null} is returned, the request succeeded and there was
|
||||
* no error.
|
||||
*
|
||||
* @return A JSON-RPC 2.0 error object, {@code null} if the
|
||||
* response indicates success.
|
||||
*/
|
||||
public JSONRPC2Error getError() {
|
||||
/**
|
||||
* Gets the error object indicating the cause of the request failure.
|
||||
* If a {@code null} is returned, the request succeeded and there was
|
||||
* no error.
|
||||
*
|
||||
* @return A JSON-RPC 2.0 error object, {@code null} if the
|
||||
* response indicates success.
|
||||
*/
|
||||
public JSONRPC2Error getError() {
|
||||
|
||||
return error;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A convinience method to check if the response indicates success or
|
||||
* failure of the request. Alternatively, you can use the
|
||||
* {@code #getError} method for this purpose.
|
||||
*
|
||||
* @return {@code true} if the request succeeded, {@code false} if
|
||||
* there was an error.
|
||||
*/
|
||||
public boolean indicatesSuccess() {
|
||||
/**
|
||||
* A convinience method to check if the response indicates success or
|
||||
* failure of the request. Alternatively, you can use the
|
||||
* {@code #getError} method for this purpose.
|
||||
*
|
||||
* @return {@code true} if the request succeeded, {@code false} if
|
||||
* there was an error.
|
||||
*/
|
||||
public boolean indicatesSuccess() {
|
||||
|
||||
if (error == null)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (error == null)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the request identifier echoed back to the caller.
|
||||
*
|
||||
* @param id The value must <a href="#map">map</a> to a JSON scalar.
|
||||
* Pass a {@code null} if the request identifier couldn't
|
||||
* be determined (e.g. due to a parse error).
|
||||
*/
|
||||
public void setID(final Object id) {
|
||||
/**
|
||||
* Sets the request identifier echoed back to the caller.
|
||||
*
|
||||
* @param id The value must <a href="#map">map</a> to a JSON scalar.
|
||||
* Pass a {@code null} if the request identifier couldn't
|
||||
* be determined (e.g. due to a parse error).
|
||||
*/
|
||||
public void setID(final Object id) {
|
||||
|
||||
if ( id != null &&
|
||||
! (id instanceof Boolean) &&
|
||||
! (id instanceof Number ) &&
|
||||
! (id instanceof String ) )
|
||||
throw new IllegalArgumentException("The request identifier must map to a JSON scalar");
|
||||
if (id != null &&
|
||||
!(id instanceof Boolean) &&
|
||||
!(id instanceof Number) &&
|
||||
!(id instanceof String))
|
||||
throw new IllegalArgumentException("The request identifier must map to a JSON scalar");
|
||||
|
||||
this.id = id;
|
||||
}
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the request identifier that is echoed back to the caller.
|
||||
*
|
||||
* @return The request identifier. If there was an error during the
|
||||
* the request retrieval (e.g. parse error) and the identifier
|
||||
* couldn't be determined, the value will be {@code null}.
|
||||
*/
|
||||
public Object getID() {
|
||||
/**
|
||||
* Gets the request identifier that is echoed back to the caller.
|
||||
*
|
||||
* @return The request identifier. If there was an error during the
|
||||
* the request retrieval (e.g. parse error) and the identifier
|
||||
* couldn't be determined, the value will be {@code null}.
|
||||
*/
|
||||
public Object getID() {
|
||||
|
||||
return id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a JSON representation of this JSON-RPC 2.0 response.
|
||||
*
|
||||
* @return A JSON object representing the response.
|
||||
*/
|
||||
public JSONObject toJSON() {
|
||||
/**
|
||||
* Gets a JSON representation of this JSON-RPC 2.0 response.
|
||||
*
|
||||
* @return A JSON object representing the response.
|
||||
*/
|
||||
public JSONObject toJSON() {
|
||||
|
||||
JSONObject out = new JSONObject();
|
||||
JSONObject out = new JSONObject();
|
||||
|
||||
// Result and error are mutually exclusive
|
||||
if (error != null) {
|
||||
out.put("error", error.toJSON());
|
||||
}
|
||||
else {
|
||||
out.put("result", result);
|
||||
}
|
||||
// Result and error are mutually exclusive
|
||||
if (error != null) {
|
||||
out.put("error", error.toJSON());
|
||||
}
|
||||
else {
|
||||
out.put("result", result);
|
||||
}
|
||||
|
||||
out.put("id", id);
|
||||
out.put("id", id);
|
||||
|
||||
out.put("jsonrpc", "2.0");
|
||||
out.put("jsonrpc", "2.0");
|
||||
|
||||
return out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,178 +21,178 @@ import java.util.Hashtable;
|
||||
public class Dispatcher {
|
||||
|
||||
|
||||
/**
|
||||
* Hashtable of request name / handler pairs.
|
||||
*/
|
||||
private Hashtable<String,RequestHandler> requestHandlers;
|
||||
/**
|
||||
* Hashtable of request name / handler pairs.
|
||||
*/
|
||||
private Hashtable<String, RequestHandler> requestHandlers;
|
||||
|
||||
|
||||
/**
|
||||
* Hashtable of notification name / handler pairs.
|
||||
*/
|
||||
private Hashtable<String,NotificationHandler> notificationHandlers;
|
||||
/**
|
||||
* Hashtable of notification name / handler pairs.
|
||||
*/
|
||||
private Hashtable<String, NotificationHandler> notificationHandlers;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new dispatcher with no registered handlers.
|
||||
*/
|
||||
public Dispatcher() {
|
||||
/**
|
||||
* Creates a new dispatcher with no registered handlers.
|
||||
*/
|
||||
public Dispatcher() {
|
||||
|
||||
requestHandlers = new Hashtable<String,RequestHandler>();
|
||||
notificationHandlers = new Hashtable<String,NotificationHandler>();
|
||||
}
|
||||
requestHandlers = new Hashtable<String, RequestHandler>();
|
||||
notificationHandlers = new Hashtable<String, NotificationHandler>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers a new JSON-RPC 2.0 request handler.
|
||||
*
|
||||
* @param handler The request handler to register.
|
||||
*
|
||||
* @throws IllegalArgumentException On attempting to register a handler
|
||||
* that duplicates an existing request
|
||||
* name.
|
||||
*/
|
||||
public void register(final RequestHandler handler) {
|
||||
/**
|
||||
* Registers a new JSON-RPC 2.0 request handler.
|
||||
*
|
||||
* @param handler The request handler to register.
|
||||
*
|
||||
* @throws IllegalArgumentException On attempting to register a handler
|
||||
* that duplicates an existing request
|
||||
* name.
|
||||
*/
|
||||
public void register(final RequestHandler handler) {
|
||||
|
||||
for (String name: handler.handledRequests()) {
|
||||
for (String name : handler.handledRequests()) {
|
||||
|
||||
if (requestHandlers.containsKey(name))
|
||||
throw new IllegalArgumentException("Cannot register a duplicate handler for request " + name);
|
||||
if (requestHandlers.containsKey(name))
|
||||
throw new IllegalArgumentException("Cannot register a duplicate handler for request " + name);
|
||||
|
||||
requestHandlers.put(name, handler);
|
||||
}
|
||||
}
|
||||
requestHandlers.put(name, handler);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers a new JSON-RPC 2.0 notification handler.
|
||||
*
|
||||
* @param handler The notification handler to register.
|
||||
*
|
||||
* @throws IllegalArgumentException On attempting to register a handler
|
||||
* that duplicates an existing
|
||||
* notification name.
|
||||
*/
|
||||
public void register(final NotificationHandler handler) {
|
||||
/**
|
||||
* Registers a new JSON-RPC 2.0 notification handler.
|
||||
*
|
||||
* @param handler The notification handler to register.
|
||||
*
|
||||
* @throws IllegalArgumentException On attempting to register a handler
|
||||
* that duplicates an existing
|
||||
* notification name.
|
||||
*/
|
||||
public void register(final NotificationHandler handler) {
|
||||
|
||||
for (String name: handler.handledNotifications()) {
|
||||
for (String name : handler.handledNotifications()) {
|
||||
|
||||
if (notificationHandlers.containsKey(name))
|
||||
throw new IllegalArgumentException("Cannot register a duplicate handler for notification " + name);
|
||||
if (notificationHandlers.containsKey(name))
|
||||
throw new IllegalArgumentException("Cannot register a duplicate handler for notification " + name);
|
||||
|
||||
notificationHandlers.put(name, handler);
|
||||
}
|
||||
}
|
||||
notificationHandlers.put(name, handler);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the registered request names.
|
||||
*
|
||||
* @return The request names.
|
||||
*/
|
||||
public String[] handledRequests() {
|
||||
/**
|
||||
* Returns the registered request names.
|
||||
*
|
||||
* @return The request names.
|
||||
*/
|
||||
public String[] handledRequests() {
|
||||
|
||||
return requestHandlers.keySet().toArray(new String[0]);
|
||||
}
|
||||
return requestHandlers.keySet().toArray(new String[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the registered notification names.
|
||||
*
|
||||
* @return The notification names.
|
||||
*/
|
||||
public String[] handledNotifications() {
|
||||
/**
|
||||
* Returns the registered notification names.
|
||||
*
|
||||
* @return The notification names.
|
||||
*/
|
||||
public String[] handledNotifications() {
|
||||
|
||||
return notificationHandlers.keySet().toArray(new String[0]);
|
||||
}
|
||||
return notificationHandlers.keySet().toArray(new String[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the handler for the specified JSON-RPC 2.0 request name.
|
||||
*
|
||||
* @param requestName The request name to lookup.
|
||||
*
|
||||
* @return The corresponding request handler or {@code null} if none
|
||||
* was found.
|
||||
*/
|
||||
public RequestHandler getRequestHandler(final String requestName) {
|
||||
/**
|
||||
* Gets the handler for the specified JSON-RPC 2.0 request name.
|
||||
*
|
||||
* @param requestName The request name to lookup.
|
||||
*
|
||||
* @return The corresponding request handler or {@code null} if none
|
||||
* was found.
|
||||
*/
|
||||
public RequestHandler getRequestHandler(final String requestName) {
|
||||
|
||||
return requestHandlers.get(requestName);
|
||||
}
|
||||
return requestHandlers.get(requestName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the handler for the specified JSON-RPC 2.0 notification name.
|
||||
*
|
||||
* @param notificationName The notification name to lookup.
|
||||
*
|
||||
* @return The corresponding notification handler or {@code null} if
|
||||
* none was found.
|
||||
*/
|
||||
public NotificationHandler getNotificationHandler(final String notificationName) {
|
||||
/**
|
||||
* Gets the handler for the specified JSON-RPC 2.0 notification name.
|
||||
*
|
||||
* @param notificationName The notification name to lookup.
|
||||
*
|
||||
* @return The corresponding notification handler or {@code null} if
|
||||
* none was found.
|
||||
*/
|
||||
public NotificationHandler getNotificationHandler(final String notificationName) {
|
||||
|
||||
return notificationHandlers.get(notificationName);
|
||||
}
|
||||
return notificationHandlers.get(notificationName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches the specified JSON-RPC 2.0 request to the appropriate
|
||||
* handler for processing and returns the response.
|
||||
*
|
||||
* @param request The JSON-RPC 2.0 request to dispatch for
|
||||
* processing.
|
||||
* @param requestCtx Context information about the request, may be
|
||||
* {@code null} if undefined.
|
||||
*
|
||||
* @return The response, which may indicate a processing error, such
|
||||
* as METHOD_NOT_FOUND.
|
||||
*/
|
||||
public JSONRPC2Response dispatch(final JSONRPC2Request request, final MessageContext requestCtx) {
|
||||
/**
|
||||
* Dispatches the specified JSON-RPC 2.0 request to the appropriate
|
||||
* handler for processing and returns the response.
|
||||
*
|
||||
* @param request The JSON-RPC 2.0 request to dispatch for
|
||||
* processing.
|
||||
* @param requestCtx Context information about the request, may be
|
||||
* {@code null} if undefined.
|
||||
*
|
||||
* @return The response, which may indicate a processing error, such
|
||||
* as METHOD_NOT_FOUND.
|
||||
*/
|
||||
public JSONRPC2Response dispatch(final JSONRPC2Request request, final MessageContext requestCtx) {
|
||||
|
||||
final String method = request.getMethod();
|
||||
final String method = request.getMethod();
|
||||
|
||||
RequestHandler handler = getRequestHandler(method);
|
||||
RequestHandler handler = getRequestHandler(method);
|
||||
|
||||
if (handler == null) {
|
||||
if (handler == null) {
|
||||
|
||||
// We didn't find a handler for the requested RPC
|
||||
// We didn't find a handler for the requested RPC
|
||||
|
||||
Object id = request.getID();
|
||||
Object id = request.getID();
|
||||
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, id);
|
||||
}
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, id);
|
||||
}
|
||||
|
||||
// Process the request
|
||||
// Process the request
|
||||
|
||||
return handler.process(request, requestCtx);
|
||||
}
|
||||
return handler.process(request, requestCtx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches the specified JSON-RPC 2.0 notification to the appropriate
|
||||
* handler for processing.
|
||||
*
|
||||
* <p>Note that JSON-RPC 2.0 notifications don't produce a response!
|
||||
*
|
||||
* @param notification The JSON-RPC 2.0 notification to dispatch for
|
||||
* processing.
|
||||
* @param notificationCtx Context information about the notification,
|
||||
* may be {@code null} if undefined.
|
||||
*/
|
||||
public void dispatch(final JSONRPC2Notification notification, final MessageContext notificationCtx) {
|
||||
/**
|
||||
* Dispatches the specified JSON-RPC 2.0 notification to the appropriate
|
||||
* handler for processing.
|
||||
*
|
||||
* <p>Note that JSON-RPC 2.0 notifications don't produce a response!
|
||||
*
|
||||
* @param notification The JSON-RPC 2.0 notification to dispatch for
|
||||
* processing.
|
||||
* @param notificationCtx Context information about the notification,
|
||||
* may be {@code null} if undefined.
|
||||
*/
|
||||
public void dispatch(final JSONRPC2Notification notification, final MessageContext notificationCtx) {
|
||||
|
||||
final String method = notification.getMethod();
|
||||
final String method = notification.getMethod();
|
||||
|
||||
NotificationHandler handler = getNotificationHandler(method);
|
||||
NotificationHandler handler = getNotificationHandler(method);
|
||||
|
||||
if (handler == null) {
|
||||
if (handler == null) {
|
||||
|
||||
// We didn't find a handler for the requested RPC
|
||||
return;
|
||||
}
|
||||
// We didn't find a handler for the requested RPC
|
||||
return;
|
||||
}
|
||||
|
||||
// Process the notification
|
||||
// Process the notification
|
||||
|
||||
handler.process(notification, notificationCtx);
|
||||
}
|
||||
handler.process(notification, notificationCtx);
|
||||
}
|
||||
}
|
||||
|
@ -23,224 +23,224 @@ import java.security.cert.X509Certificate;
|
||||
public class MessageContext {
|
||||
|
||||
|
||||
/**
|
||||
* The client hostname.
|
||||
*/
|
||||
private String clientHostName = null;
|
||||
/**
|
||||
* The client hostname.
|
||||
*/
|
||||
private String clientHostName = null;
|
||||
|
||||
|
||||
/**
|
||||
* The client IP address.
|
||||
*/
|
||||
private String clientInetAddress = null;
|
||||
/**
|
||||
* The client IP address.
|
||||
*/
|
||||
private String clientInetAddress = null;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether the request was received over HTTPS.
|
||||
*/
|
||||
private boolean secure = false;
|
||||
/**
|
||||
* Indicates whether the request was received over HTTPS.
|
||||
*/
|
||||
private boolean secure = false;
|
||||
|
||||
|
||||
/**
|
||||
* The authenticated client principal.
|
||||
*/
|
||||
private Principal principal = null;
|
||||
/**
|
||||
* The authenticated client principal.
|
||||
*/
|
||||
private Principal principal = null;
|
||||
|
||||
|
||||
/**
|
||||
* Minimal implementation of the {@link java.security.Principal}
|
||||
* interface.
|
||||
*/
|
||||
protected class BasicPrincipal implements Principal {
|
||||
/**
|
||||
* Minimal implementation of the {@link java.security.Principal}
|
||||
* interface.
|
||||
*/
|
||||
protected class BasicPrincipal implements Principal {
|
||||
|
||||
/**
|
||||
* The principal name.
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* The principal name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new principal.
|
||||
*
|
||||
* @param name The principal name.
|
||||
*/
|
||||
public BasicPrincipal(final String name) {
|
||||
/**
|
||||
* Creates a new principal.
|
||||
*
|
||||
* @param name The principal name.
|
||||
*/
|
||||
public BasicPrincipal(final String name) {
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks for equality.
|
||||
*
|
||||
* @param another The object to compare to.
|
||||
*/
|
||||
public boolean equals(final Object another) {
|
||||
/**
|
||||
* Checks for equality.
|
||||
*
|
||||
* @param another The object to compare to.
|
||||
*/
|
||||
public boolean equals(final Object another) {
|
||||
|
||||
if (another instanceof Principal && ((Principal)another).getName().equals(this.getName()))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (another instanceof Principal && ((Principal)another).getName().equals(this.getName()))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a hash code for this principal.
|
||||
*
|
||||
* @return The hash code.
|
||||
*/
|
||||
public int hashCode() {
|
||||
/**
|
||||
* Returns a hash code for this principal.
|
||||
*
|
||||
* @return The hash code.
|
||||
*/
|
||||
public int hashCode() {
|
||||
|
||||
if (name == null)
|
||||
return 0;
|
||||
else
|
||||
return name.hashCode();
|
||||
}
|
||||
if (name == null)
|
||||
return 0;
|
||||
else
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the principal name.
|
||||
*
|
||||
* @return The principal name.
|
||||
*/
|
||||
public String getName() {
|
||||
/**
|
||||
* Returns the principal name.
|
||||
*
|
||||
* @return The principal name.
|
||||
*/
|
||||
public String getName() {
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 request / notification context.
|
||||
*
|
||||
* @param clientHostName The client host name, {@code null} if
|
||||
* unknown.
|
||||
* @param clientInetAddress The client IP address, {@code null} if
|
||||
* unknown.
|
||||
* @param secure Specifies a request received over HTTPS.
|
||||
* @param principalName Specifies the authenticated client principle
|
||||
* name, {@code null} if none.
|
||||
*/
|
||||
public MessageContext(final String clientHostName,
|
||||
final String clientInetAddress,
|
||||
final boolean secure,
|
||||
final String principalName) {
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 request / notification context.
|
||||
*
|
||||
* @param clientHostName The client host name, {@code null} if
|
||||
* unknown.
|
||||
* @param clientInetAddress The client IP address, {@code null} if
|
||||
* unknown.
|
||||
* @param secure Specifies a request received over HTTPS.
|
||||
* @param principalName Specifies the authenticated client principle
|
||||
* name, {@code null} if none.
|
||||
*/
|
||||
public MessageContext(final String clientHostName,
|
||||
final String clientInetAddress,
|
||||
final boolean secure,
|
||||
final String principalName) {
|
||||
|
||||
this.clientHostName = clientHostName;
|
||||
this.clientInetAddress = clientInetAddress;
|
||||
this.secure = secure;
|
||||
this.clientHostName = clientHostName;
|
||||
this.clientInetAddress = clientInetAddress;
|
||||
this.secure = secure;
|
||||
|
||||
this.principal = new BasicPrincipal(principalName);
|
||||
}
|
||||
this.principal = new BasicPrincipal(principalName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 request / notification context. No
|
||||
* authenticated client principal is specified.
|
||||
*
|
||||
* @param clientHostName The client host name, {@code null} if
|
||||
* unknown.
|
||||
* @param clientInetAddress The client IP address, {@code null} if
|
||||
* unknown.
|
||||
* @param secure Specifies a request received over HTTPS.
|
||||
*/
|
||||
public MessageContext(final String clientHostName,
|
||||
final String clientInetAddress,
|
||||
final boolean secure) {
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 request / notification context. No
|
||||
* authenticated client principal is specified.
|
||||
*
|
||||
* @param clientHostName The client host name, {@code null} if
|
||||
* unknown.
|
||||
* @param clientInetAddress The client IP address, {@code null} if
|
||||
* unknown.
|
||||
* @param secure Specifies a request received over HTTPS.
|
||||
*/
|
||||
public MessageContext(final String clientHostName,
|
||||
final String clientInetAddress,
|
||||
final boolean secure) {
|
||||
|
||||
this(clientHostName, clientInetAddress, secure, null);
|
||||
}
|
||||
this(clientHostName, clientInetAddress, secure, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 request / notification context. Indicates
|
||||
* an insecure transport (plain HTTP) and no authenticated client
|
||||
* principal.
|
||||
*
|
||||
* @param clientHostName The client host name, {@code null} if
|
||||
* unknown.
|
||||
* @param clientInetAddress The client IP address, {@code null} if
|
||||
* unknown.
|
||||
*/
|
||||
public MessageContext(final String clientHostName,
|
||||
final String clientInetAddress) {
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 request / notification context. Indicates
|
||||
* an insecure transport (plain HTTP) and no authenticated client
|
||||
* principal.
|
||||
*
|
||||
* @param clientHostName The client host name, {@code null} if
|
||||
* unknown.
|
||||
* @param clientInetAddress The client IP address, {@code null} if
|
||||
* unknown.
|
||||
*/
|
||||
public MessageContext(final String clientHostName,
|
||||
final String clientInetAddress) {
|
||||
|
||||
this(clientHostName, clientInetAddress, false, null);
|
||||
}
|
||||
this(clientHostName, clientInetAddress, false, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 request / notification context from the
|
||||
* specified HTTP request.
|
||||
*
|
||||
* @param httpRequest The HTTP request.
|
||||
*/
|
||||
public MessageContext(final HttpServletRequest httpRequest) {
|
||||
/**
|
||||
* Creates a new JSON-RPC 2.0 request / notification context from the
|
||||
* specified HTTP request.
|
||||
*
|
||||
* @param httpRequest The HTTP request.
|
||||
*/
|
||||
public MessageContext(final HttpServletRequest httpRequest) {
|
||||
|
||||
clientInetAddress = httpRequest.getRemoteAddr();
|
||||
clientInetAddress = httpRequest.getRemoteAddr();
|
||||
|
||||
clientHostName = httpRequest.getRemoteHost();
|
||||
clientHostName = httpRequest.getRemoteHost();
|
||||
|
||||
if (clientHostName != null && clientHostName.equals(clientInetAddress))
|
||||
clientHostName = null; // not resolved actually
|
||||
if (clientHostName != null && clientHostName.equals(clientInetAddress))
|
||||
clientHostName = null; // not resolved actually
|
||||
|
||||
secure = httpRequest.isSecure();
|
||||
secure = httpRequest.isSecure();
|
||||
|
||||
X509Certificate[] certs = (X509Certificate[])httpRequest.getAttribute("javax.servlet.request.X509Certificate");
|
||||
X509Certificate[] certs = (X509Certificate[])httpRequest.getAttribute("javax.servlet.request.X509Certificate");
|
||||
|
||||
String principalName = null;
|
||||
String principalName = null;
|
||||
|
||||
if (certs != null)
|
||||
principalName = certs[0].getSubjectDN().getName();
|
||||
if (certs != null)
|
||||
principalName = certs[0].getSubjectDN().getName();
|
||||
|
||||
principal = new BasicPrincipal(principalName);
|
||||
}
|
||||
principal = new BasicPrincipal(principalName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the host name of the client that sent the request /
|
||||
* notification.
|
||||
*
|
||||
* @return The client host name, {@code null} if unknown.
|
||||
*/
|
||||
public String getClientHostName() {
|
||||
/**
|
||||
* Gets the host name of the client that sent the request /
|
||||
* notification.
|
||||
*
|
||||
* @return The client host name, {@code null} if unknown.
|
||||
*/
|
||||
public String getClientHostName() {
|
||||
|
||||
return clientHostName;
|
||||
}
|
||||
return clientHostName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the IP address of the client that sent the request /
|
||||
* notification.
|
||||
*
|
||||
* @return The client IP address, {@code null} if unknown.
|
||||
*/
|
||||
public String getClientInetAddress() {
|
||||
/**
|
||||
* Gets the IP address of the client that sent the request /
|
||||
* notification.
|
||||
*
|
||||
* @return The client IP address, {@code null} if unknown.
|
||||
*/
|
||||
public String getClientInetAddress() {
|
||||
|
||||
return clientInetAddress;
|
||||
}
|
||||
return clientInetAddress;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates whether the request / notification was received over a
|
||||
* secure HTTPS connection.
|
||||
*
|
||||
* @return {@code true} If the request was received over HTTPS,
|
||||
* {@code false} if it was received over plain HTTP.
|
||||
*/
|
||||
public boolean isSecure() {
|
||||
/**
|
||||
* Indicates whether the request / notification was received over a
|
||||
* secure HTTPS connection.
|
||||
*
|
||||
* @return {@code true} If the request was received over HTTPS,
|
||||
* {@code false} if it was received over plain HTTP.
|
||||
*/
|
||||
public boolean isSecure() {
|
||||
|
||||
return secure;
|
||||
}
|
||||
return secure;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the authenticated client principal, {@code null} if none.
|
||||
*
|
||||
* @return The client principal, {@code null} if none.
|
||||
*/
|
||||
public Principal getPrincipal() {
|
||||
/**
|
||||
* Returns the authenticated client principal, {@code null} if none.
|
||||
*
|
||||
* @return The client principal, {@code null} if none.
|
||||
*/
|
||||
public Principal getPrincipal() {
|
||||
|
||||
return principal;
|
||||
}
|
||||
return principal;
|
||||
}
|
||||
}
|
||||
|
@ -13,22 +13,22 @@ import com.thetransactioncompany.jsonrpc2.JSONRPC2Notification;
|
||||
public interface NotificationHandler {
|
||||
|
||||
|
||||
/**
|
||||
* Gets the JSON-RPC 2.0 notification method names that this handler
|
||||
* processes.
|
||||
*
|
||||
* @return The method names of the served JSON-RPC 2.0 notifications.
|
||||
*/
|
||||
public String[] handledNotifications();
|
||||
/**
|
||||
* Gets the JSON-RPC 2.0 notification method names that this handler
|
||||
* processes.
|
||||
*
|
||||
* @return The method names of the served JSON-RPC 2.0 notifications.
|
||||
*/
|
||||
public String[] handledNotifications();
|
||||
|
||||
|
||||
/**
|
||||
* Processes a JSON-RPC 2.0 notification.
|
||||
*
|
||||
* @param notification A valid JSON-RPC 2.0 notification instance.
|
||||
* @param notificationCtx Context information about the notification,
|
||||
* may be {@code null} if undefined.
|
||||
*/
|
||||
public void process(final JSONRPC2Notification notification, final MessageContext notificationCtx);
|
||||
/**
|
||||
* Processes a JSON-RPC 2.0 notification.
|
||||
*
|
||||
* @param notification A valid JSON-RPC 2.0 notification instance.
|
||||
* @param notificationCtx Context information about the notification,
|
||||
* may be {@code null} if undefined.
|
||||
*/
|
||||
public void process(final JSONRPC2Notification notification, final MessageContext notificationCtx);
|
||||
|
||||
}
|
||||
|
@ -14,24 +14,24 @@ import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
|
||||
public interface RequestHandler {
|
||||
|
||||
|
||||
/**
|
||||
* Gets the JSON-RPC 2.0 request method names that this handler
|
||||
* processes.
|
||||
*
|
||||
* @return The method names of the served JSON-RPC 2.0 requests.
|
||||
*/
|
||||
public String[] handledRequests();
|
||||
/**
|
||||
* Gets the JSON-RPC 2.0 request method names that this handler
|
||||
* processes.
|
||||
*
|
||||
* @return The method names of the served JSON-RPC 2.0 requests.
|
||||
*/
|
||||
public String[] handledRequests();
|
||||
|
||||
|
||||
/**
|
||||
* Processes a JSON-RPC 2.0 request.
|
||||
*
|
||||
* @param request A valid JSON-RPC 2.0 request instance.
|
||||
* @param requestCtx Context information about the request, may be
|
||||
* {@code null} if undefined.
|
||||
*
|
||||
* @return The resulting JSON-RPC 2.0 response.
|
||||
*/
|
||||
public JSONRPC2Response process(final JSONRPC2Request request, final MessageContext requestCtx);
|
||||
/**
|
||||
* Processes a JSON-RPC 2.0 request.
|
||||
*
|
||||
* @param request A valid JSON-RPC 2.0 request instance.
|
||||
* @param requestCtx Context information about the request, may be
|
||||
* {@code null} if undefined.
|
||||
*
|
||||
* @return The resulting JSON-RPC 2.0 response.
|
||||
*/
|
||||
public JSONRPC2Response process(final JSONRPC2Request request, final MessageContext requestCtx);
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,86 +12,86 @@ import com.thetransactioncompany.jsonrpc2.JSONRPC2Error;
|
||||
*/
|
||||
public abstract class ParamsRetriever {
|
||||
|
||||
/**
|
||||
* Returns the parameter count.
|
||||
*
|
||||
* @return The number of parameters.
|
||||
*/
|
||||
public abstract int size();
|
||||
/**
|
||||
* Returns the parameter count.
|
||||
*
|
||||
* @return The number of parameters.
|
||||
*/
|
||||
public abstract int size();
|
||||
|
||||
|
||||
/**
|
||||
* Throws a {@code JSONRPC2Error.INVALID_PARAMS} exception if the input
|
||||
* string doesn't match a value in the specified string array.
|
||||
*
|
||||
* <p>This method is intended to check a string against a set of
|
||||
* acceptable values.
|
||||
*
|
||||
* @param input The string to check.
|
||||
* @param enumStrings The acceptable string values.
|
||||
* @param ignoreCase {@code true} for a case insensitive match.
|
||||
*
|
||||
* @return The matching string value.
|
||||
*
|
||||
* @throws JSONRPC2Error With proper code and message if the input
|
||||
* string didn't match.
|
||||
*/
|
||||
protected static String ensureEnumString(final String input, final String[] enumStrings, final boolean ignoreCase)
|
||||
throws JSONRPC2Error {
|
||||
/**
|
||||
* Throws a {@code JSONRPC2Error.INVALID_PARAMS} exception if the input
|
||||
* string doesn't match a value in the specified string array.
|
||||
*
|
||||
* <p>This method is intended to check a string against a set of
|
||||
* acceptable values.
|
||||
*
|
||||
* @param input The string to check.
|
||||
* @param enumStrings The acceptable string values.
|
||||
* @param ignoreCase {@code true} for a case insensitive match.
|
||||
*
|
||||
* @return The matching string value.
|
||||
*
|
||||
* @throws JSONRPC2Error With proper code and message if the input
|
||||
* string didn't match.
|
||||
*/
|
||||
protected static String ensureEnumString(final String input, final String[] enumStrings, final boolean ignoreCase)
|
||||
throws JSONRPC2Error {
|
||||
|
||||
for (String en: enumStrings) {
|
||||
for (String en : enumStrings) {
|
||||
|
||||
if (ignoreCase) {
|
||||
if (en.toLowerCase().equals(input.toLowerCase()))
|
||||
return en;
|
||||
}
|
||||
else {
|
||||
if (en.equals(input))
|
||||
return en;
|
||||
}
|
||||
}
|
||||
if (ignoreCase) {
|
||||
if (en.toLowerCase().equals(input.toLowerCase()))
|
||||
return en;
|
||||
}
|
||||
else {
|
||||
if (en.equals(input))
|
||||
return en;
|
||||
}
|
||||
}
|
||||
|
||||
// No match -> raise error
|
||||
throw JSONRPC2Error.INVALID_PARAMS;
|
||||
}
|
||||
// No match -> raise error
|
||||
throw JSONRPC2Error.INVALID_PARAMS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Throws a {@code JSONRPC2Error.INVALID_PARAMS} exception if the input
|
||||
* string doesn't match a constant name in the specified enumeration
|
||||
* class.
|
||||
*
|
||||
* <p>This method is intended to check a string against a set of
|
||||
* acceptable values.
|
||||
*
|
||||
* @param input The string to check.
|
||||
* @param enumClass The enumeration class specifying the acceptable
|
||||
* constant names.
|
||||
* @param ignoreCase {@code true} for a case insensitive match.
|
||||
*
|
||||
* @return The matching enumeration constant.
|
||||
*
|
||||
* @throws JSONRPC2Error With proper code and message if the input
|
||||
* string didn't match.
|
||||
*/
|
||||
protected static <T extends Enum<T>> T ensureEnumString(final String input, final Class<T> enumClass, final boolean ignoreCase)
|
||||
throws JSONRPC2Error {
|
||||
/**
|
||||
* Throws a {@code JSONRPC2Error.INVALID_PARAMS} exception if the input
|
||||
* string doesn't match a constant name in the specified enumeration
|
||||
* class.
|
||||
*
|
||||
* <p>This method is intended to check a string against a set of
|
||||
* acceptable values.
|
||||
*
|
||||
* @param input The string to check.
|
||||
* @param enumClass The enumeration class specifying the acceptable
|
||||
* constant names.
|
||||
* @param ignoreCase {@code true} for a case insensitive match.
|
||||
*
|
||||
* @return The matching enumeration constant.
|
||||
*
|
||||
* @throws JSONRPC2Error With proper code and message if the input
|
||||
* string didn't match.
|
||||
*/
|
||||
protected static <T extends Enum<T>> T ensureEnumString(final String input, final Class<T> enumClass, final boolean ignoreCase)
|
||||
throws JSONRPC2Error {
|
||||
|
||||
for (T en: enumClass.getEnumConstants()) {
|
||||
for (T en : enumClass.getEnumConstants()) {
|
||||
|
||||
if (ignoreCase) {
|
||||
if (en.toString().toLowerCase().equals(input.toLowerCase()))
|
||||
return en;
|
||||
}
|
||||
else {
|
||||
if (en.toString().equals(input))
|
||||
return en;
|
||||
}
|
||||
if (ignoreCase) {
|
||||
if (en.toString().toLowerCase().equals(input.toLowerCase()))
|
||||
return en;
|
||||
}
|
||||
else {
|
||||
if (en.toString().equals(input))
|
||||
return en;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// No match -> raise error
|
||||
throw JSONRPC2Error.INVALID_PARAMS;
|
||||
}
|
||||
// No match -> raise error
|
||||
throw JSONRPC2Error.INVALID_PARAMS;
|
||||
}
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@
|
||||
* <ul>
|
||||
* <li>The {@link com.thetransactioncompany.jsonrpc2.util.PositionalParamsRetriever}
|
||||
* class is for extracting <em>positional parameters</em> (packed in a
|
||||
* JSON array).
|
||||
* JSON array).
|
||||
* <li>The {@link com.thetransactioncompany.jsonrpc2.util.NamedParamsRetriever}
|
||||
* class is for extracting <em>named parameters</em> (packed in a JSON
|
||||
* object).
|
||||
|
@ -45,7 +45,7 @@ import java.security.KeyStore;
|
||||
*
|
||||
* @author hottuna
|
||||
*/
|
||||
public class I2PControlController{
|
||||
public class I2PControlController {
|
||||
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(I2PControlController.class);
|
||||
private static String _pluginDir = "";
|
||||
private static ConfigurationManager _conf;
|
||||
@ -57,7 +57,7 @@ public class I2PControlController{
|
||||
if (args.length != 3 || (!"-d".equals(args[0])))
|
||||
throw new IllegalArgumentException("Usage: PluginController -d $PLUGINDIR [start|stop]");
|
||||
|
||||
if ("start".equals(args[2])){
|
||||
if ("start".equals(args[2])) {
|
||||
File pluginDir = new File(args[1]);
|
||||
if (!pluginDir.exists())
|
||||
throw new IllegalArgumentException("Plugin directory " + pluginDir.getAbsolutePath() + " does not exist");
|
||||
@ -79,10 +79,10 @@ public class I2PControlController{
|
||||
I2PAppContext.getGlobalContext().logManager().getLog(JSONRPC2Servlet.class).setMinimumPriority(Log.DEBUG);
|
||||
|
||||
try {
|
||||
Connector ssl = buildDefaultListenter();
|
||||
Connector ssl = buildDefaultListenter();
|
||||
_server = buildServer(ssl);
|
||||
} catch (IOException e) {
|
||||
_log.error("Unable to add listener " + _conf.getConf("i2pcontrol.listen.address", "127.0.0.1")+":"+_conf.getConf("i2pcontrol.listen.port", 7560) + " - " + e.getMessage());
|
||||
_log.error("Unable to add listener " + _conf.getConf("i2pcontrol.listen.address", "127.0.0.1") + ":" + _conf.getConf("i2pcontrol.listen.port", 7560) + " - " + e.getMessage());
|
||||
} catch (ClassNotFoundException e) {
|
||||
_log.error("Unable to find class net.i2p.i2pcontrol.JSONRPCServlet: " + e.getMessage());
|
||||
} catch (InstantiationException e) {
|
||||
@ -103,7 +103,7 @@ public class I2PControlController{
|
||||
*/
|
||||
public static Connector buildDefaultListenter() throws UnknownHostException {
|
||||
SslSocketConnector ssl = buildSslListener(_conf.getConf("i2pcontrol.listen.address", "127.0.0.1"),
|
||||
_conf.getConf("i2pcontrol.listen.port", 7650));
|
||||
_conf.getConf("i2pcontrol.listen.port", 7650));
|
||||
return ssl;
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ public class I2PControlController{
|
||||
* @throws InstantiationException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public static Server buildServer(Connector ssl) throws UnknownHostException, Exception, InstantiationException, IllegalAccessException{
|
||||
public static Server buildServer(Connector ssl) throws UnknownHostException, Exception, InstantiationException, IllegalAccessException {
|
||||
Server server = new Server();
|
||||
server.addConnector(ssl);
|
||||
|
||||
@ -136,9 +136,9 @@ public class I2PControlController{
|
||||
* @return - Newly created listener
|
||||
* @throws UnknownHostException
|
||||
*/
|
||||
public static SslSocketConnector buildSslListener(String address, int port) throws UnknownHostException{
|
||||
public static SslSocketConnector buildSslListener(String address, int port) throws UnknownHostException {
|
||||
int listeners = 0;
|
||||
if (_server != null){
|
||||
if (_server != null) {
|
||||
listeners = _server.getConnectors().length;
|
||||
}
|
||||
|
||||
@ -166,9 +166,9 @@ public class I2PControlController{
|
||||
* @param listener
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void replaceListener(Connector listener) throws Exception{
|
||||
public static void replaceListener(Connector listener) throws Exception {
|
||||
if (_server != null) {
|
||||
stopServer();
|
||||
stopServer();
|
||||
}
|
||||
_server = buildServer(listener);
|
||||
}
|
||||
@ -177,8 +177,8 @@ public class I2PControlController{
|
||||
* Get all listeners of the server.
|
||||
* @return
|
||||
*/
|
||||
public static Connector[] getListeners(){
|
||||
if (_server != null){
|
||||
public static Connector[] getListeners() {
|
||||
if (_server != null) {
|
||||
return _server.getConnectors();
|
||||
}
|
||||
return new Connector[0];
|
||||
@ -187,9 +187,9 @@ public class I2PControlController{
|
||||
/**
|
||||
* Removes all listeners
|
||||
*/
|
||||
public static void clearListeners(){
|
||||
if (_server != null){
|
||||
for (Connector listen : getListeners()){
|
||||
public static void clearListeners() {
|
||||
if (_server != null) {
|
||||
for (Connector listen : getListeners()) {
|
||||
_server.removeConnector(listen);
|
||||
}
|
||||
}
|
||||
@ -198,9 +198,9 @@ public class I2PControlController{
|
||||
private static void stopServer()
|
||||
{
|
||||
try {
|
||||
if (_server != null){
|
||||
if (_server != null) {
|
||||
_server.stop();
|
||||
for (Connector listener : _server.getConnectors()){
|
||||
for (Connector listener : _server.getConnectors()) {
|
||||
listener.stop();
|
||||
}
|
||||
_server.destroy();
|
||||
@ -221,16 +221,16 @@ public class I2PControlController{
|
||||
|
||||
// Get and stop all running threads
|
||||
ThreadGroup threadgroup = Thread.currentThread().getThreadGroup();
|
||||
Thread[] threads = new Thread[threadgroup.activeCount()+3];
|
||||
Thread[] threads = new Thread[threadgroup.activeCount() + 3];
|
||||
threadgroup.enumerate(threads, true);
|
||||
for (Thread thread : threads){
|
||||
if (thread != null ){//&& thread.isAlive()){
|
||||
for (Thread thread : threads) {
|
||||
if (thread != null) {//&& thread.isAlive()){
|
||||
thread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
for (Thread thread : threads){
|
||||
if (thread != null){
|
||||
for (Thread thread : threads) {
|
||||
if (thread != null) {
|
||||
System.out.println("Active thread: " + thread.getName());
|
||||
}
|
||||
}
|
||||
@ -239,7 +239,7 @@ public class I2PControlController{
|
||||
//Thread.currentThread().getThreadGroup().destroy();
|
||||
}
|
||||
|
||||
public static String getPluginDir(){
|
||||
public static String getPluginDir() {
|
||||
return _pluginDir;
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ public class RouterManager {
|
||||
|
||||
public static RouterContext getRouterContext() throws Exception {
|
||||
// If not running as a plugin from within I2P.
|
||||
if(context.isRouterContext()) {
|
||||
if (context.isRouterContext()) {
|
||||
return (RouterContext) context;
|
||||
}else {
|
||||
} else {
|
||||
throw new Exception("No RouterContext available!");
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public class AuthToken {
|
||||
private String id;
|
||||
private Date expiry;
|
||||
|
||||
public AuthToken(String password){
|
||||
public AuthToken(String password) {
|
||||
_secMan = SecurityManager.getInstance();
|
||||
String hash = _secMan.getPasswdHash(password);
|
||||
this.id = _secMan.getHash(hash + Calendar.getInstance().getTimeInMillis());
|
||||
@ -20,7 +20,7 @@ public class AuthToken {
|
||||
this.expiry = expiry.getTime();
|
||||
}
|
||||
|
||||
public String getId(){
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -28,23 +28,23 @@ public class AuthToken {
|
||||
* Checks whether the AuthToken has expired.
|
||||
* @return True if AuthToken hasn't expired. False in any other case.
|
||||
*/
|
||||
public boolean isValid(){
|
||||
public boolean isValid() {
|
||||
return Calendar.getInstance().getTime().before(expiry);
|
||||
}
|
||||
|
||||
public String getExpiryTime(){
|
||||
public String getExpiryTime() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat();
|
||||
sdf.applyPattern("yyyy-MM-dd HH:mm:ss");
|
||||
return sdf.format(expiry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(){
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
package net.i2p.i2pcontrol.security;
|
||||
|
||||
public class ExpiredAuthTokenException extends Exception{
|
||||
public class ExpiredAuthTokenException extends Exception {
|
||||
private static final long serialVersionUID = 2279019346592900289L;
|
||||
|
||||
private String expiryTime;
|
||||
|
||||
public ExpiredAuthTokenException(String str, String expiryTime){
|
||||
public ExpiredAuthTokenException(String str, String expiryTime) {
|
||||
super(str);
|
||||
this.expiryTime = expiryTime;
|
||||
}
|
||||
|
||||
public String getExpirytime(){
|
||||
public String getExpirytime() {
|
||||
return expiryTime;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package net.i2p.i2pcontrol.security;
|
||||
|
||||
public class InvalidAuthTokenException extends Exception{
|
||||
public class InvalidAuthTokenException extends Exception {
|
||||
private static final long serialVersionUID = 7605321329341235577L;
|
||||
|
||||
public InvalidAuthTokenException(String str){
|
||||
public InvalidAuthTokenException(String str) {
|
||||
super(str);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import java.security.cert.X509Certificate;
|
||||
public class KeyStoreProvider {
|
||||
public static final String DEFAULT_CERTIFICATE_ALGORITHM_STRING = "RSA";
|
||||
public static final int DEFAULT_CERTIFICATE_KEY_LENGTH = 4096;
|
||||
public static final int DEFAULT_CERTIFICATE_VALIDITY = 365*10;
|
||||
public static final int DEFAULT_CERTIFICATE_VALIDITY = 365 * 10;
|
||||
public final static String DEFAULT_CERTIFICATE_DOMAIN = "net.i2p.i2pcontrol";
|
||||
public final static String DEFAULT_CERTIFICATE_ALIAS = "I2PControl CA";
|
||||
public static final String DEFAULT_KEYSTORE_NAME = "key.store";
|
||||
@ -30,8 +30,8 @@ public class KeyStoreProvider {
|
||||
DEFAULT_KEYSTORE_PASSWORD);
|
||||
}
|
||||
|
||||
public static X509Certificate readCert(KeyStore ks, String certAlias, String password){
|
||||
try{
|
||||
public static X509Certificate readCert(KeyStore ks, String certAlias, String password) {
|
||||
try {
|
||||
X509Certificate cert = (X509Certificate) ks.getCertificate(certAlias);
|
||||
|
||||
if (cert == null) {
|
||||
@ -45,13 +45,13 @@ public class KeyStoreProvider {
|
||||
System.err.println("Failed to verify caCert certificate against caCert");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (KeyStoreException e){
|
||||
} catch (KeyStoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static X509Certificate readCert(File keyStoreFile, String certAlias, String password){
|
||||
public static X509Certificate readCert(File keyStoreFile, String certAlias, String password) {
|
||||
try {
|
||||
KeyStore ks = getDefaultKeyStore();
|
||||
ks.load(new FileInputStream(keyStoreFile), password.toCharArray());
|
||||
@ -68,7 +68,7 @@ public class KeyStoreProvider {
|
||||
System.err.println("Failed to verify caCert certificate against caCert");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IOException e){
|
||||
} catch (IOException e) {
|
||||
System.err.println("Couldn't read keystore from: " + keyStoreFile.toString());
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
@ -82,7 +82,7 @@ public class KeyStoreProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PrivateKey readPrivateKey(KeyStore ks, String alias, String password){
|
||||
public static PrivateKey readPrivateKey(KeyStore ks, String alias, String password) {
|
||||
try {
|
||||
// load the key entry from the keystore
|
||||
Key key = ks.getKey(alias, password.toCharArray());
|
||||
@ -93,17 +93,17 @@ public class KeyStoreProvider {
|
||||
|
||||
PrivateKey privKey = (PrivateKey) key;
|
||||
return privKey;
|
||||
} catch (UnrecoverableKeyException e){
|
||||
} catch (UnrecoverableKeyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e){
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (KeyStoreException e){
|
||||
} catch (KeyStoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PrivateKey readPrivateKey(String alias, File keyStoreFile, String keyStorePassword, String keyPassword){
|
||||
public static PrivateKey readPrivateKey(String alias, File keyStoreFile, String keyStorePassword, String keyPassword) {
|
||||
try {
|
||||
KeyStore ks = getDefaultKeyStore();
|
||||
ks.load(new FileInputStream(keyStoreFile), keyStorePassword.toCharArray());
|
||||
@ -121,13 +121,13 @@ public class KeyStoreProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static KeyStore writeCACertToKeyStore(KeyStore keyStore, String keyPassword, String alias, PrivateKey caPrivKey, X509Certificate caCert){
|
||||
public static KeyStore writeCACertToKeyStore(KeyStore keyStore, String keyPassword, String alias, PrivateKey caPrivKey, X509Certificate caCert) {
|
||||
try {
|
||||
X509Certificate[] chain = new X509Certificate[1];
|
||||
chain[0] = caCert;
|
||||
|
||||
keyStore.setKeyEntry(alias, caPrivKey, keyPassword.toCharArray(), chain);
|
||||
File keyStoreFile = new File(I2PControlController.getPluginDir()+File.separator+DEFAULT_KEYSTORE_NAME);
|
||||
File keyStoreFile = new File(I2PControlController.getPluginDir() + File.separator + DEFAULT_KEYSTORE_NAME);
|
||||
keyStore.store(new FileOutputStream(keyStoreFile), DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
||||
return keyStore;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
@ -144,13 +144,13 @@ public class KeyStoreProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static synchronized KeyStore getDefaultKeyStore(){
|
||||
if (_keystore == null){
|
||||
public static synchronized KeyStore getDefaultKeyStore() {
|
||||
if (_keystore == null) {
|
||||
File keyStoreFile = new File(getKeyStoreLocation());
|
||||
|
||||
try {
|
||||
_keystore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
if (keyStoreFile.exists()){
|
||||
if (keyStoreFile.exists()) {
|
||||
InputStream is = new FileInputStream(keyStoreFile);
|
||||
_keystore.load(is, DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
||||
return _keystore;
|
||||
@ -158,7 +158,7 @@ public class KeyStoreProvider {
|
||||
|
||||
initialize();
|
||||
_keystore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
if (keyStoreFile.exists()){
|
||||
if (keyStoreFile.exists()) {
|
||||
InputStream is = new FileInputStream(keyStoreFile);
|
||||
_keystore.load(is, DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
||||
return _keystore;
|
||||
@ -174,8 +174,8 @@ public class KeyStoreProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getKeyStoreLocation(){
|
||||
File keyStoreFile = new File(I2PControlController.getPluginDir()+File.separator+DEFAULT_KEYSTORE_NAME);
|
||||
public static String getKeyStoreLocation() {
|
||||
File keyStoreFile = new File(I2PControlController.getPluginDir() + File.separator + DEFAULT_KEYSTORE_NAME);
|
||||
return keyStoreFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
@ -38,48 +38,48 @@ public class SecurityManager {
|
||||
private final static String SSL_PROVIDER = "SunJSSE";
|
||||
private final static String DEFAULT_AUTH_BCRYPT_SALT = "$2a$11$5aOLx2x/8i4fNaitoCSSWu";
|
||||
private final static String DEFAULT_AUTH_PASSWORD = "$2a$11$5aOLx2x/8i4fNaitoCSSWuut2wEl3Hupuca8DCT.NXzvH9fq1pBU.";
|
||||
private HashMap<String,AuthToken> authTokens;
|
||||
private HashMap<String, AuthToken> authTokens;
|
||||
private Timer timer;
|
||||
private String[] SSL_CIPHER_SUITES;
|
||||
private KeyStore _ks;
|
||||
private Log _log;
|
||||
private static SecurityManager _securityManager;
|
||||
|
||||
public static SecurityManager getInstance(){
|
||||
if (_securityManager == null){
|
||||
public static SecurityManager getInstance() {
|
||||
if (_securityManager == null) {
|
||||
_securityManager = new SecurityManager();
|
||||
}
|
||||
return _securityManager;
|
||||
}
|
||||
|
||||
private SecurityManager(){
|
||||
private SecurityManager() {
|
||||
_log = I2PAppContext.getGlobalContext().logManager().getLog(SecurityManager.class);
|
||||
authTokens = new HashMap<String,AuthToken>();
|
||||
authTokens = new HashMap<String, AuthToken>();
|
||||
|
||||
timer = new Timer("SecurityManager Timer Sweeper ");
|
||||
// Start running periodic task after 20 minutes, run periodically every 10th minute.
|
||||
timer.scheduleAtFixedRate(new Sweeper(), 1000*60*20, 1000*60*10);
|
||||
timer.scheduleAtFixedRate(new Sweeper(), 1000 * 60 * 20, 1000 * 60 * 10);
|
||||
|
||||
// Get supported SSL cipher suites.
|
||||
SocketFactory SSLF = SSLSocketFactory.getDefault();
|
||||
try{
|
||||
SSL_CIPHER_SUITES = ((SSLSocket)SSLF.createSocket()).getSupportedCipherSuites();
|
||||
} catch (Exception e){
|
||||
try {
|
||||
SSL_CIPHER_SUITES = ((SSLSocket)SSLF.createSocket()).getSupportedCipherSuites();
|
||||
} catch (Exception e) {
|
||||
_log.log(Log.CRIT, "Unable to create SSLSocket used for fetching supported ssl cipher suites.", e);
|
||||
}
|
||||
|
||||
_ks = KeyStoreProvider.getDefaultKeyStore();
|
||||
}
|
||||
|
||||
public String[] getSupprtedSSLCipherSuites(){
|
||||
public String[] getSupprtedSSLCipherSuites() {
|
||||
return SSL_CIPHER_SUITES;
|
||||
}
|
||||
|
||||
public String getSecurityProvider(){
|
||||
public String getSecurityProvider() {
|
||||
return SSL_PROVIDER;
|
||||
}
|
||||
|
||||
public void stopTimedEvents(){
|
||||
public void stopTimedEvents() {
|
||||
timer.cancel();
|
||||
}
|
||||
|
||||
@ -87,10 +87,10 @@ public class SecurityManager {
|
||||
* Return the X509Certificate of the server as a Base64 encoded string.
|
||||
* @return base64 encode of X509Certificate
|
||||
*/
|
||||
public String getBase64Cert(){
|
||||
public String getBase64Cert() {
|
||||
X509Certificate caCert = KeyStoreProvider.readCert(_ks,
|
||||
KeyStoreProvider.DEFAULT_CERTIFICATE_ALIAS,
|
||||
KeyStoreProvider.DEFAULT_KEYSTORE_PASSWORD);
|
||||
KeyStoreProvider.DEFAULT_CERTIFICATE_ALIAS,
|
||||
KeyStoreProvider.DEFAULT_KEYSTORE_PASSWORD);
|
||||
return getBase64FromCert(caCert);
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ public class SecurityManager {
|
||||
* @param cert
|
||||
* @return base64 encode of X509Certificate
|
||||
*/
|
||||
private static String getBase64FromCert(X509Certificate cert){
|
||||
private static String getBase64FromCert(X509Certificate cert) {
|
||||
try {
|
||||
return Base64.encode(cert.getEncoded());
|
||||
} catch (CertificateEncodingException e) {
|
||||
@ -115,7 +115,7 @@ public class SecurityManager {
|
||||
* @param pwd
|
||||
* @return BCrypt hash of salt and input string
|
||||
*/
|
||||
public String getPasswdHash(String pwd){
|
||||
public String getPasswdHash(String pwd) {
|
||||
return BCrypt.hashpw(pwd, ConfigurationManager.getInstance().getConf("auth.salt", DEFAULT_AUTH_BCRYPT_SALT));
|
||||
}
|
||||
|
||||
@ -137,9 +137,9 @@ public class SecurityManager {
|
||||
* The token will be valid for one day.
|
||||
* @return Returns AuthToken if password is valid. If password is invalid null will be returned.
|
||||
*/
|
||||
public AuthToken validatePasswd(String pwd){
|
||||
public AuthToken validatePasswd(String pwd) {
|
||||
String storedPass = ConfigurationManager.getInstance().getConf("auth.password", DEFAULT_AUTH_PASSWORD);
|
||||
if (getPasswdHash(pwd).equals(storedPass)){
|
||||
if (getPasswdHash(pwd).equals(storedPass)) {
|
||||
AuthToken token = new AuthToken(pwd);
|
||||
synchronized (authTokens) {
|
||||
authTokens.put(token.getId(), token);
|
||||
@ -155,11 +155,11 @@ public class SecurityManager {
|
||||
* @param newPasswd
|
||||
* @return Returns true if a new password was set.
|
||||
*/
|
||||
public boolean setPasswd(String newPasswd){
|
||||
public boolean setPasswd(String newPasswd) {
|
||||
String newHash = getPasswdHash(newPasswd);
|
||||
String oldHash = ConfigurationManager.getInstance().getConf("auth.password", DEFAULT_AUTH_PASSWORD);
|
||||
|
||||
if (!newHash.equals(oldHash)){
|
||||
if (!newHash.equals(oldHash)) {
|
||||
ConfigurationManager.getInstance().setConf("auth.password", newHash);
|
||||
synchronized (authTokens) {
|
||||
authTokens.clear();
|
||||
@ -177,9 +177,9 @@ public class SecurityManager {
|
||||
*/
|
||||
public void verifyToken(String tokenID) throws InvalidAuthTokenException, ExpiredAuthTokenException {
|
||||
AuthToken token = authTokens.get(tokenID);
|
||||
if (token == null){
|
||||
if (token == null) {
|
||||
throw new InvalidAuthTokenException("AuthToken with ID: " + tokenID + " couldn't be found.");
|
||||
} else if (!token.isValid()){
|
||||
} else if (!token.isValid()) {
|
||||
synchronized (authTokens) {
|
||||
authTokens.remove(token.getId());
|
||||
}
|
||||
@ -194,19 +194,19 @@ public class SecurityManager {
|
||||
* @author hottuna
|
||||
*
|
||||
*/
|
||||
private class Sweeper extends TimerTask{
|
||||
private class Sweeper extends TimerTask {
|
||||
@Override
|
||||
public void run(){
|
||||
public void run() {
|
||||
_log.debug("Starting cleanup job..");
|
||||
ArrayList<String> arr = new ArrayList<String>();
|
||||
for (Map.Entry<String,AuthToken> e : authTokens.entrySet()){
|
||||
for (Map.Entry<String, AuthToken> e : authTokens.entrySet()) {
|
||||
AuthToken token = e.getValue();
|
||||
if (!token.isValid()){
|
||||
if (!token.isValid()) {
|
||||
arr.add(e.getKey());
|
||||
}
|
||||
}
|
||||
synchronized (authTokens) {
|
||||
for (String s : arr){
|
||||
for (String s : arr) {
|
||||
authTokens.remove(s);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,176 +23,176 @@
|
||||
// * @version 0.2
|
||||
// */
|
||||
//public class TestBCrypt extends TestCase {
|
||||
// String test_vectors[][] = {
|
||||
// { "",
|
||||
// "$2a$06$DCq7YPn5Rq63x1Lad4cll.",
|
||||
// "$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s." },
|
||||
// { "",
|
||||
// "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.",
|
||||
// "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye" },
|
||||
// { "",
|
||||
// "$2a$10$k1wbIrmNyFAPwPVPSVa/ze",
|
||||
// "$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW" },
|
||||
// { "",
|
||||
// "$2a$12$k42ZFHFWqBp3vWli.nIn8u",
|
||||
// "$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO" },
|
||||
// { "a",
|
||||
// "$2a$06$m0CrhHm10qJ3lXRY.5zDGO",
|
||||
// "$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe" },
|
||||
// { "a",
|
||||
// "$2a$08$cfcvVd2aQ8CMvoMpP2EBfe",
|
||||
// "$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V." },
|
||||
// { "a",
|
||||
// "$2a$10$k87L/MF28Q673VKh8/cPi.",
|
||||
// "$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u" },
|
||||
// { "a",
|
||||
// "$2a$12$8NJH3LsPrANStV6XtBakCe",
|
||||
// "$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS" },
|
||||
// { "abc",
|
||||
// "$2a$06$If6bvum7DFjUnE9p2uDeDu",
|
||||
// "$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i" },
|
||||
// { "abc",
|
||||
// "$2a$08$Ro0CUfOqk6cXEKf3dyaM7O",
|
||||
// "$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm" },
|
||||
// { "abc",
|
||||
// "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.",
|
||||
// "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi" },
|
||||
// { "abc",
|
||||
// "$2a$12$EXRkfkdmXn2gzds2SSitu.",
|
||||
// "$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q" },
|
||||
// { "abcdefghijklmnopqrstuvwxyz",
|
||||
// "$2a$06$.rCVZVOThsIa97pEDOxvGu",
|
||||
// "$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC" },
|
||||
// { "abcdefghijklmnopqrstuvwxyz",
|
||||
// "$2a$08$aTsUwsyowQuzRrDqFflhge",
|
||||
// "$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz." },
|
||||
// { "abcdefghijklmnopqrstuvwxyz",
|
||||
// "$2a$10$fVH8e28OQRj9tqiDXs1e1u",
|
||||
// "$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq" },
|
||||
// { "abcdefghijklmnopqrstuvwxyz",
|
||||
// "$2a$12$D4G5f18o7aMMfwasBL7Gpu",
|
||||
// "$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG" },
|
||||
// { "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
||||
// "$2a$06$fPIsBO8qRqkjj273rfaOI.",
|
||||
// "$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO" },
|
||||
// { "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
||||
// "$2a$08$Eq2r4G/76Wv39MzSX262hu",
|
||||
// "$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW" },
|
||||
// { "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
||||
// "$2a$10$LgfYWkbzEvQ4JakH7rOvHe",
|
||||
// "$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS" },
|
||||
// { "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
||||
// "$2a$12$WApznUOJfkEGSmYRfnkrPO",
|
||||
// "$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC" },
|
||||
// };
|
||||
// String test_vectors[][] = {
|
||||
// { "",
|
||||
// "$2a$06$DCq7YPn5Rq63x1Lad4cll.",
|
||||
// "$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s." },
|
||||
// { "",
|
||||
// "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.",
|
||||
// "$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye" },
|
||||
// { "",
|
||||
// "$2a$10$k1wbIrmNyFAPwPVPSVa/ze",
|
||||
// "$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW" },
|
||||
// { "",
|
||||
// "$2a$12$k42ZFHFWqBp3vWli.nIn8u",
|
||||
// "$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO" },
|
||||
// { "a",
|
||||
// "$2a$06$m0CrhHm10qJ3lXRY.5zDGO",
|
||||
// "$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe" },
|
||||
// { "a",
|
||||
// "$2a$08$cfcvVd2aQ8CMvoMpP2EBfe",
|
||||
// "$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V." },
|
||||
// { "a",
|
||||
// "$2a$10$k87L/MF28Q673VKh8/cPi.",
|
||||
// "$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u" },
|
||||
// { "a",
|
||||
// "$2a$12$8NJH3LsPrANStV6XtBakCe",
|
||||
// "$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS" },
|
||||
// { "abc",
|
||||
// "$2a$06$If6bvum7DFjUnE9p2uDeDu",
|
||||
// "$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i" },
|
||||
// { "abc",
|
||||
// "$2a$08$Ro0CUfOqk6cXEKf3dyaM7O",
|
||||
// "$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm" },
|
||||
// { "abc",
|
||||
// "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.",
|
||||
// "$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi" },
|
||||
// { "abc",
|
||||
// "$2a$12$EXRkfkdmXn2gzds2SSitu.",
|
||||
// "$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q" },
|
||||
// { "abcdefghijklmnopqrstuvwxyz",
|
||||
// "$2a$06$.rCVZVOThsIa97pEDOxvGu",
|
||||
// "$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC" },
|
||||
// { "abcdefghijklmnopqrstuvwxyz",
|
||||
// "$2a$08$aTsUwsyowQuzRrDqFflhge",
|
||||
// "$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz." },
|
||||
// { "abcdefghijklmnopqrstuvwxyz",
|
||||
// "$2a$10$fVH8e28OQRj9tqiDXs1e1u",
|
||||
// "$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq" },
|
||||
// { "abcdefghijklmnopqrstuvwxyz",
|
||||
// "$2a$12$D4G5f18o7aMMfwasBL7Gpu",
|
||||
// "$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG" },
|
||||
// { "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
||||
// "$2a$06$fPIsBO8qRqkjj273rfaOI.",
|
||||
// "$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO" },
|
||||
// { "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
||||
// "$2a$08$Eq2r4G/76Wv39MzSX262hu",
|
||||
// "$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW" },
|
||||
// { "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
||||
// "$2a$10$LgfYWkbzEvQ4JakH7rOvHe",
|
||||
// "$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS" },
|
||||
// { "~!@#$%^&*() ~!@#$%^&*()PNBFRD",
|
||||
// "$2a$12$WApznUOJfkEGSmYRfnkrPO",
|
||||
// "$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC" },
|
||||
// };
|
||||
//
|
||||
// /**
|
||||
// * Entry point for unit tests
|
||||
// * @param args unused
|
||||
// */
|
||||
// public static void main(String[] args) {
|
||||
// junit.textui.TestRunner.run(TestBCrypt.class);
|
||||
// }
|
||||
// /**
|
||||
// * Entry point for unit tests
|
||||
// * @param args unused
|
||||
// */
|
||||
// public static void main(String[] args) {
|
||||
// junit.textui.TestRunner.run(TestBCrypt.class);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Test method for 'BCrypt.hashpw(String, String)'
|
||||
// */
|
||||
// public void testHashpw() {
|
||||
// System.out.print("BCrypt.hashpw(): ");
|
||||
// for (int i = 0; i < test_vectors.length; i++) {
|
||||
// String plain = test_vectors[i][0];
|
||||
// String salt = test_vectors[i][1];
|
||||
// String expected = test_vectors[i][2];
|
||||
// String hashed = BCrypt.hashpw(plain, salt);
|
||||
// assertEquals(hashed, expected);
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
// /**
|
||||
// * Test method for 'BCrypt.hashpw(String, String)'
|
||||
// */
|
||||
// public void testHashpw() {
|
||||
// System.out.print("BCrypt.hashpw(): ");
|
||||
// for (int i = 0; i < test_vectors.length; i++) {
|
||||
// String plain = test_vectors[i][0];
|
||||
// String salt = test_vectors[i][1];
|
||||
// String expected = test_vectors[i][2];
|
||||
// String hashed = BCrypt.hashpw(plain, salt);
|
||||
// assertEquals(hashed, expected);
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Test method for 'BCrypt.gensalt(int)'
|
||||
// */
|
||||
// public void testGensaltInt() {
|
||||
// System.out.print("BCrypt.gensalt(log_rounds):");
|
||||
// for (int i = 4; i <= 12; i++) {
|
||||
// System.out.print(" " + Integer.toString(i) + ":");
|
||||
// for (int j = 0; j < test_vectors.length; j += 4) {
|
||||
// String plain = test_vectors[j][0];
|
||||
// String salt = BCrypt.gensalt(i);
|
||||
// String hashed1 = BCrypt.hashpw(plain, salt);
|
||||
// String hashed2 = BCrypt.hashpw(plain, hashed1);
|
||||
// assertEquals(hashed1, hashed2);
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
// /**
|
||||
// * Test method for 'BCrypt.gensalt(int)'
|
||||
// */
|
||||
// public void testGensaltInt() {
|
||||
// System.out.print("BCrypt.gensalt(log_rounds):");
|
||||
// for (int i = 4; i <= 12; i++) {
|
||||
// System.out.print(" " + Integer.toString(i) + ":");
|
||||
// for (int j = 0; j < test_vectors.length; j += 4) {
|
||||
// String plain = test_vectors[j][0];
|
||||
// String salt = BCrypt.gensalt(i);
|
||||
// String hashed1 = BCrypt.hashpw(plain, salt);
|
||||
// String hashed2 = BCrypt.hashpw(plain, hashed1);
|
||||
// assertEquals(hashed1, hashed2);
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Test method for 'BCrypt.gensalt()'
|
||||
// */
|
||||
// public void testGensalt() {
|
||||
// System.out.print("BCrypt.gensalt(): ");
|
||||
// for (int i = 0; i < test_vectors.length; i += 4) {
|
||||
// String plain = test_vectors[i][0];
|
||||
// String salt = BCrypt.gensalt();
|
||||
// String hashed1 = BCrypt.hashpw(plain, salt);
|
||||
// String hashed2 = BCrypt.hashpw(plain, hashed1);
|
||||
// assertEquals(hashed1, hashed2);
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
// /**
|
||||
// * Test method for 'BCrypt.gensalt()'
|
||||
// */
|
||||
// public void testGensalt() {
|
||||
// System.out.print("BCrypt.gensalt(): ");
|
||||
// for (int i = 0; i < test_vectors.length; i += 4) {
|
||||
// String plain = test_vectors[i][0];
|
||||
// String salt = BCrypt.gensalt();
|
||||
// String hashed1 = BCrypt.hashpw(plain, salt);
|
||||
// String hashed2 = BCrypt.hashpw(plain, hashed1);
|
||||
// assertEquals(hashed1, hashed2);
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Test method for 'BCrypt.checkpw(String, String)'
|
||||
// * expecting success
|
||||
// */
|
||||
// public void testCheckpw_success() {
|
||||
// System.out.print("BCrypt.checkpw w/ good passwords: ");
|
||||
// for (int i = 0; i < test_vectors.length; i++) {
|
||||
// String plain = test_vectors[i][0];
|
||||
// String expected = test_vectors[i][2];
|
||||
// assertTrue(BCrypt.checkpw(plain, expected));
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
// /**
|
||||
// * Test method for 'BCrypt.checkpw(String, String)'
|
||||
// * expecting success
|
||||
// */
|
||||
// public void testCheckpw_success() {
|
||||
// System.out.print("BCrypt.checkpw w/ good passwords: ");
|
||||
// for (int i = 0; i < test_vectors.length; i++) {
|
||||
// String plain = test_vectors[i][0];
|
||||
// String expected = test_vectors[i][2];
|
||||
// assertTrue(BCrypt.checkpw(plain, expected));
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Test method for 'BCrypt.checkpw(String, String)'
|
||||
// * expecting failure
|
||||
// */
|
||||
// public void testCheckpw_failure() {
|
||||
// System.out.print("BCrypt.checkpw w/ bad passwords: ");
|
||||
// for (int i = 0; i < test_vectors.length; i++) {
|
||||
// int broken_index = (i + 4) % test_vectors.length;
|
||||
// String plain = test_vectors[i][0];
|
||||
// String expected = test_vectors[broken_index][2];
|
||||
// assertFalse(BCrypt.checkpw(plain, expected));
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
// /**
|
||||
// * Test method for 'BCrypt.checkpw(String, String)'
|
||||
// * expecting failure
|
||||
// */
|
||||
// public void testCheckpw_failure() {
|
||||
// System.out.print("BCrypt.checkpw w/ bad passwords: ");
|
||||
// for (int i = 0; i < test_vectors.length; i++) {
|
||||
// int broken_index = (i + 4) % test_vectors.length;
|
||||
// String plain = test_vectors[i][0];
|
||||
// String expected = test_vectors[broken_index][2];
|
||||
// assertFalse(BCrypt.checkpw(plain, expected));
|
||||
// System.out.print(".");
|
||||
// }
|
||||
// System.out.println("");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Test for correct hashing of non-US-ASCII passwords
|
||||
// */
|
||||
// public void testInternationalChars() {
|
||||
// System.out.print("BCrypt.hashpw w/ international chars: ");
|
||||
// String pw1 = "ππππππππ";
|
||||
// String pw2 = "????????";
|
||||
// /**
|
||||
// * Test for correct hashing of non-US-ASCII passwords
|
||||
// */
|
||||
// public void testInternationalChars() {
|
||||
// System.out.print("BCrypt.hashpw w/ international chars: ");
|
||||
// String pw1 = "ππππππππ";
|
||||
// String pw2 = "????????";
|
||||
//
|
||||
// String h1 = BCrypt.hashpw(pw1, BCrypt.gensalt());
|
||||
// assertFalse(BCrypt.checkpw(pw2, h1));
|
||||
// System.out.print(".");
|
||||
// String h1 = BCrypt.hashpw(pw1, BCrypt.gensalt());
|
||||
// assertFalse(BCrypt.checkpw(pw2, h1));
|
||||
// System.out.print(".");
|
||||
//
|
||||
// String h2 = BCrypt.hashpw(pw2, BCrypt.gensalt());
|
||||
// assertFalse(BCrypt.checkpw(pw1, h2));
|
||||
// System.out.print(".");
|
||||
// System.out.println("");
|
||||
// }
|
||||
// String h2 = BCrypt.hashpw(pw2, BCrypt.gensalt());
|
||||
// assertFalse(BCrypt.checkpw(pw1, h2));
|
||||
// System.out.print(".");
|
||||
// System.out.println("");
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
|
@ -34,7 +34,7 @@ import java.io.*;
|
||||
/**
|
||||
* Provide an JSON-RPC 2.0 API for remote controlling of I2P
|
||||
*/
|
||||
public class JSONRPC2Servlet extends HttpServlet{
|
||||
public class JSONRPC2Servlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = -45075606818515212L;
|
||||
private static final int BUFFER_LENGTH = 2048;
|
||||
@ -44,7 +44,7 @@ public class JSONRPC2Servlet extends HttpServlet{
|
||||
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
public void init() {
|
||||
_log = I2PAppContext.getGlobalContext().logManager().getLog(JSONRPC2Servlet.class);
|
||||
readBuffer = new char[BUFFER_LENGTH];
|
||||
|
||||
@ -60,7 +60,7 @@ public class JSONRPC2Servlet extends HttpServlet{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException{
|
||||
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
|
||||
httpServletResponse.setContentType("text/html");
|
||||
PrintWriter out = httpServletResponse.getWriter();
|
||||
out.println("Nothing to see here");
|
||||
@ -68,7 +68,7 @@ public class JSONRPC2Servlet extends HttpServlet{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException{
|
||||
protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
|
||||
String req = getRequest(httpServletRequest.getInputStream());
|
||||
httpServletResponse.setContentType("application/json");
|
||||
PrintWriter out = httpServletResponse.getWriter();
|
||||
@ -95,10 +95,10 @@ public class JSONRPC2Servlet extends HttpServlet{
|
||||
}
|
||||
}
|
||||
|
||||
private String getRequest(ServletInputStream sis) throws IOException{
|
||||
private String getRequest(ServletInputStream sis) throws IOException {
|
||||
Writer writer = new StringWriter();
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(sis,"UTF-8"));
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(sis, "UTF-8"));
|
||||
int n;
|
||||
while ((n = reader.read(readBuffer)) != -1) {
|
||||
writer.write(readBuffer, 0, n);
|
||||
|
@ -33,9 +33,9 @@ public class ConfigurationManager {
|
||||
* Should only be set before getInstance is first called.
|
||||
* @param dir
|
||||
*/
|
||||
public static void setConfDir(String dir){
|
||||
if (!configLocationModified){
|
||||
if (dir.endsWith("/")){
|
||||
public static void setConfDir(String dir) {
|
||||
if (!configLocationModified) {
|
||||
if (dir.endsWith("/")) {
|
||||
configLocation = dir + configLocation;
|
||||
} else {
|
||||
configLocation = dir + "/" + configLocation;
|
||||
@ -48,7 +48,7 @@ public class ConfigurationManager {
|
||||
}
|
||||
|
||||
public synchronized static ConfigurationManager getInstance() {
|
||||
if(instance == null) {
|
||||
if (instance == null) {
|
||||
instance = new ConfigurationManager();
|
||||
}
|
||||
return instance;
|
||||
@ -60,9 +60,9 @@ public class ConfigurationManager {
|
||||
* @param settingNames Command line settingNameuments to the application
|
||||
*/
|
||||
public void loadsettingNameuments(String[] settingNames) {
|
||||
for(int i=0; i<settingNames.length; i++) {
|
||||
for (int i = 0; i < settingNames.length; i++) {
|
||||
String settingName = settingNames[i];
|
||||
if(settingName.startsWith("--")) {
|
||||
if (settingName.startsWith("--")) {
|
||||
parseConfigStr(settingName.substring(2));
|
||||
}
|
||||
}
|
||||
@ -71,11 +71,11 @@ public class ConfigurationManager {
|
||||
/**
|
||||
* Reads configuration from file itoopie.conf, every line is parsed as key=value.
|
||||
*/
|
||||
public static void readConfFile(){
|
||||
public static void readConfFile() {
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(configLocation));
|
||||
String input;
|
||||
while ((input = br.readLine()) != null){
|
||||
while ((input = br.readLine()) != null) {
|
||||
parseConfigStr(input);
|
||||
}
|
||||
br.close();
|
||||
@ -89,20 +89,20 @@ public class ConfigurationManager {
|
||||
/**
|
||||
* Write configuration into default config file.
|
||||
*/
|
||||
public static void writeConfFile(){
|
||||
TreeMap<String,String> tree = new TreeMap<String,String>();
|
||||
for (Entry<String,String> e : stringConfigurations.entrySet()){
|
||||
public static void writeConfFile() {
|
||||
TreeMap<String, String> tree = new TreeMap<String, String>();
|
||||
for (Entry<String, String> e : stringConfigurations.entrySet()) {
|
||||
tree.put(e.getKey(), e.getValue());
|
||||
}
|
||||
for (Entry<String,Integer> e : integerConfigurations.entrySet()){
|
||||
for (Entry<String, Integer> e : integerConfigurations.entrySet()) {
|
||||
tree.put(e.getKey(), e.getValue().toString());
|
||||
}
|
||||
for (Entry<String,Boolean> e : booleanConfigurations.entrySet()){
|
||||
for (Entry<String, Boolean> e : booleanConfigurations.entrySet()) {
|
||||
tree.put(e.getKey(), e.getValue().toString());
|
||||
}
|
||||
try {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(configLocation));
|
||||
for (Entry<String,String> e : tree.entrySet()){
|
||||
for (Entry<String, String> e : tree.entrySet()) {
|
||||
bw.write(e.getKey() + "=" + e.getValue() + "\r\n");
|
||||
}
|
||||
bw.close();
|
||||
@ -116,22 +116,22 @@ public class ConfigurationManager {
|
||||
* where value will (in order) be parsed as integer/boolean/string.
|
||||
* @param str
|
||||
*/
|
||||
public static void parseConfigStr(String str){
|
||||
public static void parseConfigStr(String str) {
|
||||
int eqIndex = str.indexOf('=');
|
||||
if (eqIndex != -1){
|
||||
if (eqIndex != -1) {
|
||||
String key = str.substring(0, eqIndex).trim().toLowerCase();
|
||||
String value = str.substring(eqIndex+1, str.length()).trim();
|
||||
String value = str.substring(eqIndex + 1, str.length()).trim();
|
||||
//Try parse as integer.
|
||||
try {
|
||||
int i = Integer.parseInt(value);
|
||||
integerConfigurations.put(key, i);
|
||||
return;
|
||||
} catch (NumberFormatException e){}
|
||||
} catch (NumberFormatException e) {}
|
||||
//Check if value is a bool
|
||||
if (value.toLowerCase().equals("true")){
|
||||
if (value.toLowerCase().equals("true")) {
|
||||
booleanConfigurations.put(key, Boolean.TRUE);
|
||||
return;
|
||||
} else if (value.toLowerCase().equals("false")){
|
||||
} else if (value.toLowerCase().equals("false")) {
|
||||
booleanConfigurations.put(key, Boolean.FALSE);
|
||||
return;
|
||||
}
|
||||
@ -148,7 +148,7 @@ public class ConfigurationManager {
|
||||
*/
|
||||
public boolean getConf(String settingName, boolean defaultValue) {
|
||||
Boolean value = booleanConfigurations.get(settingName);
|
||||
if(value != null) {
|
||||
if (value != null) {
|
||||
return value;
|
||||
} else {
|
||||
booleanConfigurations.put(settingName, defaultValue);
|
||||
@ -165,7 +165,7 @@ public class ConfigurationManager {
|
||||
*/
|
||||
public int getConf(String settingName, int defaultValue) {
|
||||
Integer value = integerConfigurations.get(settingName);
|
||||
if(value != null) {
|
||||
if (value != null) {
|
||||
return value;
|
||||
} else {
|
||||
integerConfigurations.put(settingName, defaultValue);
|
||||
@ -181,7 +181,7 @@ public class ConfigurationManager {
|
||||
*/
|
||||
public String getConf(String settingName, String defaultValue) {
|
||||
String value = stringConfigurations.get(settingName);
|
||||
if(value != null) {
|
||||
if (value != null) {
|
||||
return value;
|
||||
} else {
|
||||
stringConfigurations.put(settingName, defaultValue);
|
||||
@ -194,7 +194,7 @@ public class ConfigurationManager {
|
||||
* @param settingName
|
||||
* @param nbr
|
||||
*/
|
||||
public void setConf(String settingName, int nbr){
|
||||
public void setConf(String settingName, int nbr) {
|
||||
integerConfigurations.put(settingName, nbr);
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ public class ConfigurationManager {
|
||||
* @param settingName
|
||||
* @param string
|
||||
*/
|
||||
public void setConf(String settingName, String str){
|
||||
public void setConf(String settingName, String str) {
|
||||
stringConfigurations.put(settingName, str);
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ public class ConfigurationManager {
|
||||
* @param settingName
|
||||
* @param boolean
|
||||
*/
|
||||
public void setConf(String settingName, boolean bool){
|
||||
public void setConf(String settingName, boolean bool) {
|
||||
booleanConfigurations.put(settingName, bool);
|
||||
}
|
||||
}
|
||||
|
@ -13,9 +13,7 @@ import net.i2p.util.Log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
public class AdvancedSettingsHandler implements RequestHandler {
|
||||
@ -23,7 +21,7 @@ public class AdvancedSettingsHandler implements RequestHandler {
|
||||
private static RouterContext _context;
|
||||
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(AdvancedSettingsHandler.class);
|
||||
|
||||
static{
|
||||
static {
|
||||
try {
|
||||
_context = RouterManager.getRouterContext();
|
||||
} catch (Exception e) {
|
||||
@ -34,12 +32,12 @@ public class AdvancedSettingsHandler implements RequestHandler {
|
||||
private String[] requiredArgs = {};
|
||||
// Reports the method names of the handled requests
|
||||
public String[] handledRequests() {
|
||||
return new String[]{"AdvancedSettings"};
|
||||
return new String[] {"AdvancedSettings"};
|
||||
}
|
||||
|
||||
// Processes the requests
|
||||
@SuppressWarnings("unchecked")
|
||||
public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
|
||||
public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
|
||||
if (req.getMethod().equals("AdvancedSettings")) {
|
||||
JSONRPC2Error err = JSONRPC2Helper.validateParams(requiredArgs, req);
|
||||
if (err != null) {
|
||||
@ -47,109 +45,109 @@ public class AdvancedSettingsHandler implements RequestHandler {
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
Map outParams = new HashMap();
|
||||
|
||||
if (inParams.containsKey("setAll")) {
|
||||
Object obj = inParams.get("setAll");
|
||||
if (!(obj instanceof Map)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Value of \"setAll\" is not a Map");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
Object obj = inParams.get("setAll");
|
||||
if (!(obj instanceof Map)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Value of \"setAll\" is not a Map");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
Map objMap = (Map) inParams.get("setAll");
|
||||
if (objMap.size() > 0)
|
||||
{
|
||||
if (!(objMap.keySet().toArray()[0] instanceof String) &&
|
||||
!(objMap.values().toArray()[0] instanceof String)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Map of settings does not contain String keys and values");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
@SuppressWarnings("rawtypes")
|
||||
Map objMap = (Map) inParams.get("setAll");
|
||||
if (objMap.size() > 0)
|
||||
{
|
||||
if (!(objMap.keySet().toArray()[0] instanceof String) &&
|
||||
!(objMap.values().toArray()[0] instanceof String)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Map of settings does not contain String keys and values");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
|
||||
if (!checkTypes(objMap)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Some of the supplied values are not strings");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
if (!checkTypes(objMap)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Some of the supplied values are not strings");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
|
||||
Map<String, String> allSettings = (Map<String, String>) objMap;
|
||||
boolean success = setAdvancedSettings(allSettings, true);
|
||||
if (!success) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Failed to save new config");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
Map<String, String> allSettings = (Map<String, String>) objMap;
|
||||
boolean success = setAdvancedSettings(allSettings, true);
|
||||
if (!success) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Failed to save new config");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
|
||||
} else {
|
||||
// Empty list of settings submitted
|
||||
boolean success = setAdvancedSettings(null, true);
|
||||
if (!success) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Failed to save new config");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Empty list of settings submitted
|
||||
boolean success = setAdvancedSettings(null, true);
|
||||
if (!success) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Failed to save new config");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("getAll")) {
|
||||
outParams.put("getAll", getAdvancedSettings());
|
||||
outParams.put("getAll", getAdvancedSettings());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("set")) {
|
||||
Object obj = inParams.get("set");
|
||||
if (!(obj instanceof Map)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Value of \"set\" is not a Map");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
Object obj = inParams.get("set");
|
||||
if (!(obj instanceof Map)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Value of \"set\" is not a Map");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
|
||||
Map objMap = (Map) inParams.get("set");
|
||||
if (objMap.size() > 0)
|
||||
{
|
||||
if (!(objMap.keySet().toArray()[0] instanceof String) &&
|
||||
!(objMap.values().toArray()[0] instanceof String)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Map of settings does not contain String keys and values");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
Map objMap = (Map) inParams.get("set");
|
||||
if (objMap.size() > 0)
|
||||
{
|
||||
if (!(objMap.keySet().toArray()[0] instanceof String) &&
|
||||
!(objMap.values().toArray()[0] instanceof String)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Map of settings does not contain String keys and values");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
|
||||
if (!checkTypes(objMap)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Some of the supplied values are not strings");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
if (!checkTypes(objMap)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Some of the supplied values are not strings");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
|
||||
Map<String, String> allSettings = (Map<String, String>) objMap;
|
||||
boolean success = setAdvancedSettings(allSettings, false);
|
||||
if (!success) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Failed to save new config");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
Map<String, String> allSettings = (Map<String, String>) objMap;
|
||||
boolean success = setAdvancedSettings(allSettings, false);
|
||||
if (!success) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"Failed to save new config");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
|
||||
} else {
|
||||
// Empty list of settings submitted
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Map of settings does not contain any entries");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
} else {
|
||||
// Empty list of settings submitted
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Map of settings does not contain any entries");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("get")) {
|
||||
Object obj = inParams.get("get");
|
||||
if(!(obj instanceof String)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Value of \"get\" is not a string");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
String getStr = (String) obj;
|
||||
String getVal = getAdvancedSetting(getStr);
|
||||
Map<String, String> outMap = new HashMap<String, String>();
|
||||
outMap.put(getStr, getVal);
|
||||
outParams.put("get", outMap);
|
||||
Object obj = inParams.get("get");
|
||||
if (!(obj instanceof String)) {
|
||||
JSONRPC2Error rpcErr = new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"Value of \"get\" is not a string");
|
||||
return new JSONRPC2Response(rpcErr, req.getID());
|
||||
}
|
||||
String getStr = (String) obj;
|
||||
String getVal = getAdvancedSetting(getStr);
|
||||
Map<String, String> outMap = new HashMap<String, String>();
|
||||
outMap.put(getStr, getVal);
|
||||
outParams.put("get", outMap);
|
||||
}
|
||||
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
@ -160,7 +158,7 @@ public class AdvancedSettingsHandler implements RequestHandler {
|
||||
}
|
||||
|
||||
private String getAdvancedSetting(String key) {
|
||||
return _context.router().getConfigSetting(key);
|
||||
return _context.router().getConfigSetting(key);
|
||||
}
|
||||
|
||||
|
||||
@ -170,24 +168,24 @@ public class AdvancedSettingsHandler implements RequestHandler {
|
||||
|
||||
private boolean checkTypes(Map<String, Object> newSettings) {
|
||||
for (String key : newSettings.keySet()) {
|
||||
if (!(newSettings.get(key) instanceof String)) {
|
||||
return false;
|
||||
}
|
||||
if (!(newSettings.get(key) instanceof String)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setAdvancedSettings(Map<String, String> newSettings, boolean clearConfig) {
|
||||
Set<String> unsetKeys = null;
|
||||
Set<String> unsetKeys = null;
|
||||
|
||||
if(clearConfig) {
|
||||
unsetKeys = new HashSet<String>(_context.router().getConfigSettings());
|
||||
if (clearConfig) {
|
||||
unsetKeys = new HashSet<String>(_context.router().getConfigSettings());
|
||||
|
||||
for (String key : newSettings.keySet()) {
|
||||
unsetKeys.remove(key);
|
||||
}
|
||||
}
|
||||
for (String key : newSettings.keySet()) {
|
||||
unsetKeys.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
return _context.router().saveConfig(newSettings, unsetKeys);
|
||||
}
|
||||
|
@ -31,10 +31,10 @@ import java.util.Map;
|
||||
|
||||
public class AuthenticateHandler implements RequestHandler {
|
||||
|
||||
private String[] requiredArgs = {"Password","API"};
|
||||
private String[] requiredArgs = {"Password", "API"};
|
||||
// Reports the method names of the handled requests
|
||||
public String[] handledRequests() {
|
||||
return new String[]{"Authenticate"};
|
||||
return new String[] {"Authenticate"};
|
||||
}
|
||||
|
||||
// Processes the requests
|
||||
@ -51,7 +51,7 @@ public class AuthenticateHandler implements RequestHandler {
|
||||
// Try get an AuthToken
|
||||
|
||||
AuthToken token = SecurityManager.getInstance().validatePasswd(pwd);
|
||||
if (token == null){
|
||||
if (token == null) {
|
||||
return new JSONRPC2Response(JSONRPC2ExtendedError.INVALID_PASSWORD, req.getID());
|
||||
}
|
||||
|
||||
@ -74,23 +74,23 @@ public class AuthenticateHandler implements RequestHandler {
|
||||
/**
|
||||
* Validate the provided I2PControl API version against the ones supported by I2PControl.
|
||||
*/
|
||||
private static JSONRPC2Error validateAPIVersion(Object api){
|
||||
private static JSONRPC2Error validateAPIVersion(Object api) {
|
||||
|
||||
Integer apiVersion;
|
||||
try {
|
||||
apiVersion = ((Long) api).intValue();
|
||||
} catch (ClassCastException e){
|
||||
} catch (ClassCastException e) {
|
||||
e.printStackTrace();
|
||||
return JSONRPC2ExtendedError.UNSPECIFIED_API_VERSION;
|
||||
}
|
||||
|
||||
if (!I2PControlVersion.SUPPORTED_API_VERSIONS.contains(apiVersion)){
|
||||
if (!I2PControlVersion.SUPPORTED_API_VERSIONS.contains(apiVersion)) {
|
||||
String supportedAPIVersions = "";
|
||||
for (Integer i : I2PControlVersion.SUPPORTED_API_VERSIONS){
|
||||
supportedAPIVersions += ", "+ i;
|
||||
for (Integer i : I2PControlVersion.SUPPORTED_API_VERSIONS) {
|
||||
supportedAPIVersions += ", " + i;
|
||||
}
|
||||
return new JSONRPC2Error(JSONRPC2ExtendedError.UNSUPPORTED_API_VERSION.getCode(),
|
||||
"The provided API version \'" + apiVersion + "\' is not supported. The supported versions are" + supportedAPIVersions+".");
|
||||
"The provided API version \'" + apiVersion + "\' is not supported. The supported versions are" + supportedAPIVersions + ".");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ public class EchoHandler implements RequestHandler {
|
||||
private String[] requiredArgs = {"Echo"};
|
||||
// Reports the method names of the handled requests
|
||||
public String[] handledRequests() {
|
||||
return new String[]{"Echo"};
|
||||
return new String[] {"Echo"};
|
||||
}
|
||||
|
||||
// Processes the requests
|
||||
|
@ -34,7 +34,7 @@ public class GetRateHandler implements RequestHandler {
|
||||
private String[] requiredArgs = {"Stat", "Period"};
|
||||
// Reports the method names of the handled requests
|
||||
public String[] handledRequests() {
|
||||
return new String[]{"GetRate"};
|
||||
return new String[] {"GetRate"};
|
||||
}
|
||||
|
||||
// Processes the requests
|
||||
@ -47,20 +47,20 @@ public class GetRateHandler implements RequestHandler {
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
|
||||
String input = (String) inParams.get("Stat");
|
||||
if (input == null){
|
||||
if (input == null) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
}
|
||||
long period;
|
||||
try{
|
||||
try {
|
||||
period = (Long) inParams.get("Period");
|
||||
} catch (NumberFormatException e){
|
||||
} catch (NumberFormatException e) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
}
|
||||
|
||||
RateStat rateStat = I2PAppContext.getGlobalContext().statManager().getRate(input);
|
||||
|
||||
// If RateStat or the requested period doesn't already exist, create them.
|
||||
if (rateStat == null || rateStat.getRate(period) == null){
|
||||
if (rateStat == null || rateStat.getRate(period) == null) {
|
||||
long[] tempArr = new long[1];
|
||||
tempArr[0] = period;
|
||||
I2PAppContext.getGlobalContext().statManager().createRequiredRateStat(input, "I2PControl", "I2PControl", tempArr);
|
||||
|
@ -43,7 +43,7 @@ public class I2PControlHandler implements RequestHandler {
|
||||
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(I2PControlHandler.class);
|
||||
private static final ConfigurationManager _conf = ConfigurationManager.getInstance();
|
||||
|
||||
static{
|
||||
static {
|
||||
try {
|
||||
_context = RouterManager.getRouterContext();
|
||||
} catch (Exception e) {
|
||||
@ -53,30 +53,30 @@ public class I2PControlHandler implements RequestHandler {
|
||||
|
||||
// Reports the method names of the handled requests
|
||||
public String[] handledRequests() {
|
||||
return new String[]{"I2PControl"};
|
||||
return new String[] {"I2PControl"};
|
||||
}
|
||||
|
||||
// Processes the requests
|
||||
public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
|
||||
if (req.getMethod().equals("I2PControl")) {
|
||||
return process(req);
|
||||
}else {
|
||||
} else {
|
||||
// Method name not supported
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private JSONRPC2Response process(JSONRPC2Request req){
|
||||
private JSONRPC2Response process(JSONRPC2Request req) {
|
||||
JSONRPC2Error err = JSONRPC2Helper.validateParams(null, req);
|
||||
if (err != null)
|
||||
return new JSONRPC2Response(err, req.getID());
|
||||
|
||||
if (_context == null){
|
||||
if (_context == null) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
}
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
Map outParams = new HashMap();
|
||||
@ -85,21 +85,21 @@ public class I2PControlHandler implements RequestHandler {
|
||||
boolean settingsSaved = false;
|
||||
String inParam;
|
||||
|
||||
if (inParams.containsKey("i2pcontrol.port")){
|
||||
if (inParams.containsKey("i2pcontrol.port")) {
|
||||
Integer oldPort = _conf.getConf("i2pcontrol.listen.port", 7650);
|
||||
if ((inParam = (String) inParams.get("i2pcontrol.port")) != null){
|
||||
if (oldPort == null || !inParam.equals(oldPort.toString())){
|
||||
if ((inParam = (String) inParams.get("i2pcontrol.port")) != null) {
|
||||
if (oldPort == null || !inParam.equals(oldPort.toString())) {
|
||||
Integer newPort;
|
||||
try {
|
||||
newPort = Integer.valueOf(inParam);
|
||||
if (newPort < 1 || newPort > 65535){
|
||||
if (newPort < 1 || newPort > 65535) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
} catch (NumberFormatException e){
|
||||
} catch (NumberFormatException e) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2pcontrol.port\" must be a string representing a number in the range 1-65535. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2pcontrol.port\" must be a string representing a number in the range 1-65535. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
}
|
||||
try {
|
||||
SslSocketConnector ssl = I2PControlController.buildSslListener(_conf.getConf("i2pcontrol.listen.address", "127.0.0.1"), newPort);
|
||||
@ -118,24 +118,24 @@ public class I2PControlHandler implements RequestHandler {
|
||||
SslSocketConnector ssl = I2PControlController.buildSslListener(_conf.getConf("i2pcontrol.listen.address", "127.0.0.1"), oldPort);
|
||||
I2PControlController.clearListeners();
|
||||
I2PControlController.replaceListener(ssl);
|
||||
} catch (Exception e2){
|
||||
_log.log(Log.CRIT, "Unable to resume server on previous listening port." );
|
||||
} catch (Exception e2) {
|
||||
_log.log(Log.CRIT, "Unable to resume server on previous listening port.");
|
||||
}
|
||||
_log.error("Client tried to set listen port to, " + newPort + " which isn't valid.", e);
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2pcontrol.port\" has been set to a port that is already in use, reverting. " +
|
||||
inParam + " is an already used port.\n"
|
||||
+ "Exception: " + e.toString()),
|
||||
req.getID());
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2pcontrol.port\" has been set to a port that is already in use, reverting. " +
|
||||
inParam + " is an already used port.\n"
|
||||
+ "Exception: " + e.toString()),
|
||||
req.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(inParams.containsKey("i2pcontrol.password")){
|
||||
if ((inParam = (String) inParams.get("i2pcontrol.password")) != null){
|
||||
if (SecurityManager.getInstance().setPasswd(inParam)){
|
||||
if (inParams.containsKey("i2pcontrol.password")) {
|
||||
if ((inParam = (String) inParams.get("i2pcontrol.password")) != null) {
|
||||
if (SecurityManager.getInstance().setPasswd(inParam)) {
|
||||
outParams.put("i2pcontrol.password", null);
|
||||
settingsSaved = true;
|
||||
}
|
||||
@ -143,20 +143,20 @@ public class I2PControlHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if(inParams.containsKey("i2pcontrol.address")){
|
||||
if (inParams.containsKey("i2pcontrol.address")) {
|
||||
String oldAddress = _conf.getConf("i2pcontrol.listen.address", "127.0.0.1");
|
||||
if ((inParam = (String) inParams.get("i2pcontrol.address")) != null){
|
||||
if ((inParam = (String) inParams.get("i2pcontrol.address")) != null) {
|
||||
if ((oldAddress == null || !inParam.equals(oldAddress.toString()) &&
|
||||
(inParam.equals("0.0.0.0") || inParam.equals("127.0.0.1")))){
|
||||
(inParam.equals("0.0.0.0") || inParam.equals("127.0.0.1")))) {
|
||||
InetAddress[] newAddress;
|
||||
|
||||
try {
|
||||
newAddress = InetAddress.getAllByName(inParam);
|
||||
} catch (UnknownHostException e){
|
||||
} catch (UnknownHostException e) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2pcontrol.address\" must be a string representing a hostname or ipaddress. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2pcontrol.address\" must be a string representing a hostname or ipaddress. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
}
|
||||
try {
|
||||
SslSocketConnector ssl = I2PControlController.buildSslListener(inParam, _conf.getConf("i2pcontrol.listen.port", 7650));
|
||||
@ -173,13 +173,13 @@ public class I2PControlHandler implements RequestHandler {
|
||||
SslSocketConnector ssl = I2PControlController.buildSslListener(inParam, _conf.getConf("i2pcontrol.listen.port", 7650));
|
||||
I2PControlController.clearListeners();
|
||||
I2PControlController.replaceListener(ssl);
|
||||
} catch (Exception e2){
|
||||
_log.log(Log.CRIT, "Unable to resume server on previous listening ip." );
|
||||
} catch (Exception e2) {
|
||||
_log.log(Log.CRIT, "Unable to resume server on previous listening ip.");
|
||||
}
|
||||
_log.error("Client tried to set listen address to, " + newAddress.toString() + " which isn't valid.", e);
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2pcontrol.address\" has been set to an invalid address, reverting. "), req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2pcontrol.address\" has been set to an invalid address, reverting. "), req.getID());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -37,32 +37,32 @@ public class JSONRPC2Helper {
|
||||
* @param useAuth - If true, will validate authentication token.
|
||||
* @return - null if no errors were found. Corresponding JSONRPC2Error if error is found.
|
||||
*/
|
||||
public static JSONRPC2Error validateParams(String[] requiredArgs, JSONRPC2Request req, Boolean useAuth){
|
||||
public static JSONRPC2Error validateParams(String[] requiredArgs, JSONRPC2Request req, Boolean useAuth) {
|
||||
|
||||
// Error on unnamed parameters
|
||||
if (req.getParamsType() != JSONRPC2ParamsType.OBJECT){
|
||||
if (req.getParamsType() != JSONRPC2ParamsType.OBJECT) {
|
||||
return JSONRPC2Error.INVALID_PARAMS;
|
||||
}
|
||||
HashMap params = (HashMap) req.getParams();
|
||||
|
||||
// Validate authentication token.
|
||||
if (useAuth){
|
||||
if (useAuth) {
|
||||
JSONRPC2Error err = validateToken(params);
|
||||
if (err != null){
|
||||
if (err != null) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// If there exist any required arguments.
|
||||
if (requiredArgs != null && requiredArgs.length > 0){
|
||||
if (requiredArgs != null && requiredArgs.length > 0) {
|
||||
String missingArgs = "";
|
||||
for (int i = 0; i < requiredArgs.length; i++){
|
||||
if (!params.containsKey(requiredArgs[i])){
|
||||
for (int i = 0; i < requiredArgs.length; i++) {
|
||||
if (!params.containsKey(requiredArgs[i])) {
|
||||
missingArgs = missingArgs.concat(requiredArgs[i] + ",");
|
||||
}
|
||||
}
|
||||
if (missingArgs.length() > 0){
|
||||
missingArgs = missingArgs.substring(0, missingArgs.length()-1);
|
||||
if (missingArgs.length() > 0) {
|
||||
missingArgs = missingArgs.substring(0, missingArgs.length() - 1);
|
||||
return new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(), "Missing parameter(s): " + missingArgs);
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,7 @@ public class JSONRPC2Helper {
|
||||
* @param req - Incoming JSONRPC2 request
|
||||
* @return - null if no errors were found. Corresponding JSONRPC2Error if error is found.
|
||||
*/
|
||||
public static JSONRPC2Error validateParams(String[] requiredArgs, JSONRPC2Request req){
|
||||
public static JSONRPC2Error validateParams(String[] requiredArgs, JSONRPC2Request req) {
|
||||
return validateParams(requiredArgs, req, JSONRPC2Helper.USE_AUTH);
|
||||
}
|
||||
|
||||
@ -86,18 +86,18 @@ public class JSONRPC2Helper {
|
||||
* @param req - Parameters of incoming request
|
||||
* @return null if everything is fine, JSONRPC2Error for any corresponding error.
|
||||
*/
|
||||
private static JSONRPC2Error validateToken(HashMap params){
|
||||
private static JSONRPC2Error validateToken(HashMap params) {
|
||||
String tokenID = (String) params.get("Token");
|
||||
if (tokenID == null){
|
||||
if (tokenID == null) {
|
||||
return JSONRPC2ExtendedError.NO_TOKEN;
|
||||
}
|
||||
try {
|
||||
SecurityManager.getInstance().verifyToken(tokenID);
|
||||
} catch (InvalidAuthTokenException e){
|
||||
} catch (InvalidAuthTokenException e) {
|
||||
return JSONRPC2ExtendedError.INVALID_TOKEN;
|
||||
} catch (ExpiredAuthTokenException e){
|
||||
} catch (ExpiredAuthTokenException e) {
|
||||
JSONRPC2Error err = new JSONRPC2ExtendedError(JSONRPC2ExtendedError.TOKEN_EXPIRED.getCode(),
|
||||
"Provided authentication token expired "+e.getExpirytime()+", will be removed.");
|
||||
"Provided authentication token expired " + e.getExpirytime() + ", will be removed.");
|
||||
return err;
|
||||
}
|
||||
return null;
|
||||
|
@ -44,7 +44,7 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
private static RouterContext _context;
|
||||
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(NetworkSettingHandler.class);
|
||||
|
||||
static{
|
||||
static {
|
||||
try {
|
||||
_context = RouterManager.getRouterContext();
|
||||
} catch (Exception e) {
|
||||
@ -54,30 +54,30 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
|
||||
// Reports the method names of the handled requests
|
||||
public String[] handledRequests() {
|
||||
return new String[]{"NetworkSetting"};
|
||||
return new String[] {"NetworkSetting"};
|
||||
}
|
||||
|
||||
// Processes the requests
|
||||
public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
|
||||
if (req.getMethod().equals("NetworkSetting")) {
|
||||
return process(req);
|
||||
}else {
|
||||
} else {
|
||||
// Method name not supported
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private JSONRPC2Response process(JSONRPC2Request req){
|
||||
private JSONRPC2Response process(JSONRPC2Request req) {
|
||||
JSONRPC2Error err = JSONRPC2Helper.validateParams(null, req);
|
||||
if (err != null)
|
||||
return new JSONRPC2Response(err, req.getID());
|
||||
|
||||
if (_context == null){
|
||||
if (_context == null) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
}
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
Map outParams = new HashMap();
|
||||
@ -86,21 +86,21 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
boolean settingsSaved = false;
|
||||
String inParam;
|
||||
|
||||
if (inParams.containsKey("i2p.router.net.ntcp.port")){
|
||||
if (inParams.containsKey("i2p.router.net.ntcp.port")) {
|
||||
String oldNTCPPort = _context.getProperty(NTCPTransport.PROP_I2NP_NTCP_PORT);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ntcp.port")) != null){
|
||||
if (oldNTCPPort == null || !oldNTCPPort.equals(inParam.trim())){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ntcp.port")) != null) {
|
||||
if (oldNTCPPort == null || !oldNTCPPort.equals(inParam.trim())) {
|
||||
Integer newPort;
|
||||
try {
|
||||
newPort = Integer.valueOf(inParam);
|
||||
if (newPort < 1 || newPort > 65535){
|
||||
if (newPort < 1 || newPort > 65535) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
} catch (NumberFormatException e){
|
||||
} catch (NumberFormatException e) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.ntcp.port\" must be a string representing a number in the range 1-65535. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.ntcp.port\" must be a string representing a number in the range 1-65535. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
}
|
||||
HashMap<String, String> config = new HashMap<String, String>();
|
||||
config.put(NTCPTransport.PROP_I2NP_NTCP_PORT, String.valueOf(newPort));
|
||||
@ -109,10 +109,10 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
restartNeeded = true;
|
||||
}
|
||||
settingsSaved = true;
|
||||
} else{
|
||||
} else {
|
||||
String sAutoPort = _context.getProperty(NTCPTransport.PROP_I2NP_NTCP_AUTO_PORT, "true");
|
||||
boolean oldAutoPort = "true".equalsIgnoreCase(sAutoPort);
|
||||
if (oldAutoPort){
|
||||
if (oldAutoPort) {
|
||||
String oldSSUPort = "" + _context.getProperty(UDPTransport.PROP_INTERNAL_PORT, 8887);
|
||||
outParams.put("i2p.router.net.ntcp.port", oldSSUPort);
|
||||
} else {
|
||||
@ -121,32 +121,32 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if(inParams.containsKey("i2p.router.net.ntcp.hostname")){
|
||||
if (inParams.containsKey("i2p.router.net.ntcp.hostname")) {
|
||||
String oldNTCPHostname = _context.getProperty(NTCPTransport.PROP_I2NP_NTCP_HOSTNAME);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ntcp.hostname")) != null){
|
||||
if (oldNTCPHostname == null || !oldNTCPHostname.equals(inParam.trim())){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ntcp.hostname")) != null) {
|
||||
if (oldNTCPHostname == null || !oldNTCPHostname.equals(inParam.trim())) {
|
||||
_context.router().saveConfig(NTCPTransport.PROP_I2NP_NTCP_HOSTNAME, inParam);
|
||||
restartNeeded = true;
|
||||
}
|
||||
settingsSaved = true;
|
||||
} else {
|
||||
outParams.put("i2p.router.net.ntcp.hostname", oldNTCPHostname);
|
||||
} else {
|
||||
outParams.put("i2p.router.net.ntcp.hostname", oldNTCPHostname);
|
||||
}
|
||||
}
|
||||
|
||||
if(inParams.containsKey("i2p.router.net.ntcp.autoip")){
|
||||
if (inParams.containsKey("i2p.router.net.ntcp.autoip")) {
|
||||
String oldNTCPAutoIP = _context.getProperty(NTCPTransport.PROP_I2NP_NTCP_AUTO_IP);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ntcp.autoip")) != null){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ntcp.autoip")) != null) {
|
||||
inParam = inParam.trim().toLowerCase();
|
||||
if (oldNTCPAutoIP == null || !oldNTCPAutoIP.equals(inParam)){
|
||||
if ("always".equals(inParam) || "true".equals(inParam) || "false".equals(inParam)){
|
||||
if (oldNTCPAutoIP == null || !oldNTCPAutoIP.equals(inParam)) {
|
||||
if ("always".equals(inParam) || "true".equals(inParam) || "false".equals(inParam)) {
|
||||
_context.router().saveConfig(NTCPTransport.PROP_I2NP_NTCP_AUTO_IP, inParam);
|
||||
restartNeeded = true;
|
||||
} else {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.ntcp.autoip\" can only be always, true or false. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.ntcp.autoip\" can only be always, true or false. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
}
|
||||
}
|
||||
settingsSaved = true;
|
||||
@ -155,21 +155,21 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.net.ssu.port")){
|
||||
if (inParams.containsKey("i2p.router.net.ssu.port")) {
|
||||
String oldSSUPort = "" + _context.getProperty(UDPTransport.PROP_INTERNAL_PORT, 8887);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ssu.port")) != null){
|
||||
if (oldSSUPort== null || !oldSSUPort.equals(inParam.trim())){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ssu.port")) != null) {
|
||||
if (oldSSUPort == null || !oldSSUPort.equals(inParam.trim())) {
|
||||
Integer newPort;
|
||||
try {
|
||||
newPort = Integer.valueOf(inParam);
|
||||
if (newPort < 1 || newPort > 65535){
|
||||
if (newPort < 1 || newPort > 65535) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
} catch (NumberFormatException e){
|
||||
} catch (NumberFormatException e) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.ssu.port\" must be a string representing a number in the range 1-65535. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.ssu.port\" must be a string representing a number in the range 1-65535. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
}
|
||||
HashMap<String, String> config = new HashMap<String, String>();
|
||||
config.put(UDPTransport.PROP_EXTERNAL_PORT, String.valueOf(newPort));
|
||||
@ -183,10 +183,10 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.net.ssu.hostname")){
|
||||
if (inParams.containsKey("i2p.router.net.ssu.hostname")) {
|
||||
String oldSSUHostname = _context.getProperty(UDPTransport.PROP_EXTERNAL_HOST);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ssu.hostname")) != null){
|
||||
if (oldSSUHostname == null || !oldSSUHostname.equals(inParam.trim())){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ssu.hostname")) != null) {
|
||||
if (oldSSUHostname == null || !oldSSUHostname.equals(inParam.trim())) {
|
||||
_context.router().saveConfig(UDPTransport.PROP_EXTERNAL_HOST, inParam);
|
||||
restartNeeded = true;
|
||||
}
|
||||
@ -196,19 +196,19 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.net.ssu.autoip")){
|
||||
if (inParams.containsKey("i2p.router.net.ssu.autoip")) {
|
||||
String oldSSUAutoIP = _context.getProperty(UDPTransport.PROP_SOURCES);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ssu.autoip")) != null){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ssu.autoip")) != null) {
|
||||
inParam = inParam.trim().toLowerCase();
|
||||
if (oldSSUAutoIP == null || !oldSSUAutoIP.equals(inParam)){
|
||||
if (inParam.equals("ssu") || inParam.equals("local,ssu") || inParam.equals("upnp,ssu") || inParam.equals("local,upnp,ssu")){
|
||||
_context.router().saveConfig(UDPTransport.PROP_SOURCES, inParam);
|
||||
restartNeeded = true;
|
||||
if (oldSSUAutoIP == null || !oldSSUAutoIP.equals(inParam)) {
|
||||
if (inParam.equals("ssu") || inParam.equals("local,ssu") || inParam.equals("upnp,ssu") || inParam.equals("local,upnp,ssu")) {
|
||||
_context.router().saveConfig(UDPTransport.PROP_SOURCES, inParam);
|
||||
restartNeeded = true;
|
||||
} else {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.ssu.autoip\" can only be ssu/local,upnp,ssu/local/ssu/upnp,ssu. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.ssu.autoip\" can only be ssu/local,upnp,ssu/local/ssu/upnp,ssu. " + inParam + " isn't valid."),
|
||||
req.getID());
|
||||
}
|
||||
}
|
||||
settingsSaved = true;
|
||||
@ -218,8 +218,8 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
}
|
||||
|
||||
// Non-setable key.
|
||||
if (inParams.containsKey("i2p.router.net.ssu.detectedip")){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ssu.autoip")) == null){
|
||||
if (inParams.containsKey("i2p.router.net.ssu.detectedip")) {
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.ssu.autoip")) == null) {
|
||||
byte[] ipBytes = _context.router().getRouterInfo().getTargetAddress("SSU").getIP();
|
||||
try {
|
||||
InetAddress i = InetAddress.getByAddress(ipBytes);
|
||||
@ -230,10 +230,10 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.net.upnp")){
|
||||
if (inParams.containsKey("i2p.router.net.upnp")) {
|
||||
String oldUPNP = _context.getProperty(TransportManager.PROP_ENABLE_UPNP);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.upnp")) != null){
|
||||
if (oldUPNP == null || !oldUPNP.equals(inParam.trim())){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.upnp")) != null) {
|
||||
if (oldUPNP == null || !oldUPNP.equals(inParam.trim())) {
|
||||
_context.router().saveConfig(TransportManager.PROP_ENABLE_UPNP, inParam);
|
||||
restartNeeded = true;
|
||||
}
|
||||
@ -243,22 +243,22 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.net.bw.share")){
|
||||
if (inParams.containsKey("i2p.router.net.bw.share")) {
|
||||
String oldShare = _context.router().getConfigSetting(Router.PROP_BANDWIDTH_SHARE_PERCENTAGE);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.bw.share")) != null){
|
||||
if (oldShare == null || !oldShare.equals(inParam.trim())){
|
||||
Integer percent;
|
||||
try{
|
||||
percent = Integer.parseInt(inParam);
|
||||
if (percent < 0 || percent > 100 || inParam.length() == 0) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
} catch (NumberFormatException e){
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.bw.share\" A positive integer must supplied, \"" + inParam + "\" isn't valid"),
|
||||
req.getID());
|
||||
}
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.bw.share")) != null) {
|
||||
if (oldShare == null || !oldShare.equals(inParam.trim())) {
|
||||
Integer percent;
|
||||
try {
|
||||
percent = Integer.parseInt(inParam);
|
||||
if (percent < 0 || percent > 100 || inParam.length() == 0) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.bw.share\" A positive integer must supplied, \"" + inParam + "\" isn't valid"),
|
||||
req.getID());
|
||||
}
|
||||
_context.router().saveConfig(Router.PROP_BANDWIDTH_SHARE_PERCENTAGE, inParam);
|
||||
}
|
||||
settingsSaved = true;
|
||||
@ -267,24 +267,24 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.net.bw.in")){
|
||||
if (inParams.containsKey("i2p.router.net.bw.in")) {
|
||||
String oldBWIn = _context.getProperty(FIFOBandwidthRefiller.PROP_INBOUND_BANDWIDTH);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.bw.in")) != null){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.bw.in")) != null) {
|
||||
Integer rate;
|
||||
try{
|
||||
try {
|
||||
rate = Integer.parseInt(inParam);
|
||||
if (rate < 0 || inParam.length() == 0) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
} catch (NumberFormatException e){
|
||||
} catch (NumberFormatException e) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.bw.in\" A positive integer must supplied, " + inParam + " isn't valid"),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.bw.in\" A positive integer must supplied, " + inParam + " isn't valid"),
|
||||
req.getID());
|
||||
}
|
||||
Integer burstRate = (rate * BW_BURST_PCT)/100;
|
||||
Integer burstRate = (rate * BW_BURST_PCT) / 100;
|
||||
Integer burstSize = (burstRate * BW_BURST_TIME);
|
||||
if (oldBWIn == null || !oldBWIn.equals(rate.toString())){
|
||||
if (oldBWIn == null || !oldBWIn.equals(rate.toString())) {
|
||||
HashMap<String, String> config = new HashMap<String, String>();
|
||||
config.put(FIFOBandwidthRefiller.PROP_INBOUND_BANDWIDTH, rate.toString());
|
||||
config.put(FIFOBandwidthRefiller.PROP_INBOUND_BURST_BANDWIDTH, burstRate.toString());
|
||||
@ -297,23 +297,23 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
outParams.put("i2p.router.net.bw.in", oldBWIn);
|
||||
}
|
||||
}
|
||||
if (inParams.containsKey("i2p.router.net.bw.out")){
|
||||
if (inParams.containsKey("i2p.router.net.bw.out")) {
|
||||
String oldBWOut = _context.getProperty(FIFOBandwidthRefiller.PROP_OUTBOUND_BANDWIDTH);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.bw.out")) != null){
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.bw.out")) != null) {
|
||||
Integer rate;
|
||||
try{
|
||||
try {
|
||||
rate = Integer.parseInt(inParam);
|
||||
if (rate < 0 || inParam.length() == 0)
|
||||
throw new NumberFormatException();
|
||||
} catch (NumberFormatException e){
|
||||
} catch (NumberFormatException e) {
|
||||
return new JSONRPC2Response(
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.bw.out\" A positive integer must supplied, " + inParam + " isn't valid"),
|
||||
req.getID());
|
||||
new JSONRPC2Error(JSONRPC2Error.INVALID_PARAMS.getCode(),
|
||||
"\"i2p.router.net.bw.out\" A positive integer must supplied, " + inParam + " isn't valid"),
|
||||
req.getID());
|
||||
}
|
||||
Integer burstRate = (rate * BW_BURST_PCT)/100;
|
||||
Integer burstRate = (rate * BW_BURST_PCT) / 100;
|
||||
Integer burstSize = (burstRate * BW_BURST_TIME);
|
||||
if (oldBWOut == null || !oldBWOut.equals(rate.toString())){
|
||||
if (oldBWOut == null || !oldBWOut.equals(rate.toString())) {
|
||||
HashMap<String, String> config = new HashMap<String, String>();
|
||||
config.put(FIFOBandwidthRefiller.PROP_OUTBOUND_BANDWIDTH, rate.toString());
|
||||
config.put(FIFOBandwidthRefiller.PROP_OUTBOUND_BURST_BANDWIDTH, burstRate.toString());
|
||||
@ -326,12 +326,12 @@ public class NetworkSettingHandler implements RequestHandler {
|
||||
outParams.put("i2p.router.net.bw.out", oldBWOut);
|
||||
}
|
||||
}
|
||||
if (inParams.containsKey("i2p.router.net.laptopmode")){
|
||||
if (inParams.containsKey("i2p.router.net.laptopmode")) {
|
||||
String oldLaptopMode = _context.getProperty(UDPTransport.PROP_LAPTOP_MODE);
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.laptopmode")) != null){
|
||||
if (oldLaptopMode == null || !oldLaptopMode.equals(inParam.trim())){
|
||||
_context.router().saveConfig(UDPTransport.PROP_LAPTOP_MODE, String.valueOf(inParam));
|
||||
}
|
||||
if ((inParam = (String) inParams.get("i2p.router.net.laptopmode")) != null) {
|
||||
if (oldLaptopMode == null || !oldLaptopMode.equals(inParam.trim())) {
|
||||
_context.router().saveConfig(UDPTransport.PROP_LAPTOP_MODE, String.valueOf(inParam));
|
||||
}
|
||||
settingsSaved = true;
|
||||
} else {
|
||||
outParams.put("i2p.router.net.laptopmode", oldLaptopMode);
|
||||
|
@ -61,7 +61,7 @@ public class RouterInfoHandler implements RequestHandler {
|
||||
} else {
|
||||
// Method name not supported
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND,
|
||||
req.getID());
|
||||
req.getID());
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,20 +73,20 @@ public class RouterInfoHandler implements RequestHandler {
|
||||
|
||||
if (_context == null) {
|
||||
return new JSONRPC2Response(new JSONRPC2Error(
|
||||
JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
}
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
Map outParams = new HashMap();
|
||||
|
||||
if (inParams.containsKey("i2p.router.version")) {
|
||||
try {
|
||||
Class rvClass = Class.forName("net.i2p.router.RouterVersion");
|
||||
java.lang.reflect.Field field = rvClass.getDeclaredField("FULL_VERSION");
|
||||
String fullVersion = (String) field.get(new RouterVersion());
|
||||
outParams.put("i2p.router.version", fullVersion);
|
||||
} catch (Exception e){} // Ignore
|
||||
Class rvClass = Class.forName("net.i2p.router.RouterVersion");
|
||||
java.lang.reflect.Field field = rvClass.getDeclaredField("FULL_VERSION");
|
||||
String fullVersion = (String) field.get(new RouterVersion());
|
||||
outParams.put("i2p.router.version", fullVersion);
|
||||
} catch (Exception e) {} // Ignore
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.uptime")) {
|
||||
@ -128,7 +128,7 @@ public class RouterInfoHandler implements RequestHandler {
|
||||
|
||||
if (inParams.containsKey("i2p.router.netdb.knownpeers")) {
|
||||
// Why max(-1, 0) is used I don't know, it is the implementation used in the router console.
|
||||
outParams.put("i2p.router.netdb.knownpeers", Math.max(_context.netDb().getKnownRouters()-1,0));
|
||||
outParams.put("i2p.router.netdb.knownpeers", Math.max(_context.netDb().getKnownRouters() - 1, 0));
|
||||
}
|
||||
|
||||
if (inParams.containsKey("i2p.router.netdb.activepeers")) {
|
||||
@ -149,7 +149,7 @@ public class RouterInfoHandler implements RequestHandler {
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
private static enum NETWORK_STATUS{
|
||||
private static enum NETWORK_STATUS {
|
||||
OK,
|
||||
TESTING,
|
||||
FIREWALLED,
|
||||
|
@ -62,7 +62,7 @@ public class RouterManagerHandler implements RequestHandler {
|
||||
} else {
|
||||
// Method name not supported
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND,
|
||||
req.getID());
|
||||
req.getID());
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,32 +73,33 @@ public class RouterManagerHandler implements RequestHandler {
|
||||
|
||||
if (_context == null) {
|
||||
return new JSONRPC2Response(new JSONRPC2Error(
|
||||
JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
JSONRPC2Error.INTERNAL_ERROR.getCode(),
|
||||
"RouterContext was not initialized. Query failed"),
|
||||
req.getID());
|
||||
}
|
||||
HashMap inParams = (HashMap) req.getParams();
|
||||
final Map outParams = new HashMap();
|
||||
|
||||
if (inParams.containsKey("Shutdown")) {
|
||||
outParams.put("Shutdown", null);
|
||||
(new Thread(){
|
||||
(new Thread() {
|
||||
@Override
|
||||
public void run(){
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(SHUTDOWN_WAIT);
|
||||
} catch (InterruptedException e) {}
|
||||
_context.addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD));
|
||||
_context.router().shutdown(Router.EXIT_HARD); }
|
||||
_context.router().shutdown(Router.EXIT_HARD);
|
||||
}
|
||||
}).start();
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("Restart")) {
|
||||
outParams.put("Restart", null);
|
||||
(new Thread(){
|
||||
(new Thread() {
|
||||
@Override
|
||||
public void run(){
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(SHUTDOWN_WAIT);
|
||||
} catch (InterruptedException e) {}
|
||||
@ -111,9 +112,9 @@ public class RouterManagerHandler implements RequestHandler {
|
||||
|
||||
if (inParams.containsKey("ShutdownGraceful")) {
|
||||
outParams.put("ShutdownGraceful", null);
|
||||
(new Thread(){
|
||||
(new Thread() {
|
||||
@Override
|
||||
public void run(){
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(SHUTDOWN_WAIT);
|
||||
} catch (InterruptedException e) {}
|
||||
@ -126,23 +127,24 @@ public class RouterManagerHandler implements RequestHandler {
|
||||
|
||||
if (inParams.containsKey("RestartGraceful")) {
|
||||
outParams.put("RestartGraceful", null);
|
||||
(new Thread(){
|
||||
(new Thread() {
|
||||
@Override
|
||||
public void run(){
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(SHUTDOWN_WAIT);
|
||||
} catch (InterruptedException e) {}
|
||||
_context.addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL_RESTART));
|
||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART); }
|
||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
|
||||
}
|
||||
}).start();
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("Reseed")){
|
||||
if (inParams.containsKey("Reseed")) {
|
||||
outParams.put("Reseed", null);
|
||||
(new Thread(){
|
||||
(new Thread() {
|
||||
@Override
|
||||
public void run(){
|
||||
public void run() {
|
||||
ReseedChecker reseeder = new ReseedChecker(_context);
|
||||
reseeder.requestReseed();
|
||||
}
|
||||
@ -150,10 +152,10 @@ public class RouterManagerHandler implements RequestHandler {
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("FindUpdates")){
|
||||
Thread t = new Thread(){
|
||||
if (inParams.containsKey("FindUpdates")) {
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run(){
|
||||
public void run() {
|
||||
ClientAppManager clmgr = I2PAppContext.getCurrentContext().clientAppManager();
|
||||
if (clmgr == null) {
|
||||
outParams.put("FindUpdates", "ClientAppManager is null");
|
||||
@ -175,10 +177,10 @@ public class RouterManagerHandler implements RequestHandler {
|
||||
return new JSONRPC2Response(outParams, req.getID());
|
||||
}
|
||||
|
||||
if (inParams.containsKey("Update")){
|
||||
Thread t = new Thread(){
|
||||
if (inParams.containsKey("Update")) {
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run(){
|
||||
public void run() {
|
||||
ClientAppManager clmgr = I2PAppContext.getCurrentContext().clientAppManager();
|
||||
if (clmgr == null) {
|
||||
outParams.put("Update", "ClientAppManager is null");
|
||||
@ -196,7 +198,9 @@ public class RouterManagerHandler implements RequestHandler {
|
||||
}
|
||||
boolean isUpdating = upmgr.isUpdateInProgress(UpdateType.ROUTER_SIGNED);
|
||||
while (isUpdating) {
|
||||
try { Thread.sleep(100);} catch (Exception e){}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (Exception e) {}
|
||||
isUpdating = upmgr.isUpdateInProgress(UpdateType.ROUTER_SIGNED);
|
||||
}
|
||||
outParams.put("Update", upmgr.getStatus());
|
||||
|
@ -15,133 +15,133 @@ import java.util.StringTokenizer;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public class ItemList {
|
||||
private String sp=",";
|
||||
List items=new ArrayList();
|
||||
private String sp = ",";
|
||||
List items = new ArrayList();
|
||||
|
||||
|
||||
public ItemList(){}
|
||||
public ItemList() {}
|
||||
|
||||
|
||||
public ItemList(String s){
|
||||
this.split(s,sp,items);
|
||||
}
|
||||
public ItemList(String s) {
|
||||
this.split(s, sp, items);
|
||||
}
|
||||
|
||||
public ItemList(String s,String sp){
|
||||
this.sp=s;
|
||||
this.split(s,sp,items);
|
||||
}
|
||||
public ItemList(String s, String sp) {
|
||||
this.sp = s;
|
||||
this.split(s, sp, items);
|
||||
}
|
||||
|
||||
public ItemList(String s,String sp,boolean isMultiToken){
|
||||
split(s,sp,items,isMultiToken);
|
||||
}
|
||||
public ItemList(String s, String sp, boolean isMultiToken) {
|
||||
split(s, sp, items, isMultiToken);
|
||||
}
|
||||
|
||||
public List getItems(){
|
||||
return this.items;
|
||||
}
|
||||
public List getItems() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public String[] getArray(){
|
||||
return (String[])this.items.toArray();
|
||||
}
|
||||
public String[] getArray() {
|
||||
return (String[])this.items.toArray();
|
||||
}
|
||||
|
||||
public void split(String s,String sp,List append,boolean isMultiToken){
|
||||
if(s==null || sp==null)
|
||||
return;
|
||||
if(isMultiToken){
|
||||
StringTokenizer tokens=new StringTokenizer(s,sp);
|
||||
while(tokens.hasMoreTokens()){
|
||||
append.add(tokens.nextToken().trim());
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.split(s,sp,append);
|
||||
}
|
||||
}
|
||||
public void split(String s, String sp, List append, boolean isMultiToken) {
|
||||
if (s == null || sp == null)
|
||||
return;
|
||||
if (isMultiToken) {
|
||||
StringTokenizer tokens = new StringTokenizer(s, sp);
|
||||
while (tokens.hasMoreTokens()) {
|
||||
append.add(tokens.nextToken().trim());
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.split(s, sp, append);
|
||||
}
|
||||
}
|
||||
|
||||
public void split(String s,String sp,List append){
|
||||
if(s==null || sp==null)
|
||||
return;
|
||||
int pos=0;
|
||||
int prevPos=0;
|
||||
do{
|
||||
prevPos=pos;
|
||||
pos=s.indexOf(sp,pos);
|
||||
if(pos==-1)
|
||||
break;
|
||||
append.add(s.substring(prevPos,pos).trim());
|
||||
pos+=sp.length();
|
||||
}while(pos!=-1);
|
||||
append.add(s.substring(prevPos).trim());
|
||||
}
|
||||
public void split(String s, String sp, List append) {
|
||||
if (s == null || sp == null)
|
||||
return;
|
||||
int pos = 0;
|
||||
int prevPos = 0;
|
||||
do {
|
||||
prevPos = pos;
|
||||
pos = s.indexOf(sp, pos);
|
||||
if (pos == -1)
|
||||
break;
|
||||
append.add(s.substring(prevPos, pos).trim());
|
||||
pos += sp.length();
|
||||
} while (pos != -1);
|
||||
append.add(s.substring(prevPos).trim());
|
||||
}
|
||||
|
||||
public void setSP(String sp){
|
||||
this.sp=sp;
|
||||
}
|
||||
public void setSP(String sp) {
|
||||
this.sp = sp;
|
||||
}
|
||||
|
||||
public void add(int i,String item){
|
||||
if(item==null)
|
||||
return;
|
||||
items.add(i,item.trim());
|
||||
}
|
||||
public void add(int i, String item) {
|
||||
if (item == null)
|
||||
return;
|
||||
items.add(i, item.trim());
|
||||
}
|
||||
|
||||
public void add(String item){
|
||||
if(item==null)
|
||||
return;
|
||||
items.add(item.trim());
|
||||
}
|
||||
public void add(String item) {
|
||||
if (item == null)
|
||||
return;
|
||||
items.add(item.trim());
|
||||
}
|
||||
|
||||
public void addAll(ItemList list){
|
||||
items.addAll(list.items);
|
||||
}
|
||||
public void addAll(ItemList list) {
|
||||
items.addAll(list.items);
|
||||
}
|
||||
|
||||
public void addAll(String s){
|
||||
this.split(s,sp,items);
|
||||
}
|
||||
public void addAll(String s) {
|
||||
this.split(s, sp, items);
|
||||
}
|
||||
|
||||
public void addAll(String s,String sp){
|
||||
this.split(s,sp,items);
|
||||
}
|
||||
public void addAll(String s, String sp) {
|
||||
this.split(s, sp, items);
|
||||
}
|
||||
|
||||
public void addAll(String s,String sp,boolean isMultiToken){
|
||||
this.split(s,sp,items,isMultiToken);
|
||||
}
|
||||
public void addAll(String s, String sp, boolean isMultiToken) {
|
||||
this.split(s, sp, items, isMultiToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i 0-based
|
||||
* @return
|
||||
*/
|
||||
public String get(int i){
|
||||
return (String)items.get(i);
|
||||
}
|
||||
/**
|
||||
* @param i 0-based
|
||||
* @return
|
||||
*/
|
||||
public String get(int i) {
|
||||
return (String)items.get(i);
|
||||
}
|
||||
|
||||
public int size(){
|
||||
return items.size();
|
||||
}
|
||||
public int size() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return toString(sp);
|
||||
}
|
||||
public String toString() {
|
||||
return toString(sp);
|
||||
}
|
||||
|
||||
public String toString(String sp){
|
||||
StringBuffer sb=new StringBuffer();
|
||||
public String toString(String sp) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for(int i=0;i<items.size();i++){
|
||||
if(i==0)
|
||||
sb.append(items.get(i));
|
||||
else{
|
||||
sb.append(sp);
|
||||
sb.append(items.get(i));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
if (i == 0)
|
||||
sb.append(items.get(i));
|
||||
else {
|
||||
sb.append(sp);
|
||||
sb.append(items.get(i));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
items.clear();
|
||||
}
|
||||
public void clear() {
|
||||
items.clear();
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
sp=",";
|
||||
items.clear();
|
||||
}
|
||||
public void reset() {
|
||||
sp = ",";
|
||||
items.clear();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import java.util.List;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public class JSONArray extends ArrayList implements List, JSONAware, JSONStreamAware {
|
||||
private static final long serialVersionUID = 3957988303675231981L;
|
||||
private static final long serialVersionUID = 3957988303675231981L;
|
||||
|
||||
/**
|
||||
* Encode a list into JSON text and write it to out.
|
||||
@ -28,79 +28,79 @@ public class JSONArray extends ArrayList implements List, JSONAware, JSONStreamA
|
||||
* @param list
|
||||
* @param out
|
||||
*/
|
||||
public static void writeJSONString(List list, Writer out) throws IOException{
|
||||
if(list == null){
|
||||
out.write("null");
|
||||
return;
|
||||
}
|
||||
public static void writeJSONString(List list, Writer out) throws IOException {
|
||||
if (list == null) {
|
||||
out.write("null");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean first = true;
|
||||
Iterator iter=list.iterator();
|
||||
boolean first = true;
|
||||
Iterator iter = list.iterator();
|
||||
|
||||
out.write('[');
|
||||
while(iter.hasNext()){
|
||||
if(first)
|
||||
while (iter.hasNext()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
out.write(',');
|
||||
|
||||
Object value=iter.next();
|
||||
if(value == null){
|
||||
out.write("null");
|
||||
continue;
|
||||
}
|
||||
Object value = iter.next();
|
||||
if (value == null) {
|
||||
out.write("null");
|
||||
continue;
|
||||
}
|
||||
|
||||
JSONValue.writeJSONString(value, out);
|
||||
}
|
||||
out.write(']');
|
||||
}
|
||||
JSONValue.writeJSONString(value, out);
|
||||
}
|
||||
out.write(']');
|
||||
}
|
||||
|
||||
public void writeJSONString(Writer out) throws IOException{
|
||||
writeJSONString(this, out);
|
||||
}
|
||||
public void writeJSONString(Writer out) throws IOException {
|
||||
writeJSONString(this, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list to JSON text. The result is a JSON array.
|
||||
* If this list is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
|
||||
*
|
||||
* @see org.json.simple.JSONValue#toJSONString(Object)
|
||||
*
|
||||
* @param list
|
||||
* @return JSON text, or "null" if list is null.
|
||||
*/
|
||||
public static String toJSONString(List list){
|
||||
if(list == null)
|
||||
return "null";
|
||||
/**
|
||||
* Convert a list to JSON text. The result is a JSON array.
|
||||
* If this list is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
|
||||
*
|
||||
* @see org.json.simple.JSONValue#toJSONString(Object)
|
||||
*
|
||||
* @param list
|
||||
* @return JSON text, or "null" if list is null.
|
||||
*/
|
||||
public static String toJSONString(List list) {
|
||||
if (list == null)
|
||||
return "null";
|
||||
|
||||
boolean first = true;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Iterator iter=list.iterator();
|
||||
Iterator iter = list.iterator();
|
||||
|
||||
sb.append('[');
|
||||
while(iter.hasNext()){
|
||||
if(first)
|
||||
while (iter.hasNext()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
sb.append(',');
|
||||
|
||||
Object value=iter.next();
|
||||
if(value == null){
|
||||
sb.append("null");
|
||||
continue;
|
||||
}
|
||||
sb.append(JSONValue.toJSONString(value));
|
||||
}
|
||||
Object value = iter.next();
|
||||
if (value == null) {
|
||||
sb.append("null");
|
||||
continue;
|
||||
}
|
||||
sb.append(JSONValue.toJSONString(value));
|
||||
}
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toJSONString(){
|
||||
return toJSONString(this);
|
||||
}
|
||||
public String toJSONString() {
|
||||
return toJSONString(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return toJSONString();
|
||||
}
|
||||
public String toString() {
|
||||
return toJSONString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -5,8 +5,8 @@ package org.json.simple;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public interface JSONAware {
|
||||
/**
|
||||
* @return JSON text
|
||||
*/
|
||||
String toJSONString();
|
||||
/**
|
||||
* @return JSON text
|
||||
*/
|
||||
String toJSONString();
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ import java.util.Map;
|
||||
*
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware{
|
||||
private static final long serialVersionUID = -503443796854799292L;
|
||||
public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware {
|
||||
private static final long serialVersionUID = -503443796854799292L;
|
||||
|
||||
/**
|
||||
* Encode a map into JSON text and write it to out.
|
||||
@ -27,103 +27,103 @@ public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAwa
|
||||
* @param map
|
||||
* @param out
|
||||
*/
|
||||
public static void writeJSONString(Map map, Writer out) throws IOException {
|
||||
if(map == null){
|
||||
out.write("null");
|
||||
return;
|
||||
}
|
||||
public static void writeJSONString(Map map, Writer out) throws IOException {
|
||||
if (map == null) {
|
||||
out.write("null");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean first = true;
|
||||
Iterator iter=map.entrySet().iterator();
|
||||
boolean first = true;
|
||||
Iterator iter = map.entrySet().iterator();
|
||||
|
||||
out.write('{');
|
||||
while(iter.hasNext()){
|
||||
if(first)
|
||||
while (iter.hasNext()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
out.write(',');
|
||||
Map.Entry entry=(Map.Entry)iter.next();
|
||||
Map.Entry entry = (Map.Entry)iter.next();
|
||||
out.write('\"');
|
||||
out.write(escape(String.valueOf(entry.getKey())));
|
||||
out.write('\"');
|
||||
out.write(':');
|
||||
JSONValue.writeJSONString(entry.getValue(), out);
|
||||
}
|
||||
out.write('}');
|
||||
}
|
||||
JSONValue.writeJSONString(entry.getValue(), out);
|
||||
}
|
||||
out.write('}');
|
||||
}
|
||||
|
||||
public void writeJSONString(Writer out) throws IOException{
|
||||
writeJSONString(this, out);
|
||||
}
|
||||
public void writeJSONString(Writer out) throws IOException {
|
||||
writeJSONString(this, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a map to JSON text. The result is a JSON object.
|
||||
* If this map is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
|
||||
*
|
||||
* @see org.json.simple.JSONValue#toJSONString(Object)
|
||||
*
|
||||
* @param map
|
||||
* @return JSON text, or "null" if map is null.
|
||||
*/
|
||||
public static String toJSONString(Map map){
|
||||
if(map == null)
|
||||
return "null";
|
||||
/**
|
||||
* Convert a map to JSON text. The result is a JSON object.
|
||||
* If this map is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
|
||||
*
|
||||
* @see org.json.simple.JSONValue#toJSONString(Object)
|
||||
*
|
||||
* @param map
|
||||
* @return JSON text, or "null" if map is null.
|
||||
*/
|
||||
public static String toJSONString(Map map) {
|
||||
if (map == null)
|
||||
return "null";
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
boolean first = true;
|
||||
Iterator iter=map.entrySet().iterator();
|
||||
Iterator iter = map.entrySet().iterator();
|
||||
|
||||
sb.append('{');
|
||||
while(iter.hasNext()){
|
||||
if(first)
|
||||
while (iter.hasNext()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
sb.append(',');
|
||||
|
||||
Map.Entry entry=(Map.Entry)iter.next();
|
||||
toJSONString(String.valueOf(entry.getKey()),entry.getValue(), sb);
|
||||
}
|
||||
Map.Entry entry = (Map.Entry)iter.next();
|
||||
toJSONString(String.valueOf(entry.getKey()), entry.getValue(), sb);
|
||||
}
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toJSONString(){
|
||||
return toJSONString(this);
|
||||
}
|
||||
public String toJSONString() {
|
||||
return toJSONString(this);
|
||||
}
|
||||
|
||||
private static String toJSONString(String key,Object value, StringBuffer sb){
|
||||
sb.append('\"');
|
||||
if(key == null)
|
||||
private static String toJSONString(String key, Object value, StringBuffer sb) {
|
||||
sb.append('\"');
|
||||
if (key == null)
|
||||
sb.append("null");
|
||||
else
|
||||
JSONValue.escape(key, sb);
|
||||
sb.append('\"').append(':');
|
||||
sb.append('\"').append(':');
|
||||
|
||||
sb.append(JSONValue.toJSONString(value));
|
||||
sb.append(JSONValue.toJSONString(value));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return toJSONString();
|
||||
}
|
||||
|
||||
public static String toString(String key,Object value){
|
||||
StringBuffer sb = new StringBuffer();
|
||||
toJSONString(key, value, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
|
||||
* It's the same as JSONValue.escape() only for compatibility here.
|
||||
*
|
||||
* @see org.json.simple.JSONValue#escape(String)
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static String escape(String s){
|
||||
return JSONValue.escape(s);
|
||||
}
|
||||
public String toString() {
|
||||
return toJSONString();
|
||||
}
|
||||
|
||||
public static String toString(String key, Object value) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
toJSONString(key, value, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
|
||||
* It's the same as JSONValue.escape() only for compatibility here.
|
||||
*
|
||||
* @see org.json.simple.JSONValue#escape(String)
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static String escape(String s) {
|
||||
return JSONValue.escape(s);
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import java.io.Writer;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public interface JSONStreamAware {
|
||||
/**
|
||||
* write JSON string to out.
|
||||
*/
|
||||
void writeJSONString(Writer out) throws IOException;
|
||||
/**
|
||||
* write JSON string to out.
|
||||
*/
|
||||
void writeJSONString(Writer out) throws IOException;
|
||||
}
|
||||
|
@ -19,64 +19,64 @@ import java.util.Map;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public class JSONValue {
|
||||
/**
|
||||
* Parse JSON text into java object from the input source.
|
||||
* Please use parseWithException() if you don't want to ignore the exception.
|
||||
*
|
||||
* @see org.json.simple.parser.JSONParser#parse(Reader)
|
||||
* @see #parseWithException(Reader)
|
||||
*
|
||||
* @param in
|
||||
* @return Instance of the following:
|
||||
* org.json.simple.JSONObject,
|
||||
* org.json.simple.JSONArray,
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean,
|
||||
* null
|
||||
*
|
||||
*/
|
||||
public static Object parse(Reader in){
|
||||
try{
|
||||
JSONParser parser=new JSONParser();
|
||||
return parser.parse(in);
|
||||
}
|
||||
catch(Exception e){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Parse JSON text into java object from the input source.
|
||||
* Please use parseWithException() if you don't want to ignore the exception.
|
||||
*
|
||||
* @see org.json.simple.parser.JSONParser#parse(Reader)
|
||||
* @see #parseWithException(Reader)
|
||||
*
|
||||
* @param in
|
||||
* @return Instance of the following:
|
||||
* org.json.simple.JSONObject,
|
||||
* org.json.simple.JSONArray,
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean,
|
||||
* null
|
||||
*
|
||||
*/
|
||||
public static Object parse(Reader in) {
|
||||
try {
|
||||
JSONParser parser = new JSONParser();
|
||||
return parser.parse(in);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object parse(String s){
|
||||
StringReader in=new StringReader(s);
|
||||
return parse(in);
|
||||
}
|
||||
public static Object parse(String s) {
|
||||
StringReader in = new StringReader(s);
|
||||
return parse(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON text into java object from the input source.
|
||||
*
|
||||
* @see org.json.simple.parser.JSONParser
|
||||
*
|
||||
* @param in
|
||||
* @return Instance of the following:
|
||||
* org.json.simple.JSONObject,
|
||||
* org.json.simple.JSONArray,
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean,
|
||||
* null
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static Object parseWithException(Reader in) throws IOException, ParseException{
|
||||
JSONParser parser=new JSONParser();
|
||||
return parser.parse(in);
|
||||
}
|
||||
/**
|
||||
* Parse JSON text into java object from the input source.
|
||||
*
|
||||
* @see org.json.simple.parser.JSONParser
|
||||
*
|
||||
* @param in
|
||||
* @return Instance of the following:
|
||||
* org.json.simple.JSONObject,
|
||||
* org.json.simple.JSONArray,
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean,
|
||||
* null
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static Object parseWithException(Reader in) throws IOException, ParseException {
|
||||
JSONParser parser = new JSONParser();
|
||||
return parser.parse(in);
|
||||
}
|
||||
|
||||
public static Object parseWithException(String s) throws ParseException{
|
||||
JSONParser parser=new JSONParser();
|
||||
return parser.parse(s);
|
||||
}
|
||||
public static Object parseWithException(String s) throws ParseException {
|
||||
JSONParser parser = new JSONParser();
|
||||
return parser.parse(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode an object into JSON text and write it to out.
|
||||
@ -92,129 +92,129 @@ public class JSONValue {
|
||||
* @param value
|
||||
* @param writer
|
||||
*/
|
||||
public static void writeJSONString(Object value, Writer out) throws IOException {
|
||||
if(value == null){
|
||||
out.write("null");
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof String){
|
||||
out.write('\"');
|
||||
out.write(escape((String)value));
|
||||
out.write('\"');
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Double){
|
||||
if(((Double)value).isInfinite() || ((Double)value).isNaN())
|
||||
out.write("null");
|
||||
else
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Float){
|
||||
if(((Float)value).isInfinite() || ((Float)value).isNaN())
|
||||
out.write("null");
|
||||
else
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Number){
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Boolean){
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if((value instanceof JSONStreamAware)){
|
||||
((JSONStreamAware)value).writeJSONString(out);
|
||||
return;
|
||||
}
|
||||
|
||||
if((value instanceof JSONAware)){
|
||||
out.write(((JSONAware)value).toJSONString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Map){
|
||||
JSONObject.writeJSONString((Map)value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof List){
|
||||
JSONArray.writeJSONString((List)value, out);
|
||||
public static void writeJSONString(Object value, Writer out) throws IOException {
|
||||
if (value == null) {
|
||||
out.write("null");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
out.write(value.toString());
|
||||
}
|
||||
if (value instanceof String) {
|
||||
out.write('\"');
|
||||
out.write(escape((String)value));
|
||||
out.write('\"');
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an object to JSON text.
|
||||
* <p>
|
||||
* If this object is a Map or a List, and it's also a JSONAware, JSONAware will be considered firstly.
|
||||
* <p>
|
||||
* DO NOT call this method from toJSONString() of a class that implements both JSONAware and Map or List with
|
||||
* "this" as the parameter, use JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead.
|
||||
*
|
||||
* @see org.json.simple.JSONObject#toJSONString(Map)
|
||||
* @see org.json.simple.JSONArray#toJSONString(List)
|
||||
*
|
||||
* @param value
|
||||
* @return JSON text, or "null" if value is null or it's an NaN or an INF number.
|
||||
*/
|
||||
public static String toJSONString(Object value){
|
||||
if(value == null)
|
||||
return "null";
|
||||
if (value instanceof Double) {
|
||||
if (((Double)value).isInfinite() || ((Double)value).isNaN())
|
||||
out.write("null");
|
||||
else
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof String)
|
||||
return "\""+escape((String)value)+"\"";
|
||||
if (value instanceof Float) {
|
||||
if (((Float)value).isInfinite() || ((Float)value).isNaN())
|
||||
out.write("null");
|
||||
else
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Double){
|
||||
if(((Double)value).isInfinite() || ((Double)value).isNaN())
|
||||
return "null";
|
||||
else
|
||||
return value.toString();
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Float){
|
||||
if(((Float)value).isInfinite() || ((Float)value).isNaN())
|
||||
return "null";
|
||||
else
|
||||
return value.toString();
|
||||
}
|
||||
if (value instanceof Boolean) {
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Number)
|
||||
return value.toString();
|
||||
if ((value instanceof JSONStreamAware)) {
|
||||
((JSONStreamAware)value).writeJSONString(out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Boolean)
|
||||
return value.toString();
|
||||
if ((value instanceof JSONAware)) {
|
||||
out.write(((JSONAware)value).toJSONString());
|
||||
return;
|
||||
}
|
||||
|
||||
if((value instanceof JSONAware))
|
||||
return ((JSONAware)value).toJSONString();
|
||||
if (value instanceof Map) {
|
||||
JSONObject.writeJSONString((Map)value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Map)
|
||||
return JSONObject.toJSONString((Map)value);
|
||||
if (value instanceof List) {
|
||||
JSONArray.writeJSONString((List)value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof List)
|
||||
return JSONArray.toJSONString((List)value);
|
||||
out.write(value.toString());
|
||||
}
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
/**
|
||||
* Convert an object to JSON text.
|
||||
* <p>
|
||||
* If this object is a Map or a List, and it's also a JSONAware, JSONAware will be considered firstly.
|
||||
* <p>
|
||||
* DO NOT call this method from toJSONString() of a class that implements both JSONAware and Map or List with
|
||||
* "this" as the parameter, use JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead.
|
||||
*
|
||||
* @see org.json.simple.JSONObject#toJSONString(Map)
|
||||
* @see org.json.simple.JSONArray#toJSONString(List)
|
||||
*
|
||||
* @param value
|
||||
* @return JSON text, or "null" if value is null or it's an NaN or an INF number.
|
||||
*/
|
||||
public static String toJSONString(Object value) {
|
||||
if (value == null)
|
||||
return "null";
|
||||
|
||||
/**
|
||||
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static String escape(String s){
|
||||
if(s==null)
|
||||
return null;
|
||||
if (value instanceof String)
|
||||
return "\"" + escape((String)value) + "\"";
|
||||
|
||||
if (value instanceof Double) {
|
||||
if (((Double)value).isInfinite() || ((Double)value).isNaN())
|
||||
return "null";
|
||||
else
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
if (value instanceof Float) {
|
||||
if (((Float)value).isInfinite() || ((Float)value).isNaN())
|
||||
return "null";
|
||||
else
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
if (value instanceof Number)
|
||||
return value.toString();
|
||||
|
||||
if (value instanceof Boolean)
|
||||
return value.toString();
|
||||
|
||||
if ((value instanceof JSONAware))
|
||||
return ((JSONAware)value).toJSONString();
|
||||
|
||||
if (value instanceof Map)
|
||||
return JSONObject.toJSONString((Map)value);
|
||||
|
||||
if (value instanceof List)
|
||||
return JSONArray.toJSONString((List)value);
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static String escape(String s) {
|
||||
if (s == null)
|
||||
return null;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
escape(s, sb);
|
||||
return sb.toString();
|
||||
@ -225,48 +225,48 @@ public class JSONValue {
|
||||
* @param sb
|
||||
*/
|
||||
static void escape(String s, StringBuffer sb) {
|
||||
for(int i=0;i<s.length();i++){
|
||||
char ch=s.charAt(i);
|
||||
switch(ch){
|
||||
case '"':
|
||||
sb.append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
sb.append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
sb.append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
sb.append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
sb.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
sb.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
sb.append("\\t");
|
||||
break;
|
||||
case '/':
|
||||
sb.append("\\/");
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char ch = s.charAt(i);
|
||||
switch (ch) {
|
||||
case '"':
|
||||
sb.append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
sb.append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
sb.append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
sb.append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
sb.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
sb.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
sb.append("\\t");
|
||||
break;
|
||||
case '/':
|
||||
sb.append("\\/");
|
||||
break;
|
||||
default:
|
||||
//Reference: http://www.unicode.org/versions/Unicode5.1.0/
|
||||
if((ch>='\u0000' && ch<='\u001F') || (ch>='\u007F' && ch<='\u009F') || (ch>='\u2000' && ch<='\u20FF')){
|
||||
String ss=Integer.toHexString(ch);
|
||||
sb.append("\\u");
|
||||
for(int k=0;k<4-ss.length();k++){
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(ss.toUpperCase());
|
||||
}
|
||||
else{
|
||||
sb.append(ch);
|
||||
}
|
||||
}
|
||||
}//for
|
||||
}
|
||||
if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) {
|
||||
String ss = Integer.toHexString(ch);
|
||||
sb.append("\\u");
|
||||
for (int k = 0; k < 4 - ss.length(); k++) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(ss.toUpperCase());
|
||||
}
|
||||
else {
|
||||
sb.append(ch);
|
||||
}
|
||||
}
|
||||
}//for
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,13 +11,13 @@ import java.util.Map;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public interface ContainerFactory {
|
||||
/**
|
||||
* @return A Map instance to store JSON object, or null if you want to use org.json.simple.JSONObject.
|
||||
*/
|
||||
Map createObjectContainer();
|
||||
/**
|
||||
* @return A Map instance to store JSON object, or null if you want to use org.json.simple.JSONObject.
|
||||
*/
|
||||
Map createObjectContainer();
|
||||
|
||||
/**
|
||||
* @return A List instance to store JSON array, or null if you want to use org.json.simple.JSONArray.
|
||||
*/
|
||||
List creatArrayContainer();
|
||||
/**
|
||||
* @return A List instance to store JSON array, or null if you want to use org.json.simple.JSONArray.
|
||||
*/
|
||||
List creatArrayContainer();
|
||||
}
|
||||
|
@ -11,100 +11,100 @@ import java.io.IOException;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public interface ContentHandler {
|
||||
/**
|
||||
* Receive notification of the beginning of JSON processing.
|
||||
* The parser will invoke this method only once.
|
||||
/**
|
||||
* Receive notification of the beginning of JSON processing.
|
||||
* The parser will invoke this method only once.
|
||||
*
|
||||
* @throws ParseException
|
||||
* - JSONParser will stop and throw the same exception to the caller when receiving this exception.
|
||||
*/
|
||||
void startJSON() throws ParseException, IOException;
|
||||
* @throws ParseException
|
||||
* - JSONParser will stop and throw the same exception to the caller when receiving this exception.
|
||||
*/
|
||||
void startJSON() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of JSON processing.
|
||||
*
|
||||
* @throws ParseException
|
||||
*/
|
||||
void endJSON() throws ParseException, IOException;
|
||||
/**
|
||||
* Receive notification of the end of JSON processing.
|
||||
*
|
||||
* @throws ParseException
|
||||
*/
|
||||
void endJSON() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON object.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON object.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* - JSONParser will stop and throw the same exception to the caller when receiving this exception.
|
||||
* @see #endJSON
|
||||
*/
|
||||
boolean startObject() throws ParseException, IOException;
|
||||
*/
|
||||
boolean startObject() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of a JSON object.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
/**
|
||||
* Receive notification of the end of a JSON object.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
*
|
||||
* @see #startObject
|
||||
*/
|
||||
boolean endObject() throws ParseException, IOException;
|
||||
*/
|
||||
boolean endObject() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON object entry.
|
||||
*
|
||||
* @param key - Key of a JSON object entry.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON object entry.
|
||||
*
|
||||
* @param key - Key of a JSON object entry.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
*
|
||||
* @see #endObjectEntry
|
||||
*/
|
||||
boolean startObjectEntry(String key) throws ParseException, IOException;
|
||||
*/
|
||||
boolean startObjectEntry(String key) throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of the value of previous object entry.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
/**
|
||||
* Receive notification of the end of the value of previous object entry.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
*
|
||||
* @see #startObjectEntry
|
||||
*/
|
||||
boolean endObjectEntry() throws ParseException, IOException;
|
||||
*/
|
||||
boolean endObjectEntry() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON array.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON array.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
*
|
||||
* @see #endArray
|
||||
*/
|
||||
boolean startArray() throws ParseException, IOException;
|
||||
*/
|
||||
boolean startArray() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of a JSON array.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
/**
|
||||
* Receive notification of the end of a JSON array.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
*
|
||||
* @see #startArray
|
||||
*/
|
||||
boolean endArray() throws ParseException, IOException;
|
||||
*/
|
||||
boolean endArray() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the JSON primitive values:
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean
|
||||
* null
|
||||
*
|
||||
* @param value - Instance of the following:
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean
|
||||
* null
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
*/
|
||||
boolean primitive(Object value) throws ParseException, IOException;
|
||||
/**
|
||||
* Receive notification of the JSON primitive values:
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean
|
||||
* null
|
||||
*
|
||||
* @param value - Instance of the following:
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean
|
||||
* null
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
*/
|
||||
boolean primitive(Object value) throws ParseException, IOException;
|
||||
|
||||
}
|
||||
|
@ -21,32 +21,32 @@ import java.util.Map;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public class JSONParser {
|
||||
public static final int S_INIT=0;
|
||||
public static final int S_IN_FINISHED_VALUE=1;//string,number,boolean,null,object,array
|
||||
public static final int S_IN_OBJECT=2;
|
||||
public static final int S_IN_ARRAY=3;
|
||||
public static final int S_PASSED_PAIR_KEY=4;
|
||||
public static final int S_IN_PAIR_VALUE=5;
|
||||
public static final int S_END=6;
|
||||
public static final int S_IN_ERROR=-1;
|
||||
public static final int S_INIT = 0;
|
||||
public static final int S_IN_FINISHED_VALUE = 1; //string,number,boolean,null,object,array
|
||||
public static final int S_IN_OBJECT = 2;
|
||||
public static final int S_IN_ARRAY = 3;
|
||||
public static final int S_PASSED_PAIR_KEY = 4;
|
||||
public static final int S_IN_PAIR_VALUE = 5;
|
||||
public static final int S_END = 6;
|
||||
public static final int S_IN_ERROR = -1;
|
||||
|
||||
private LinkedList handlerStatusStack;
|
||||
private Yylex lexer = new Yylex((Reader)null);
|
||||
private Yytoken token = null;
|
||||
private int status = S_INIT;
|
||||
private LinkedList handlerStatusStack;
|
||||
private Yylex lexer = new Yylex((Reader)null);
|
||||
private Yytoken token = null;
|
||||
private int status = S_INIT;
|
||||
|
||||
private int peekStatus(LinkedList statusStack){
|
||||
if(statusStack.size()==0)
|
||||
return -1;
|
||||
Integer status=(Integer)statusStack.getFirst();
|
||||
return status.intValue();
|
||||
}
|
||||
private int peekStatus(LinkedList statusStack) {
|
||||
if (statusStack.size() == 0)
|
||||
return -1;
|
||||
Integer status = (Integer)statusStack.getFirst();
|
||||
return status.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the parser to the initial state without resetting the underlying reader.
|
||||
*
|
||||
*/
|
||||
public void reset(){
|
||||
public void reset() {
|
||||
token = null;
|
||||
status = S_INIT;
|
||||
handlerStatusStack = null;
|
||||
@ -59,475 +59,475 @@ public class JSONParser {
|
||||
* @throws IOException
|
||||
* @throws ParseException
|
||||
*/
|
||||
public void reset(Reader in){
|
||||
lexer.yyreset(in);
|
||||
reset();
|
||||
}
|
||||
public void reset(Reader in) {
|
||||
lexer.yyreset(in);
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The position of the beginning of the current token.
|
||||
*/
|
||||
public int getPosition(){
|
||||
return lexer.getPosition();
|
||||
}
|
||||
/**
|
||||
* @return The position of the beginning of the current token.
|
||||
*/
|
||||
public int getPosition() {
|
||||
return lexer.getPosition();
|
||||
}
|
||||
|
||||
public Object parse(String s) throws ParseException{
|
||||
return parse(s, (ContainerFactory)null);
|
||||
}
|
||||
public Object parse(String s) throws ParseException {
|
||||
return parse(s, (ContainerFactory)null);
|
||||
}
|
||||
|
||||
public Object parse(String s, ContainerFactory containerFactory) throws ParseException{
|
||||
StringReader in=new StringReader(s);
|
||||
try{
|
||||
return parse(in, containerFactory);
|
||||
}
|
||||
catch(IOException ie){
|
||||
/*
|
||||
* Actually it will never happen.
|
||||
*/
|
||||
throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
|
||||
}
|
||||
}
|
||||
public Object parse(String s, ContainerFactory containerFactory) throws ParseException {
|
||||
StringReader in = new StringReader(s);
|
||||
try {
|
||||
return parse(in, containerFactory);
|
||||
}
|
||||
catch (IOException ie) {
|
||||
/*
|
||||
* Actually it will never happen.
|
||||
*/
|
||||
throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
|
||||
}
|
||||
}
|
||||
|
||||
public Object parse(Reader in) throws IOException, ParseException{
|
||||
return parse(in, (ContainerFactory)null);
|
||||
}
|
||||
public Object parse(Reader in) throws IOException, ParseException {
|
||||
return parse(in, (ContainerFactory)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON text into java object from the input source.
|
||||
*
|
||||
* @param in
|
||||
/**
|
||||
* Parse JSON text into java object from the input source.
|
||||
*
|
||||
* @param in
|
||||
* @param containerFactory - Use this factory to createyour own JSON object and JSON array containers.
|
||||
* @return Instance of the following:
|
||||
* org.json.simple.JSONObject,
|
||||
* org.json.simple.JSONArray,
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean,
|
||||
* null
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws ParseException
|
||||
*/
|
||||
public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, ParseException{
|
||||
reset(in);
|
||||
LinkedList statusStack = new LinkedList();
|
||||
LinkedList valueStack = new LinkedList();
|
||||
* @return Instance of the following:
|
||||
* org.json.simple.JSONObject,
|
||||
* org.json.simple.JSONArray,
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean,
|
||||
* null
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws ParseException
|
||||
*/
|
||||
public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, ParseException {
|
||||
reset(in);
|
||||
LinkedList statusStack = new LinkedList();
|
||||
LinkedList valueStack = new LinkedList();
|
||||
|
||||
try{
|
||||
do{
|
||||
nextToken();
|
||||
switch(status){
|
||||
case S_INIT:
|
||||
switch(token.type){
|
||||
case Yytoken.TYPE_VALUE:
|
||||
status=S_IN_FINISHED_VALUE;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(token.value);
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
status=S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(createObjectContainer(containerFactory));
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
status=S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(createArrayContainer(containerFactory));
|
||||
break;
|
||||
default:
|
||||
status=S_IN_ERROR;
|
||||
}//inner switch
|
||||
break;
|
||||
try {
|
||||
do {
|
||||
nextToken();
|
||||
switch (status) {
|
||||
case S_INIT:
|
||||
switch (token.type) {
|
||||
case Yytoken.TYPE_VALUE:
|
||||
status = S_IN_FINISHED_VALUE;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(token.value);
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
status = S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(createObjectContainer(containerFactory));
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
status = S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(createArrayContainer(containerFactory));
|
||||
break;
|
||||
default:
|
||||
status = S_IN_ERROR;
|
||||
}//inner switch
|
||||
break;
|
||||
|
||||
case S_IN_FINISHED_VALUE:
|
||||
if(token.type==Yytoken.TYPE_EOF)
|
||||
return valueStack.removeFirst();
|
||||
else
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
case S_IN_FINISHED_VALUE:
|
||||
if (token.type == Yytoken.TYPE_EOF)
|
||||
return valueStack.removeFirst();
|
||||
else
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
|
||||
case S_IN_OBJECT:
|
||||
switch(token.type){
|
||||
case Yytoken.TYPE_COMMA:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
if(token.value instanceof String){
|
||||
String key=(String)token.value;
|
||||
valueStack.addFirst(key);
|
||||
status=S_PASSED_PAIR_KEY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
}
|
||||
else{
|
||||
status=S_IN_ERROR;
|
||||
}
|
||||
break;
|
||||
case Yytoken.TYPE_RIGHT_BRACE:
|
||||
if(valueStack.size()>1){
|
||||
statusStack.removeFirst();
|
||||
valueStack.removeFirst();
|
||||
status=peekStatus(statusStack);
|
||||
}
|
||||
else{
|
||||
status=S_IN_FINISHED_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status=S_IN_ERROR;
|
||||
break;
|
||||
}//inner switch
|
||||
break;
|
||||
case S_IN_OBJECT:
|
||||
switch (token.type) {
|
||||
case Yytoken.TYPE_COMMA:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
if (token.value instanceof String) {
|
||||
String key = (String)token.value;
|
||||
valueStack.addFirst(key);
|
||||
status = S_PASSED_PAIR_KEY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
}
|
||||
else {
|
||||
status = S_IN_ERROR;
|
||||
}
|
||||
break;
|
||||
case Yytoken.TYPE_RIGHT_BRACE:
|
||||
if (valueStack.size() > 1) {
|
||||
statusStack.removeFirst();
|
||||
valueStack.removeFirst();
|
||||
status = peekStatus(statusStack);
|
||||
}
|
||||
else {
|
||||
status = S_IN_FINISHED_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = S_IN_ERROR;
|
||||
break;
|
||||
}//inner switch
|
||||
break;
|
||||
|
||||
case S_PASSED_PAIR_KEY:
|
||||
switch(token.type){
|
||||
case Yytoken.TYPE_COLON:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
statusStack.removeFirst();
|
||||
String key=(String)valueStack.removeFirst();
|
||||
Map parent=(Map)valueStack.getFirst();
|
||||
parent.put(key,token.value);
|
||||
status=peekStatus(statusStack);
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
statusStack.removeFirst();
|
||||
key=(String)valueStack.removeFirst();
|
||||
parent=(Map)valueStack.getFirst();
|
||||
List newArray=createArrayContainer(containerFactory);
|
||||
parent.put(key,newArray);
|
||||
status=S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(newArray);
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
statusStack.removeFirst();
|
||||
key=(String)valueStack.removeFirst();
|
||||
parent=(Map)valueStack.getFirst();
|
||||
Map newObject=createObjectContainer(containerFactory);
|
||||
parent.put(key,newObject);
|
||||
status=S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(newObject);
|
||||
break;
|
||||
default:
|
||||
status=S_IN_ERROR;
|
||||
}
|
||||
break;
|
||||
case S_PASSED_PAIR_KEY:
|
||||
switch (token.type) {
|
||||
case Yytoken.TYPE_COLON:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
statusStack.removeFirst();
|
||||
String key = (String)valueStack.removeFirst();
|
||||
Map parent = (Map)valueStack.getFirst();
|
||||
parent.put(key, token.value);
|
||||
status = peekStatus(statusStack);
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
statusStack.removeFirst();
|
||||
key = (String)valueStack.removeFirst();
|
||||
parent = (Map)valueStack.getFirst();
|
||||
List newArray = createArrayContainer(containerFactory);
|
||||
parent.put(key, newArray);
|
||||
status = S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(newArray);
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
statusStack.removeFirst();
|
||||
key = (String)valueStack.removeFirst();
|
||||
parent = (Map)valueStack.getFirst();
|
||||
Map newObject = createObjectContainer(containerFactory);
|
||||
parent.put(key, newObject);
|
||||
status = S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(newObject);
|
||||
break;
|
||||
default:
|
||||
status = S_IN_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case S_IN_ARRAY:
|
||||
switch(token.type){
|
||||
case Yytoken.TYPE_COMMA:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
List val=(List)valueStack.getFirst();
|
||||
val.add(token.value);
|
||||
break;
|
||||
case Yytoken.TYPE_RIGHT_SQUARE:
|
||||
if(valueStack.size()>1){
|
||||
statusStack.removeFirst();
|
||||
valueStack.removeFirst();
|
||||
status=peekStatus(statusStack);
|
||||
}
|
||||
else{
|
||||
status=S_IN_FINISHED_VALUE;
|
||||
}
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
val=(List)valueStack.getFirst();
|
||||
Map newObject=createObjectContainer(containerFactory);
|
||||
val.add(newObject);
|
||||
status=S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(newObject);
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
val=(List)valueStack.getFirst();
|
||||
List newArray=createArrayContainer(containerFactory);
|
||||
val.add(newArray);
|
||||
status=S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(newArray);
|
||||
break;
|
||||
default:
|
||||
status=S_IN_ERROR;
|
||||
}//inner switch
|
||||
break;
|
||||
case S_IN_ERROR:
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}//switch
|
||||
if(status==S_IN_ERROR){
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
}while(token.type!=Yytoken.TYPE_EOF);
|
||||
}
|
||||
catch(IOException ie){
|
||||
throw ie;
|
||||
}
|
||||
case S_IN_ARRAY:
|
||||
switch (token.type) {
|
||||
case Yytoken.TYPE_COMMA:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
List val = (List)valueStack.getFirst();
|
||||
val.add(token.value);
|
||||
break;
|
||||
case Yytoken.TYPE_RIGHT_SQUARE:
|
||||
if (valueStack.size() > 1) {
|
||||
statusStack.removeFirst();
|
||||
valueStack.removeFirst();
|
||||
status = peekStatus(statusStack);
|
||||
}
|
||||
else {
|
||||
status = S_IN_FINISHED_VALUE;
|
||||
}
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
val = (List)valueStack.getFirst();
|
||||
Map newObject = createObjectContainer(containerFactory);
|
||||
val.add(newObject);
|
||||
status = S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(newObject);
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
val = (List)valueStack.getFirst();
|
||||
List newArray = createArrayContainer(containerFactory);
|
||||
val.add(newArray);
|
||||
status = S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
valueStack.addFirst(newArray);
|
||||
break;
|
||||
default:
|
||||
status = S_IN_ERROR;
|
||||
}//inner switch
|
||||
break;
|
||||
case S_IN_ERROR:
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}//switch
|
||||
if (status == S_IN_ERROR) {
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
} while (token.type != Yytoken.TYPE_EOF);
|
||||
}
|
||||
catch (IOException ie) {
|
||||
throw ie;
|
||||
}
|
||||
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
|
||||
private void nextToken() throws ParseException, IOException{
|
||||
token = lexer.yylex();
|
||||
if(token == null)
|
||||
token = new Yytoken(Yytoken.TYPE_EOF, null);
|
||||
}
|
||||
private void nextToken() throws ParseException, IOException {
|
||||
token = lexer.yylex();
|
||||
if (token == null)
|
||||
token = new Yytoken(Yytoken.TYPE_EOF, null);
|
||||
}
|
||||
|
||||
private Map createObjectContainer(ContainerFactory containerFactory){
|
||||
if(containerFactory == null)
|
||||
return new JSONObject();
|
||||
Map m = containerFactory.createObjectContainer();
|
||||
private Map createObjectContainer(ContainerFactory containerFactory) {
|
||||
if (containerFactory == null)
|
||||
return new JSONObject();
|
||||
Map m = containerFactory.createObjectContainer();
|
||||
|
||||
if(m == null)
|
||||
return new JSONObject();
|
||||
return m;
|
||||
}
|
||||
if (m == null)
|
||||
return new JSONObject();
|
||||
return m;
|
||||
}
|
||||
|
||||
private List createArrayContainer(ContainerFactory containerFactory){
|
||||
if(containerFactory == null)
|
||||
return new JSONArray();
|
||||
List l = containerFactory.creatArrayContainer();
|
||||
private List createArrayContainer(ContainerFactory containerFactory) {
|
||||
if (containerFactory == null)
|
||||
return new JSONArray();
|
||||
List l = containerFactory.creatArrayContainer();
|
||||
|
||||
if(l == null)
|
||||
return new JSONArray();
|
||||
return l;
|
||||
}
|
||||
if (l == null)
|
||||
return new JSONArray();
|
||||
return l;
|
||||
}
|
||||
|
||||
public void parse(String s, ContentHandler contentHandler) throws ParseException{
|
||||
parse(s, contentHandler, false);
|
||||
}
|
||||
public void parse(String s, ContentHandler contentHandler) throws ParseException {
|
||||
parse(s, contentHandler, false);
|
||||
}
|
||||
|
||||
public void parse(String s, ContentHandler contentHandler, boolean isResume) throws ParseException{
|
||||
StringReader in=new StringReader(s);
|
||||
try{
|
||||
parse(in, contentHandler, isResume);
|
||||
}
|
||||
catch(IOException ie){
|
||||
/*
|
||||
* Actually it will never happen.
|
||||
*/
|
||||
throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
|
||||
}
|
||||
}
|
||||
public void parse(String s, ContentHandler contentHandler, boolean isResume) throws ParseException {
|
||||
StringReader in = new StringReader(s);
|
||||
try {
|
||||
parse(in, contentHandler, isResume);
|
||||
}
|
||||
catch (IOException ie) {
|
||||
/*
|
||||
* Actually it will never happen.
|
||||
*/
|
||||
throw new ParseException(-1, ParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
|
||||
}
|
||||
}
|
||||
|
||||
public void parse(Reader in, ContentHandler contentHandler) throws IOException, ParseException{
|
||||
parse(in, contentHandler, false);
|
||||
}
|
||||
public void parse(Reader in, ContentHandler contentHandler) throws IOException, ParseException {
|
||||
parse(in, contentHandler, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream processing of JSON text.
|
||||
*
|
||||
* @see ContentHandler
|
||||
*
|
||||
* @param in
|
||||
* @param contentHandler
|
||||
* @param isResume - Indicates if it continues previous parsing operation.
|
||||
/**
|
||||
* Stream processing of JSON text.
|
||||
*
|
||||
* @see ContentHandler
|
||||
*
|
||||
* @param in
|
||||
* @param contentHandler
|
||||
* @param isResume - Indicates if it continues previous parsing operation.
|
||||
* If set to true, resume parsing the old stream, and parameter 'in' will be ignored.
|
||||
* If this method is called for the first time in this instance, isResume will be ignored.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws ParseException
|
||||
*/
|
||||
public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, ParseException{
|
||||
if(!isResume){
|
||||
reset(in);
|
||||
handlerStatusStack = new LinkedList();
|
||||
}
|
||||
else{
|
||||
if(handlerStatusStack == null){
|
||||
isResume = false;
|
||||
reset(in);
|
||||
handlerStatusStack = new LinkedList();
|
||||
}
|
||||
}
|
||||
* If this method is called for the first time in this instance, isResume will be ignored.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws ParseException
|
||||
*/
|
||||
public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, ParseException {
|
||||
if (!isResume) {
|
||||
reset(in);
|
||||
handlerStatusStack = new LinkedList();
|
||||
}
|
||||
else {
|
||||
if (handlerStatusStack == null) {
|
||||
isResume = false;
|
||||
reset(in);
|
||||
handlerStatusStack = new LinkedList();
|
||||
}
|
||||
}
|
||||
|
||||
LinkedList statusStack = handlerStatusStack;
|
||||
LinkedList statusStack = handlerStatusStack;
|
||||
|
||||
try{
|
||||
do{
|
||||
switch(status){
|
||||
case S_INIT:
|
||||
contentHandler.startJSON();
|
||||
nextToken();
|
||||
switch(token.type){
|
||||
case Yytoken.TYPE_VALUE:
|
||||
status=S_IN_FINISHED_VALUE;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if(!contentHandler.primitive(token.value))
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
status=S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if(!contentHandler.startObject())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
status=S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if(!contentHandler.startArray())
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
status=S_IN_ERROR;
|
||||
}//inner switch
|
||||
break;
|
||||
try {
|
||||
do {
|
||||
switch (status) {
|
||||
case S_INIT:
|
||||
contentHandler.startJSON();
|
||||
nextToken();
|
||||
switch (token.type) {
|
||||
case Yytoken.TYPE_VALUE:
|
||||
status = S_IN_FINISHED_VALUE;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if (!contentHandler.primitive(token.value))
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
status = S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if (!contentHandler.startObject())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
status = S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if (!contentHandler.startArray())
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
status = S_IN_ERROR;
|
||||
}//inner switch
|
||||
break;
|
||||
|
||||
case S_IN_FINISHED_VALUE:
|
||||
nextToken();
|
||||
if(token.type==Yytoken.TYPE_EOF){
|
||||
contentHandler.endJSON();
|
||||
status = S_END;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
status = S_IN_ERROR;
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
case S_IN_FINISHED_VALUE:
|
||||
nextToken();
|
||||
if (token.type == Yytoken.TYPE_EOF) {
|
||||
contentHandler.endJSON();
|
||||
status = S_END;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
status = S_IN_ERROR;
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
|
||||
case S_IN_OBJECT:
|
||||
nextToken();
|
||||
switch(token.type){
|
||||
case Yytoken.TYPE_COMMA:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
if(token.value instanceof String){
|
||||
String key=(String)token.value;
|
||||
status=S_PASSED_PAIR_KEY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if(!contentHandler.startObjectEntry(key))
|
||||
return;
|
||||
}
|
||||
else{
|
||||
status=S_IN_ERROR;
|
||||
}
|
||||
break;
|
||||
case Yytoken.TYPE_RIGHT_BRACE:
|
||||
if(statusStack.size()>1){
|
||||
statusStack.removeFirst();
|
||||
status=peekStatus(statusStack);
|
||||
}
|
||||
else{
|
||||
status=S_IN_FINISHED_VALUE;
|
||||
}
|
||||
if(!contentHandler.endObject())
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
status=S_IN_ERROR;
|
||||
break;
|
||||
}//inner switch
|
||||
break;
|
||||
case S_IN_OBJECT:
|
||||
nextToken();
|
||||
switch (token.type) {
|
||||
case Yytoken.TYPE_COMMA:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
if (token.value instanceof String) {
|
||||
String key = (String)token.value;
|
||||
status = S_PASSED_PAIR_KEY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if (!contentHandler.startObjectEntry(key))
|
||||
return;
|
||||
}
|
||||
else {
|
||||
status = S_IN_ERROR;
|
||||
}
|
||||
break;
|
||||
case Yytoken.TYPE_RIGHT_BRACE:
|
||||
if (statusStack.size() > 1) {
|
||||
statusStack.removeFirst();
|
||||
status = peekStatus(statusStack);
|
||||
}
|
||||
else {
|
||||
status = S_IN_FINISHED_VALUE;
|
||||
}
|
||||
if (!contentHandler.endObject())
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
status = S_IN_ERROR;
|
||||
break;
|
||||
}//inner switch
|
||||
break;
|
||||
|
||||
case S_PASSED_PAIR_KEY:
|
||||
nextToken();
|
||||
switch(token.type){
|
||||
case Yytoken.TYPE_COLON:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
statusStack.removeFirst();
|
||||
status=peekStatus(statusStack);
|
||||
if(!contentHandler.primitive(token.value))
|
||||
return;
|
||||
if(!contentHandler.endObjectEntry())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
statusStack.removeFirst();
|
||||
statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
|
||||
status=S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if(!contentHandler.startArray())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
statusStack.removeFirst();
|
||||
statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
|
||||
status=S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if(!contentHandler.startObject())
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
status=S_IN_ERROR;
|
||||
}
|
||||
break;
|
||||
case S_PASSED_PAIR_KEY:
|
||||
nextToken();
|
||||
switch (token.type) {
|
||||
case Yytoken.TYPE_COLON:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
statusStack.removeFirst();
|
||||
status = peekStatus(statusStack);
|
||||
if (!contentHandler.primitive(token.value))
|
||||
return;
|
||||
if (!contentHandler.endObjectEntry())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
statusStack.removeFirst();
|
||||
statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
|
||||
status = S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if (!contentHandler.startArray())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
statusStack.removeFirst();
|
||||
statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
|
||||
status = S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if (!contentHandler.startObject())
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
status = S_IN_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case S_IN_PAIR_VALUE:
|
||||
/*
|
||||
* S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token,
|
||||
* therefore delay consuming token until next round.
|
||||
*/
|
||||
statusStack.removeFirst();
|
||||
status = peekStatus(statusStack);
|
||||
if(!contentHandler.endObjectEntry())
|
||||
return;
|
||||
break;
|
||||
case S_IN_PAIR_VALUE:
|
||||
/*
|
||||
* S_IN_PAIR_VALUE is just a marker to indicate the end of an object entry, it doesn't proccess any token,
|
||||
* therefore delay consuming token until next round.
|
||||
*/
|
||||
statusStack.removeFirst();
|
||||
status = peekStatus(statusStack);
|
||||
if (!contentHandler.endObjectEntry())
|
||||
return;
|
||||
break;
|
||||
|
||||
case S_IN_ARRAY:
|
||||
nextToken();
|
||||
switch(token.type){
|
||||
case Yytoken.TYPE_COMMA:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
if(!contentHandler.primitive(token.value))
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_RIGHT_SQUARE:
|
||||
if(statusStack.size()>1){
|
||||
statusStack.removeFirst();
|
||||
status=peekStatus(statusStack);
|
||||
}
|
||||
else{
|
||||
status=S_IN_FINISHED_VALUE;
|
||||
}
|
||||
if(!contentHandler.endArray())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
status=S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if(!contentHandler.startObject())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
status=S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if(!contentHandler.startArray())
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
status=S_IN_ERROR;
|
||||
}//inner switch
|
||||
break;
|
||||
case S_IN_ARRAY:
|
||||
nextToken();
|
||||
switch (token.type) {
|
||||
case Yytoken.TYPE_COMMA:
|
||||
break;
|
||||
case Yytoken.TYPE_VALUE:
|
||||
if (!contentHandler.primitive(token.value))
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_RIGHT_SQUARE:
|
||||
if (statusStack.size() > 1) {
|
||||
statusStack.removeFirst();
|
||||
status = peekStatus(statusStack);
|
||||
}
|
||||
else {
|
||||
status = S_IN_FINISHED_VALUE;
|
||||
}
|
||||
if (!contentHandler.endArray())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_BRACE:
|
||||
status = S_IN_OBJECT;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if (!contentHandler.startObject())
|
||||
return;
|
||||
break;
|
||||
case Yytoken.TYPE_LEFT_SQUARE:
|
||||
status = S_IN_ARRAY;
|
||||
statusStack.addFirst(new Integer(status));
|
||||
if (!contentHandler.startArray())
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
status = S_IN_ERROR;
|
||||
}//inner switch
|
||||
break;
|
||||
|
||||
case S_END:
|
||||
return;
|
||||
case S_END:
|
||||
return;
|
||||
|
||||
case S_IN_ERROR:
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}//switch
|
||||
if(status==S_IN_ERROR){
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
}while(token.type!=Yytoken.TYPE_EOF);
|
||||
}
|
||||
catch(IOException ie){
|
||||
status = S_IN_ERROR;
|
||||
throw ie;
|
||||
}
|
||||
catch(ParseException pe){
|
||||
status = S_IN_ERROR;
|
||||
throw pe;
|
||||
}
|
||||
catch(RuntimeException re){
|
||||
status = S_IN_ERROR;
|
||||
throw re;
|
||||
}
|
||||
catch(Error e){
|
||||
status = S_IN_ERROR;
|
||||
throw e;
|
||||
}
|
||||
case S_IN_ERROR:
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}//switch
|
||||
if (status == S_IN_ERROR) {
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
} while (token.type != Yytoken.TYPE_EOF);
|
||||
}
|
||||
catch (IOException ie) {
|
||||
status = S_IN_ERROR;
|
||||
throw ie;
|
||||
}
|
||||
catch (ParseException pe) {
|
||||
status = S_IN_ERROR;
|
||||
throw pe;
|
||||
}
|
||||
catch (RuntimeException re) {
|
||||
status = S_IN_ERROR;
|
||||
throw re;
|
||||
}
|
||||
catch (Error e) {
|
||||
status = S_IN_ERROR;
|
||||
throw e;
|
||||
}
|
||||
|
||||
status = S_IN_ERROR;
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
status = S_IN_ERROR;
|
||||
throw new ParseException(getPosition(), ParseException.ERROR_UNEXPECTED_TOKEN, token);
|
||||
}
|
||||
}
|
||||
|
@ -7,84 +7,84 @@ package org.json.simple.parser;
|
||||
*
|
||||
*/
|
||||
public class ParseException extends Exception {
|
||||
private static final long serialVersionUID = -7880698968187728548L;
|
||||
private static final long serialVersionUID = -7880698968187728548L;
|
||||
|
||||
public static final int ERROR_UNEXPECTED_CHAR = 0;
|
||||
public static final int ERROR_UNEXPECTED_TOKEN = 1;
|
||||
public static final int ERROR_UNEXPECTED_EXCEPTION = 2;
|
||||
public static final int ERROR_UNEXPECTED_CHAR = 0;
|
||||
public static final int ERROR_UNEXPECTED_TOKEN = 1;
|
||||
public static final int ERROR_UNEXPECTED_EXCEPTION = 2;
|
||||
|
||||
private int errorType;
|
||||
private Object unexpectedObject;
|
||||
private int position;
|
||||
private int errorType;
|
||||
private Object unexpectedObject;
|
||||
private int position;
|
||||
|
||||
public ParseException(int errorType){
|
||||
this(-1, errorType, null);
|
||||
}
|
||||
public ParseException(int errorType) {
|
||||
this(-1, errorType, null);
|
||||
}
|
||||
|
||||
public ParseException(int errorType, Object unexpectedObject){
|
||||
this(-1, errorType, unexpectedObject);
|
||||
}
|
||||
public ParseException(int errorType, Object unexpectedObject) {
|
||||
this(-1, errorType, unexpectedObject);
|
||||
}
|
||||
|
||||
public ParseException(int position, int errorType, Object unexpectedObject){
|
||||
this.position = position;
|
||||
this.errorType = errorType;
|
||||
this.unexpectedObject = unexpectedObject;
|
||||
}
|
||||
public ParseException(int position, int errorType, Object unexpectedObject) {
|
||||
this.position = position;
|
||||
this.errorType = errorType;
|
||||
this.unexpectedObject = unexpectedObject;
|
||||
}
|
||||
|
||||
public int getErrorType() {
|
||||
return errorType;
|
||||
}
|
||||
public int getErrorType() {
|
||||
return errorType;
|
||||
}
|
||||
|
||||
public void setErrorType(int errorType) {
|
||||
this.errorType = errorType;
|
||||
}
|
||||
public void setErrorType(int errorType) {
|
||||
this.errorType = errorType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.json.simple.parser.JSONParser#getPosition()
|
||||
*
|
||||
* @return The character position (starting with 0) of the input where the error occurs.
|
||||
*/
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
/**
|
||||
* @see org.json.simple.parser.JSONParser#getPosition()
|
||||
*
|
||||
* @return The character position (starting with 0) of the input where the error occurs.
|
||||
*/
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.json.simple.parser.Yytoken
|
||||
*
|
||||
* @return One of the following base on the value of errorType:
|
||||
* ERROR_UNEXPECTED_CHAR java.lang.Character
|
||||
* ERROR_UNEXPECTED_TOKEN org.json.simple.parser.Yytoken
|
||||
* ERROR_UNEXPECTED_EXCEPTION java.lang.Exception
|
||||
*/
|
||||
public Object getUnexpectedObject() {
|
||||
return unexpectedObject;
|
||||
}
|
||||
/**
|
||||
* @see org.json.simple.parser.Yytoken
|
||||
*
|
||||
* @return One of the following base on the value of errorType:
|
||||
* ERROR_UNEXPECTED_CHAR java.lang.Character
|
||||
* ERROR_UNEXPECTED_TOKEN org.json.simple.parser.Yytoken
|
||||
* ERROR_UNEXPECTED_EXCEPTION java.lang.Exception
|
||||
*/
|
||||
public Object getUnexpectedObject() {
|
||||
return unexpectedObject;
|
||||
}
|
||||
|
||||
public void setUnexpectedObject(Object unexpectedObject) {
|
||||
this.unexpectedObject = unexpectedObject;
|
||||
}
|
||||
public void setUnexpectedObject(Object unexpectedObject) {
|
||||
this.unexpectedObject = unexpectedObject;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
StringBuffer sb = new StringBuffer();
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
switch(errorType){
|
||||
case ERROR_UNEXPECTED_CHAR:
|
||||
sb.append("Unexpected character (").append(unexpectedObject).append(") at position ").append(position).append(".");
|
||||
break;
|
||||
case ERROR_UNEXPECTED_TOKEN:
|
||||
sb.append("Unexpected token ").append(unexpectedObject).append(" at position ").append(position).append(".");
|
||||
break;
|
||||
case ERROR_UNEXPECTED_EXCEPTION:
|
||||
sb.append("Unexpected exception at position ").append(position).append(": ").append(unexpectedObject);
|
||||
break;
|
||||
default:
|
||||
sb.append("Unkown error at position ").append(position).append(".");
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
switch (errorType) {
|
||||
case ERROR_UNEXPECTED_CHAR:
|
||||
sb.append("Unexpected character (").append(unexpectedObject).append(") at position ").append(position).append(".");
|
||||
break;
|
||||
case ERROR_UNEXPECTED_TOKEN:
|
||||
sb.append("Unexpected token ").append(unexpectedObject).append(" at position ").append(position).append(".");
|
||||
break;
|
||||
case ERROR_UNEXPECTED_EXCEPTION:
|
||||
sb.append("Unexpected exception at position ").append(position).append(": ").append(unexpectedObject);
|
||||
break;
|
||||
default:
|
||||
sb.append("Unkown error at position ").append(position).append(".");
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,51 +8,51 @@ package org.json.simple.parser;
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public class Yytoken {
|
||||
public static final int TYPE_VALUE=0;//JSON primitive value: string,number,boolean,null
|
||||
public static final int TYPE_LEFT_BRACE=1;
|
||||
public static final int TYPE_RIGHT_BRACE=2;
|
||||
public static final int TYPE_LEFT_SQUARE=3;
|
||||
public static final int TYPE_RIGHT_SQUARE=4;
|
||||
public static final int TYPE_COMMA=5;
|
||||
public static final int TYPE_COLON=6;
|
||||
public static final int TYPE_EOF=-1;//end of file
|
||||
public static final int TYPE_VALUE = 0; //JSON primitive value: string,number,boolean,null
|
||||
public static final int TYPE_LEFT_BRACE = 1;
|
||||
public static final int TYPE_RIGHT_BRACE = 2;
|
||||
public static final int TYPE_LEFT_SQUARE = 3;
|
||||
public static final int TYPE_RIGHT_SQUARE = 4;
|
||||
public static final int TYPE_COMMA = 5;
|
||||
public static final int TYPE_COLON = 6;
|
||||
public static final int TYPE_EOF = -1; //end of file
|
||||
|
||||
public int type=0;
|
||||
public Object value=null;
|
||||
public int type = 0;
|
||||
public Object value = null;
|
||||
|
||||
public Yytoken(int type,Object value){
|
||||
this.type=type;
|
||||
this.value=value;
|
||||
}
|
||||
public Yytoken(int type, Object value) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
StringBuffer sb = new StringBuffer();
|
||||
switch(type){
|
||||
case TYPE_VALUE:
|
||||
sb.append("VALUE(").append(value).append(")");
|
||||
break;
|
||||
case TYPE_LEFT_BRACE:
|
||||
sb.append("LEFT BRACE({)");
|
||||
break;
|
||||
case TYPE_RIGHT_BRACE:
|
||||
sb.append("RIGHT BRACE(})");
|
||||
break;
|
||||
case TYPE_LEFT_SQUARE:
|
||||
sb.append("LEFT SQUARE([)");
|
||||
break;
|
||||
case TYPE_RIGHT_SQUARE:
|
||||
sb.append("RIGHT SQUARE(])");
|
||||
break;
|
||||
case TYPE_COMMA:
|
||||
sb.append("COMMA(,)");
|
||||
break;
|
||||
case TYPE_COLON:
|
||||
sb.append("COLON(:)");
|
||||
break;
|
||||
case TYPE_EOF:
|
||||
sb.append("END OF FILE");
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
switch (type) {
|
||||
case TYPE_VALUE:
|
||||
sb.append("VALUE(").append(value).append(")");
|
||||
break;
|
||||
case TYPE_LEFT_BRACE:
|
||||
sb.append("LEFT BRACE({)");
|
||||
break;
|
||||
case TYPE_RIGHT_BRACE:
|
||||
sb.append("RIGHT BRACE(})");
|
||||
break;
|
||||
case TYPE_LEFT_SQUARE:
|
||||
sb.append("LEFT SQUARE([)");
|
||||
break;
|
||||
case TYPE_RIGHT_SQUARE:
|
||||
sb.append("RIGHT SQUARE(])");
|
||||
break;
|
||||
case TYPE_COMMA:
|
||||
sb.append("COMMA(,)");
|
||||
break;
|
||||
case TYPE_COLON:
|
||||
sb.append("COLON(:)");
|
||||
break;
|
||||
case TYPE_EOF:
|
||||
sb.append("END OF FILE");
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user