mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
[java] JRT file system API
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,7 @@ import com.intellij.lang.LangBundle;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.impl.jrt.JrtFileSystem;
|
||||
import com.intellij.openapi.vfs.jrt.JrtFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.presentation.java.ClassPresentationUtil;
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.impl.jrt.JrtFileSystem;
|
||||
import com.intellij.openapi.vfs.jrt.JrtFileSystem;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
@@ -665,12 +665,10 @@ public class JavaSdkImpl extends JavaSdk {
|
||||
List<VirtualFile> result = ContainerUtil.newArrayList();
|
||||
VirtualFileManager fileManager = VirtualFileManager.getInstance();
|
||||
|
||||
String path = file.getPath();
|
||||
if (JrtFileSystem.isModularJdk(path)) {
|
||||
String url = VirtualFileManager.constructUrl(JrtFileSystem.PROTOCOL, FileUtil.toSystemIndependentName(path) + JrtFileSystem.SEPARATOR);
|
||||
for (String module : JrtFileSystem.listModules(path)) {
|
||||
ContainerUtil.addIfNotNull(result, fileManager.findFileByUrl(url + module));
|
||||
}
|
||||
VirtualFile jrt = fileManager.findFileByUrl(
|
||||
VirtualFileManager.constructUrl(JrtFileSystem.PROTOCOL, FileUtil.toSystemIndependentName(file.getPath()) + JrtFileSystem.SEPARATOR));
|
||||
if (jrt != null) {
|
||||
ContainerUtil.addAll(result, jrt.getChildren());
|
||||
}
|
||||
|
||||
for (File root : JavaSdkUtil.getJdkClassesRoots(file, isJre)) {
|
||||
|
||||
+10
-70
@@ -23,18 +23,22 @@ import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.impl.ArchiveHandler;
|
||||
import com.intellij.openapi.vfs.newvfs.*;
|
||||
import com.intellij.openapi.vfs.jrt.JrtFileSystem;
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
|
||||
import com.intellij.openapi.vfs.newvfs.VfsImplUtil;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -42,36 +46,19 @@ import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.intellij.util.containers.ContainerUtil.newTroveMap;
|
||||
|
||||
public class JrtFileSystem extends ArchiveFileSystem {
|
||||
public static final String PROTOCOL = StandardFileSystems.JRT_PROTOCOL;
|
||||
public static final String PROTOCOL_PREFIX = StandardFileSystems.JRT_PROTOCOL_PREFIX;
|
||||
public static final String SEPARATOR = JarFileSystem.JAR_SEPARATOR;
|
||||
|
||||
private static final boolean SUPPORTED =
|
||||
SystemInfo.isJavaVersionAtLeast("9") || SystemInfo.isJavaVersionAtLeast("1.8") && !SystemInfo.isJavaVersionAtLeast("1.9");
|
||||
|
||||
private static final URI ROOT_URI = URI.create("jrt:/");
|
||||
|
||||
public class JrtFileSystemImpl extends JrtFileSystem {
|
||||
private final Map<String, ArchiveHandler> myHandlers = newTroveMap(FileUtil.PATH_HASHING_STRATEGY);
|
||||
private final AtomicBoolean mySubscribed = new AtomicBoolean(false);
|
||||
|
||||
public JrtFileSystem() {
|
||||
public JrtFileSystemImpl() {
|
||||
scheduleConfiguredSdkCheck();
|
||||
}
|
||||
|
||||
@@ -213,51 +200,4 @@ public class JrtFileSystem extends ArchiveFileSystem {
|
||||
protected boolean isCorrectFileType(@NotNull VirtualFile local) {
|
||||
return isModularJdk(FileUtil.toSystemDependentName(local.getPath()));
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
return SUPPORTED;
|
||||
}
|
||||
|
||||
public static boolean isModularJdk(@NotNull String homePath) {
|
||||
return new File(homePath, "lib/modules").exists() && new File(homePath, "jrt-fs.jar").isFile();
|
||||
}
|
||||
|
||||
public static boolean isRoot(@NotNull VirtualFile file) {
|
||||
return file.getParent() == null && file.getFileSystem() instanceof JrtFileSystem;
|
||||
}
|
||||
|
||||
public static boolean isModuleRoot(@NotNull VirtualFile file) {
|
||||
VirtualFile parent = file.getParent();
|
||||
return parent != null && isRoot(parent);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<String> listModules(@NotNull String path) {
|
||||
try {
|
||||
Path root = getFileSystem(path).getPath("/modules");
|
||||
return Files.list(root).map(p -> p.getFileName().toString()).collect(Collectors.toList());
|
||||
}
|
||||
catch (IOException | InvalidPathException e) {
|
||||
Logger.getInstance(JrtFileSystem.class).warn(path, e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
static FileSystem getFileSystem(String path) throws IOException {
|
||||
try {
|
||||
if (SystemInfo.isJavaVersionAtLeast("9")) {
|
||||
return FileSystems.newFileSystem(ROOT_URI, Collections.singletonMap("java.home", path));
|
||||
}
|
||||
else {
|
||||
File file = new File(path, "jrt-fs.jar");
|
||||
if (!file.exists()) throw new IOException("Missing provider: " + file);
|
||||
URL url = file.toURI().toURL();
|
||||
ClassLoader loader = new URLClassLoader(new URL[]{url}, null);
|
||||
return FileSystems.newFileSystem(ROOT_URI, Collections.emptyMap(), loader);
|
||||
}
|
||||
}
|
||||
catch (Error e) {
|
||||
throw new IOException("Error mounting JRT filesystem at " + path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,20 +15,27 @@
|
||||
*/
|
||||
package com.intellij.openapi.vfs.impl.jrt;
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.vfs.impl.ArchiveHandler;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
class JrtHandler extends ArchiveHandler {
|
||||
private static final URI ROOT_URI = URI.create("jrt:/");
|
||||
|
||||
private SoftReference<FileSystem> myFileSystem;
|
||||
|
||||
public JrtHandler(@NotNull String path) {
|
||||
@@ -38,8 +45,23 @@ class JrtHandler extends ArchiveHandler {
|
||||
private synchronized FileSystem getFileSystem() throws IOException {
|
||||
FileSystem fs = SoftReference.dereference(myFileSystem);
|
||||
if (fs == null) {
|
||||
fs = JrtFileSystem.getFileSystem(getFile().getPath());
|
||||
myFileSystem = new SoftReference<>(fs);
|
||||
String path = getFile().getPath();
|
||||
try {
|
||||
if (SystemInfo.isJavaVersionAtLeast("9")) {
|
||||
fs = FileSystems.newFileSystem(ROOT_URI, Collections.singletonMap("java.home", path));
|
||||
}
|
||||
else {
|
||||
File file = new File(path, "jrt-fs.jar");
|
||||
if (!file.exists()) throw new IOException("Missing provider: " + file);
|
||||
URL url = file.toURI().toURL();
|
||||
ClassLoader loader = new URLClassLoader(new URL[]{url}, null);
|
||||
fs = FileSystems.newFileSystem(ROOT_URI, Collections.emptyMap(), loader);
|
||||
}
|
||||
myFileSystem = new SoftReference<>(fs);
|
||||
}
|
||||
catch (RuntimeException | Error e) {
|
||||
throw new IOException("Error mounting JRT filesystem at " + path, e);
|
||||
}
|
||||
}
|
||||
return fs;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.intellij.openapi.roots.SourceFolder;
|
||||
import com.intellij.openapi.roots.ui.configuration.SourceRootPresentation;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.impl.jrt.JrtFileSystem;
|
||||
import com.intellij.openapi.vfs.jrt.JrtFileSystem;
|
||||
import com.intellij.openapi.vfs.newvfs.ArchiveFileSystem;
|
||||
import com.intellij.psi.JavaDirectoryService;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
|
||||
Reference in New Issue
Block a user