1
1
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspServerTelemetryManager.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspServerTelemetryManager.java
2
- index d82646afb1..7f4c88acd1 100644
2
+ index d82646afb1..5018896480 100644
3
3
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspServerTelemetryManager.java
4
4
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspServerTelemetryManager.java
5
5
@@ -21,6 +21,7 @@ package org.netbeans.modules.java.lsp.server.protocol;
@@ -10,16 +10,16 @@ index d82646afb1..7f4c88acd1 100644
10
10
import java.math.BigInteger;
11
11
import java.nio.charset.StandardCharsets;
12
12
import java.security.MessageDigest;
13
- @@ -28,25 +29,30 @@ import java.security.NoSuchAlgorithmException;
13
+ @@ -28,25 +29,36 @@ import java.security.NoSuchAlgorithmException;
14
14
import java.util.ArrayList;
15
15
import java.util.Collection;
16
16
import java.util.Collections;
17
17
- import java.util.HashSet;
18
18
+ import java.util.Iterator;
19
19
import java.util.List;
20
20
import java.util.Map;
21
- - import java.util.Set;
22
21
+ import java.util.NavigableMap;
22
+ import java.util.Set;
23
23
+ import java.util.TreeMap;
24
24
import java.util.WeakHashMap;
25
25
+ import java.util.concurrent.CompletableFuture;
@@ -33,19 +33,24 @@ index d82646afb1..7f4c88acd1 100644
33
33
import org.eclipse.lsp4j.ConfigurationParams;
34
34
import org.eclipse.lsp4j.MessageType;
35
35
import org.eclipse.lsp4j.services.LanguageClient;
36
+ + import org.netbeans.api.annotations.common.NonNull;
36
37
+ import org.netbeans.api.java.platform.JavaPlatform;
38
+ + import org.netbeans.api.java.project.JavaProjectConstants;
37
39
import org.netbeans.api.java.queries.CompilerOptionsQuery;
38
40
import org.netbeans.api.java.queries.CompilerOptionsQuery.Result;
39
41
import org.netbeans.api.project.Project;
40
42
import org.netbeans.api.project.ProjectManager;
43
+ + import org.netbeans.api.project.ProjectUtils;
44
+ + import org.netbeans.api.project.SourceGroup;
41
45
import org.netbeans.api.project.ui.ProjectProblems;
42
46
+ import org.netbeans.modules.java.platform.implspi.JavaPlatformProvider;
43
47
import org.openide.filesystems.FileObject;
44
48
- import org.openide.util.Exceptions;
49
+ + import org.openide.filesystems.FileUtil;
45
50
import org.openide.util.Lookup;
46
51
47
52
/**
48
- @@ -55,130 +61,205 @@ import org.openide.util.Lookup;
53
+ @@ -55,130 +67,261 @@ import org.openide.util.Lookup;
49
54
*/
50
55
public class LspServerTelemetryManager {
51
56
@@ -86,15 +91,15 @@ index d82646afb1..7f4c88acd1 100644
86
91
+
87
92
+ private static final LspServerTelemetryManager instance = new LspServerTelemetryManager();
88
93
+ }
89
-
94
+ +
90
95
+ private final WeakHashMap<LanguageClient, WeakReference<Future<Void>>> clients = new WeakHashMap<>();
91
96
+ private volatile boolean telemetryEnabled = false;
92
97
+ private long lspServerIntializationTime;
93
98
+
94
99
+ public boolean isTelemetryEnabled() {
95
100
+ return telemetryEnabled;
96
101
+ }
97
- +
102
+
98
103
+ public void connect(LanguageClient client, Future<Void> future) {
99
104
synchronized (clients) {
100
105
- for (Map.Entry<LanguageClient, Future<Void>> entry : clients.entrySet()) {
@@ -168,50 +173,28 @@ index d82646afb1..7f4c88acd1 100644
168
173
}
169
174
170
175
- public void sendWorkspaceInfo(LanguageClient client, List<FileObject> workspaceClientFolders, Collection<Project> prjs, long timeToOpenPrjs) {
176
+ - JsonObject properties = new JsonObject();
177
+ - JsonArray prjProps = new JsonArray();
171
178
+ private boolean isInvalidClient(WeakReference<Future<Void>> closeListener) {
172
179
+ Future<Void> close = closeListener == null ? null : closeListener.get();
173
180
+ return close == null || close.isDone();
174
181
+ }
175
- +
176
- + public CompletableFuture<Void> sendWorkspaceInfo(LanguageClient client, List<FileObject> workspaceClientFolders, Collection<Project> projects, long timeToOpenProjects) {
177
- JsonObject properties = new JsonObject();
178
- - JsonArray prjProps = new JsonArray();
179
- + List<CompletableFuture<JsonObject>> createProjectFutures = new ArrayList<>();
180
182
181
183
- Map<String, Project> mp = prjs.stream()
182
184
- .collect(Collectors.toMap(project -> project.getProjectDirectory().getPath(), project -> project));
185
+ + public CompletableFuture<Void> sendWorkspaceInfo(LanguageClient client, List<FileObject> workspaceClientFolders, Collection<Project> projects, long timeToOpenProjects) {
186
+ + JsonObject properties = new JsonObject();
187
+
183
188
+ NavigableMap<String, Project> mp = projects.stream()
184
189
+ .collect(Collectors.toMap(project -> project.getProjectDirectory().getPath(), project -> project, (p1, p2) -> p1, TreeMap<String, Project>::new));
185
-
190
+ + List<CompletableFuture<JsonObject>> createProjectFutures = new ArrayList<>();
186
191
for (FileObject workspaceFolder : workspaceClientFolders) {
187
192
try {
188
193
- JsonObject obj = new JsonObject();
189
194
+ boolean noProjectFound = true;
190
195
String prjPath = workspaceFolder.getPath();
191
196
- String prjId = this.getPrjId(prjPath);
192
197
- obj.addProperty("id", prjId);
193
- -
194
- - // In future if different JDK is used for different project then this can be updated
195
- - obj.addProperty("javaVersion", System.getProperty("java.version"));
196
- -
197
- - if (mp.containsKey(prjPath)) {
198
- - Project prj = mp.get(prjPath);
199
- -
200
- - ProjectManager.Result r = ProjectManager.getDefault().isProject2(prj.getProjectDirectory());
201
- - String projectType = r.getProjectType();
202
- - obj.addProperty("buildTool", (projectType.contains("maven") ? "MavenProject" : "GradleProject"));
203
- -
204
- - obj.addProperty("openedWithProblems", ProjectProblems.isBroken(prj));
205
- -
206
- - boolean isPreviewFlagEnabled = this.isEnablePreivew(prj.getProjectDirectory(), projectType);
207
- - obj.addProperty("enablePreview", isPreviewFlagEnabled);
208
- - } else {
209
- - obj.addProperty("buildTool", this.STANDALONE_PRJ);
210
- - obj.addProperty("javaVersion", System.getProperty("java.version"));
211
- - obj.addProperty("openedWithProblems", false);
212
- -
213
- - boolean isPreviewFlagEnabled = this.isEnablePreivew(workspaceFolder, this.STANDALONE_PRJ);
214
- - obj.addProperty("enablePreview", isPreviewFlagEnabled);
215
198
+ String prjPathWithSlash = null;
216
199
+ for (Map.Entry<String, Project> p : mp.tailMap(prjPath, true).entrySet()) {
217
200
+ String projectPath = p.getKey();
@@ -221,20 +204,15 @@ index d82646afb1..7f4c88acd1 100644
221
204
+ noProjectFound = false;
222
205
+ break;
223
206
+ }
224
- + prjPathWithSlash = prjPath + '/';
207
+ + prjPathWithSlash = prjPath + '/';
225
208
+ }
226
209
+ if (projectPath.startsWith(prjPathWithSlash)) {
227
210
+ createProjectFutures.add(createProjectInfo(p.getKey(), p.getValue(), workspaceFolder, client));
228
211
+ noProjectFound = false;
229
212
+ continue;
230
213
+ }
231
214
+ break;
232
- }
233
- -
234
- - prjProps.add(obj);
235
- -
236
- - } catch (NoSuchAlgorithmException ex) {
237
- - Exceptions.printStackTrace(ex);
215
+ + }
238
216
+ if (noProjectFound) {
239
217
+ // No project found
240
218
+ createProjectFutures.add(createProjectInfo(prjPath, null, workspaceFolder, client));
@@ -243,10 +221,11 @@ index d82646afb1..7f4c88acd1 100644
243
221
+ LOG.log(Level.INFO, "NoSuchAlgorithmException while creating workspaceInfo event: {0}", e.getMessage());
244
222
+ } catch (Exception e) {
245
223
+ LOG.log(Level.INFO, "Exception while creating workspaceInfo event: {0}", e.getMessage());
246
- }
247
- }
248
-
249
- - properties.add("prjsInfo", prjProps);
224
+ + }
225
+ + }
226
+
227
+ - // In future if different JDK is used for different project then this can be updated
228
+ - obj.addProperty("javaVersion", System.getProperty("java.version"));
250
229
+ return CompletableFuture.allOf(createProjectFutures.toArray(new CompletableFuture[0]))
251
230
+ .thenApply((ignored) -> {
252
231
+ JsonArray prjProps = new JsonArray();
@@ -255,16 +234,37 @@ index d82646afb1..7f4c88acd1 100644
255
234
+ })
256
235
+ .thenAccept((prjProps) -> {
257
236
+ properties.add("projectInfo", prjProps);
237
+
238
+ - if (mp.containsKey(prjPath)) {
239
+ - Project prj = mp.get(prjPath);
258
240
+ properties.addProperty("projInitTimeTaken", timeToOpenProjects);
259
241
+ properties.addProperty("numProjects", workspaceClientFolders.size());
260
242
+ properties.addProperty("lspInitTimeTaken", System.currentTimeMillis() - this.lspServerIntializationTime);
243
+
244
+ - ProjectManager.Result r = ProjectManager.getDefault().isProject2(prj.getProjectDirectory());
245
+ - String projectType = r.getProjectType();
246
+ - obj.addProperty("buildTool", (projectType.contains("maven") ? "MavenProject" : "GradleProject"));
247
+ -
248
+ - obj.addProperty("openedWithProblems", ProjectProblems.isBroken(prj));
249
+ -
250
+ - boolean isPreviewFlagEnabled = this.isEnablePreivew(prj.getProjectDirectory(), projectType);
251
+ - obj.addProperty("enablePreview", isPreviewFlagEnabled);
252
+ - } else {
253
+ - obj.addProperty("buildTool", this.STANDALONE_PRJ);
254
+ - obj.addProperty("javaVersion", System.getProperty("java.version"));
255
+ - obj.addProperty("openedWithProblems", false);
256
+ -
257
+ - boolean isPreviewFlagEnabled = this.isEnablePreivew(workspaceFolder, this.STANDALONE_PRJ);
258
+ - obj.addProperty("enablePreview", isPreviewFlagEnabled);
259
+ - }
260
+ -
261
+ - prjProps.add(obj);
261
262
+ this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), LspServerTelemetryManager.WORKSPACE_INFO_EVT, properties));
262
263
+ });
263
264
+ }
264
265
265
- - properties.addProperty("timeToOpenPrjs", timeToOpenPrjs);
266
- - properties.addProperty("numOfPrjsOpened", workspaceClientFolders.size());
267
- - properties.addProperty("lspServerInitializationTime", System.currentTimeMillis() - this.lspServerIntiailizationTime);
266
+ - } catch (NoSuchAlgorithmException ex) {
267
+ - Exceptions.printStackTrace(ex);
268
268
+ private CompletableFuture<JsonObject> createProjectInfo(String prjPath, Project prj, FileObject workspaceFolder, LanguageClient client) throws NoSuchAlgorithmException {
269
269
+ JsonObject obj = new JsonObject();
270
270
+ String prjId = getPrjId(prjPath);
@@ -283,28 +283,35 @@ index d82646afb1..7f4c88acd1 100644
283
283
+ } catch (RuntimeException e) {
284
284
+ LOG.log(Level.INFO, "Exception while checking project problems for workspaceInfo event: {0}", e.getMessage());
285
285
+ projectHasProblems = true;
286
- + }
286
+ }
287
287
+ obj.addProperty("isOpenedWithProblems", projectHasProblems);
288
- + }
288
+ }
289
289
+ String javaVersion = getProjectJavaVersion();
290
290
+ obj.addProperty("javaVersion", javaVersion);
291
- + obj.addProperty("buildTool", projectType.name());
292
- + return isPreviewEnabled(projectDirectory, projectType , client).thenApply(isPreviewFlagEnabled -> {
291
+ + if (projectType != null) obj.addProperty("buildTool", projectType.name());
292
+ + return isPreviewEnabled(projectDirectory, prj , client).thenApply(isPreviewFlagEnabled -> {
293
293
+ obj.addProperty("isPreviewEnabled", isPreviewFlagEnabled);
294
294
+ return obj;
295
295
+ });
296
296
+ }
297
297
298
+ - properties.add("prjsInfo", prjProps);
299
+ -
300
+ - properties.addProperty("timeToOpenPrjs", timeToOpenPrjs);
301
+ - properties.addProperty("numOfPrjsOpened", workspaceClientFolders.size());
302
+ - properties.addProperty("lspServerInitializationTime", System.currentTimeMillis() - this.lspServerIntiailizationTime);
303
+ -
298
304
- this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), this.WORKSPACE_INFO_EVT, properties));
299
- + public CompletableFuture<Boolean> isPreviewEnabled(FileObject source, ProjectType prjType ) {
300
- + return isPreviewEnabled(source, prjType , null);
305
+ + public CompletableFuture<Boolean> isPreviewEnabled(FileObject source, Project prj ) {
306
+ + return isPreviewEnabled(source, prj , null);
301
307
}
302
308
-
303
309
- private boolean isEnablePreivew(FileObject source, String prjType) {
304
310
- if (prjType.equals(this.STANDALONE_PRJ)) {
305
311
- NbCodeLanguageClient client = Lookup.getDefault().lookup(NbCodeLanguageClient.class);
306
312
+
307
- + public CompletableFuture<Boolean> isPreviewEnabled(FileObject source, ProjectType prjType, LanguageClient languageClient) {
313
+ + public CompletableFuture<Boolean> isPreviewEnabled(FileObject source, Project prj, LanguageClient languageClient) {
314
+ + ProjectType prjType = prj == null ? ProjectType.standalone : getProjectType(prj);
308
315
+ if (prjType == ProjectType.standalone) {
309
316
+ NbCodeLanguageClient client = languageClient instanceof NbCodeLanguageClient ? (NbCodeLanguageClient) languageClient : null;
310
317
if (client == null) {
@@ -320,25 +327,76 @@ index d82646afb1..7f4c88acd1 100644
320
327
- client.configuration(new ConfigurationParams(Collections.singletonList(conf))).thenAccept(c -> {
321
328
- String config = ((JsonPrimitive) ((List<Object>) c).get(0)).getAsString();
322
329
- isEnablePreviewSet.set(config.contains(this.ENABLE_PREVIEW));
323
- - });
324
- -
325
- - return isEnablePreviewSet.get();
326
330
+ conf.setSection(client.getNbCodeCapabilities().getConfigurationPrefix() + "runConfig.vmOptions");
327
331
+ return client.configuration(new ConfigurationParams(Collections.singletonList(conf)))
328
332
+ .thenApply(c -> {
329
333
+ return c != null && !c.isEmpty()
330
334
+ && ((JsonPrimitive) c.get(0)).getAsString().contains(ENABLE_PREVIEW);
331
- + });
335
+ });
336
+
337
+ - return isEnablePreviewSet.get();
332
338
}
333
- -
339
+
340
+ + boolean previewEnabled;
341
+ + previewEnabled = source != null && isPreviewEnabledForSource(source);
342
+ + if (!previewEnabled && prjType == ProjectType.gradle) {
343
+ + assert prj != null;
344
+ + FileObject prjRoot = prj.getProjectDirectory();
345
+ + String relativePath = prjRoot == null ? null : FileUtil.getRelativePath(prjRoot, source);
346
+ + if (relativePath == null || relativePath.isEmpty()) {
347
+ + // The source is not inside the project root, and,
348
+ + // so the project contents need to be checked for preview-enabled
349
+ + previewEnabled = previewEnabled || isPreviewEnabledForAnyProjectSourceRoot(prj);
350
+ + previewEnabled = previewEnabled || isPreviewEnabledForAnyContainedProjects(prj);
351
+ + }
352
+ + }
353
+ +
354
+ + return CompletableFuture.completedFuture(previewEnabled);
355
+ + }
356
+ +
357
+ + private boolean isPreviewEnabledForAnyContainedProjects(@NonNull Project project) {
358
+ + Set<Project> subProjects = ProjectUtils.getContainedProjects(project, false);
359
+ + if (subProjects != null) {
360
+ + for (Project subProject : subProjects) {
361
+ + if (isPreviewEnabledForAnyProjectSourceRoot(subProject)) {
362
+ + return true;
363
+ + }
364
+ + }
365
+ + for (Project subProject : subProjects) {
366
+ + if (isPreviewEnabledForAnyContainedProjects(subProject)) {
367
+ + return true;
368
+ + }
369
+ + }
370
+ + }
371
+ + return false;
372
+ + }
373
+ +
374
+ + private boolean isPreviewEnabledForAnyProjectSourceRoot(@NonNull Project project) {
375
+ + SourceGroup[] sources = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
376
+ + if (sources == null || sources.length == 0) {
377
+ + FileObject root = project.getProjectDirectory();
378
+ + if (root != null && isPreviewEnabledForSource(root)) {
379
+ + return true;
380
+ + }
381
+ + } else {
382
+ + for (SourceGroup s : sources) {
383
+ + FileObject root = s.getRootFolder();
384
+ + if (root != null && isPreviewEnabledForSource(root)) {
385
+ + return true;
386
+ + }
387
+ + }
388
+ + }
389
+ + return false;
390
+ + }
334
391
+
392
+ + private boolean isPreviewEnabledForSource(@NonNull FileObject source) {
335
393
Result result = CompilerOptionsQuery.getOptions(source);
336
394
- return result.getArguments().contains(this.ENABLE_PREVIEW);
337
- + return CompletableFuture.completedFuture( result.getArguments().contains(ENABLE_PREVIEW) );
395
+ + return result.getArguments().contains(ENABLE_PREVIEW);
338
396
}
339
397
340
398
private String getPrjId(String prjPath) throws NoSuchAlgorithmException {
341
- @@ -187,15 +268,50 @@ public class LspServerTelemetryManager {
399
+ @@ -187,15 +330,54 @@ public class LspServerTelemetryManager {
342
400
343
401
BigInteger number = new BigInteger(1, hash);
344
402
@@ -387,9 +445,13 @@ index d82646afb1..7f4c88acd1 100644
387
445
+ }
388
446
+
389
447
+ public ProjectType getProjectType(Project prj) {
390
- + ProjectManager.Result r = ProjectManager.getDefault().isProject2(prj.getProjectDirectory());
448
+ + FileObject prjDir = prj.getProjectDirectory();
449
+ + ProjectManager.Result r = prjDir == null ? null : ProjectManager.getDefault().isProject2(prjDir);
391
450
+ String projectType = r == null ? null : r.getProjectType();
392
- + return projectType != null && projectType.contains(ProjectType.maven.name()) ? ProjectType.maven : ProjectType.gradle;
451
+ + return projectType == null ? null
452
+ + : projectType.contains(ProjectType.maven.name()) ? ProjectType.maven
453
+ + : projectType.contains(ProjectType.gradle.name()) ? ProjectType.gradle
454
+ + : null;
393
455
+ }
394
456
}
395
457
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeClientCapabilities.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeClientCapabilities.java
0 commit comments