diff --git a/java/java-impl/src/com/intellij/openapi/vfs/impl/jrt/JrtFileSystem.java b/java/java-impl/src/com/intellij/openapi/vfs/impl/jrt/JrtFileSystem.java index 37af0d931e44..320bc1e95701 100644 --- a/java/java-impl/src/com/intellij/openapi/vfs/impl/jrt/JrtFileSystem.java +++ b/java/java-impl/src/com/intellij/openapi/vfs/impl/jrt/JrtFileSystem.java @@ -38,6 +38,7 @@ import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.List; @@ -86,6 +87,13 @@ public class JrtFileSystem extends ArchiveFileSystem { return PROTOCOL; } + @Nullable + @Override + protected String normalize(@NotNull String path) { + int p = path.indexOf(SEPARATOR); + return p > 0 ? FileUtil.normalize(path.substring(0, p)) + path.substring(p) : super.normalize(path); + } + @NotNull @Override protected String extractLocalPath(@NotNull String rootPath) { @@ -111,7 +119,7 @@ public class JrtFileSystem extends ArchiveFileSystem { protected ArchiveHandler getHandler(@NotNull VirtualFile entryFile) { checkSubscription(); - String homePath = FileUtil.toSystemIndependentName(extractLocalPath(extractRootPath(entryFile.getPath()))); + String homePath = extractLocalPath(extractRootPath(entryFile.getPath())); ArchiveHandler handler = myHandlers.get(homePath); if (handler == null) { handler = isSupported() ? new JrtHandler(homePath) : new JrtHandlerStub(homePath); @@ -180,6 +188,11 @@ public class JrtFileSystem extends ArchiveFileSystem { VfsImplUtil.refresh(this, asynchronous); } + @Override + protected boolean isCorrectFileType(@NotNull VirtualFile local) { + return isModularJdk(FileUtil.toSystemDependentName(local.getPath())); + } + public static boolean isSupported() { return SUPPORTED; } diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/ArchiveFileSystem.java b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/ArchiveFileSystem.java index 8efb4489ddd8..74e759a6bec2 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/ArchiveFileSystem.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/ArchiveFileSystem.java @@ -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. @@ -15,14 +15,13 @@ */ package com.intellij.openapi.vfs.newvfs; +import com.intellij.openapi.fileTypes.FileTypeRegistry; +import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream; import com.intellij.openapi.util.io.FileAttributes; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsBundle; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.impl.ArchiveHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -73,8 +72,8 @@ public abstract class ArchiveFileSystem extends NewVirtualFileSystem { VirtualFile local = LOCAL_FILE.get(root); if (local == null) { - String localPath = extractLocalPath(extractRootPath(entry.getPath())); - local = LocalFileSystem.getInstance().findFileByPath(localPath); + String localPath = extractLocalPath(root.getPath()); + local = StandardFileSystems.local().findFileByPath(localPath); if (local != null) LOCAL_FILE.set(root, local); } return local; @@ -229,4 +228,25 @@ public abstract class ArchiveFileSystem extends NewVirtualFileSystem { public OutputStream getOutputStream(@NotNull VirtualFile file, Object requestor, long modStamp, long timeStamp) throws IOException { throw new IOException(VfsBundle.message("jar.modification.not.supported.error", file.getUrl())); } -} + + // service methods + + /** + * Returns a local file of an archive which hosts a root with the given path + * (i.e.: "jar:///path/to/jar.jar!/" => file:///path/to/jar.jar), + * or null if the local file is of incorrect type. + */ + @Nullable + public VirtualFile findLocalByRootPath(@NotNull String rootPath) { + String localPath = extractLocalPath(rootPath); + VirtualFile local = StandardFileSystems.local().findFileByPath(localPath); + return local != null && isCorrectFileType(local) ? local : null; + } + + /** + * Implementations should return {@code false} if the given file may not host this file system. + */ + protected boolean isCorrectFileType(@NotNull VirtualFile local) { + return FileTypeRegistry.getInstance().getFileTypeByFileName(local.getName()) == FileTypes.ARCHIVE; + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index d24660c5b48a..a7182e0a73a9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -20,9 +20,6 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.FileTypeRegistry; -import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.LowMemoryWatcher; import com.intellij.openapi.util.ShutDownTracker; @@ -861,7 +858,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone @Override @Nullable - public VirtualFileSystemEntry findRoot(@NotNull String basePath, @NotNull NewVirtualFileSystem fs) { + public VirtualFileSystemEntry findRoot(@NotNull final String basePath, @NotNull NewVirtualFileSystem fs) { if (basePath.isEmpty()) { LOG.error("Invalid root, fs=" + fs); return null; @@ -872,30 +869,21 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone VirtualFileSystemEntry root = myRoots.get(rootUrl); if (root != null) return root; - final VirtualFileSystemEntry newRoot; - String rootPathBeforeSplash; String rootName; - - if (fs instanceof JarFileSystem) { - String parentPath = basePath.substring(0, basePath.indexOf(JarFileSystem.JAR_SEPARATOR)); - VirtualFile parentFile = LocalFileSystem.getInstance().findFileByPath(parentPath); - if (parentFile == null) return null; - FileType type = FileTypeRegistry.getInstance().getFileTypeByFileName(parentFile.getName()); - if (type != FileTypes.ARCHIVE) return null; - rootName = parentFile.getName(); - rootPathBeforeSplash = parentFile.getPath() + "!"; + if (fs instanceof ArchiveFileSystem) { + VirtualFile localFile = ((ArchiveFileSystem)fs).findLocalByRootPath(basePath); + if (localFile == null) return null; + rootName = localFile.getName(); } else { rootName = basePath; - rootPathBeforeSplash = StringUtil.trimEnd(basePath, "/"); } - final String finalRootPathBeforeSplash = rootPathBeforeSplash; FileAttributes attributes = fs.getAttributes(new StubVirtualFile() { @NotNull @Override public String getPath() { - return finalRootPathBeforeSplash + "/"; + return basePath; } @Nullable @@ -912,7 +900,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone VfsData.Segment segment = VfsData.getSegment(rootId, true); VfsData.DirectoryData directoryData = new VfsData.DirectoryData(); - newRoot = new FsRoot(rootId, segment, directoryData, fs, rootName, rootPathBeforeSplash); + VirtualFileSystemEntry newRoot = new FsRoot(rootId, segment, directoryData, fs, rootName, StringUtil.trimEnd(basePath, "/")); boolean mark; synchronized (myRoots) { @@ -1312,7 +1300,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone @NotNull @Override public String getPath() { - return myPathBeforeSlash + "/"; + return myPathBeforeSlash + '/'; } @NotNull @@ -1321,5 +1309,4 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone return getFileSystem().getProtocol() + "://" + getPath(); } } - -} +} \ No newline at end of file