| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| part of file.src.backends.chroot; |
| |
| abstract class _ChrootFileSystemEntity<T extends FileSystemEntity, |
| D extends io.FileSystemEntity> extends ForwardingFileSystemEntity<T, D> { |
| @override |
| final ChrootFileSystem fileSystem; |
| |
| @override |
| final String path; |
| |
| _ChrootFileSystemEntity(this.fileSystem, this.path); |
| |
| @override |
| String get dirname => fileSystem.path.dirname(path); |
| |
| @override |
| String get basename => fileSystem.path.basename(path); |
| |
| @override |
| D get delegate => getDelegate(); |
| |
| /// Gets the delegate file system entity in the underlying file system that |
| /// corresponds to this entity's local file system path. |
| /// |
| /// If [followLinks] is true and this entity's path references a symbolic |
| /// link, then the path of the delegate entity will reference the ultimate |
| /// target of that symbolic link. Symbolic links in the middle of the path |
| /// will always be resolved in the delegate entity's path. |
| D getDelegate({bool followLinks: false}) => |
| _rawDelegate(fileSystem._real(path, followLinks: followLinks)); |
| |
| /// Returns the expected type of this entity, which may differ from the type |
| /// of the entity that's found at the path specified by this entity. |
| FileSystemEntityType get expectedType; |
| |
| /// Returns a delegate entity at the specified [realPath] (the path in the |
| /// underlying file system). |
| D _rawDelegate(String realPath); |
| |
| /// Gets the path of this entity as an absolute path (unchanged if the |
| /// entity already specifies an absolute path). |
| String get _absolutePath => fileSystem.path.absolute(path); |
| |
| /// Tells whether this entity's path references a symbolic link. |
| bool get _isLink => |
| fileSystem.typeSync(path, followLinks: false) == |
| FileSystemEntityType.LINK; |
| |
| @override |
| Directory wrapDirectory(io.Directory delegate) => |
| new _ChrootDirectory.wrapped(fileSystem, delegate, relative: !isAbsolute); |
| |
| @override |
| File wrapFile(io.File delegate) => |
| new _ChrootFile.wrapped(fileSystem, delegate, relative: !isAbsolute); |
| |
| @override |
| Link wrapLink(io.Link delegate) => |
| new _ChrootLink.wrapped(fileSystem, delegate, relative: !isAbsolute); |
| |
| @override |
| Uri get uri => new Uri.file(path); |
| |
| @override |
| Future<bool> exists() => getDelegate(followLinks: true).exists(); |
| |
| @override |
| bool existsSync() => getDelegate(followLinks: true).existsSync(); |
| |
| @override |
| Future<String> resolveSymbolicLinks() async => resolveSymbolicLinksSync(); |
| |
| @override |
| String resolveSymbolicLinksSync() => |
| fileSystem._resolve(path, notFound: _NotFoundBehavior.throwError); |
| |
| @override |
| Future<FileStat> stat() { |
| D delegate; |
| try { |
| delegate = getDelegate(followLinks: true); |
| } on FileSystemException { |
| return new Future<FileStat>.value(const _NotFoundFileStat()); |
| } |
| return delegate.stat(); |
| } |
| |
| @override |
| FileStat statSync() { |
| D delegate; |
| try { |
| delegate = getDelegate(followLinks: true); |
| } on FileSystemException { |
| return const _NotFoundFileStat(); |
| } |
| return delegate.statSync(); |
| } |
| |
| @override |
| Future<T> delete({bool recursive: false}) async { |
| String path = fileSystem._resolve(this.path, |
| followLinks: false, notFound: _NotFoundBehavior.throwError); |
| |
| String real(String path) => fileSystem._real(path, resolve: false); |
| Future<FileSystemEntityType> type(String path) => |
| fileSystem.delegate.type(real(path), followLinks: false); |
| |
| if (await type(path) == FileSystemEntityType.LINK) { |
| if (expectedType == FileSystemEntityType.LINK) { |
| await fileSystem.delegate.link(real(path)).delete(); |
| } else { |
| String resolvedPath = fileSystem._resolve(p.basename(path), |
| from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail); |
| if (!recursive && await type(resolvedPath) != expectedType) { |
| throw expectedType == FileSystemEntityType.FILE |
| ? common.isADirectory(path) |
| : common.notADirectory(path); |
| } |
| await fileSystem.delegate.link(real(path)).delete(); |
| } |
| return this as T; |
| } else { |
| return wrap( |
| await _rawDelegate(real(path)).delete(recursive: recursive) as D); |
| } |
| } |
| |
| @override |
| void deleteSync({bool recursive: false}) { |
| String path = fileSystem._resolve(this.path, |
| followLinks: false, notFound: _NotFoundBehavior.throwError); |
| |
| String real(String path) => fileSystem._real(path, resolve: false); |
| FileSystemEntityType type(String path) => |
| fileSystem.delegate.typeSync(real(path), followLinks: false); |
| |
| if (type(path) == FileSystemEntityType.LINK) { |
| if (expectedType == FileSystemEntityType.LINK) { |
| fileSystem.delegate.link(real(path)).deleteSync(); |
| } else { |
| String resolvedPath = fileSystem._resolve(p.basename(path), |
| from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail); |
| if (!recursive && type(resolvedPath) != expectedType) { |
| throw expectedType == FileSystemEntityType.FILE |
| ? common.isADirectory(path) |
| : common.notADirectory(path); |
| } |
| fileSystem.delegate.link(real(path)).deleteSync(); |
| } |
| } else { |
| _rawDelegate(real(path)).deleteSync(recursive: recursive); |
| } |
| } |
| |
| @override |
| Stream<FileSystemEvent> watch({ |
| int events: FileSystemEvent.ALL, |
| bool recursive: false, |
| }) => |
| throw new UnsupportedError('watch is not supported on ChrootFileSystem'); |
| |
| @override |
| bool get isAbsolute => fileSystem.path.isAbsolute(path); |
| } |