@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); } }
private void applyItem(PathData item) throws IOException { if (getDepth() >= getOptions().getMinDepth()) { Result result = getRootExpression().apply(item, getDepth()); if (Result.STOP.equals(result)) { addStop(item); } } }
getOptions().setFollowLink(true); } else if (cf.getOpt(OPTION_FOLLOW_ARG_LINK)) { getOptions().setFollowArgLink(true); Expression expression = parseExpression(expressionArgs); if (!expression.isAction()) { Expression and = getExpression(And.class); Deque<Expression> children = new LinkedList<Expression>(); children.add(getExpression(Print.class)); children.add(expression); and.addChildren(children); setRootExpression(expression);
@Override protected void processPath(PathData item) throws IOException { if (getOptions().isDepthFirst()) { // depth first so leave until post processing return; } applyItem(item); }
@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; }
LinkedList<PathData> items = createDirectories(); Find find = new Find(); find.getOptions().setDepthFirst(true); find.getOptions().setMinDepth(1); find.setConf(conf); PrintStream out = mock(PrintStream.class); find.getOptions().setOut(out); PrintStream err = mock(PrintStream.class); find.getOptions().setErr(err); Expression expr = mock(Expression.class); when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS); FileStatusChecker fsCheck = mock(FileStatusChecker.class); Expression test = new TestExpression(expr, fsCheck); find.setRootExpression(test); find.processArguments(items); inOrder.verify(expr).setOptions(find.getOptions()); inOrder.verify(expr).prepare(); inOrder.verify(expr).apply(item1aa, 2);
@Test public void processOptionsNoExpression() throws IOException { Find find = new Find(); find.setConf(conf); String args = "path"; String expected = "Print(;)"; find.processOptions(getArgs(args)); Expression expression = find.getRootExpression(); assertEquals(expected, expression.toString()); }
Deque<Expression> primaries = new LinkedList<Expression>(); Deque<Expression> operators = new LinkedList<Expression>(); Expression prevExpr = getExpression(And.class); while (!args.isEmpty()) { String arg = args.pop(); if ("(".equals(arg)) { Expression expr = parseExpression(args); primaries.add(expr); prevExpr = new BaseExpression() { } else if (isExpression(arg)) { Expression expr = getExpression(arg); expr.addArguments(args); if (expr.isOperator()) { } else { if (!prevExpr.isOperator()) { Expression and = getExpression(And.class); while (!operators.isEmpty()) { if (operators.peek().getPrecedence() >= and.getPrecedence()) { return primaries.isEmpty() ? getExpression(Print.class) : primaries.pop();
@Override protected void processArguments(LinkedList<PathData> args) throws IOException { Expression expr = getRootExpression(); expr.setOptions(getOptions()); expr.prepare(); super.processArguments(args); expr.finish(); }
@Test public void processOptionsFollowLink() throws IOException { Find find = new Find(); String args = "-L path"; find.processOptions(getArgs(args)); assertTrue(find.getOptions().isFollowLink()); assertFalse(find.getOptions().isFollowArgLink()); }
/** Create a new set of find options. */ private FindOptions createOptions() { FindOptions options = new FindOptions(); options.setOut(out); options.setErr(err); options.setIn(System.in); options.setCommandFactory(getCommandFactory()); options.setConfiguration(getConf()); return options; }
/** Gets an instance of an expression from the factory. */ private Expression getExpression( Class<? extends Expression> expressionClass) { return ExpressionFactory.getExpressionFactory().createExpression( expressionClass, getConf()); }
/** Returns the current find options, creating them if necessary. */ @InterfaceAudience.Private FindOptions getOptions() { if (options == null) { options = createOptions(); } return options; }
LinkedList<PathData> items = createDirectories(); Find find = new Find(); find.getOptions().setDepthFirst(true); find.getOptions().setMinDepth(1); find.setConf(conf); PrintStream out = mock(PrintStream.class); find.getOptions().setOut(out); PrintStream err = mock(PrintStream.class); find.getOptions().setErr(err); Expression expr = mock(Expression.class); when(expr.apply((PathData) any(), anyInt())).thenReturn(Result.PASS); FileStatusChecker fsCheck = mock(FileStatusChecker.class); Expression test = new TestExpression(expr, fsCheck); find.setRootExpression(test); find.processArguments(items); inOrder.verify(expr).setOptions(find.getOptions()); inOrder.verify(expr).prepare(); inOrder.verify(expr).apply(item1aa, 2);
@Test public void processOptionsNoop() throws IOException { Find find = new Find(); find.setConf(conf); String args = "path -name one -name two -print"; String expected = "And(;And(;Name(one;),Name(two;)),Print(;))"; find.processOptions(getArgs(args)); Expression expression = find.getRootExpression(); assertEquals(expected, expression.toString()); }
@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 postProcessPath(PathData item) throws IOException { if (!getOptions().isDepthFirst()) { // not depth first so already processed return; } applyItem(item); }
Deque<Expression> primaries = new LinkedList<Expression>(); Deque<Expression> operators = new LinkedList<Expression>(); Expression prevExpr = getExpression(And.class); while (!args.isEmpty()) { String arg = args.pop(); if ("(".equals(arg)) { Expression expr = parseExpression(args); primaries.add(expr); prevExpr = new BaseExpression() { } else if (isExpression(arg)) { Expression expr = getExpression(arg); expr.addArguments(args); if (expr.isOperator()) { } else { if (!prevExpr.isOperator()) { Expression and = getExpression(And.class); while (!operators.isEmpty()) { if (operators.peek().getPrecedence() >= and.getPrecedence()) { return primaries.isEmpty() ? getExpression(Print.class) : primaries.pop();
@Override protected void processArguments(LinkedList<PathData> args) throws IOException { Expression expr = getRootExpression(); expr.setOptions(getOptions()); expr.prepare(); super.processArguments(args); expr.finish(); }
@Test public void processOptionsFollowLink() throws IOException { Find find = new Find(); String args = "-L path"; find.processOptions(getArgs(args)); assertTrue(find.getOptions().isFollowLink()); assertFalse(find.getOptions().isFollowArgLink()); }