package net.minecraft.server.packs.linkfs; import com.google.common.base.Splitter; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import java.nio.file.FileStore; import java.nio.file.FileSystem; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.WatchService; import java.nio.file.attribute.UserPrincipalLookupService; import java.nio.file.spi.FileSystemProvider; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.jetbrains.annotations.Nullable; public class LinkFileSystem extends FileSystem { private static final Set VIEWS = Set.of("basic"); public static final String PATH_SEPARATOR = "/"; private static final Splitter PATH_SPLITTER = Splitter.on('/'); private final FileStore store; private final FileSystemProvider provider = new LinkFSProvider(); private final LinkFSPath root; LinkFileSystem(String name, LinkFileSystem.DirectoryEntry root) { this.store = new LinkFSFileStore(name); this.root = buildPath(root, this, "", null); } private static LinkFSPath buildPath(LinkFileSystem.DirectoryEntry directory, LinkFileSystem fileSystem, String name, @Nullable LinkFSPath parent) { Object2ObjectOpenHashMap object2ObjectOpenHashMap = new Object2ObjectOpenHashMap<>(); LinkFSPath linkFSPath = new LinkFSPath(fileSystem, name, parent, new PathContents.DirectoryContents(object2ObjectOpenHashMap)); directory.files .forEach((string, path) -> object2ObjectOpenHashMap.put(string, new LinkFSPath(fileSystem, string, linkFSPath, new PathContents.FileContents(path)))); directory.children.forEach((string, directoryEntry) -> object2ObjectOpenHashMap.put(string, buildPath(directoryEntry, fileSystem, string, linkFSPath))); object2ObjectOpenHashMap.trim(); return linkFSPath; } public FileSystemProvider provider() { return this.provider; } public void close() { } public boolean isOpen() { return true; } public boolean isReadOnly() { return true; } public String getSeparator() { return "/"; } public Iterable getRootDirectories() { return List.of(this.root); } public Iterable getFileStores() { return List.of(this.store); } public Set supportedFileAttributeViews() { return VIEWS; } public Path getPath(String string, String... strings) { Stream stream = Stream.of(string); if (strings.length > 0) { stream = Stream.concat(stream, Stream.of(strings)); } String string2 = (String)stream.collect(Collectors.joining("/")); if (string2.equals("/")) { return this.root; } else if (string2.startsWith("/")) { LinkFSPath linkFSPath = this.root; for (String string3 : PATH_SPLITTER.split(string2.substring(1))) { if (string3.isEmpty()) { throw new IllegalArgumentException("Empty paths not allowed"); } linkFSPath = linkFSPath.resolveName(string3); } return linkFSPath; } else { LinkFSPath linkFSPath = null; for (String string3 : PATH_SPLITTER.split(string2)) { if (string3.isEmpty()) { throw new IllegalArgumentException("Empty paths not allowed"); } linkFSPath = new LinkFSPath(this, string3, linkFSPath, PathContents.RELATIVE); } if (linkFSPath == null) { throw new IllegalArgumentException("Empty paths not allowed"); } else { return linkFSPath; } } } public PathMatcher getPathMatcher(String string) { throw new UnsupportedOperationException(); } public UserPrincipalLookupService getUserPrincipalLookupService() { throw new UnsupportedOperationException(); } public WatchService newWatchService() { throw new UnsupportedOperationException(); } public FileStore store() { return this.store; } public LinkFSPath rootPath() { return this.root; } public static LinkFileSystem.Builder builder() { return new LinkFileSystem.Builder(); } public static class Builder { private final LinkFileSystem.DirectoryEntry root = new LinkFileSystem.DirectoryEntry(); public LinkFileSystem.Builder put(List pathString, String fileName, Path filePath) { LinkFileSystem.DirectoryEntry directoryEntry = this.root; for (String string : pathString) { directoryEntry = (LinkFileSystem.DirectoryEntry)directoryEntry.children.computeIfAbsent(string, stringx -> new LinkFileSystem.DirectoryEntry()); } directoryEntry.files.put(fileName, filePath); return this; } public LinkFileSystem.Builder put(List pathString, Path filePath) { if (pathString.isEmpty()) { throw new IllegalArgumentException("Path can't be empty"); } else { int i = pathString.size() - 1; return this.put(pathString.subList(0, i), (String)pathString.get(i), filePath); } } public FileSystem build(String name) { return new LinkFileSystem(name, this.root); } } record DirectoryEntry(Map children, Map files) { public DirectoryEntry() { this(new HashMap(), new HashMap()); } } }