Skip to content

Commit ca947ac

Browse files
authored
feat: Jackson used in dev-server (#21056)
Use jackson instead of elemental in the dev-server. part of #20741
1 parent b3acc4e commit ca947ac

File tree

11 files changed

+125
-58
lines changed

11 files changed

+125
-58
lines changed

flow-server/src/main/java/com/vaadin/flow/hotswap/Hotswapper.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.vaadin.flow.di.Lookup;
4242
import com.vaadin.flow.internal.BrowserLiveReload;
4343
import com.vaadin.flow.internal.BrowserLiveReloadAccessor;
44+
import com.vaadin.flow.internal.JacksonUtils;
4445
import com.vaadin.flow.router.internal.RouteTarget;
4546
import com.vaadin.flow.router.internal.RouteUtil;
4647
import com.vaadin.flow.server.RouteRegistry;
@@ -56,8 +57,6 @@
5657
import com.vaadin.flow.server.VaadinService;
5758
import com.vaadin.flow.server.VaadinSession;
5859

59-
import elemental.json.Json;
60-
6160
/**
6261
* Entry point for application classes hot reloads.
6362
* <p>
@@ -185,7 +184,8 @@ public void onHotswap(URI[] createdResources, URI[] modifiedResources,
185184
ResourceBundle.clearCache();
186185

187186
// Trigger any potential Hilla translation updates
188-
liveReload.sendHmrEvent("translations-update", Json.createObject());
187+
liveReload.sendHmrEvent("translations-update",
188+
JacksonUtils.createObjectNode());
189189

190190
// Trigger any potential Flow translation updates
191191
EnumMap<UIRefreshStrategy, List<UI>> refreshActions = new EnumMap<>(

flow-server/src/main/java/com/vaadin/flow/internal/BrowserLiveReload.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@
1515
*/
1616
package com.vaadin.flow.internal;
1717

18+
import com.fasterxml.jackson.databind.JsonNode;
1819
import org.atmosphere.cpr.AtmosphereResource;
1920

2021
import com.vaadin.flow.server.communication.FragmentedMessageHolder;
2122

22-
import elemental.json.JsonObject;
23-
2423
/**
2524
* Provides a way to reload browser tabs via web socket connection passed as a
2625
* {@link AtmosphereResource}.
@@ -126,6 +125,6 @@ default void refresh(boolean refreshLayouts) {
126125
* @param eventData
127126
* the event data
128127
*/
129-
void sendHmrEvent(String event, JsonObject eventData);
128+
void sendHmrEvent(String event, JsonNode eventData);
130129

131130
}

