Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LSP: Open sources from Jar files as read-only from their true locations. #6286

Merged
merged 1 commit into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,17 @@
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.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
Expand Down Expand Up @@ -69,60 +67,10 @@ public synchronized String uriToLSP(String lspUri) {
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();
if (file.isFolder()) {
if (cache.exists() && cache.isFile()) {
if (!cache.delete()) {
return uri;
}
}
cache.mkdir();
return cache.toURI().toString();
} else if (file.isData()) {
try {
if (cache.exists() && cache.isDirectory()) {
FileUtil.toFileObject(cache).delete();
}
try (OutputStream out = new FileOutputStream(cache)) {
out.write(file.asBytes());
return cache.toURI().toString();
}
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
try {
return URLMapper.findURL(file, URLMapper.EXTERNAL).toURI().toString();
} catch (URISyntaxException ex) {
Exceptions.printStackTrace(ex);
}
}
if (uriUri.getScheme().equals("nbfs")) { // NOI18N
Expand Down Expand Up @@ -150,30 +98,9 @@ public synchronized String uriToLSP(String lspUri) {

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);
}
}
try {
return URLDecoder.decode(nbUri, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException ex) {}
return uri;
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ private InitializeResult constructInitResponse(InitializeParams init, JavaSource
Set<String> commands = new LinkedHashSet<>(Arrays.asList(GRAALVM_PAUSE_SCRIPT,
NBLS_BUILD_WORKSPACE,
NBLS_CLEAN_WORKSPACE,
NBLS_GET_ARCHIVE_FILE_CONTENT,
JAVA_RUN_PROJECT_ACTION,
JAVA_FIND_DEBUG_ATTACH_CONFIGURATIONS,
JAVA_FIND_DEBUG_PROCESS_TO_ATTACH,
Expand Down Expand Up @@ -989,6 +990,7 @@ public void setTrace(SetTraceParams params) {
public static final String JAVA_SUPER_IMPLEMENTATION = "java.super.implementation";
public static final String GRAALVM_PAUSE_SCRIPT = "graalvm.pause.script";
public static final String JAVA_RUN_PROJECT_ACTION = "java.project.run.action";
public static final String NBLS_GET_ARCHIVE_FILE_CONTENT = "nbls.get.archive.file.content";

/**
* Enumerates project configurations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,20 @@ public CompletableFuture<Object> executeCommand(ExecuteCommandParams params) {
progressOfCompilation.checkStatus();
return progressOfCompilation.getFinishFuture();
}
case Server.NBLS_GET_ARCHIVE_FILE_CONTENT: {
CompletableFuture<Object> future = new CompletableFuture<>();
try {
String uri = ((JsonPrimitive) params.getArguments().get(0)).getAsString();
FileObject file = Utils.fromUri(uri);
if (file != null) {
future.complete(file.asText("UTF-8"));
}
future.complete(null);
} catch (IOException ioe) {
future.completeExceptionally(ioe);
}
return future;
}
case Server.JAVA_GET_PROJECT_SOURCE_ROOTS: {
String uri = ((JsonPrimitive) params.getArguments().get(0)).getAsString();
String type = params.getArguments().size() > 1 ? ((JsonPrimitive) params.getArguments().get(1)).getAsString() : JavaProjectConstants.SOURCES_TYPE_JAVA;
Expand Down
8 changes: 8 additions & 0 deletions java/java.lsp.server/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,14 @@ export function activate(context: ExtensionContext): VSNetBeansAPI {
context.subscriptions.push(commands.registerCommand('nbls.node.properties.edit',
async (node) => await PropertiesView.createOrShow(context, node, (await client).findTreeViewService())));

const archiveFileProvider = <vscode.TextDocumentContentProvider> {
provideTextDocumentContent: async (uri: vscode.Uri, token: vscode.CancellationToken): Promise<string> => {
return await commands.executeCommand('nbls.get.archive.file.content', uri.toString());
}
};
context.subscriptions.push(workspace.registerTextDocumentContentProvider('jar', archiveFileProvider));
context.subscriptions.push(workspace.registerTextDocumentContentProvider('nbjrt', archiveFileProvider));

launchConfigurations.updateLaunchConfig();

// register completions:
Expand Down