/** * Returns a new PathData with the given extension. * @param extension for the suffix * @return PathData * @throws IOException shouldn't happen */ public PathData suffix(String extension) throws IOException { return new PathData(fs, this+extension); }
@Override protected List<PathData> expandArgument(String arg) throws IOException { List<PathData> items = new LinkedList<PathData>(); items.add(new PathData(arg, getConf())); return items; }
@Override protected List<PathData> expandArgument(String arg) throws IOException { List<PathData> items = new LinkedList<PathData>(); items.add(new PathData(arg, getConf())); return items; }
@Override public PathData next() throws IOException { FileStatus file = stats.next(); String child = getStringForChildPath(file.getPath()); return new PathData(fs, child, file); } };
@Override protected List<PathData> expandArgument(String arg) throws IOException { List<PathData> items = new LinkedList<PathData>(); try { items.add(new PathData(new URI(arg), getConf())); } catch (URISyntaxException e) { if (Path.WINDOWS) { // Unlike URI, PathData knows how to parse Windows drive-letter paths. items.add(new PathData(arg, getConf())); } else { throw new IOException("unexpected URISyntaxException", e); } } return items; }
/** * The last arg is expected to be a local path, if only one argument is * given then the destination will be the current directory * @param args is the list of arguments */ protected void getLocalDestination(LinkedList<String> args) throws IOException { String pathString = (args.size() < 2) ? Path.CUR_DIR : args.removeLast(); try { dst = new PathData(new URI(pathString), getConf()); } catch (URISyntaxException e) { if (Path.WINDOWS) { // Unlike URI, PathData knows how to parse Windows drive-letter paths. dst = new PathData(pathString, getConf()); } else { throw new IOException("unexpected URISyntaxException", e); } } }
@Override protected List<PathData> expandArgument(String arg) throws IOException { List<PathData> items = new LinkedList<PathData>(); if (arg.equals("-")) { readStdin = true; } else { try { items.add(new PathData(new URI(arg), getConf())); } catch (URISyntaxException e) { if (Path.WINDOWS) { // Unlike URI, PathData knows how to parse Windows drive-letter paths. items.add(new PathData(arg, getConf())); } else { throw new IOException("Unexpected URISyntaxException: " + e.toString()); } } } return items; }
/** * Returns a list of PathData objects of the items contained in the given * directory. * @return list of PathData objects for its children * @throws IOException if anything else goes wrong... */ public PathData[] getDirectoryContents() throws IOException { checkIfExists(FileTypeRequirement.SHOULD_BE_DIRECTORY); FileStatus[] stats = fs.listStatus(path); PathData[] items = new PathData[stats.length]; for (int i=0; i < stats.length; i++) { // preserve relative paths String child = getStringForChildPath(stats[i].getPath()); items[i] = new PathData(fs, child, stats[i]); } Arrays.sort(items); return items; }
/** * Creates a new object for a child entry in this directory * @param child the basename will be appended to this object's path * @return PathData for the child * @throws IOException if this object does not exist or is not a directory */ public PathData getPathDataForChild(PathData child) throws IOException { checkIfExists(FileTypeRequirement.SHOULD_BE_DIRECTORY); return new PathData(fs, getStringForChildPath(child.path)); }
@Override protected void processOptions(LinkedList<String> args) throws IOException { try { CommandFormat cf = new CommandFormat(2, Integer.MAX_VALUE, "nl", "skip-empty-file"); cf.parse(args); delimiter = cf.getOpt("nl") ? "\n" : null; skipEmptyFileDelimiter = cf.getOpt("skip-empty-file"); dst = new PathData(new URI(args.removeLast()), getConf()); if (dst.exists && dst.stat.isDirectory()) { throw new PathIsDirectoryException(dst.toString()); } srcs = new LinkedList<PathData>(); } catch (URISyntaxException e) { throw new IOException("unexpected URISyntaxException", e); } }
/** * The last arg is expected to be a remote path, if only one argument is * given then the destination will be the remote user's directory * @param args is the list of arguments * @throws PathIOException if path doesn't exist or matches too many times */ protected void getRemoteDestination(LinkedList<String> args) throws IOException { if (args.size() < 2) { dst = new PathData(Path.CUR_DIR, getConf()); } else { String pathString = args.removeLast(); // if the path is a glob, then it must match one and only one path PathData[] items = PathData.expandAsGlob(pathString, getConf()); switch (items.length) { case 0: throw new PathNotFoundException(pathString); case 1: dst = items[0]; break; default: throw new PathIOException(pathString, "Too many matches"); } } }
@Override protected boolean isPathRecursable(PathData item) throws IOException { if (item.stat.isDirectory()) { return true; } if (item.stat.isSymlink()) { PathData linkedItem = new PathData(item.fs.resolvePath(item.stat.getSymlink()).toString(), getConf()); if (linkedItem.stat.isDirectory()) { if (getOptions().isFollowLink()) { return true; } if (getOptions().isFollowArgLink() && (getDepth() == 0)) { return true; } } } return false; }
@Override protected void recursePath(PathData item) throws IOException { if (isStop(item)) { // this item returned a stop result so don't recurse any further return; } if (getDepth() >= getOptions().getMaxDepth()) { // reached the maximum depth so don't got any further. return; } if (item.stat.isSymlink() && getOptions().isFollowLink()) { PathData linkedItem = new PathData(item.stat.getSymlink().toString(), getConf()); if (isAncestor(item, linkedItem)) { getOptions().getErr().println( "Infinite loop ignored: " + item.toString() + " -> " + linkedItem.toString()); return; } if (linkedItem.exists) { item = linkedItem; } } if (item.stat.isDirectory()) { super.recursePath(item); } }
/** * Returns a new PathData with the given extension. * @param extension for the suffix * @return PathData * @throws IOException shouldn't happen */ public PathData suffix(String extension) throws IOException { return new PathData(fs, this+extension); }
/** * Creates a new object for a child entry in this directory * @param child the basename will be appended to this object's path * @return PathData for the child * @throws IOException if this object does not exist or is not a directory */ public PathData getPathDataForChild(PathData child) throws IOException { checkIfExists(FileTypeRequirement.SHOULD_BE_DIRECTORY); return new PathData(fs, getStringForChildPath(child.path)); }
@Test (timeout = 30000) public void testWithDirStringAndConf() throws Exception { String dirString = "d1"; PathData item = new PathData(dirString, conf); checkPathData(dirString, item); // properly implementing symlink support in various commands will require // trailing slashes to be retained dirString = "d1/"; item = new PathData(dirString, conf); checkPathData(dirString, item); }
@Before public void resetMock() throws IOException { reset(mockFs); target = new PathData(path.toString(), conf); cmd = new CopyCommands.Put(); cmd.setConf(conf); }
@Test public void applyNotMatch() throws IOException { setup("name"); PathData item = new PathData("/directory/path/notname", mockFs.getConf()); assertEquals(Result.FAIL, name.apply(item, -1)); }
@Test public void applyGlobNotMatch() throws IOException { setup("n*e"); PathData item = new PathData("/directory/path/notmatch", mockFs.getConf()); assertEquals(Result.FAIL, name.apply(item, -1)); } }