172 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| 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<String> 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<String, LinkFSPath> 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<Path> getRootDirectories() {
 | |
| 		return List.of(this.root);
 | |
| 	}
 | |
| 
 | |
| 	public Iterable<FileStore> getFileStores() {
 | |
| 		return List.of(this.store);
 | |
| 	}
 | |
| 
 | |
| 	public Set<String> supportedFileAttributeViews() {
 | |
| 		return VIEWS;
 | |
| 	}
 | |
| 
 | |
| 	public Path getPath(String string, String... strings) {
 | |
| 		Stream<String> 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<String> 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<String> 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<String, LinkFileSystem.DirectoryEntry> children, Map<String, Path> files) {
 | |
| 
 | |
| 		public DirectoryEntry() {
 | |
| 			this(new HashMap(), new HashMap());
 | |
| 		}
 | |
| 	}
 | |
| }
 |