From 140e077627fc14763d3431276890167de768907e Mon Sep 17 00:00:00 2001 From: Achal Talati Date: Mon, 25 Aug 2025 14:22:21 +0530 Subject: [PATCH 1/3] fix for workspaceChange events reporting enable preview boolean incorrect for the standalone projects --- .../java/lsp/server/telemetry/SourceInfo.java | 18 ++-- patches/nb-telemetry.diff | 87 ++++++++++--------- 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java b/nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java index 9c6adac3..8b4a441e 100644 --- a/nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java +++ b/nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java @@ -20,7 +20,10 @@ import java.lang.ref.WeakReference; import java.net.URI; import java.util.Map; +import java.util.concurrent.ExecutionException; import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import org.eclipse.lsp4j.services.LanguageClient; @@ -38,7 +41,7 @@ import org.openide.util.Lookup; class SourceInfo { - + private static final Logger LOG = Logger.getLogger(SourceInfo.class.getName()); private final FileObject file; private final Project owner; final JavaFileObject source; @@ -108,10 +111,15 @@ public String getJavaVersion() { return LspServerTelemetryManager.getJavaRuntimeVersion(lookupFunction); } - public boolean getPreviewEnabled() { - return LspServerTelemetryManager.getInstance().isPreviewEnabled(file, - owner == null ? LspServerTelemetryManager.ProjectType.standalone : LspServerTelemetryManager.getInstance().getProjectType(owner), - getLanguageClient()); + public boolean getPreviewEnabled(){ + try { + return LspServerTelemetryManager.getInstance().isPreviewEnabled(file, + owner == null ? LspServerTelemetryManager.ProjectType.standalone : LspServerTelemetryManager.getInstance().getProjectType(owner), + getLanguageClient()).get(); + } catch (InterruptedException | ExecutionException ex) { + LOG.log(Level.FINE, "exception while checking if preview enabled: {0}", (Object) ex); + } + return false; } public static SourceInfo getSourceObject(ErrorProvider.Context context) { diff --git a/patches/nb-telemetry.diff b/patches/nb-telemetry.diff index 358845e1..6ccce1b3 100644 --- a/patches/nb-telemetry.diff +++ b/patches/nb-telemetry.diff @@ -1,5 +1,5 @@ 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 -index d82646afb1..b008279cc4 100644 +index d82646afb1..7f4c88acd1 100644 --- 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 @@ -21,6 +21,7 @@ package org.netbeans.modules.java.lsp.server.protocol; @@ -10,7 +10,7 @@ index d82646afb1..b008279cc4 100644 import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; -@@ -28,25 +29,29 @@ import java.security.NoSuchAlgorithmException; +@@ -28,25 +29,30 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -22,6 +22,7 @@ index d82646afb1..b008279cc4 100644 +import java.util.NavigableMap; +import java.util.TreeMap; import java.util.WeakHashMap; ++import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; @@ -44,7 +45,7 @@ index d82646afb1..b008279cc4 100644 import org.openide.util.Lookup; /** -@@ -55,130 +60,200 @@ import org.openide.util.Lookup; +@@ -55,130 +61,205 @@ import org.openide.util.Lookup; */ public class LspServerTelemetryManager { @@ -85,11 +86,11 @@ index d82646afb1..b008279cc4 100644 + + private static final LspServerTelemetryManager instance = new LspServerTelemetryManager(); + } -+ + + private final WeakHashMap>> clients = new WeakHashMap<>(); + private volatile boolean telemetryEnabled = false; + private long lspServerIntializationTime; - ++ + public boolean isTelemetryEnabled() { + return telemetryEnabled; + } @@ -172,9 +173,10 @@ index d82646afb1..b008279cc4 100644 + return close == null || close.isDone(); + } + -+ public void sendWorkspaceInfo(LanguageClient client, List workspaceClientFolders, Collection projects, long timeToOpenProjects) { ++ public CompletableFuture sendWorkspaceInfo(LanguageClient client, List workspaceClientFolders, Collection projects, long timeToOpenProjects) { JsonObject properties = new JsonObject(); - JsonArray prjProps = new JsonArray(); +- JsonArray prjProps = new JsonArray(); ++ List> createProjectFutures = new ArrayList<>(); - Map mp = prjs.stream() - .collect(Collectors.toMap(project -> project.getProjectDirectory().getPath(), project -> project)); @@ -215,14 +217,14 @@ index d82646afb1..b008279cc4 100644 + String projectPath = p.getKey(); + if (prjPathWithSlash == null) { + if (prjPath.equals(projectPath)) { -+ prjProps.add(createProjectInfo(prjPath, p.getValue(), workspaceFolder, client)); ++ createProjectFutures.add(createProjectInfo(prjPath, p.getValue(), workspaceFolder, client)); + noProjectFound = false; + break; + } + prjPathWithSlash = prjPath + '/'; + } + if (projectPath.startsWith(prjPathWithSlash)) { -+ prjProps.add(createProjectInfo(p.getKey(), p.getValue(), workspaceFolder, client)); ++ createProjectFutures.add(createProjectInfo(p.getKey(), p.getValue(), workspaceFolder, client)); + noProjectFound = false; + continue; + } @@ -235,7 +237,7 @@ index d82646afb1..b008279cc4 100644 - Exceptions.printStackTrace(ex); + if (noProjectFound) { + // No project found -+ prjProps.add(createProjectInfo(prjPath, null, workspaceFolder, client)); ++ createProjectFutures.add(createProjectInfo(prjPath, null, workspaceFolder, client)); + } + } catch (NoSuchAlgorithmException e) { + LOG.log(Level.INFO, "NoSuchAlgorithmException while creating workspaceInfo event: {0}", e.getMessage()); @@ -245,24 +247,25 @@ index d82646afb1..b008279cc4 100644 } - properties.add("prjsInfo", prjProps); -+ properties.add("projectInfo", prjProps); ++ return CompletableFuture.allOf(createProjectFutures.toArray(new CompletableFuture[0])) ++ .thenApply((ignored) -> { ++ JsonArray prjProps = new JsonArray(); ++ createProjectFutures.forEach((f) -> prjProps.add(f.join())); ++ return prjProps; ++ }) ++ .thenAccept((prjProps) -> { ++ properties.add("projectInfo", prjProps); ++ properties.addProperty("projInitTimeTaken", timeToOpenProjects); ++ properties.addProperty("numProjects", workspaceClientFolders.size()); ++ properties.addProperty("lspInitTimeTaken", System.currentTimeMillis() - this.lspServerIntializationTime); ++ this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), LspServerTelemetryManager.WORKSPACE_INFO_EVT, properties)); ++ }); ++ } - properties.addProperty("timeToOpenPrjs", timeToOpenPrjs); - properties.addProperty("numOfPrjsOpened", workspaceClientFolders.size()); - properties.addProperty("lspServerInitializationTime", System.currentTimeMillis() - this.lspServerIntiailizationTime); -+ properties.addProperty("projInitTimeTaken", timeToOpenProjects); -+ properties.addProperty("numProjects", workspaceClientFolders.size()); -+ properties.addProperty("lspInitTimeTaken", System.currentTimeMillis() - this.lspServerIntializationTime); - -- this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), this.WORKSPACE_INFO_EVT, properties)); -+ this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), LspServerTelemetryManager.WORKSPACE_INFO_EVT, properties)); - } -- -- private boolean isEnablePreivew(FileObject source, String prjType) { -- if (prjType.equals(this.STANDALONE_PRJ)) { -- NbCodeLanguageClient client = Lookup.getDefault().lookup(NbCodeLanguageClient.class); -+ -+ private JsonObject createProjectInfo(String prjPath, Project prj, FileObject workspaceFolder, LanguageClient client) throws NoSuchAlgorithmException { ++ private CompletableFuture createProjectInfo(String prjPath, Project prj, FileObject workspaceFolder, LanguageClient client) throws NoSuchAlgorithmException { + JsonObject obj = new JsonObject(); + String prjId = getPrjId(prjPath); + obj.addProperty("id", prjId); @@ -286,27 +289,32 @@ index d82646afb1..b008279cc4 100644 + String javaVersion = getProjectJavaVersion(); + obj.addProperty("javaVersion", javaVersion); + obj.addProperty("buildTool", projectType.name()); -+ boolean isPreviewFlagEnabled = isPreviewEnabled(projectDirectory, projectType, client); -+ obj.addProperty("isPreviewEnabled", isPreviewFlagEnabled); -+ return obj; ++ return isPreviewEnabled(projectDirectory, projectType, client).thenApply(isPreviewFlagEnabled -> { ++ obj.addProperty("isPreviewEnabled", isPreviewFlagEnabled); ++ return obj; ++ }); + } -+ -+ public boolean isPreviewEnabled(FileObject source, ProjectType prjType) { + +- this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), this.WORKSPACE_INFO_EVT, properties)); ++ public CompletableFuture isPreviewEnabled(FileObject source, ProjectType prjType) { + return isPreviewEnabled(source, prjType, null); -+ } + } +- +- private boolean isEnablePreivew(FileObject source, String prjType) { +- if (prjType.equals(this.STANDALONE_PRJ)) { +- NbCodeLanguageClient client = Lookup.getDefault().lookup(NbCodeLanguageClient.class); + -+ public boolean isPreviewEnabled(FileObject source, ProjectType prjType, LanguageClient languageClient) { ++ public CompletableFuture isPreviewEnabled(FileObject source, ProjectType prjType, LanguageClient languageClient) { + if (prjType == ProjectType.standalone) { -+ NbCodeLanguageClient client = languageClient instanceof NbCodeLanguageClient ? (NbCodeLanguageClient) languageClient : null ; ++ NbCodeLanguageClient client = languageClient instanceof NbCodeLanguageClient ? (NbCodeLanguageClient) languageClient : null; if (client == null) { - return false; + client = Lookup.getDefault().lookup(NbCodeLanguageClient.class); + if (client == null) { -+ return false; ++ return CompletableFuture.completedFuture(false); + } } - AtomicBoolean isEnablePreviewSet = new AtomicBoolean(false); -+ boolean[] isEnablePreviewSet = {false}; ConfigurationItem conf = new ConfigurationItem(); - conf.setSection(client.getNbCodeCapabilities().getAltConfigurationPrefix() + "runConfig.vmOptions"); - client.configuration(new ConfigurationParams(Collections.singletonList(conf))).thenAccept(c -> { @@ -316,22 +324,21 @@ index d82646afb1..b008279cc4 100644 - - return isEnablePreviewSet.get(); + conf.setSection(client.getNbCodeCapabilities().getConfigurationPrefix() + "runConfig.vmOptions"); -+ client.configuration(new ConfigurationParams(Collections.singletonList(conf))) -+ .thenAccept(c -> { -+ isEnablePreviewSet[0] = c != null && !c.isEmpty() ++ return client.configuration(new ConfigurationParams(Collections.singletonList(conf))) ++ .thenApply(c -> { ++ return c != null && !c.isEmpty() + && ((JsonPrimitive) c.get(0)).getAsString().contains(ENABLE_PREVIEW); + }); -+ return isEnablePreviewSet[0]; } - + Result result = CompilerOptionsQuery.getOptions(source); - return result.getArguments().contains(this.ENABLE_PREVIEW); -+ return result.getArguments().contains(ENABLE_PREVIEW); ++ return CompletableFuture.completedFuture(result.getArguments().contains(ENABLE_PREVIEW)); } private String getPrjId(String prjPath) throws NoSuchAlgorithmException { -@@ -187,15 +262,50 @@ public class LspServerTelemetryManager { +@@ -187,15 +268,50 @@ public class LspServerTelemetryManager { BigInteger number = new BigInteger(1, hash); From 46e6f8d61cea0c37466466063f1421fcdb08754a Mon Sep 17 00:00:00 2001 From: Siddharth Srinivasan Date: Mon, 25 Aug 2025 12:26:08 +0530 Subject: [PATCH 2/3] 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. --- .../java/lsp/server/telemetry/SourceInfo.java | 2 +- patches/nb-telemetry.diff | 190 ++++++++++++------ 2 files changed, 127 insertions(+), 65 deletions(-) diff --git a/nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java b/nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java index 8b4a441e..101eb2be 100644 --- a/nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java +++ b/nbcode/telemetry/src/org/netbeans/modules/nbcode/java/lsp/server/telemetry/SourceInfo.java @@ -114,7 +114,7 @@ public String getJavaVersion() { public boolean getPreviewEnabled(){ try { return LspServerTelemetryManager.getInstance().isPreviewEnabled(file, - owner == null ? LspServerTelemetryManager.ProjectType.standalone : LspServerTelemetryManager.getInstance().getProjectType(owner), + owner, getLanguageClient()).get(); } catch (InterruptedException | ExecutionException ex) { LOG.log(Level.FINE, "exception while checking if preview enabled: {0}", (Object) ex); diff --git a/patches/nb-telemetry.diff b/patches/nb-telemetry.diff index 6ccce1b3..87f9d4ee 100644 --- a/patches/nb-telemetry.diff +++ b/patches/nb-telemetry.diff @@ -1,5 +1,5 @@ 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 -index d82646afb1..7f4c88acd1 100644 +index d82646afb1..5018896480 100644 --- 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 @@ -21,6 +21,7 @@ package org.netbeans.modules.java.lsp.server.protocol; @@ -10,7 +10,7 @@ index d82646afb1..7f4c88acd1 100644 import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; -@@ -28,25 +29,30 @@ import java.security.NoSuchAlgorithmException; +@@ -28,25 +29,36 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -18,8 +18,8 @@ index d82646afb1..7f4c88acd1 100644 +import java.util.Iterator; import java.util.List; import java.util.Map; --import java.util.Set; +import java.util.NavigableMap; + import java.util.Set; +import java.util.TreeMap; import java.util.WeakHashMap; +import java.util.concurrent.CompletableFuture; @@ -33,19 +33,24 @@ index d82646afb1..7f4c88acd1 100644 import org.eclipse.lsp4j.ConfigurationParams; import org.eclipse.lsp4j.MessageType; import org.eclipse.lsp4j.services.LanguageClient; ++import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.java.platform.JavaPlatform; ++import org.netbeans.api.java.project.JavaProjectConstants; import org.netbeans.api.java.queries.CompilerOptionsQuery; import org.netbeans.api.java.queries.CompilerOptionsQuery.Result; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectManager; ++import org.netbeans.api.project.ProjectUtils; ++import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.ui.ProjectProblems; +import org.netbeans.modules.java.platform.implspi.JavaPlatformProvider; import org.openide.filesystems.FileObject; -import org.openide.util.Exceptions; ++import org.openide.filesystems.FileUtil; import org.openide.util.Lookup; /** -@@ -55,130 +61,205 @@ import org.openide.util.Lookup; +@@ -55,130 +67,261 @@ import org.openide.util.Lookup; */ public class LspServerTelemetryManager { @@ -86,7 +91,7 @@ index d82646afb1..7f4c88acd1 100644 + + private static final LspServerTelemetryManager instance = new LspServerTelemetryManager(); + } - ++ + private final WeakHashMap>> clients = new WeakHashMap<>(); + private volatile boolean telemetryEnabled = false; + private long lspServerIntializationTime; @@ -94,7 +99,7 @@ index d82646afb1..7f4c88acd1 100644 + public boolean isTelemetryEnabled() { + return telemetryEnabled; + } -+ + + public void connect(LanguageClient client, Future future) { synchronized (clients) { - for (Map.Entry> entry : clients.entrySet()) { @@ -168,21 +173,21 @@ index d82646afb1..7f4c88acd1 100644 } - public void sendWorkspaceInfo(LanguageClient client, List workspaceClientFolders, Collection prjs, long timeToOpenPrjs) { +- JsonObject properties = new JsonObject(); +- JsonArray prjProps = new JsonArray(); + private boolean isInvalidClient(WeakReference> closeListener) { + Future close = closeListener == null ? null : closeListener.get(); + return close == null || close.isDone(); + } -+ -+ public CompletableFuture sendWorkspaceInfo(LanguageClient client, List workspaceClientFolders, Collection projects, long timeToOpenProjects) { - JsonObject properties = new JsonObject(); -- JsonArray prjProps = new JsonArray(); -+ List> createProjectFutures = new ArrayList<>(); - Map mp = prjs.stream() - .collect(Collectors.toMap(project -> project.getProjectDirectory().getPath(), project -> project)); ++ public CompletableFuture sendWorkspaceInfo(LanguageClient client, List workspaceClientFolders, Collection projects, long timeToOpenProjects) { ++ JsonObject properties = new JsonObject(); + + NavigableMap mp = projects.stream() + .collect(Collectors.toMap(project -> project.getProjectDirectory().getPath(), project -> project, (p1, p2) -> p1, TreeMap::new)); - ++ List> createProjectFutures = new ArrayList<>(); for (FileObject workspaceFolder : workspaceClientFolders) { try { - JsonObject obj = new JsonObject(); @@ -190,28 +195,6 @@ index d82646afb1..7f4c88acd1 100644 String prjPath = workspaceFolder.getPath(); - String prjId = this.getPrjId(prjPath); - obj.addProperty("id", prjId); -- -- // In future if different JDK is used for different project then this can be updated -- obj.addProperty("javaVersion", System.getProperty("java.version")); -- -- if (mp.containsKey(prjPath)) { -- Project prj = mp.get(prjPath); -- -- ProjectManager.Result r = ProjectManager.getDefault().isProject2(prj.getProjectDirectory()); -- String projectType = r.getProjectType(); -- obj.addProperty("buildTool", (projectType.contains("maven") ? "MavenProject" : "GradleProject")); -- -- obj.addProperty("openedWithProblems", ProjectProblems.isBroken(prj)); -- -- boolean isPreviewFlagEnabled = this.isEnablePreivew(prj.getProjectDirectory(), projectType); -- obj.addProperty("enablePreview", isPreviewFlagEnabled); -- } else { -- obj.addProperty("buildTool", this.STANDALONE_PRJ); -- obj.addProperty("javaVersion", System.getProperty("java.version")); -- obj.addProperty("openedWithProblems", false); -- -- boolean isPreviewFlagEnabled = this.isEnablePreivew(workspaceFolder, this.STANDALONE_PRJ); -- obj.addProperty("enablePreview", isPreviewFlagEnabled); + String prjPathWithSlash = null; + for (Map.Entry p : mp.tailMap(prjPath, true).entrySet()) { + String projectPath = p.getKey(); @@ -221,7 +204,7 @@ index d82646afb1..7f4c88acd1 100644 + noProjectFound = false; + break; + } -+ prjPathWithSlash = prjPath + '/'; ++ prjPathWithSlash = prjPath + '/'; + } + if (projectPath.startsWith(prjPathWithSlash)) { + createProjectFutures.add(createProjectInfo(p.getKey(), p.getValue(), workspaceFolder, client)); @@ -229,12 +212,7 @@ index d82646afb1..7f4c88acd1 100644 + continue; + } + break; - } -- -- prjProps.add(obj); -- -- } catch (NoSuchAlgorithmException ex) { -- Exceptions.printStackTrace(ex); ++ } + if (noProjectFound) { + // No project found + createProjectFutures.add(createProjectInfo(prjPath, null, workspaceFolder, client)); @@ -243,10 +221,11 @@ index d82646afb1..7f4c88acd1 100644 + LOG.log(Level.INFO, "NoSuchAlgorithmException while creating workspaceInfo event: {0}", e.getMessage()); + } catch (Exception e) { + LOG.log(Level.INFO, "Exception while creating workspaceInfo event: {0}", e.getMessage()); - } - } - -- properties.add("prjsInfo", prjProps); ++ } ++ } + +- // In future if different JDK is used for different project then this can be updated +- obj.addProperty("javaVersion", System.getProperty("java.version")); + return CompletableFuture.allOf(createProjectFutures.toArray(new CompletableFuture[0])) + .thenApply((ignored) -> { + JsonArray prjProps = new JsonArray(); @@ -255,16 +234,37 @@ index d82646afb1..7f4c88acd1 100644 + }) + .thenAccept((prjProps) -> { + properties.add("projectInfo", prjProps); + +- if (mp.containsKey(prjPath)) { +- Project prj = mp.get(prjPath); + properties.addProperty("projInitTimeTaken", timeToOpenProjects); + properties.addProperty("numProjects", workspaceClientFolders.size()); + properties.addProperty("lspInitTimeTaken", System.currentTimeMillis() - this.lspServerIntializationTime); + +- ProjectManager.Result r = ProjectManager.getDefault().isProject2(prj.getProjectDirectory()); +- String projectType = r.getProjectType(); +- obj.addProperty("buildTool", (projectType.contains("maven") ? "MavenProject" : "GradleProject")); +- +- obj.addProperty("openedWithProblems", ProjectProblems.isBroken(prj)); +- +- boolean isPreviewFlagEnabled = this.isEnablePreivew(prj.getProjectDirectory(), projectType); +- obj.addProperty("enablePreview", isPreviewFlagEnabled); +- } else { +- obj.addProperty("buildTool", this.STANDALONE_PRJ); +- obj.addProperty("javaVersion", System.getProperty("java.version")); +- obj.addProperty("openedWithProblems", false); +- +- boolean isPreviewFlagEnabled = this.isEnablePreivew(workspaceFolder, this.STANDALONE_PRJ); +- obj.addProperty("enablePreview", isPreviewFlagEnabled); +- } +- +- prjProps.add(obj); + this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), LspServerTelemetryManager.WORKSPACE_INFO_EVT, properties)); + }); + } -- properties.addProperty("timeToOpenPrjs", timeToOpenPrjs); -- properties.addProperty("numOfPrjsOpened", workspaceClientFolders.size()); -- properties.addProperty("lspServerInitializationTime", System.currentTimeMillis() - this.lspServerIntiailizationTime); +- } catch (NoSuchAlgorithmException ex) { +- Exceptions.printStackTrace(ex); + private CompletableFuture createProjectInfo(String prjPath, Project prj, FileObject workspaceFolder, LanguageClient client) throws NoSuchAlgorithmException { + JsonObject obj = new JsonObject(); + String prjId = getPrjId(prjPath); @@ -283,28 +283,35 @@ index d82646afb1..7f4c88acd1 100644 + } catch (RuntimeException e) { + LOG.log(Level.INFO, "Exception while checking project problems for workspaceInfo event: {0}", e.getMessage()); + projectHasProblems = true; -+ } + } + obj.addProperty("isOpenedWithProblems", projectHasProblems); -+ } + } + String javaVersion = getProjectJavaVersion(); + obj.addProperty("javaVersion", javaVersion); -+ obj.addProperty("buildTool", projectType.name()); -+ return isPreviewEnabled(projectDirectory, projectType, client).thenApply(isPreviewFlagEnabled -> { ++ if (projectType != null) obj.addProperty("buildTool", projectType.name()); ++ return isPreviewEnabled(projectDirectory, prj, client).thenApply(isPreviewFlagEnabled -> { + obj.addProperty("isPreviewEnabled", isPreviewFlagEnabled); + return obj; + }); + } +- properties.add("prjsInfo", prjProps); +- +- properties.addProperty("timeToOpenPrjs", timeToOpenPrjs); +- properties.addProperty("numOfPrjsOpened", workspaceClientFolders.size()); +- properties.addProperty("lspServerInitializationTime", System.currentTimeMillis() - this.lspServerIntiailizationTime); +- - this.sendTelemetry(client, new TelemetryEvent(MessageType.Info.toString(), this.WORKSPACE_INFO_EVT, properties)); -+ public CompletableFuture isPreviewEnabled(FileObject source, ProjectType prjType) { -+ return isPreviewEnabled(source, prjType, null); ++ public CompletableFuture isPreviewEnabled(FileObject source, Project prj) { ++ return isPreviewEnabled(source, prj, null); } - - private boolean isEnablePreivew(FileObject source, String prjType) { - if (prjType.equals(this.STANDALONE_PRJ)) { - NbCodeLanguageClient client = Lookup.getDefault().lookup(NbCodeLanguageClient.class); + -+ public CompletableFuture isPreviewEnabled(FileObject source, ProjectType prjType, LanguageClient languageClient) { ++ public CompletableFuture isPreviewEnabled(FileObject source, Project prj, LanguageClient languageClient) { ++ ProjectType prjType = prj == null ? ProjectType.standalone : getProjectType(prj); + if (prjType == ProjectType.standalone) { + NbCodeLanguageClient client = languageClient instanceof NbCodeLanguageClient ? (NbCodeLanguageClient) languageClient : null; if (client == null) { @@ -320,25 +327,76 @@ index d82646afb1..7f4c88acd1 100644 - client.configuration(new ConfigurationParams(Collections.singletonList(conf))).thenAccept(c -> { - String config = ((JsonPrimitive) ((List) c).get(0)).getAsString(); - isEnablePreviewSet.set(config.contains(this.ENABLE_PREVIEW)); -- }); -- -- return isEnablePreviewSet.get(); + conf.setSection(client.getNbCodeCapabilities().getConfigurationPrefix() + "runConfig.vmOptions"); + return client.configuration(new ConfigurationParams(Collections.singletonList(conf))) + .thenApply(c -> { + return c != null && !c.isEmpty() + && ((JsonPrimitive) c.get(0)).getAsString().contains(ENABLE_PREVIEW); -+ }); + }); + +- return isEnablePreviewSet.get(); } -- + ++ boolean previewEnabled; ++ previewEnabled = source != null && isPreviewEnabledForSource(source); ++ if (!previewEnabled && prjType == ProjectType.gradle) { ++ assert prj != null; ++ FileObject prjRoot = prj.getProjectDirectory(); ++ String relativePath = prjRoot == null ? null : FileUtil.getRelativePath(prjRoot, source); ++ if (relativePath == null || relativePath.isEmpty()) { ++ // The source is not inside the project root, and, ++ // so the project contents need to be checked for preview-enabled ++ previewEnabled = previewEnabled || isPreviewEnabledForAnyProjectSourceRoot(prj); ++ previewEnabled = previewEnabled || isPreviewEnabledForAnyContainedProjects(prj); ++ } ++ } ++ ++ return CompletableFuture.completedFuture(previewEnabled); ++ } ++ ++ private boolean isPreviewEnabledForAnyContainedProjects(@NonNull Project project) { ++ Set subProjects = ProjectUtils.getContainedProjects(project, false); ++ if (subProjects != null) { ++ for (Project subProject : subProjects) { ++ if (isPreviewEnabledForAnyProjectSourceRoot(subProject)) { ++ return true; ++ } ++ } ++ for (Project subProject : subProjects) { ++ if (isPreviewEnabledForAnyContainedProjects(subProject)) { ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ ++ private boolean isPreviewEnabledForAnyProjectSourceRoot(@NonNull Project project) { ++ SourceGroup[] sources = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); ++ if (sources == null || sources.length == 0) { ++ FileObject root = project.getProjectDirectory(); ++ if (root != null && isPreviewEnabledForSource(root)) { ++ return true; ++ } ++ } else { ++ for (SourceGroup s : sources) { ++ FileObject root = s.getRootFolder(); ++ if (root != null && isPreviewEnabledForSource(root)) { ++ return true; ++ } ++ } ++ } ++ return false; ++ } + ++ private boolean isPreviewEnabledForSource(@NonNull FileObject source) { Result result = CompilerOptionsQuery.getOptions(source); - return result.getArguments().contains(this.ENABLE_PREVIEW); -+ return CompletableFuture.completedFuture(result.getArguments().contains(ENABLE_PREVIEW)); ++ return result.getArguments().contains(ENABLE_PREVIEW); } private String getPrjId(String prjPath) throws NoSuchAlgorithmException { -@@ -187,15 +268,50 @@ public class LspServerTelemetryManager { +@@ -187,15 +330,54 @@ public class LspServerTelemetryManager { BigInteger number = new BigInteger(1, hash); @@ -387,9 +445,13 @@ index d82646afb1..7f4c88acd1 100644 + } + + public ProjectType getProjectType(Project prj) { -+ ProjectManager.Result r = ProjectManager.getDefault().isProject2(prj.getProjectDirectory()); ++ FileObject prjDir = prj.getProjectDirectory(); ++ ProjectManager.Result r = prjDir == null ? null : ProjectManager.getDefault().isProject2(prjDir); + String projectType = r == null ? null : r.getProjectType(); -+ return projectType != null && projectType.contains(ProjectType.maven.name()) ? ProjectType.maven : ProjectType.gradle; ++ return projectType == null ? null ++ : projectType.contains(ProjectType.maven.name()) ? ProjectType.maven ++ : projectType.contains(ProjectType.gradle.name()) ? ProjectType.gradle ++ : null; + } } 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 From 6f4abd021570089d0ac15404f43fc96ea2b20bb8 Mon Sep 17 00:00:00 2001 From: Achal Talati Date: Mon, 25 Aug 2025 16:08:53 +0530 Subject: [PATCH 3/3] removed extra check for gradle and generalized a liitle bit in enable preview check --- patches/nb-telemetry.diff | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/nb-telemetry.diff b/patches/nb-telemetry.diff index 87f9d4ee..be9accc0 100644 --- a/patches/nb-telemetry.diff +++ b/patches/nb-telemetry.diff @@ -1,5 +1,5 @@ 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 -index d82646afb1..5018896480 100644 +index d82646afb1..a4a1b53e26 100644 --- 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 @@ -21,6 +21,7 @@ package org.netbeans.modules.java.lsp.server.protocol; @@ -339,14 +339,14 @@ index d82646afb1..5018896480 100644 + boolean previewEnabled; + previewEnabled = source != null && isPreviewEnabledForSource(source); -+ if (!previewEnabled && prjType == ProjectType.gradle) { ++ if (!previewEnabled) { + assert prj != null; + FileObject prjRoot = prj.getProjectDirectory(); + String relativePath = prjRoot == null ? null : FileUtil.getRelativePath(prjRoot, source); + if (relativePath == null || relativePath.isEmpty()) { + // The source is not inside the project root, and, + // so the project contents need to be checked for preview-enabled -+ previewEnabled = previewEnabled || isPreviewEnabledForAnyProjectSourceRoot(prj); ++ previewEnabled = isPreviewEnabledForAnyProjectSourceRoot(prj); + previewEnabled = previewEnabled || isPreviewEnabledForAnyContainedProjects(prj); + } + }