This is an automated email from the ASF dual-hosted git repository.
entl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 41da357 Apply LSP URI translation to debugger as well. URI
translation cache is created.
41da357 is described below
commit 41da35720129ef4f4b7c94bd22ef230ead719153
Author: Martin Entlicher <[email protected]>
AuthorDate: Mon Oct 11 07:34:07 2021 +0200
Apply LSP URI translation to debugger as well. URI translation cache is
created.
---
.../modules/java/lsp/server/URITranslator.java | 183 +++++++++++++++++++++
.../netbeans/modules/java/lsp/server/Utils.java | 89 +---------
.../lsp/server/debugging/NbProtocolServer.java | 2 +
.../lsp/server/debugging/NbSourceProvider.java | 2 +
.../breakpoints/NbBreakpointsRequestHandler.java | 2 +
5 files changed, 191 insertions(+), 87 deletions(-)
diff --git
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/URITranslator.java
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/URITranslator.java
new file mode 100644
index 0000000..a68f2f2
--- /dev/null
+++
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/URITranslator.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.lsp.server;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.URLMapper;
+import org.openide.modules.Places;
+import org.openide.util.Exceptions;
+
+/**
+ * Translation between NetBeans URIs and LSP URIs. LSP clients might not like
+ * archive URIs. The archive URIs are translated to plain file URIs from a
cache
+ * directory.
+ */
+public final class URITranslator {
+
+ private static final URITranslator INSTANCE = new URITranslator();
+
+ private final Map<String, String> uriFromCacheMap = new LRUCacheMap();
+ private final Map<String, String> uriToCacheMap = new LRUCacheMap();
+
+ public static URITranslator getDefault() {
+ return INSTANCE;
+ }
+
+ public synchronized String uriToLSP(String lspUri) {
+ return uriFromCacheMap.computeIfAbsent(lspUri, uri -> {
+ URI uriUri = URI.create(uri);
+ URL url;
+ try {
+ url = uriUri.toURL();
+ } catch (MalformedURLException ex) {
+ return uri;
+ }
+ if (FileUtil.isArchiveArtifact(url)) {
+ FileObject file = URLMapper.findFileObject(url);
+ if (file == null) {
+ return uri;
+ }
+ File cacheDir = getCacheDir();
+ cacheDir.mkdirs();
+ File segments = new File(cacheDir, "segments"); // NOI18N
+ Properties props = new Properties();
+
+ try (InputStream in = new FileInputStream(segments)) {
+ props.load(in);
+ } catch (IOException ex) {
+ //OK, may not exist yet
+ }
+ FileObject archive = FileUtil.getArchiveFile(file);
+ String archiveString = archive.toURL().toString();
+ File foundSegment = null;
+ for (String segment : props.stringPropertyNames()) {
+ if (archiveString.equals(props.getProperty(segment))) {
+ foundSegment = new File(cacheDir, segment);
+ break;
+ }
+ }
+ if (foundSegment == null) {
+ int i = 0;
+ while (props.getProperty("s" + i) != null) { // NOI18N
+ i++;
+ }
+ foundSegment = new File(cacheDir, "s" + i); // NOI18N
+ props.put("s" + i, archiveString); // NOI18N
+ try (OutputStream in = new FileOutputStream(segments)) {
+ props.store(in, "");
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ File cache = new File(foundSegment,
FileUtil.getRelativePath(FileUtil.getArchiveRoot(archive), file));
+ cache.getParentFile().mkdirs();
+ try (OutputStream out = new FileOutputStream(cache)) {
+ out.write(file.asBytes());
+ return cache.toURI().toString();
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ if (uriUri.getScheme().equals("nbfs")) { // NOI18N
+ FileObject file = URLMapper.findFileObject(url);
+ if (file == null) {
+ return uri;
+ }
+ try {
+ String txt = file.asText("UTF-8"); // NOI18N
+ try (OutputStream os = file.getOutputStream()) {
+ os.write(txt.getBytes("UTF-8")); // NOI18N
+ }
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ try {
+ uri = URLMapper.findURL(file,
URLMapper.EXTERNAL).toURI().toString();
+ } catch (URISyntaxException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ return uri;
+ });
+ }
+
+ public synchronized String uriFromLSP(String nbUri) {
+ return uriToCacheMap.computeIfAbsent(nbUri, uri -> {
+ URI uriUri = URI.create(uri);
+ File cacheDir = getCacheDir();
+ URI relative = cacheDir.toURI().relativize(uriUri);
+ if (relative != null && new File(cacheDir,
relative.toString()).canRead()) {
+ String segmentAndPath = relative.toString();
+ int slash = segmentAndPath.indexOf('/');
+ String segment = segmentAndPath.substring(0, slash);
+ String path = segmentAndPath.substring(slash + 1);
+ File segments = new File(cacheDir, "segments"); // NOI18N
+ Properties props = new Properties();
+
+ try (InputStream in = new FileInputStream(segments)) {
+ props.load(in);
+ String archiveUri = props.getProperty(segment);
+ FileObject archive =
URLMapper.findFileObject(URI.create(archiveUri).toURL());
+ archive = archive != null ?
FileUtil.getArchiveRoot(archive) : null;
+ FileObject file = archive != null ?
archive.getFileObject(path) : null;
+ if (file != null) {
+ return file.toURI().toString();
+ }
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ return uri;
+ });
+ }
+
+ private static File getCacheDir() {
+ return Places.getCacheSubfile("java-server"); // NOI18N
+ }
+
+ private static class LRUCacheMap extends LinkedHashMap<String, String> {
+
+ private static final int MAX_SIZE = 2048;
+
+ LRUCacheMap() {
+ super(32, 0.75f, true);
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
+ return size() > MAX_SIZE;
+ }
+
+ }
+}
diff --git
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/Utils.java
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/Utils.java
index 309a3de..ec5af37 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/Utils.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/Utils.java
@@ -132,99 +132,14 @@ public class Utils {
}
public static synchronized String toUri(FileObject file) {
- if (FileUtil.isArchiveArtifact(file)) {
- //VS code cannot open jar:file: URLs, workaround:
- File cacheDir = getCacheDir();
- cacheDir.mkdirs();
- File segments = new File(cacheDir, "segments");
- Properties props = new Properties();
-
- try (InputStream in = new FileInputStream(segments)) {
- props.load(in);
- } catch (IOException ex) {
- //OK, may not exist yet
- }
- FileObject archive = FileUtil.getArchiveFile(file);
- String archiveString = archive.toURL().toString();
- File foundSegment = null;
- for (String segment : props.stringPropertyNames()) {
- if (archiveString.equals(props.getProperty(segment))) {
- foundSegment = new File(cacheDir, segment);
- break;
- }
- }
- if (foundSegment == null) {
- int i = 0;
- while (props.getProperty("s" + i) != null)
- i++;
- foundSegment = new File(cacheDir, "s" + i);
- props.put("s" + i, archiveString);
- try (OutputStream in = new FileOutputStream(segments)) {
- props.store(in, "");
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
- File cache = new File(foundSegment,
FileUtil.getRelativePath(FileUtil.getArchiveRoot(archive), file));
- cache.getParentFile().mkdirs();
- try (OutputStream out = new FileOutputStream(cache)) {
- out.write(file.asBytes());
- return cache.toURI().toString();
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
- URI uri = file.toURI();
- if (uri.getScheme().equals("nbfs")) {
- try {
- String txt = file.asText("UTF-8");
- try (OutputStream os = file.getOutputStream()) {
- os.write(txt.getBytes("UTF-8"));
- }
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- try {
- uri = URLMapper.findURL(file, URLMapper.EXTERNAL).toURI();
- } catch (URISyntaxException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
- return uri.toString();
+ return URITranslator.getDefault().uriToLSP(file.toURI().toString());
}
public static synchronized FileObject fromUri(String uri) throws
MalformedURLException {
- File cacheDir = getCacheDir();
- URI uriUri = URI.create(uri);
- URI relative = cacheDir.toURI().relativize(uriUri);
- if (relative != null && new File(cacheDir,
relative.toString()).canRead()) {
- String segmentAndPath = relative.toString();
- int slash = segmentAndPath.indexOf('/');
- String segment = segmentAndPath.substring(0, slash);
- String path = segmentAndPath.substring(slash + 1);
- File segments = new File(cacheDir, "segments");
- Properties props = new Properties();
-
- try (InputStream in = new FileInputStream(segments)) {
- props.load(in);
- String archiveUri = props.getProperty(segment);
- FileObject archive =
URLMapper.findFileObject(URI.create(archiveUri).toURL());
- archive = archive != null ? FileUtil.getArchiveRoot(archive) :
null;
- FileObject file = archive != null ?
archive.getFileObject(path) : null;
- if (file != null) {
- return file;
- }
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
- }
- }
+ uri = URITranslator.getDefault().uriFromLSP(uri);
return URLMapper.findFileObject(URI.create(uri).toURL());
}
- private static File getCacheDir() {
- return Places.getCacheSubfile("java-server");
- }
-
private static final char[] SNIPPET_ESCAPE_CHARS = new char[] { '\\', '$',
'}' };
/**
* Escape special characters in a completion snippet. Characters '$' and
'}'
diff --git
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/NbProtocolServer.java
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/NbProtocolServer.java
index 08b133b..7807fdb 100644
---
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/NbProtocolServer.java
+++
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/NbProtocolServer.java
@@ -80,6 +80,7 @@ import org.netbeans.api.debugger.jpda.ObjectVariable;
import org.netbeans.api.debugger.jpda.Variable;
import org.netbeans.modules.debugger.jpda.truffle.vars.TruffleVariable;
import org.netbeans.modules.java.lsp.server.LspSession;
+import org.netbeans.modules.java.lsp.server.URITranslator;
import
org.netbeans.modules.java.lsp.server.debugging.breakpoints.NbBreakpointsRequestHandler;
import
org.netbeans.modules.java.lsp.server.debugging.attach.NbAttachRequestHandler;
import org.netbeans.modules.java.lsp.server.debugging.launch.NbDebugSession;
@@ -321,6 +322,7 @@ public final class NbProtocolServer implements
IDebugProtocolServer, LspSession.
stackFrame.setName(frame.getName());
URI sourceURI = frame.getSourceURI();
if (sourceURI != null) {
+ sourceURI =
URI.create(URITranslator.getDefault().uriToLSP(sourceURI.toString()));
Source source = new Source();
String scheme = sourceURI.getScheme();
if (null == scheme || scheme.isEmpty() ||
"file".equalsIgnoreCase(scheme)) {
diff --git
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/NbSourceProvider.java
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/NbSourceProvider.java
index 9e598bd..35167ee 100644
---
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/NbSourceProvider.java
+++
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/NbSourceProvider.java
@@ -37,6 +37,7 @@ import java.util.logging.Logger;
import org.eclipse.lsp4j.debug.Source;
import org.netbeans.api.java.classpath.ClassPath;
+import org.netbeans.modules.java.lsp.server.URITranslator;
import org.openide.filesystems.FileObject;
/**
@@ -96,6 +97,7 @@ public final class NbSourceProvider {
public Source getSource(String sourceName, String debuggerURI) {
return uriToSource.computeIfAbsent(debuggerURI, uri -> {
+ uri = URITranslator.getDefault().uriToLSP(uri);
Source source = new Source();
source.setName(sourceName);
source.setSourceReference(0);
diff --git
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/breakpoints/NbBreakpointsRequestHandler.java
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/breakpoints/NbBreakpointsRequestHandler.java
index cde3ce4..948441f 100644
---
a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/breakpoints/NbBreakpointsRequestHandler.java
+++
b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/debugging/breakpoints/NbBreakpointsRequestHandler.java
@@ -36,6 +36,7 @@ import
org.eclipse.lsp4j.debug.SetExceptionBreakpointsArguments;
import org.eclipse.lsp4j.debug.Source;
import org.eclipse.lsp4j.debug.SourceBreakpoint;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
+import org.netbeans.modules.java.lsp.server.URITranslator;
import org.netbeans.modules.java.lsp.server.debugging.DebugAdapterContext;
import org.netbeans.modules.java.lsp.server.debugging.utils.ErrorUtilities;
@@ -75,6 +76,7 @@ public final class NbBreakpointsRequestHandler {
ResponseErrorCode.InvalidParams);
return resultFuture;
}
+ sourcePath = URITranslator.getDefault().uriFromLSP(sourcePath);
List<Breakpoint> res = new ArrayList<>();
NbBreakpoint[] toAdds =
this.convertClientBreakpointsToDebugger(source, sourcePath,
arguments.getBreakpoints(), context);
// Decode the URI if it comes encoded:
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists