/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.core.jsonrpc.impl; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcError; import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcParams; import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcRequest; import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcResponse; import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcResult; import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcUnmarshaller; import java.util.ArrayList; import java.util.List; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Collections.singletonList; @Singleton public class GsonJsonRpcUnmarshaller implements JsonRpcUnmarshaller { private final JsonParser jsonParser; @Inject public GsonJsonRpcUnmarshaller(JsonParser jsonParser) { this.jsonParser = jsonParser; } @Override public List<String> unmarshalArray(String message) { return getArray(message, jsonParser.parse(message).isJsonArray()); } @Override public JsonRpcRequest unmarshalRequest(String message) { checkNotNull(message, "Message must not be null"); checkArgument(!message.isEmpty(), "Message must not be empty"); JsonObject request = jsonParser.parse(message).getAsJsonObject(); String method = getMethod(request); String id = getId(request); JsonRpcParams params = getParams(request); return new JsonRpcRequest(id, method, params); } @Override public JsonRpcResponse unmarshalResponse(String message) { checkNotNull(message, "Message must not be null"); checkArgument(!message.isEmpty(), "Message must not be empty"); JsonObject response = jsonParser.parse(message).getAsJsonObject(); String id = getId(response); JsonRpcResult result = getResult(response); JsonRpcError error = getError(response); return new JsonRpcResponse(id, result, error); } private JsonRpcError getError(JsonObject response) { if (!response.has("error")) { return null; } int code = response.get("error").getAsJsonObject().get("code").getAsInt(); String errorMessage = response.get("error").getAsJsonObject().get("message").getAsString(); return new JsonRpcError(code, errorMessage); } private JsonRpcResult getResult(JsonObject response) { if (!response.has("result")) { return null; } JsonElement jsonElement = response.get("result"); if (!jsonElement.isJsonArray()) { return new JsonRpcResult(getInnerItem(jsonElement)); } JsonArray jsonArray = jsonElement.getAsJsonArray(); int size = jsonArray.size(); List<Object> innerResults = new ArrayList<>(size); for (int i = 0; i < size; i++) { JsonElement innerJsonElement = jsonArray.get(i); innerResults.add(getInnerItem(innerJsonElement)); } return new JsonRpcResult(innerResults); } private JsonRpcParams getParams(JsonObject jsonObject) { if (!jsonObject.has("params")) { return null; } JsonElement jsonElement = jsonObject.get("params"); if (!jsonElement.isJsonArray()) { return new JsonRpcParams(getInnerItem(jsonElement)); } JsonArray jsonArray = jsonElement.getAsJsonArray(); int size = jsonArray.size(); List<Object> innerParameters = new ArrayList<>(size); for (int i = 0; i < size; i++) { JsonElement innerJsonElement = jsonArray.get(i); innerParameters.add(getInnerItem(innerJsonElement)); } return new JsonRpcParams(innerParameters); } private String getId(JsonObject jsonObject) { return jsonObject.has("id") ? jsonObject.get("id").getAsString() : null; } private String getMethod(JsonObject jsonObject) { return jsonObject.get("method").getAsString(); } private List<String> getArray(String message, boolean isArray) { if (!isArray) { return singletonList(message); } JsonArray jsonArray = jsonParser.parse(message).getAsJsonArray(); int size = jsonArray.size(); List<String> result = new ArrayList<>(size); for (int i = 0; i < size; i++) { JsonElement jsonElement = jsonArray.get(i); result.add(jsonElement.toString()); } return result; } private Object getInnerItem(JsonElement jsonElement) { if (jsonElement.isJsonNull()) { return null; } if (jsonElement.isJsonObject()) { return jsonElement.getAsJsonObject(); } if (jsonElement.isJsonPrimitive()) { JsonPrimitive jsonPrimitive = jsonElement.getAsJsonPrimitive(); if (jsonPrimitive.isNumber()) { return jsonPrimitive.getAsDouble(); } else if (jsonPrimitive.isString()) { return jsonPrimitive.getAsString(); } else { return jsonPrimitive.getAsBoolean(); } } throw new IllegalStateException("Unexpected json element type"); } }