Skip to content

Commit 11cff66

Browse files
committed
Same instance of Gson across LS beans. Test with Lsp4j Gson
Signed-off-by: BoykoAlex <alex.boyko@broadcom.com>
1 parent c3269ff commit 11cff66

File tree

17 files changed

+210
-90
lines changed

17 files changed

+210
-90
lines changed

headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/bootiful/BoshLanguageServerTestConfiguration.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2018 Pivotal, Inc.
2+
* Copyright (c) 2018, 2026 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -10,14 +10,22 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.bosh.bootiful;
1212

13+
import java.util.Optional;
14+
import java.util.function.Consumer;
15+
16+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
1317
import org.springframework.context.annotation.Bean;
1418
import org.springframework.context.annotation.Configuration;
1519
import org.springframework.ide.vscode.bosh.BoshCliConfig;
1620
import org.springframework.ide.vscode.bosh.mocks.MockCloudConfigProvider;
21+
import org.springframework.ide.vscode.commons.languageserver.LanguageServerRunner;
1722
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
1823
import org.springframework.ide.vscode.commons.util.text.LanguageId;
24+
import org.springframework.ide.vscode.languageserver.testharness.HarnessLanguageServerRunner;
1925
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
2026

27+
import com.google.gson.GsonBuilder;
28+
2129
@Configuration
2230
public class BoshLanguageServerTestConfiguration {
2331

@@ -32,4 +40,11 @@ public class BoshLanguageServerTestConfiguration {
3240
);
3341
return harness;
3442
}
43+
44+
@ConditionalOnMissingBean(LanguageServerRunner.class)
45+
@Bean
46+
HarnessLanguageServerRunner harnessLanguageServerRunner(Optional<Consumer<GsonBuilder>> configGsonOpt) {
47+
return new HarnessLanguageServerRunner(configGsonOpt);
48+
}
49+
3550
}

headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/LanguageServerRunner.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2016, 2019 Pivotal, Inc.
2+
* Copyright (c) 2016, 2026 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -21,6 +21,7 @@
2121
import java.nio.channels.AsynchronousServerSocketChannel;
2222
import java.nio.channels.AsynchronousSocketChannel;
2323
import java.nio.channels.Channels;
24+
import java.util.Optional;
2425
import java.util.concurrent.ExecutorService;
2526
import java.util.concurrent.Executors;
2627
import java.util.concurrent.Future;
@@ -39,6 +40,7 @@
3940
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
4041
import org.springframework.ide.vscode.commons.protocol.STS4LanguageClient;
4142

43+
import com.google.gson.Gson;
4244
import com.google.gson.GsonBuilder;
4345

