/** * Compute the correct {@link OwnerAndPermission} obtained from replicating source owner and permissions and applying * the {@link PreserveAttributes} rules for fromPath and every ancestor up to but excluding toPath. * * @return A list of the computed {@link OwnerAndPermission}s starting from fromPath, up to but excluding toPath. * @throws IOException if toPath is not an ancestor of fromPath. */ public static List<OwnerAndPermission> resolveReplicatedOwnerAndPermissionsRecursively(FileSystem sourceFs, Path fromPath, Path toPath, CopyConfiguration copyConfiguration) throws IOException { if (!PathUtils.isAncestor(toPath, fromPath)) { throw new IOException(String.format("toPath %s must be an ancestor of fromPath %s.", toPath, fromPath)); } List<OwnerAndPermission> ownerAndPermissions = Lists.newArrayList(); Path currentPath = fromPath; while (PathUtils.isAncestor(toPath, currentPath.getParent())) { ownerAndPermissions.add(resolveReplicatedOwnerAndPermission(sourceFs, currentPath, copyConfiguration)); currentPath = currentPath.getParent(); } return ownerAndPermissions; }
protected static Path replacedPrefix(Path sourcePath, Path prefixTobeReplaced, Path prefixReplacement) { Path sourcePathWithoutSchemeAndAuthority = PathUtils.getPathWithoutSchemeAndAuthority(sourcePath); Preconditions.checkArgument(PathUtils.isAncestor(prefixTobeReplaced, sourcePathWithoutSchemeAndAuthority), "When replacing prefix, all locations must be descendants of the prefix. " + "The prefix: %s, file location: %s.", prefixTobeReplaced, sourcePathWithoutSchemeAndAuthority); Path relativePath = PathUtils.relativizePath(sourcePathWithoutSchemeAndAuthority, prefixTobeReplaced); Path result = new Path(prefixReplacement, relativePath); return result; }
/** * Load at most one *.properties files from path and each ancestor of path up to and including {@link #rootDirectory}. * Higher directories will serve as fallback for lower directories, and sysProps will serve as fallback for all of them. * @throws IOException */ private Config loadAncestorGlobalConfigs(Path path, Config sysProps) throws IOException { Config config = sysProps; if (!PathUtils.isAncestor(this.rootDirectory, path)) { log.warn(String.format("Loaded path %s is not a descendant of root path %s. Cannot load global properties.", path, this.rootDirectory)); } else { List<Path> ancestorPaths = Lists.newArrayList(); while (PathUtils.isAncestor(this.rootDirectory, path)) { ancestorPaths.add(path); path = path.getParent(); } List<Path> reversedAncestors = Lists.reverse(ancestorPaths); for (Path ancestor : reversedAncestors) { config = findAndLoadGlobalConfigInDirectory(ancestor, config); } } return config; }
/** * Find and load all pull files under a base {@link Path} recursively. * @param path base {@link Path} where pull files should be found recursively. * @param sysProps A {@link Config} used as fallback. * @param loadGlobalProperties if true, will also load at most one *.properties file per directory from the * {@link #rootDirectory} to the pull file {@link Path} for each pull file. * @return The loaded {@link Config}s. */ public Collection<Config> loadPullFilesRecursively(Path path, Config sysProps, boolean loadGlobalProperties) { try { Config fallback = sysProps; if (loadGlobalProperties && PathUtils.isAncestor(this.rootDirectory, path.getParent())) { fallback = loadAncestorGlobalConfigs(path.getParent(), fallback); } return loadPullFilesRecursivelyHelper(path, fallback, loadGlobalProperties); } catch (IOException ioe) { return Lists.newArrayList(); } }
if (PathUtils.isAncestor(datasetCommonRoot, new Path(u.getPath()))) { URI floor = uriSet.floor(u); if (floor != null && PathUtils.isAncestor(new Path(floor.getPath()), new Path(u.getPath()))) { noneLeaf.add(floor);
/** * Deletes empty directories starting with startPath and all ancestors up to but not including limitPath. * @param fs {@link FileSystem} where paths are located. * @param limitPath only {@link Path}s that are strict descendants of this path will be deleted. * @param startPath first {@link Path} to delete. Afterwards empty ancestors will be deleted. * @throws IOException */ public static void deleteEmptyParentDirectories(FileSystem fs, Path limitPath, Path startPath) throws IOException { if (PathUtils.isAncestor(limitPath, startPath) && !PathUtils.getPathWithoutSchemeAndAuthority(limitPath) .equals(PathUtils.getPathWithoutSchemeAndAuthority(startPath)) && fs.listStatus(startPath).length == 0) { if (!fs.delete(startPath, false)) { log.warn("Failed to delete empty directory " + startPath); } else { log.info("Deleted empty directory " + startPath); } deleteEmptyParentDirectories(fs, limitPath, startPath.getParent()); } }
Preconditions.checkArgument(this.dataset.getTableRootPath().isPresent(), "Cannot move paths to a new root unless table has exactly one location."); Preconditions.checkArgument(PathUtils.isAncestor(this.dataset.getTableRootPath().get(), sourcePath), "When moving paths to a new root, all locations must be descendants of the table root location. " + "Table root location: %s, file location: %s.", this.dataset.getTableRootPath(), sourcePath);