Skip to content

Commit 79389ff

Browse files
committed
Implement ExpressionValue as a sealed class and support (de)serializing it. It is now part of the API as kernels may need to use it.
1 parent 5ab0625 commit 79389ff

File tree

7 files changed

+111
-15
lines changed

7 files changed

+111
-15
lines changed

src/main/java/io/github/spencerpark/jupyter/channels/JupyterSocket.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.google.gson.JsonElement;
66
import com.google.gson.JsonParser;
77
import com.google.gson.reflect.TypeToken;
8+
import io.github.spencerpark.jupyter.kernel.ExpressionValue;
89
import io.github.spencerpark.jupyter.kernel.KernelConnectionProperties;
910
import io.github.spencerpark.jupyter.kernel.history.HistoryEntry;
1011
import io.github.spencerpark.jupyter.messages.*;
@@ -30,6 +31,7 @@ protected static String formatAddress(String transport, String ip, int port) {
3031
private static final byte[] IDENTITY_BLOB_DELIMITER = "<IDS|MSG>".getBytes(ASCII); // Comes from a python bytestring
3132
private static final Gson replyGson = new GsonBuilder()
3233
.registerTypeAdapter(HistoryEntry.class, HistoryEntryAdapter.INSTANCE)
34+
.registerTypeAdapter(ExpressionValue.class, ExpressionValueAdapter.INSTANCE)
3335
.create();
3436
private static final Gson gson = new GsonBuilder()
3537
.registerTypeAdapter(KernelTimestamp.class, KernelTimestampAdapter.INSTANCE)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package io.github.spencerpark.jupyter.kernel;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
import io.github.spencerpark.jupyter.kernel.display.DisplayData;
5+
6+
import java.util.List;
7+
8+
public abstract class ExpressionValue {
9+
10+
private ExpressionValue() { } // Seal the class
11+
12+
public abstract boolean isSuccess();
13+
14+
public static class Error extends ExpressionValue {
15+
@SerializedName("ename")
16+
protected final String errName;
17+
@SerializedName("evalue")
18+
protected final String errMsg;
19+
@SerializedName("traceback")
20+
protected final List<String> stacktrace;
21+
22+
public Error(String errName, String errMsg, List<String> stacktrace) {
23+
this.errName = errName;
24+
this.errMsg = errMsg;
25+
this.stacktrace = stacktrace;
26+
}
27+
28+
@Override
29+
public boolean isSuccess() {
30+
return false;
31+
}
32+
33+
public String getErrName() {
34+
return this.errName;
35+
}
36+
37+
public String getErrMsg() {
38+
return this.errMsg;
39+
}
40+
41+
public List<String> getStacktrace() {
42+
return this.stacktrace;
43+
}
44+
}
45+
46+
public static class Success extends ExpressionValue {
47+
protected final DisplayData data;
48+
49+
public Success(DisplayData data) {
50+
this.data = data;
51+
}
52+
53+
@Override
54+
public boolean isSuccess() {
55+
return true;
56+
}
57+
58+
public DisplayData getData() {
59+
return this.data;
60+
}
61+
}
62+
}

src/main/java/io/github/spencerpark/jupyter/messages/ExpressionValue.java

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.github.spencerpark.jupyter.messages.adapters;
2+
3+
import com.google.gson.*;
4+
import io.github.spencerpark.jupyter.kernel.display.DisplayData;
5+
import io.github.spencerpark.jupyter.kernel.ExpressionValue;
6+
7+
import java.lang.reflect.Type;
8+
9+
/**
10+
* Decode/encode an {@link ExpressionValue} as either a {@link ExpressionValue.Error} or {@link ExpressionValue.Success}
11+
* based on the {@code "status"} field.
12+
*/
13+
public class ExpressionValueAdapter implements JsonSerializer<ExpressionValue>, JsonDeserializer<ExpressionValue> {
14+
public static final ExpressionValueAdapter INSTANCE = new ExpressionValueAdapter();
15+
16+
private ExpressionValueAdapter() { }
17+
18+
@Override
19+
public ExpressionValue deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext ctx) throws JsonParseException {
20+
if (jsonElement.isJsonObject()) {
21+
JsonElement status = jsonElement.getAsJsonObject().get("status");
22+
if (status != null && status.isJsonPrimitive()
23+
&& status.getAsString().equalsIgnoreCase("error"))
24+
return ctx.deserialize(jsonElement, ExpressionValue.Error.class);
25+
}
26+
27+
DisplayData data = ctx.deserialize(jsonElement, DisplayData.class);
28+
return new ExpressionValue.Success(data);
29+
}
30+
31+
@Override
32+
public JsonElement serialize(ExpressionValue exprVal, Type type, JsonSerializationContext ctx) {
33+
if (exprVal.isSuccess())
34+
return ctx.serialize(exprVal, ExpressionValue.Success.class);
35+
else
36+
return ctx.serialize(exprVal, ExpressionValue.Error.class);
37+
}
38+
}

