Skip to content

Commit 46e6f8d

Browse files
committed
Fixed nb-telemetry isPreviewEnabled for gradle projects
1. For gradle projects, the CompilerOptionsQuery provides the required compiler arguments for a Source file/folder, not the project root. Thus, fixed the public LspServerTelemetryManager.isPreviewEnabled() methods to query the source roots of the current gradle project and sub-projects in order to check for the existence of the enable-preview compiler argument. 2. Fixed LspServerTelemetryManger.getProjectType() to return "gradle" only when the project name contains "gradle". For other kinds of netbeans projects, not maven/gradle, the returned value is null. This avoids wrong metrics collected for unsupported project types, such as ant, openjdk, make etc.
1 parent 7df1b4c commit 46e6f8d

File tree

2 files changed

+127
-65
lines changed

2 files changed

+127
-65
lines changed

nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public String getJavaVersion() {
114114
public boolean getPreviewEnabled(){
115115
try {
116116
return LspServerTelemetryManager.getInstance().isPreviewEnabled(file,
117-
owner == null ? LspServerTelemetryManager.ProjectType.standalone : LspServerTelemetryManager.getInstance().getProjectType(owner),
117+
owner,
118118
getLanguageClient()).get();
119119
} catch (InterruptedException | ExecutionException ex) {
120120
LOG.log(Level.FINE, "exception while checking if preview enabled: {0}", (Object) ex);

patches/nb-telemetry.diff

Lines changed: 126 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
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
33
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspServerTelemetryManager.java
44
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspServerTelemetryManager.java
55
@@ -21,6 +21,7 @@ package org.netbeans.modules.java.lsp.server.protocol;
@@ -10,16 +10,16 @@ index d82646afb1..7f4c88acd1 100644
1010
import java.math.BigInteger;
1111
import java.nio.charset.StandardCharsets;
1212
import java.security.MessageDigest;
13-
@@ -28,25 +29,30 @@ import java.security.NoSuchAlgorithmException;
13+
@@ -28,25 +29,36 @@ import java.security.NoSuchAlgorithmException;
1414
import java.util.ArrayList;
1515
import java.util.Collection;
1616
import java.util.Collections;
1717
-import java.util.HashSet;
1818
+import java.util.Iterator;
1919
import java.util.List;
2020
import java.util.Map;
21-
-import java.util.Set;
2221
+import java.util.NavigableMap;
22+
import java.util.Set;
2323
+import java.util.TreeMap;
2424
import java.util.WeakHashMap;
2525
+import java.util.concurrent.CompletableFuture;
@@ -33,19 +33,24 @@ index d82646afb1..7f4c88acd1 100644
3333
import org.eclipse.lsp4j.ConfigurationParams;
3434
import org.eclipse.lsp4j.MessageType;
3535
import org.eclipse.lsp4j.services.LanguageClient;
36+
+import org.netbeans.api.annotations.common.NonNull;
3637
+import org.netbeans.api.java.platform.JavaPlatform;
38+
+import org.netbeans.api.java.project.JavaProjectConstants;
3739
import org.netbeans.api.java.queries.CompilerOptionsQuery;
3840
import org.netbeans.api.java.queries.CompilerOptionsQuery.Result;
3941
import org.netbeans.api.project.Project;
4042
import org.netbeans.api.project.ProjectManager;
43+
+import org.netbeans.api.project.ProjectUtils;
44+
+import org.netbeans.api.project.SourceGroup;
4145
import org.netbeans.api.project.ui.ProjectProblems;
4246
+import org.netbeans.modules.java.platform.implspi.JavaPlatformProvider;
4347
import org.openide.filesystems.FileObject;
4448
-import org.openide.util.Exceptions;
49+
+import org.openide.filesystems.FileUtil;
4550
import org.openide.util.Lookup;
4651

4752
/**
48-
@@ -55,130 +61,205 @@ import org.openide.util.Lookup;
53+
@@ -55,130 +67,261 @@ import org.openide.util.Lookup;
4954
*/
5055
public class LspServerTelemetryManager {
5156

@@ -86,15 +91,15 @@ index d82646afb1..7f4c88acd1 100644
8691
+
8792
+ private static final LspServerTelemetryManager instance = new LspServerTelemetryManager();
8893
+ }
89-
94+
+
9095
+ private final WeakHashMap<LanguageClient, WeakReference<Future<Void>>> clients = new WeakHashMap<>();
9196
+ private volatile boolean telemetryEnabled = false;
9297
+ private long lspServerIntializationTime;
9398
+
9499
+ public boolean isTelemetryEnabled() {
95100
+ return telemetryEnabled;
96101
+ }
97-
+
102+
98103
+ public void connect(LanguageClient client, Future<Void> future) {
99104
synchronized (clients) {
100105
- for (Map.Entry<LanguageClient, Future<Void>> entry : clients.entrySet()) {
@@ -168,50 +173,28 @@ index d82646afb1..7f4c88acd1 100644
168173
}
169174

170175
- public void sendWorkspaceInfo(LanguageClient client, List<FileObject> workspaceClientFolders, Collection<Project> prjs, long timeToOpenPrjs) {
176+
- JsonObject properties = new JsonObject();
177+
- JsonArray prjProps = new JsonArray();
171178
+ private boolean isInvalidClient(WeakReference<Future<Void>> closeListener) {
172179
+ Future<Void> close = closeListener == null ? null : closeListener.get();
173180
+ return close == null || close.isDone();
174181
+ }
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<>();
180182

181183
- Map<String, Project> mp = prjs.stream()
182184
- .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+
183188
+ NavigableMap<String, Project> mp = projects.stream()
184189
+ .collect(Collectors.toMap(project -> project.getProjectDirectory().getPath(), project -> project, (p1, p2) -> p1, TreeMap<String, Project>::new));
185-
190+
+ List<CompletableFuture<JsonObject>> createProjectFutures = new ArrayList<>();
186191
for (FileObject workspaceFolder : workspaceClientFolders) {
187192
try {
188193
- JsonObject obj = new JsonObject();
189194
+ boolean noProjectFound = true;
190195
String prjPath = workspaceFolder.getPath();
191196
- String prjId = this.getPrjId(prjPath);
192197
- 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);
215198
+ String prjPathWithSlash = null;
216199
+ for (Map.Entry<String, Project> p : mp.tailMap(prjPath, true).entrySet()) {
217200
+ String projectPath = p.getKey();
@@ -221,20 +204,15 @@ index d82646afb1..7f4c88acd1 100644
221204
+ noProjectFound = false;
222205
+ break;
223206
+ }
224-
+ prjPathWithSlash = prjPath + '/';
207+
+ prjPathWithSlash = prjPath + '/';
225208
+ }
226209
+ if (projectPath.startsWith(prjPathWithSlash)) {
227210
+ createProjectFutures.add(createProjectInfo(p.getKey(), p.getValue(), workspaceFolder, client));
228211
+ noProjectFound = false;
229212
+ continue;
230213
+ }
231214
+ break;
232-
}
233-
-
234-
- prjProps.add(obj);
235-
-
236-
- } catch (NoSuchAlgorithmException ex) {
237-
- Exceptions.printStackTrace(ex);
215+
+ }
238216
+ if (noProjectFound) {
239217
+ // No project found
240218
+ createProjectFutures.add(createProjectInfo(prjPath, null, workspaceFolder, client));
@@ -243,10 +221,11 @@ index d82646afb1..7f4c88acd1 100644
243221
+ LOG.log(Level.INFO, "NoSuchAlgorithmException while creating workspaceInfo event: {0}", e.getMessage());
244222
+ } catch (Exception e) {
245223
+ 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"));
250229
+ return CompletableFuture.allOf(createProjectFutures.toArray(new CompletableFuture[0]))
251230
+ .thenApply((ignored) -> {
252231
+ JsonArray prjProps = new JsonArray();
@@ -255,16 +234,37 @@ index d82646afb1..7f4c88acd1 100644
255234
+ })
256235
+ .thenAccept((prjProps) -> {
257236
+ properties.add("projectInfo", prjProps);
237+
238+
- if (mp.containsKey(prjPath)) {
239+
- Project prj = mp.get(prjPath);
258240
+ properties.addProperty("projInitTimeTaken", timeToOpenProjects);
259241
+ properties.addProperty("numProjects", workspaceClientFolders.size());
260242
+ 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);
261262
+ this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), LspServerTelemetryManager.WORKSPACE_INFO_EVT, properties));
262263
+ });
263264
+ }
264265

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);
268268
+ private CompletableFuture<JsonObject> createProjectInfo(String prjPath, Project prj, FileObject workspaceFolder, LanguageClient client) throws NoSuchAlgorithmException {
269269
+ JsonObject obj = new JsonObject();
270270
+ String prjId = getPrjId(prjPath);
@@ -283,28 +283,35 @@ index d82646afb1..7f4c88acd1 100644
283283
+ } catch (RuntimeException e) {
284284
+ LOG.log(Level.INFO, "Exception while checking project problems for workspaceInfo event: {0}", e.getMessage());
285285
+ projectHasProblems = true;
286-
+ }
286+
}
287287
+ obj.addProperty("isOpenedWithProblems", projectHasProblems);
288-
+ }
288+
}
289289
+ String javaVersion = getProjectJavaVersion();
290290
+ 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 -> {
293293
+ obj.addProperty("isPreviewEnabled", isPreviewFlagEnabled);
294294
+ return obj;
295295
+ });
296296
+ }
297297

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+
-
298304
- 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);
301307
}
302308
-
303309
- private boolean isEnablePreivew(FileObject source, String prjType) {
304310
- if (prjType.equals(this.STANDALONE_PRJ)) {
305311
- NbCodeLanguageClient client = Lookup.getDefault().lookup(NbCodeLanguageClient.class);
306312
+
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);
308315
+ if (prjType == ProjectType.standalone) {
309316
+ NbCodeLanguageClient client = languageClient instanceof NbCodeLanguageClient ? (NbCodeLanguageClient) languageClient : null;
310317
if (client == null) {
@@ -320,25 +327,76 @@ index d82646afb1..7f4c88acd1 100644
320327
- client.configuration(new ConfigurationParams(Collections.singletonList(conf))).thenAccept(c -> {
321328
- String config = ((JsonPrimitive) ((List<Object>) c).get(0)).getAsString();
322329
- isEnablePreviewSet.set(config.contains(this.ENABLE_PREVIEW));
323-
- });
324-
-
325-
- return isEnablePreviewSet.get();
326330
+ conf.setSection(client.getNbCodeCapabilities().getConfigurationPrefix() + "runConfig.vmOptions");
327331
+ return client.configuration(new ConfigurationParams(Collections.singletonList(conf)))
328332
+ .thenApply(c -> {
329333
+ return c != null && !c.isEmpty()
330334
+ && ((JsonPrimitive) c.get(0)).getAsString().contains(ENABLE_PREVIEW);
331-
+ });
335+
});
336+
337+
- return isEnablePreviewSet.get();
332338
}
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+
+ }
334391
+
392+
+ private boolean isPreviewEnabledForSource(@NonNull FileObject source) {
335393
Result result = CompilerOptionsQuery.getOptions(source);
336394
- return result.getArguments().contains(this.ENABLE_PREVIEW);
337-
+ return CompletableFuture.completedFuture(result.getArguments().contains(ENABLE_PREVIEW));
395+
+ return result.getArguments().contains(ENABLE_PREVIEW);
338396
}
339397

340398
private String getPrjId(String prjPath) throws NoSuchAlgorithmException {
341-
@@ -187,15 +268,50 @@ public class LspServerTelemetryManager {
399+
@@ -187,15 +330,54 @@ public class LspServerTelemetryManager {
342400

343401
BigInteger number = new BigInteger(1, hash);
344402

@@ -387,9 +445,13 @@ index d82646afb1..7f4c88acd1 100644
387445
+ }
388446
+
389447
+ 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);
391450
+ 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;
393455
+ }
394456
}
395457
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

Comments
 (0)