4446
/**
@@ -101,14 +103,16 @@ public void run(String... args) throws Exception {
101103

102104
private Function<MessageConsumer, MessageConsumer> messageConsumer;
103105

104-
private Consumer<GsonBuilder> configureGson;
106+
private Optional<Consumer<GsonBuilder>> configureGsonOpt;
107+
108+
Launcher<STS4LanguageClient> launcher;
105109

106-
public LanguageServerRunner(LanguageServerProperties properties, SimpleLanguageServer languageServer, Function<MessageConsumer, MessageConsumer> messageConsumer, Consumer<GsonBuilder> configureGson) {
110+
public LanguageServerRunner(LanguageServerProperties properties, SimpleLanguageServer languageServer, Function<MessageConsumer, MessageConsumer> messageConsumer, Optional<Consumer<GsonBuilder>> configureGsonOpt) {
107111
super();
108112
this.properties = properties;
109113
this.languageServer = languageServer;
110114
this.messageConsumer = messageConsumer;
111-
this.configureGson = configureGson;
115+
this.configureGsonOpt = configureGsonOpt;
112116
}
113117

114118
public void start() throws Exception {
@@ -189,7 +193,7 @@ public void startAsServer() throws Exception {
189193
int serverPort = properties.getStandalonePort();
190194
log.info("Starting LS as standlone server port = {}", serverPort);
191195

192-
Launcher<STS4LanguageClient> launcher = createSocketLauncher(languageServer, STS4LanguageClient.class,
196+
launcher = createSocketLauncher(languageServer, STS4LanguageClient.class,
193197
new InetSocketAddress("localhost", serverPort), createServerThreads(), messageConsumer);
194198

195199
languageServer.connect(launcher.getRemoteProxy());
@@ -213,7 +217,7 @@ private <T> Launcher<T> createSocketLauncher(
213217
AsynchronousSocketChannel socketChannel = serverSocket.accept().get();
214218
log.info("Client connected via socket");
215219
return Launcher.createIoLauncher(localService, remoteInterface, Channels.newInputStream(socketChannel),
216-
Channels.newOutputStream(socketChannel), executorService, wrapper, configureGson);
220+
Channels.newOutputStream(socketChannel), executorService, wrapper, configureGsonOpt.orElse(null));
217221
}
218222

219223
private static Connection connectToNode() throws IOException {
@@ -241,13 +245,13 @@ private static Connection connectToNode() throws IOException {
241245
private Future<Void> runAsync(Connection connection) throws Exception {
242246
LanguageServer server = this.languageServer;
243247
ExecutorService executor = createServerThreads();
244-
Launcher<STS4LanguageClient> launcher = Launcher.createIoLauncher(server,
248+
launcher = Launcher.createIoLauncher(server,
245249
STS4LanguageClient.class,
246250
connection.in,
247251
connection.out,
248252
executor,
249253
messageConsumer,
250-
configureGson
254+
configureGsonOpt.orElse(null)
251255
);
252256

253257
if (server instanceof LanguageClientAware) {
@@ -258,4 +262,8 @@ private Future<Void> runAsync(Connection connection) throws Exception {
258262
return launcher.startListening();
259263
}
260264

265+
public Gson getGson() {
266+
// Should only return successfully if connected to client
267+
return launcher.getRemoteEndpoint().getJsonHandler().getGson();
268+
}
261269
}

headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/json/DidChangeWatchedFilesRegistrationOptions.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017 Pivotal, Inc.
2+
* Copyright (c) 2017, 2026 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -13,9 +13,8 @@
1313
import java.util.ArrayList;
1414
import java.util.List;
1515

16+
import org.eclipse.lsp4j.jsonrpc.util.ToStringBuilder;
1617
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
17-
import org.eclipse.xtext.xbase.lib.Pure;
18-
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
1918

2019
/**
2120
* Model object to be used in <code>client/registerCapability</code> JSON message to register file watchers
@@ -36,7 +35,6 @@ public DidChangeWatchedFilesRegistrationOptions(@NonNull final List<FileSystemWa
3635
this.watchers = watchers;
3736
}
3837

39-
@Pure
4038
@NonNull
4139
public List<FileSystemWatcher> getRegistrations() {
4240
return this.watchers;
@@ -47,15 +45,13 @@ public void setRegistrations(@NonNull final List<FileSystemWatcher> watchers) {
4745
}
4846

4947
@Override
50-
@Pure
5148
public String toString() {
5249
ToStringBuilder b = new ToStringBuilder(this);
5350
b.add("watchers", this.watchers);
5451
return b.toString();
5552
}
5653

5754
@Override
58-
@Pure
5955
public boolean equals(final Object obj) {
6056
if (this == obj)
6157
return true;
@@ -73,7 +69,6 @@ public boolean equals(final Object obj) {
7369
}
7470

7571
@Override
76-
@Pure
7772
public int hashCode() {
7873
final int prime = 31;
7974
int result = 1;

headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/json/FileSystemWatcher.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017 Pivotal, Inc.
2+
* Copyright (c) 2017, 2026 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -10,9 +10,8 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.commons.languageserver.json;
1212

13+
import org.eclipse.lsp4j.jsonrpc.util.ToStringBuilder;
1314
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
14-
import org.eclipse.xtext.xbase.lib.Pure;
15-
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
1615

1716
/**
1817
* Model object to be used in <code>client/registerCapability</code> JSON message to register a file watcher
@@ -54,7 +53,6 @@ public FileSystemWatcher(@NonNull final String globPattern, final int kind) {
5453
this.kind = kind;
5554
}
5655

57-
@Pure
5856
@NonNull
5957
public String getGlobPattern() {
6058
return this.globPattern;
@@ -64,7 +62,6 @@ public void setGlobPattern(@NonNull final String globPattern) {
6462
this.globPattern = globPattern;
6563
}
6664

67-
@Pure
6865
@NonNull
6966
public int getKind() {
7067
return this.kind;
@@ -78,7 +75,6 @@ public void setKind(final int kind) {
7875
}
7976

8077
@Override
81-
@Pure
8278
public String toString() {
8379
ToStringBuilder b = new ToStringBuilder(this);
8480
b.add("globPattern", this.globPattern);
@@ -87,7 +83,6 @@ public String toString() {
8783
}
8884

8985
@Override
90-
@Pure
9186
public boolean equals(final Object obj) {
9287
if (this == obj)
9388
return true;
@@ -107,7 +102,6 @@ public boolean equals(final Object obj) {
107102
}
108103

109104
@Override
110-
@Pure
111105
public int hashCode() {
112106
final int prime = 31;
113107
int result = 1;

headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2016, 2024 VMware Inc.
2+
* Copyright (c) 2016, 2026 VMware Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -81,6 +81,7 @@
8181
import org.slf4j.LoggerFactory;
8282
import org.springframework.context.ApplicationContext;
8383
import org.springframework.ide.vscode.commons.languageserver.DiagnosticService;
84+
import org.springframework.ide.vscode.commons.languageserver.LanguageServerRunner;
8485
import org.springframework.ide.vscode.commons.languageserver.MessageService;
8586
import org.springframework.ide.vscode.commons.languageserver.ProgressService;
8687
import org.springframework.ide.vscode.commons.languageserver.Sts4LanguageServer;
@@ -261,6 +262,10 @@ public SimpleLanguageServer(String extensionId, ApplicationContext appContext, L
261262
this.CODE_ACTION_COMMAND_ID = "sts."+EXTENSION_ID+".codeAction";
262263
this.COMMAND_LIST_COMMAND_ID = "sts." + EXTENSION_ID + ".commandList";
263264
}
265+
266+
public Gson getGson() {
267+
return appContext.getBean(LanguageServerRunner.class).getGson();
268+
}
264269

265270
protected CompletableFuture<Object> executeCommand(ExecuteCommandParams params) {
266271
ExecuteCommandHandler handler = commands.get(params.getCommand());
@@ -286,7 +291,7 @@ protected CompletableFuture<Object> executeCommand(ExecuteCommandParams params)
286291
})
287292
.toFuture();
288293
} else if (COMMAND_LIST_COMMAND_ID.equals(params.getCommand())) {
289-
Gson gson = new Gson();
294+
Gson gson = getGson();
290295
CompletableFuture<Object> execution = CompletableFuture.completedFuture(null);
291296
for (Object json : params.getArguments()) {
292297
Command cmd = json instanceof Command ? (Command) json : gson.fromJson(json instanceof JsonElement ? (JsonElement) json : gson.toJsonTree(json), Command.class);

headless-services/commons/commons-lsp-extensions/src/main/java/org/springframework/ide/vscode/commons/protocol/spring/Bean.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023, 2025 VMware, Inc.
2+
* Copyright (c) 2023, 2026 VMware, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -17,7 +17,6 @@
1717
import org.eclipse.lsp4j.Location;
1818
import org.eclipse.lsp4j.SymbolKind;
1919

20-
import com.google.common.collect.ImmutableSet;
2120
import com.google.gson.Gson;
2221

2322
public class Bean extends AbstractSpringIndexElement implements SymbolElement {
@@ -26,7 +25,7 @@ public class Bean extends AbstractSpringIndexElement implements SymbolElement {
2625
private final String type;
2726
private final Location location;
2827
private final InjectionPoint[] injectionPoints;
29-
private final Set<String> supertypes;
28+
private final String[] supertypes;
3029
private final AnnotationMetadata[] annotations;
3130
private final boolean isConfiguration;
3231
private final String symbolLabel;
@@ -61,7 +60,7 @@ public Bean(
6160
this.supertypes = null;
6261
}
6362
else {
64-
this.supertypes = sanitizedSuperTypes;
63+
this.supertypes = sanitizedSuperTypes == null ? null : sanitizedSuperTypes.toArray(new String[sanitizedSuperTypes.size()]);
6564
}
6665

6766
if (annotations != null && annotations.length == 0) {
@@ -89,7 +88,7 @@ public InjectionPoint[] getInjectionPoints() {
8988
}
9089

9190
public boolean isTypeCompatibleWith(String type) {
92-
return type != null && ((this.type != null && this.type.equals(type)) || (supertypes != null && supertypes.contains(type)) || (Object.class.getName().equals(type) && !isInterface));
91+
return type != null && ((this.type != null && this.type.equals(type)) || (supertypes != null && Set.of(supertypes).contains(type)) || (Object.class.getName().equals(type) && !isInterface));
9392
}
9493

9594
public AnnotationMetadata[] getAnnotations() {
@@ -104,7 +103,14 @@ public Set<String> getSupertypes() {
104103
if (supertypes == null) {
105104
return isInterface ? DefaultValues.EMPTY_SUPERTYPES : DefaultValues.OBJECT_SUPERTYPE;
106105
} else {
107-
return isInterface ? supertypes : ImmutableSet.<String>builder().addAll(supertypes).add(Object.class.getName()).build();
106+
if (isInterface) {
107+
return Set.of(supertypes);
108+
} else {
109+
String[] all = new String[supertypes.length + 1];
110+
System.arraycopy(supertypes, 0, all, 0, supertypes.length);
111+
all[all.length - 1] = Object.class.getName();
112+
return Set.of(all);
113+
}
108114
}
109115
}
110116

headless-services/commons/language-server-starter/src/main/java/org/springframework/ide/vscode/languageserver/starter/LanguageServerRunnerAutoConf.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2018, 2022 Pivotal, Inc.
2+
* Copyright (c) 2018, 2026 Pivotal, Inc.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -45,7 +45,7 @@ LanguageServerRunner serverApp(
4545
Function<MessageConsumer, MessageConsumer> messageConsumer,
4646
Optional<Consumer<GsonBuilder>> configureGson
4747
) {
48-
return new LanguageServerRunner(properties, languageServerFactory, messageConsumer, configureGson.orElse(b -> {}));
48+
return new LanguageServerRunner(properties, languageServerFactory, messageConsumer, configureGson);
4949
}
50-
50+
5151
}

0 commit comments

Comments
 (0)