src/main/java/io/github/spencerpark/jupyter/messages/publish/PublishDisplayData.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package io.github.spencerpark.jupyter.messages.publish;
22

3-
import io.github.spencerpark.jupyter.messages.ContentType;
43
import io.github.spencerpark.jupyter.kernel.display.DisplayData;
5-
import io.github.spencerpark.jupyter.messages.ExpressionValue;
4+
import io.github.spencerpark.jupyter.messages.ContentType;
65
import io.github.spencerpark.jupyter.messages.MessageType;
76

8-
public class PublishDisplayData extends DisplayData implements ExpressionValue, ContentType<PublishDisplayData> {
7+
public class PublishDisplayData extends DisplayData implements ContentType<PublishDisplayData> {
98
public static final MessageType<PublishDisplayData> MESSAGE_TYPE = MessageType.PUBLISH_DISPLAY_DATA;
109

1110
@Override

src/main/java/io/github/spencerpark/jupyter/messages/reply/ErrorReply.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
package io.github.spencerpark.jupyter.messages.reply;
22

33
import com.google.gson.annotations.SerializedName;
4-
import io.github.spencerpark.jupyter.messages.ExpressionValue;
54
import io.github.spencerpark.jupyter.messages.MessageType;
65
import io.github.spencerpark.jupyter.messages.ReplyType;
76

87
import java.util.Arrays;
98
import java.util.List;
109
import java.util.stream.Collectors;
1110

12-
public class ErrorReply implements ExpressionValue, ReplyType<Object> {
11+
public class ErrorReply implements ReplyType<Object> {
12+
@Override
13+
public MessageType<Object> getRequestType() {
14+
return MessageType.UNKNOWN;
15+
}
16+
1317
public static ErrorReply of(Exception exception) {
1418
String name = exception.getClass().getSimpleName();
1519
String msg = exception.getLocalizedMessage();
@@ -57,9 +61,4 @@ public String getErrorMessage() {
5761
public List<String> getStacktrace() {
5862
return stacktrace;
5963
}
60-
61-
@Override
62-
public MessageType<Object> getRequestType() {
63-
return MessageType.UNKNOWN;
64-
}
6564
}

src/main/java/io/github/spencerpark/jupyter/messages/reply/ExecuteReply.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package io.github.spencerpark.jupyter.messages.reply;
22

33
import com.google.gson.annotations.SerializedName;
4-
import io.github.spencerpark.jupyter.messages.ExpressionValue;
4+
import io.github.spencerpark.jupyter.kernel.ExpressionValue;
55
import io.github.spencerpark.jupyter.messages.MessageType;
66
import io.github.spencerpark.jupyter.messages.ReplyType;
77
import io.github.spencerpark.jupyter.messages.publish.PublishDisplayData;

0 commit comments

Comments
 (0)