source) {
- try {
- fill(target, source);
- } catch (IntrospectionException ie) {
- LOGGER.error("Error in tryFill", ie);
- } catch (IllegalAccessException iae) {
- LOGGER.error("Error in tryFill", iae);
- } catch (InvocationTargetException ite) {
- LOGGER.error("Error in tryFill", ite);
- }
+ try {
+ fill(target, source);
+ } catch (IntrospectionException ie) {
+ LOGGER.error("Error in tryFill", ie);
+ } catch (IllegalAccessException iae) {
+ LOGGER.error("Error in tryFill", iae);
+ } catch (InvocationTargetException ite) {
+ LOGGER.error("Error in tryFill", ite);
+ }
}
}
diff --git a/src/main/java/com/rabbitmq/tools/json/JSONWriter.java b/src/main/java/com/rabbitmq/tools/json/JSONWriter.java
index 4a7f78c7f0..7101598040 100644
--- a/src/main/java/com/rabbitmq/tools/json/JSONWriter.java
+++ b/src/main/java/com/rabbitmq/tools/json/JSONWriter.java
@@ -53,6 +53,10 @@
import java.util.Map;
import java.util.Set;
+/**
+ * Will be removed in 6.0
+ * @deprecated Use a third-party JSON library, e.g. Jackson or Gson
+ */
public class JSONWriter {
private boolean indentMode = false;
private int indentLevel = 0;
diff --git a/src/main/java/com/rabbitmq/tools/jsonrpc/DefaultJsonRpcMapper.java b/src/main/java/com/rabbitmq/tools/jsonrpc/DefaultJsonRpcMapper.java
new file mode 100644
index 0000000000..b40789e380
--- /dev/null
+++ b/src/main/java/com/rabbitmq/tools/jsonrpc/DefaultJsonRpcMapper.java
@@ -0,0 +1,72 @@
+// Copyright (c) 2018 Pivotal Software, Inc. All rights reserved.
+//
+// This software, the RabbitMQ Java client library, is triple-licensed under the
+// Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2
+// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
+// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
+// please see LICENSE-APACHE2.
+//
+// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
+// either express or implied. See the LICENSE file for specific language governing
+// rights and limitations of this software.
+//
+// If you have any questions regarding licensing, please contact us at
+// info@rabbitmq.com.
+
+package com.rabbitmq.tools.jsonrpc;
+
+import com.rabbitmq.tools.json.JSONReader;
+import com.rabbitmq.tools.json.JSONWriter;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Simple {@link JsonRpcMapper} based on homegrown JSON utilities.
+ * Handles integers, doubles, strings, booleans, and arrays of those types.
+ *
+ * For a more comprehensive set of features, use {@link JacksonJsonRpcMapper}.
+ *
+ * Will be removed in 6.0
+ *
+ * @see JsonRpcMapper
+ * @see JacksonJsonRpcMapper
+ * @since 5.4.0
+ * @deprecated use {@link JacksonJsonRpcMapper} instead
+ */
+public class DefaultJsonRpcMapper implements JsonRpcMapper {
+
+ @Override
+ public JsonRpcRequest parse(String requestBody, ServiceDescription description) {
+ @SuppressWarnings("unchecked")
+ Map request = (Map) new JSONReader().read(requestBody);
+ return new JsonRpcRequest(
+ request.get("id"), request.get("version").toString(), request.get("method").toString(),
+ ((List>) request.get("params")).toArray()
+ );
+ }
+
+ @Override
+ public JsonRpcResponse parse(String responseBody, Class> expectedType) {
+ @SuppressWarnings("unchecked")
+ Map map = (Map) (new JSONReader().read(responseBody));
+ Map error;
+ JsonRpcException exception = null;
+ if (map.containsKey("error")) {
+ error = (Map) map.get("error");
+ exception = new JsonRpcException(
+ new JSONWriter().write(error),
+ (String) error.get("name"),
+ error.get("code") == null ? 0 : (Integer) error.get("code"),
+ (String) error.get("message"),
+ error
+ );
+ }
+ return new JsonRpcResponse(map.get("result"), map.get("error"), exception);
+ }
+
+ @Override
+ public String write(Object input) {
+ return new JSONWriter().write(input);
+ }
+}
diff --git a/src/main/java/com/rabbitmq/tools/jsonrpc/JacksonJsonRpcMapper.java b/src/main/java/com/rabbitmq/tools/jsonrpc/JacksonJsonRpcMapper.java
new file mode 100644
index 0000000000..9cb5411b25
--- /dev/null
+++ b/src/main/java/com/rabbitmq/tools/jsonrpc/JacksonJsonRpcMapper.java
@@ -0,0 +1,200 @@
+// Copyright (c) 2018 Pivotal Software, Inc. All rights reserved.
+//
+// This software, the RabbitMQ Java client library, is triple-licensed under the
+// Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2
+// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
+// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
+// please see LICENSE-APACHE2.
+//
+// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
+// either express or implied. See the LICENSE file for specific language governing
+// rights and limitations of this software.
+//
+// If you have any questions regarding licensing, please contact us at
+// info@rabbitmq.com.
+
+package com.rabbitmq.tools.jsonrpc;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.TreeNode;
+import com.fasterxml.jackson.databind.MappingJsonFactory;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ValueNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * {@link JsonRpcMapper} based on Jackson.
+ * Uses the streaming and databind modules.
+ *
+ * @see JsonRpcMapper
+ * @since 5.4.0
+ */
+public class JacksonJsonRpcMapper implements JsonRpcMapper {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JacksonJsonRpcMapper.class);
+
+ private final ObjectMapper mapper;
+
+ public JacksonJsonRpcMapper(ObjectMapper mapper) {
+ this.mapper = mapper;
+ }
+
+ public JacksonJsonRpcMapper() {
+ this(new ObjectMapper());
+ }
+
+ @Override
+ public JsonRpcRequest parse(String requestBody, ServiceDescription description) {
+ JsonFactory jsonFactory = new MappingJsonFactory();
+ String method = null, version = null;
+ final List parameters = new ArrayList<>();
+ Object id = null;
+ try (JsonParser parser = jsonFactory.createParser(requestBody)) {
+ while (parser.nextToken() != null) {
+ JsonToken token = parser.currentToken();
+ if (token == JsonToken.FIELD_NAME) {
+ String name = parser.currentName();
+ token = parser.nextToken();
+ if ("method".equals(name)) {
+ method = parser.getValueAsString();
+ } else if ("id".equals(name)) {
+ TreeNode node = parser.readValueAsTree();
+ if (node instanceof ValueNode) {
+ ValueNode idNode = (ValueNode) node;
+ if (idNode.isNull()) {
+ id = null;
+ } else if (idNode.isTextual()) {
+ id = idNode.asText();
+ } else if (idNode.isNumber()) {
+ id = Long.valueOf(idNode.asLong());
+ } else {
+ LOGGER.warn("ID type not null, text, or number {}, ignoring", idNode);
+ }
+ } else {
+ LOGGER.warn("ID not a scalar value {}, ignoring", node);
+ }
+ } else if ("version".equals(name)) {
+ version = parser.getValueAsString();
+ } else if ("params".equals(name)) {
+ if (token == JsonToken.START_ARRAY) {
+ while (parser.nextToken() != JsonToken.END_ARRAY) {
+ parameters.add(parser.readValueAsTree());
+ }
+ } else {
+ throw new IllegalStateException("Field params must be an array");
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new JsonRpcMappingException("Error during JSON parsing", e);
+ }
+
+ if (method == null) {
+ throw new IllegalArgumentException("Could not find method to invoke in request");
+ }
+
+ List