/******************************************************************************* * 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.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; import com.google.inject.Inject; import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcError; import org.eclipse.che.api.core.jsonrpc.commons.JsonRpcMarshaller; 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.dto.server.DtoFactory; import org.eclipse.che.dto.server.JsonSerializable; import java.util.List; import static org.eclipse.che.api.core.jsonrpc.commons.JsonRpcUtils.cast; public class GsonJsonRpcMarshaller implements JsonRpcMarshaller { private final JsonParser jsonParser; @Inject public GsonJsonRpcMarshaller(JsonParser jsonParser) { this.jsonParser = jsonParser; } @Override public String marshall(JsonRpcResponse response) { JsonElement jsonId = getId(response); JsonElement jsonResult = getResult(response); JsonElement jsonError = getError(response); return getResponse(jsonId, jsonResult, jsonError).toString(); } @Override public String marshall(JsonRpcRequest request) { JsonElement method = getMethod(request); JsonElement id = getId(request); JsonElement params = getParams(request); return getRequest(method, id, params).toString(); } private JsonObject getRequest(JsonElement jsonMethod, JsonElement jsonId, JsonElement jsonParams) { JsonObject jsonRequest = new JsonObject(); jsonRequest.addProperty("jsonrpc", "2.0"); jsonRequest.add("method", jsonMethod); if (jsonId != null) { jsonRequest.add("id", jsonId); } if (jsonParams != null) { jsonRequest.add("params", jsonParams); } return jsonRequest; } private JsonElement getParams(JsonRpcRequest request) { if (!request.hasParams()) { return null; } JsonRpcParams params = request.getParams(); return params.isSingle() ? getElement(params.getOne()) : getElements(params.getMany()); } private JsonElement getId(JsonRpcRequest request) { return request.hasId() ? new JsonPrimitive(request.getId()) : null; } private JsonPrimitive getMethod(JsonRpcRequest request) { return new JsonPrimitive(request.getMethod()); } private JsonObject getResponse(JsonElement jsonId, JsonElement jsonResult, JsonElement jsonError) { JsonObject jsonResponse = new JsonObject(); jsonResponse.addProperty("jsonrpc", "2.0"); if (jsonId != null) { jsonResponse.add("id", jsonId); } if (jsonResult != null) { jsonResponse.add("result", jsonResult); } else { jsonResponse.add("error", jsonError); } return jsonResponse; } private JsonObject getError(JsonRpcResponse response) { if (!response.hasError()) { return null; } JsonObject jsonError = new JsonObject(); JsonRpcError error = response.getError(); jsonError.add("code", new JsonPrimitive(error.getCode())); jsonError.add("message", new JsonPrimitive(error.getMessage())); return jsonError; } private JsonElement getResult(JsonRpcResponse response) { if (!response.hasResult()) { return null; } JsonRpcResult result = response.getResult(); return result.isSingle() ? getElement(result.getOne()) : getElements(result.getMany()); } private JsonElement getId(JsonRpcResponse response) { return response.hasId() ? new JsonPrimitive(response.getId()) : null; } private JsonElement getElements(List<?> params) { JsonArray elements = new JsonArray(); params.forEach(param -> elements.add(getJsonElement(param))); return elements; } private JsonElement getElement(Object param) { JsonElement jsonElement = getJsonElement(param); if (jsonElement.isJsonObject()) { return jsonElement; } JsonArray array = new JsonArray(); array.add(jsonElement); return array; } private JsonElement getJsonElement(Object param) { if (param == null) { return JsonNull.INSTANCE; } if (param instanceof JsonElement) { return cast(param); } if (param instanceof String) { return new JsonPrimitive((String)param); } if (param instanceof Boolean) { return new JsonPrimitive((Boolean)param); } if (param instanceof Double) { return new JsonPrimitive((Double)param); } try { return jsonParser.parse(DtoFactory.getInstance().toJson(param)); } catch (IllegalArgumentException e){ return jsonParser.parse(param.toString()); } } }