/** * Returns the URI for the given path. The given file system URI is the base against which the * path is resolved to create the returned URI. */ public URI toUri(URI fileSystemUri, JimfsPath path) { checkArgument(path.isAbsolute(), "path (%s) must be absolute", path); String root = String.valueOf(path.root()); Iterable<String> names = Iterables.transform(path.names(), Functions.toStringFunction()); return type.toUri(fileSystemUri, root, names, Files.isDirectory(path, NOFOLLOW_LINKS)); }
@Override public JimfsPath resolve(Path other) { JimfsPath otherPath = checkPath(other); if (otherPath == null) { throw new ProviderMismatchException(other.toString()); } if (isEmptyPath() || otherPath.isAbsolute()) { return otherPath; } if (otherPath.isEmptyPath()) { return this; } return pathService.createPath( root, ImmutableList.<Name>builder() .addAll(names) .addAll(otherPath.names) .build()); }
@Override public JimfsPath toAbsolutePath() { return isAbsolute() ? this : getJimfsFileSystem().getWorkingDirectory().resolve(this); }
/** * Returns whether or not this path is in a normalized form. It's normal if it both contains no * "." names and contains no ".." names in a location other than the start of the path. */ private boolean isNormal() { if (getNameCount() == 0 || (getNameCount() == 1 && !isAbsolute())) { return true; } boolean foundNonParentName = isAbsolute(); // if there's a root, the path doesn't start with .. boolean normal = true; for (Name name : names) { if (name.equals(Name.PARENT)) { if (foundNonParentName) { normal = false; break; } } else { if (name.equals(Name.SELF)) { normal = false; break; } foundNonParentName = true; } } return normal; }
@Override public JimfsPath resolveSibling(Path other) { JimfsPath otherPath = checkPath(other); if (otherPath == null) { throw new ProviderMismatchException(other.toString()); } if (otherPath.isAbsolute()) { return otherPath; } JimfsPath parent = getParent(); if (parent == null) { return otherPath; } return parent.resolve(other); }
@Override public JimfsPath normalize() { if (isNormal()) { return this; } Deque<Name> newNames = new ArrayDeque<>(); for (Name name : names) { if (name.equals(Name.PARENT)) { Name lastName = newNames.peekLast(); if (lastName != null && !lastName.equals(Name.PARENT)) { newNames.removeLast(); } else if (!isAbsolute()) { // if there's a root and we have an extra ".." that would go up above the root, ignore it newNames.add(name); } } else if (!name.equals(Name.SELF)) { newNames.add(name); } } return Iterables.elementsEqual(newNames, names) ? this : pathService.createPath(root, newNames); }
@Override public boolean endsWith(Path other) { JimfsPath otherPath = checkPath(other); if (otherPath == null) { return false; } if (otherPath.isAbsolute()) { return compareTo(otherPath) == 0; } return startsWith(names.reverse(), otherPath.names.reverse()); }
@Nullable private DirectoryEntry lookUp( File dir, JimfsPath path, Set<? super LinkOption> options, int linkDepth) throws IOException { ImmutableList<Name> names = path.names(); if (path.isAbsolute()) { // look up the root directory DirectoryEntry entry = getRoot(path.root()); if (entry == null) { // root not found; always return null as no real parent directory exists // this prevents new roots from being created in file systems supporting multiple roots return null; } else if (names.isEmpty()) { // root found, no more names to look up return entry; } else { // root found, more names to look up; set dir to the root directory for the path dir = entry.file(); } } else if (isEmpty(names)) { // set names to the canonical list of names for an empty path (singleton list of ".") names = EMPTY_PATH_NAMES; } return lookUp(dir, names, options, linkDepth); }
/** * Creates the file store for the file system. */ private static JimfsFileStore createFileStore( Configuration config, PathService pathService, FileSystemState state) { AttributeService attributeService = new AttributeService(config); // TODO(cgdecker): Make disk values configurable HeapDisk disk = new HeapDisk(config); FileFactory fileFactory = new FileFactory(disk); Map<Name, Directory> roots = new HashMap<>(); // create roots for (String root : config.roots) { JimfsPath path = pathService.parsePath(root); if (!path.isAbsolute() && path.getNameCount() == 0) { throw new IllegalArgumentException("Invalid root path: " + root); } Name rootName = path.root(); Directory rootDir = fileFactory.createRootDirectory(rootName); attributeService.setInitialAttributes(rootDir); roots.put(rootName, rootDir); } return new JimfsFileStore( new FileTree(roots), fileFactory, disk, attributeService, config.supportedFeatures, state); }
/** * Returns the URI for the given path. The given file system URI is the base against which the * path is resolved to create the returned URI. */ public URI toUri(URI fileSystemUri, JimfsPath path) { checkArgument(path.isAbsolute(), "path (%s) must be absolute", path); String root = String.valueOf(path.root()); Iterable<String> names = Iterables.transform(path.names(), Functions.toStringFunction()); return type.toUri(fileSystemUri, root, names, Files.isDirectory(path, NOFOLLOW_LINKS)); }
@Override public JimfsPath normalize() { if (isNormal()) { return this; } Deque<Name> newNames = new ArrayDeque<>(); for (Name name : names) { if (name.equals(Name.PARENT)) { Name lastName = newNames.peekLast(); if (lastName != null && !lastName.equals(Name.PARENT)) { newNames.removeLast(); } else if (!isAbsolute()) { // if there's a root and we have an extra ".." that would go up above the root, ignore it newNames.add(name); } } else if (!name.equals(Name.SELF)) { newNames.add(name); } } return newNames.equals(names) ? this : pathService.createPath(root, newNames); }
@Override public JimfsPath resolve(Path other) { JimfsPath otherPath = checkPath(other); if (otherPath == null) { throw new ProviderMismatchException(other.toString()); } if (isEmptyPath() || otherPath.isAbsolute()) { return otherPath; } if (otherPath.isEmptyPath()) { return this; } return pathService.createPath( root, ImmutableList.<Name>builder() .addAll(names) .addAll(otherPath.names) .build()); }
@Override public JimfsPath toAbsolutePath() { return isAbsolute() ? this : getJimfsFileSystem().getWorkingDirectory().resolve(this); }
/** * Returns whether or not this path is in a normalized form. It's normal if it both contains no * "." names and contains no ".." names in a location other than the start of the path. */ private boolean isNormal() { if (getNameCount() == 0 || getNameCount() == 1 && !isAbsolute()) { return true; } boolean foundNonParentName = isAbsolute(); // if there's a root, the path doesn't start with .. boolean normal = true; for (Name name : names) { if (name.equals(Name.PARENT)) { if (foundNonParentName) { normal = false; break; } } else { if (name.equals(Name.SELF)) { normal = false; break; } foundNonParentName = true; } } return normal; }
@Override public JimfsPath resolveSibling(Path other) { JimfsPath otherPath = checkPath(other); if (otherPath == null) { throw new ProviderMismatchException(other.toString()); } if (otherPath.isAbsolute()) { return otherPath; } JimfsPath parent = getParent(); if (parent == null) { return otherPath; } return parent.resolve(other); }
@Override public boolean endsWith(Path other) { JimfsPath otherPath = checkPath(other); if (otherPath == null) { return false; } if (otherPath.isAbsolute()) { return compareTo(otherPath) == 0; } return startsWith(names.reverse(), otherPath.names.reverse()); }
@Nullable private DirectoryEntry lookUp( File dir, JimfsPath path, Set<? super LinkOption> options, int linkDepth) throws IOException { ImmutableList<Name> names = path.names(); if (path.isAbsolute()) { // look up the root directory DirectoryEntry entry = getRoot(path.root()); if (entry == null) { // root not found; always return null as no real parent directory exists // this prevents new roots from being created in file systems supporting multiple roots return null; } else if (names.isEmpty()) { // root found, no more names to look up return entry; } else { // root found, more names to look up; set dir to the root directory for the path dir = entry.file(); } } else if (isEmpty(names)) { // set names to the canonical list of names for an empty path (singleton list of ".") names = EMPTY_PATH_NAMES; } return lookUp(dir, names, options, linkDepth); }
/** * Creates the file store for the file system. */ private static JimfsFileStore createFileStore( Configuration config, PathService pathService, FileSystemState state) { AttributeService attributeService = new AttributeService(config); // TODO(cgdecker): Make disk values configurable HeapDisk disk = new HeapDisk(config); FileFactory fileFactory = new FileFactory(disk); Map<Name, Directory> roots = new HashMap<>(); // create roots for (String root : config.roots) { JimfsPath path = pathService.parsePath(root); if (!path.isAbsolute() && path.getNameCount() == 0) { throw new IllegalArgumentException("Invalid root path: " + root); } Name rootName = path.root(); Directory rootDir = fileFactory.createRootDirectory(rootName); attributeService.setInitialAttributes(rootDir); roots.put(rootName, rootDir); } return new JimfsFileStore( new FileTree(roots), fileFactory, disk, attributeService, config.supportedFeatures, state); }