Skip to content

Commit

Permalink
#126: Parse Object into a JsonElement
Browse files Browse the repository at this point in the history
  • Loading branch information
spoenemann committed Feb 1, 2018
1 parent b4659be commit 74e8804
Show file tree
Hide file tree
Showing 16 changed files with 574 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,14 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type[] elementTypes = TypeUtils.getElementTypes(typeToken, Collection.class);
if (elementTypes.length != 1)
return null;
TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementTypes[0]));
Type elementType = elementTypes[0];
TypeAdapter<?> elementTypeAdapter;
if (elementType == Object.class)
elementTypeAdapter = new JsonElementTypeAdapter(gson);
else
elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
Supplier<Collection<Object>> constructor = getConstructor((Class<Collection<Object>>) typeToken.getRawType());
return (TypeAdapter<T>) create(gson, elementTypes[0], elementTypeAdapter, constructor);
return (TypeAdapter<T>) create(gson, elementType, elementTypeAdapter, constructor);
}

@SuppressWarnings({ "unchecked", "rawtypes" })
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2018 TypeFox GmbH (http://www.typefox.io) and others.
* 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
*******************************************************************************/
package org.eclipse.lsp4j.jsonrpc.json.adapters;

import java.io.IOException;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.bind.TypeAdapters;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

/**
* A type adapter that reads every input into a tree of {@link JsonElement}s.
*/
public class JsonElementTypeAdapter extends TypeAdapter<Object> {

/**
* This factory should not be registered with a GsonBuilder because it always matches.
* Use it as argument to a {@link com.google.gson.annotations.JsonAdapter} annotation like this:
* {@code @JsonAdapter(JsonElementTypeAdapter.Factory.class)}
*/
public static class Factory implements TypeAdapterFactory {

@SuppressWarnings("unchecked")
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
return (TypeAdapter<T>) new JsonElementTypeAdapter(gson);
}

}

private final Gson gson;

public JsonElementTypeAdapter(Gson gson) {
this.gson = gson;
}

@Override
public JsonElement read(JsonReader in) throws IOException {
return TypeAdapters.JSON_ELEMENT.read(in);
}

@Override
public void write(JsonWriter out, Object value) throws IOException {
if (value == null) {
out.nullValue();
} else if (value instanceof JsonElement) {
TypeAdapters.JSON_ELEMENT.write(out, (JsonElement) value);
} else {
gson.toJson(value, value.getClass(), out);;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
package org.eclipse.lsp4j.jsonrpc.messages;

import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;

import com.google.gson.annotations.JsonAdapter;

public class ResponseError {

/**
Expand Down Expand Up @@ -48,6 +51,7 @@ public void setMessage(String message) {
* A Primitive or Structured value that contains additional information
* about the error. Can be omitted.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
private Object data;

public Object getData() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
package org.eclipse.lsp4j.jsonrpc.test.json;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
Expand All @@ -22,6 +22,7 @@
import org.eclipse.lsp4j.jsonrpc.messages.Message;
import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
import org.eclipse.lsp4j.jsonrpc.messages.RequestMessage;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
import org.junit.Assert;
import org.junit.Test;
Expand Down Expand Up @@ -522,6 +523,26 @@ public void testEnumParam() {
parameters);
}

@Test
public void testResponseErrorData() {
MessageJsonHandler handler = new MessageJsonHandler(Collections.emptyMap());
ResponseMessage message = (ResponseMessage) handler.parseMessage("{\"jsonrpc\":\"2.0\","
+ "\"id\":\"2\",\n"
+ "\"error\": { \"code\": -32001, \"message\": \"foo\",\n"
+ " \"data\": { \"uri\": \"file:/foo\", \"version\": 5, \"list\": [\"a\", \"b\", \"c\"] }\n"
+ " }\n"
+ "}");
ResponseError error = message.getError();
Assert.assertTrue("Expected a JsonObject in error.data", error.getData() instanceof JsonObject);
JsonObject data = (JsonObject) error.getData();
Assert.assertEquals("file:/foo", data.get("uri").getAsString());
Assert.assertEquals(5, data.get("version").getAsInt());
JsonArray list = data.get("list").getAsJsonArray();
Assert.assertEquals("a", list.get(0).getAsString());
Assert.assertEquals("b", list.get(1).getAsString());
Assert.assertEquals("c", list.get(2).getAsString());
}

public static final <T> void swap(T[] a, int i, int j) {
T t = a[i];
a[i] = a[j];
Expand Down Expand Up @@ -652,8 +673,8 @@ public void testErrorResponse_AllOrders() {
ResponseMessage message = (ResponseMessage) handler.parseMessage(json);
Assert.assertEquals("failed", message.getError().getMessage());
Object data = message.getError().getData();
Map<String, String> expected = new HashMap<>();
expected.put("uri", "failed");
JsonObject expected = new JsonObject();
expected.addProperty("uri", "failed");
Assert.assertEquals(expected, data);
Assert.assertNull(message.getResult());
});
Expand Down
14 changes: 13 additions & 1 deletion org.eclipse.lsp4j/src/main/java/org/eclipse/lsp4j/Protocol.xtend
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@
*******************************************************************************/
package org.eclipse.lsp4j

import com.google.common.annotations.Beta
import com.google.gson.annotations.JsonAdapter
import java.util.ArrayList
import java.util.LinkedHashMap
import java.util.List
import java.util.Map
import org.eclipse.lsp4j.generator.JsonRpcData
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter
import org.eclipse.lsp4j.jsonrpc.messages.Either
import org.eclipse.lsp4j.jsonrpc.messages.Either3
import org.eclipse.lsp4j.jsonrpc.validation.NonNull
import com.google.common.annotations.Beta

@JsonRpcData
class DynamicRegistrationCapabilities {
Expand Down Expand Up @@ -444,6 +446,7 @@ class ClientCapabilities {
/**
* Experimental client capabilities.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory)
Object experimental

new() {
Expand Down Expand Up @@ -534,6 +537,7 @@ class CodeLens {
/**
* An data entry field that is preserved on a code lens item between a code lens and a code lens resolve request.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory)
Object data

new() {
Expand Down Expand Up @@ -700,6 +704,7 @@ class CompletionItem {
/**
* An data entry field that is preserved on a completion item between a completion and a completion resolve request.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory)
Object data

new() {
Expand Down Expand Up @@ -822,7 +827,11 @@ class Diagnostic {
*/
@JsonRpcData
class DidChangeConfigurationParams {
/**
* The actual changed settings.
*/
@NonNull
@JsonAdapter(JsonElementTypeAdapter.Factory)
Object settings

new() {
Expand Down Expand Up @@ -1528,6 +1537,7 @@ class InitializeParams {
/**
* User provided initialization options.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory)
Object initializationOptions

/**
Expand Down Expand Up @@ -1908,6 +1918,7 @@ class ServerCapabilities {
/**
* Experimental server capabilities.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory)
Object experimental

/**
Expand Down Expand Up @@ -2387,6 +2398,7 @@ class Registration {
/**
* Options necessary for the registration.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory)
Object registerOptions

new() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
*/
package org.eclipse.lsp4j;

import com.google.gson.annotations.JsonAdapter;
import org.eclipse.lsp4j.TextDocumentClientCapabilities;
import org.eclipse.lsp4j.WorkspaceClientCapabilities;
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;

Expand Down Expand Up @@ -40,6 +42,7 @@ public class ClientCapabilities {
/**
* Experimental client capabilities.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
private Object experimental;

public ClientCapabilities() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
*/
package org.eclipse.lsp4j;

import com.google.gson.annotations.JsonAdapter;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
Expand Down Expand Up @@ -36,6 +38,7 @@ public class CodeLens {
/**
* An data entry field that is preserved on a code lens item between a code lens and a code lens resolve request.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
private Object data;

public CodeLens() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
*/
package org.eclipse.lsp4j;

import com.google.gson.annotations.JsonAdapter;
import java.util.List;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.InsertTextFormat;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
Expand Down Expand Up @@ -92,6 +94,7 @@ public class CompletionItem {
/**
* An data entry field that is preserved on a completion item between a completion and a completion resolve request.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
private Object data;

public CompletionItem() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
*/
package org.eclipse.lsp4j;

import com.google.gson.annotations.JsonAdapter;
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
Expand All @@ -16,7 +18,11 @@
*/
@SuppressWarnings("all")
public class DidChangeConfigurationParams {
/**
* The actual changed settings.
*/
@NonNull
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
private Object settings;

public DidChangeConfigurationParams() {
Expand All @@ -26,12 +32,18 @@ public DidChangeConfigurationParams(@NonNull final Object settings) {
this.settings = settings;
}

/**
* The actual changed settings.
*/
@Pure
@NonNull
public Object getSettings() {
return this.settings;
}

/**
* The actual changed settings.
*/
public void setSettings(@NonNull final Object settings) {
this.settings = settings;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
*/
package org.eclipse.lsp4j;

import com.google.gson.annotations.JsonAdapter;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;

Expand Down Expand Up @@ -37,6 +39,7 @@ public class InitializeParams {
/**
* User provided initialization options.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
private Object initializationOptions;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
*/
package org.eclipse.lsp4j;

import com.google.gson.annotations.JsonAdapter;
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
Expand All @@ -32,6 +34,7 @@ public class Registration {
/**
* Options necessary for the registration.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
private Object registerOptions;

public Registration() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package org.eclipse.lsp4j;

import com.google.common.annotations.Beta;
import com.google.gson.annotations.JsonAdapter;
import org.eclipse.lsp4j.CodeLensOptions;
import org.eclipse.lsp4j.CompletionOptions;
import org.eclipse.lsp4j.DocumentLinkOptions;
Expand All @@ -17,6 +18,7 @@
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.TextDocumentSyncOptions;
import org.eclipse.lsp4j.WorkspaceServerCapabilities;
import org.eclipse.lsp4j.jsonrpc.json.adapters.JsonElementTypeAdapter;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
Expand Down Expand Up @@ -112,6 +114,7 @@ public class ServerCapabilities {
/**
* Experimental server capabilities.
*/
@JsonAdapter(JsonElementTypeAdapter.Factory.class)
private Object experimental;

/**
Expand Down
Loading

0 comments on commit 74e8804

Please sign in to comment.