flow-server/src/main/java/com/vaadin/flow/internal/JacksonUtils.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,12 @@ public static ValueNode nullNode() {
109109
*
110110
* @param jsonObject
111111
* JsonObject to change
112-
* @return ObjectNode of elemental json object
112+
* @return ObjectNode of elemental json object or null for null jsonObject
113113
*/
114114
public static ObjectNode mapElemental(JsonObject jsonObject) {
115+
if (jsonObject == null) {
116+
return null;
117+
}
115118
try {
116119
return (ObjectNode) objectMapper.readTree(jsonObject.toJson());
117120
} catch (JsonProcessingException e) {

flow-tests/test-dev-mode/src/main/java/com/vaadin/flow/uitest/ui/DevToolsPlugin.java

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,45 @@
11
package com.vaadin.flow.uitest.ui;
22

3+
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.fasterxml.jackson.databind.node.ObjectNode;
5+
36
import com.vaadin.base.devserver.DevToolsInterface;
47
import com.vaadin.base.devserver.DevToolsMessageHandler;
58
import com.vaadin.flow.component.UI;
69
import com.vaadin.flow.component.dependency.JsModule;
10+
import com.vaadin.flow.internal.JacksonUtils;
711
import com.vaadin.flow.server.VaadinSession;
812

9-
import elemental.json.Json;
1013
import elemental.json.JsonObject;
1114

1215
@JsModule(value = "./devtools-plugin.ts", developmentOnly = true)
1316
public class DevToolsPlugin implements DevToolsMessageHandler {
1417

1518
@Override
1619
public void handleConnect(DevToolsInterface devToolsInterface) {
17-
devToolsInterface.send("plugin-init", null);
20+
devToolsInterface.send("plugin-init", (JsonNode) null);
1821
}
1922

2023
@Override
2124
public boolean handleMessage(String command, JsonObject data,
2225
DevToolsInterface devToolsInterface) {
26+
return handleMessage(command, JacksonUtils.mapElemental(data),
27+
devToolsInterface);
28+
}
29+
30+
@Override
31+
public boolean handleMessage(String command, JsonNode data,
32+
DevToolsInterface devToolsInterface) {
2333
if (command.equals("plugin-query")) {
24-
String text = data.getString("text");
34+
String text = data.get("text").textValue();
2535

26-
JsonObject responseData = Json.createObject();
36+
ObjectNode responseData = JacksonUtils.createObjectNode();
2737
responseData.put("text", "Response for " + text);
2838
devToolsInterface.send("plugin-response", responseData);
2939

3040
VaadinSession session = VaadinSession.getCurrent();
3141
session.access(() -> {
32-
UI ui = session.getUIById((int) data.getNumber("uiId"));
42+
UI ui = session.getUIById(data.get("uiId").intValue());
3343
ui.getPage().executeJs("""
3444
const div = document.createElement('div');
3545
div.innerText = $0;

vaadin-dev-server/src/main/java/com/vaadin/base/devserver/DebugWindowConnection.java

+36-22
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,24 @@
2828
import java.util.concurrent.ConcurrentHashMap;
2929
import java.util.stream.Collectors;
3030

31+
import com.fasterxml.jackson.databind.JsonNode;
3132
import com.fasterxml.jackson.databind.ObjectMapper;
33+
import com.fasterxml.jackson.databind.node.ObjectNode;
3234
import org.atmosphere.cpr.AtmosphereResource;
3335
import org.slf4j.Logger;
3436
import org.slf4j.LoggerFactory;
3537

3638
import com.vaadin.base.devserver.stats.DevModeUsageStatistics;
3739
import com.vaadin.experimental.FeatureFlags;
38-
import com.vaadin.flow.component.UI;
3940
import com.vaadin.flow.internal.BrowserLiveReload;
41+
import com.vaadin.flow.internal.JacksonUtils;
4042
import com.vaadin.flow.server.DevToolsToken;
4143
import com.vaadin.flow.server.VaadinContext;
4244
import com.vaadin.flow.server.communication.AtmospherePushConnection.FragmentedMessage;
4345
import com.vaadin.pro.licensechecker.BuildType;
4446
import com.vaadin.pro.licensechecker.LicenseChecker;
4547
import com.vaadin.pro.licensechecker.Product;
4648

47-
import elemental.json.Json;
4849
import elemental.json.JsonObject;
4950

5051
/**
@@ -146,14 +147,14 @@ private DevToolsInterfaceImpl(
146147
}
147148

148149
@Override
149-
public void send(String command, JsonObject data) {
150-
JsonObject msg = Json.createObject();
150+
public void send(String command, JsonNode data) {
151+
ObjectNode msg = JacksonUtils.createObjectNode();
151152
msg.put("command", command);
152153
if (data != null) {
153-
msg.put("data", data);
154+
msg.set("data", data);
154155
}
155156

156-
debugWindowConnection.send(resource, msg.toJson());
157+
debugWindowConnection.send(resource, msg.toString());
157158
}
158159

159160
@Override
@@ -255,35 +256,47 @@ public boolean isLiveReload(AtmosphereResource resource) {
255256
*
256257
* @param msg
257258
* the message to broadcast
259+
* @deprecated Use {@link #broadcast(ObjectNode)} instead.
258260
*/
261+
@Deprecated
259262
public void broadcast(JsonObject msg) {
263+
this.broadcast(JacksonUtils.readTree(msg.toJson()));
264+
}
265+
266+
/**
267+
* Broadcasts the given message to all connected clients.
268+
*
269+
* @param msg
270+
* the message to broadcast
271+
*/
272+
public void broadcast(ObjectNode msg) {
260273
resources.keySet().forEach(resourceRef -> {
261274
AtmosphereResource resource = resourceRef.get();
262275
if (resource != null) {
263-
resource.getBroadcaster().broadcast(msg.toJson(), resource);
276+
resource.getBroadcaster().broadcast(msg.toString(), resource);
264277
}
265278
});
266279

267280
}
268281

269282
@Override
270283
public void reload() {
271-
JsonObject msg = Json.createObject();
284+
ObjectNode msg = JacksonUtils.createObjectNode();
272285
msg.put("command", "reload");
273286
broadcast(msg);
274287
}
275288

276289
@Override
277290
public void refresh(boolean refreshLayouts) {
278-
JsonObject msg = Json.createObject();
291+
ObjectNode msg = JacksonUtils.createObjectNode();
279292
msg.put("command", "reload");
280293
msg.put("strategy", refreshLayouts ? "full-refresh" : "refresh");
281294
broadcast(msg);
282295
}
283296

284297
@Override
285298
public void update(String path, String content) {
286-
JsonObject msg = Json.createObject();
299+
ObjectNode msg = JacksonUtils.createObjectNode();
287300
msg.put("command", "update");
288301
msg.put("path", path);
289302
msg.put("content", content);
@@ -297,17 +310,18 @@ public void onMessage(AtmosphereResource resource, String message) {
297310
getLogger().debug("Received live reload heartbeat");
298311
return;
299312
}
300-
JsonObject json = Json.parse(message);
301-
String command = json.getString("command");
302-
JsonObject data = json.getObject("data");
313+
JsonNode json = JacksonUtils.readTree(message);
314+
String command = json.get("command").textValue();
315+
JsonNode data = json.get("data");
303316
if ("setFeature".equals(command)) {
304-
FeatureFlags.get(context).setEnabled(data.getString("featureId"),
305-
data.getBoolean("enabled"));
317+
FeatureFlags.get(context).setEnabled(
318+
data.get("featureId").textValue(),
319+
data.get("enabled").booleanValue());
306320
} else if ("reportTelemetry".equals(command)) {
307321
DevModeUsageStatistics.handleBrowserData(data);
308322
} else if ("checkLicense".equals(command)) {
309-
String name = data.getString("name");
310-
String version = data.getString("version");
323+
String name = data.get("name").textValue();
324+
String version = data.get("version").textValue();
311325
Product product = new Product(name, version);
312326
boolean ok;
313327
String errorMessage = "";
@@ -382,13 +396,13 @@ public void clearFragmentedMessage(AtmosphereResource resource) {
382396
}
383397

384398
@Override
385-
public void sendHmrEvent(String event, JsonObject eventData) {
386-
JsonObject msg = Json.createObject();
399+
public void sendHmrEvent(String event, JsonNode eventData) {
400+
ObjectNode msg = JacksonUtils.createObjectNode();
387401
msg.put("command", "hmr");
388-
JsonObject data = Json.createObject();
389-
msg.put("data", data);
402+
ObjectNode data = JacksonUtils.createObjectNode();
403+
msg.set("data", data);
390404
data.put("event", event);
391-
data.put("eventData", eventData);
405+
data.set("eventData", eventData);
392406
broadcast(msg);
393407
}
394408

vaadin-dev-server/src/main/java/com/vaadin/base/devserver/DevToolsInterface.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
*/
1616
package com.vaadin.base.devserver;
1717

18+
import com.fasterxml.jackson.databind.JsonNode;
19+
20+
import com.vaadin.flow.internal.JacksonUtils;
21+
1822
import elemental.json.JsonObject;
1923

2024
/**
@@ -30,5 +34,18 @@ public interface DevToolsInterface {
3034
* @param data
3135
* data, specific to the command
3236
*/
33-
void send(String command, JsonObject data);
37+
@Deprecated
38+
default void send(String command, JsonObject data) {
39+
send(command, JacksonUtils.mapElemental(data));
40+
}
41+
42+
/**
43+
* Sends the given message to the client side.
44+
*
45+
* @param command
46+
* the command to send
47+
* @param data
48+
* data, specific to the command
49+
*/
50+
void send(String command, JsonNode data);
3451
}

vaadin-dev-server/src/main/java/com/vaadin/base/devserver/DevToolsMessageHandler.java

+26
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@
1515
*/
1616
package com.vaadin.base.devserver;
1717

18+
import com.fasterxml.jackson.databind.JsonNode;
19+
20+
import com.vaadin.flow.internal.JacksonUtils;
21+
22+
import elemental.json.Json;
1823
import elemental.json.JsonObject;
24+
import elemental.json.JsonValue;
1925

2026
/**
2127
* Handles dev tools messages from the client.
@@ -47,9 +53,29 @@ public interface DevToolsMessageHandler {
4753
* @return {@code true} if the message was handled and should not be passed
4854
* on to further handlers
4955
*/
56+
@Deprecated
5057
boolean handleMessage(String command, JsonObject data,
5158
DevToolsInterface devToolsInterface);
5259

60+
/**
61+
* Called when a message from the browser arrives.
62+
*
63+
* @param command
64+
* the command received
65+
* @param data
66+
* the data received
67+
* @param devToolsInterface
68+
* for interaction with the development tools, e.g. sending a
69+
* message
70+
* @return {@code true} if the message was handled and should not be passed
71+
* on to further handlers
72+
*/
73+
default boolean handleMessage(String command, JsonNode data,
74+
DevToolsInterface devToolsInterface) {
75+
return this.handleMessage(command, Json.parse(data.toString()),
76+
devToolsInterface);
77+
}
78+
5379
/**
5480
* Called when the browser connection disconnects.
5581
*

vaadin-dev-server/src/main/java/com/vaadin/base/devserver/stats/DevModeUsageStatistics.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
import com.vaadin.flow.server.Version;
2727
import com.vaadin.pro.licensechecker.MachineId;
2828

29-
import elemental.json.JsonObject;
30-
3129
/**
3230
* Singleton for collecting development time usage metrics
3331
* <p>
@@ -142,7 +140,7 @@ private void trackGlobalData() {
142140
* @param data
143141
* the data from the browser
144142
*/
145-
public static void handleBrowserData(JsonObject data) {
143+
public static void handleBrowserData(JsonNode data) {
146144
getLogger().debug("Received client usage statistics from the browser");
147145

148146
if (!isStatisticsEnabled()) {
@@ -151,7 +149,7 @@ public static void handleBrowserData(JsonObject data) {
151149

152150
get().storage.update((global, project) -> {
153151
try {
154-
String json = data.get("browserData").toJson();
152+
String json = data.get("browserData").toString();
155153
JsonNode clientData = JsonHelpers.getJsonMapper()
156154
.readTree(json);
157155
if (clientData != null && clientData.isObject()) {

vaadin-dev-server/src/test/java/com/vaadin/base/devserver/DebugWindowConnectionTest.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.HashMap;
2020
import java.util.Map;
2121

22+
import com.fasterxml.jackson.databind.node.ObjectNode;
2223
import org.atmosphere.cpr.AtmosphereRequest;
2324
import org.atmosphere.cpr.AtmosphereResource;
2425
import org.atmosphere.cpr.Broadcaster;
@@ -28,14 +29,12 @@
2829

2930
import com.vaadin.flow.di.Lookup;
3031
import com.vaadin.flow.internal.BrowserLiveReload;
32+
import com.vaadin.flow.internal.JacksonUtils;
3133
import com.vaadin.flow.server.DevToolsToken;
3234
import com.vaadin.flow.server.VaadinContext;
3335
import com.vaadin.flow.server.VaadinService;
3436
import com.vaadin.flow.server.startup.ApplicationConfiguration;
3537

36-
import elemental.json.Json;
37-
import elemental.json.JsonObject;
38-
3938
import static org.mockito.Mockito.times;
4039

4140
public class DebugWindowConnectionTest {
@@ -135,9 +134,9 @@ public void reload_twoConnections_sendReloadCommand() {
135134

136135
reload.reload();
137136

138-
JsonObject reloadCommand = Json.createObject();
137+
ObjectNode reloadCommand = JacksonUtils.createObjectNode();
139138
reloadCommand.put("command", "reload");
140-
String reloadJson = reloadCommand.toJson();
139+
String reloadJson = reloadCommand.toString();
141140
Mockito.verify(broadcaster).broadcast(reloadJson, resource1);
142141
Mockito.verify(broadcaster).broadcast(reloadJson, resource2);
143142
}

0 commit comments

Comments
 (0)