| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.fs.shell.find; |
| |
| import java.io.IOException; |
| import java.util.Deque; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import org.apache.hadoop.conf.Configurable; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.FileStatus; |
| import org.apache.hadoop.fs.FileSystem; |
| import org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.fs.shell.PathData; |
| |
| /** |
| * Abstract expression for use in the |
| * {@link org.apache.hadoop.fs.shell.find.Find} command. Provides default |
| * behavior for a no-argument primary expression. |
| */ |
| public abstract class BaseExpression implements Expression, Configurable { |
| private String[] usage = { "Not yet implemented" }; |
| private String[] help = { "Not yet implemented" }; |
| |
| /** Sets the usage text for this {@link Expression} */ |
| protected void setUsage(String[] usage) { |
| this.usage = usage; |
| } |
| |
| /** Sets the help text for this {@link Expression} */ |
| protected void setHelp(String[] help) { |
| this.help = help; |
| } |
| |
| @Override |
| public String[] getUsage() { |
| return this.usage; |
| } |
| |
| @Override |
| public String[] getHelp() { |
| return this.help; |
| } |
| |
| @Override |
| public void setOptions(FindOptions options) throws IOException { |
| this.options = options; |
| for (Expression child : getChildren()) { |
| child.setOptions(options); |
| } |
| } |
| |
| @Override |
| public void prepare() throws IOException { |
| for (Expression child : getChildren()) { |
| child.prepare(); |
| } |
| } |
| |
| @Override |
| public void finish() throws IOException { |
| for (Expression child : getChildren()) { |
| child.finish(); |
| } |
| } |
| |
| /** Options passed in from the {@link Find} command. */ |
| private FindOptions options; |
| |
| /** Hadoop configuration. */ |
| private Configuration conf; |
| |
| /** Arguments for this expression. */ |
| private LinkedList<String> arguments = new LinkedList<String>(); |
| |
| /** Children of this expression. */ |
| private LinkedList<Expression> children = new LinkedList<Expression>(); |
| |
| /** Return the options to be used by this expression. */ |
| protected FindOptions getOptions() { |
| return (this.options == null) ? new FindOptions() : this.options; |
| } |
| |
| @Override |
| public void setConf(Configuration conf) { |
| this.conf = conf; |
| } |
| |
| @Override |
| public Configuration getConf() { |
| return this.conf; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(getClass().getSimpleName()); |
| sb.append("("); |
| boolean firstArg = true; |
| for (String arg : getArguments()) { |
| if (!firstArg) { |
| sb.append(","); |
| } else { |
| firstArg = false; |
| } |
| sb.append(arg); |
| } |
| sb.append(";"); |
| firstArg = true; |
| for (Expression child : getChildren()) { |
| if (!firstArg) { |
| sb.append(","); |
| } else { |
| firstArg = false; |
| } |
| sb.append(child.toString()); |
| } |
| sb.append(")"); |
| return sb.toString(); |
| } |
| |
| @Override |
| public boolean isAction() { |
| for (Expression child : getChildren()) { |
| if (child.isAction()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean isOperator() { |
| return false; |
| } |
| |
| /** |
| * Returns the arguments of this expression |
| * |
| * @return list of argument strings |
| */ |
| protected List<String> getArguments() { |
| return this.arguments; |
| } |
| |
| /** |
| * Returns the argument at the given position (starting from 1). |
| * |
| * @param position |
| * argument to be returned |
| * @return requested argument |
| * @throws IOException |
| * if the argument doesn't exist or is null |
| */ |
| protected String getArgument(int position) throws IOException { |
| if (position > this.arguments.size()) { |
| throw new IOException("Missing argument at " + position); |
| } |
| String argument = this.arguments.get(position - 1); |
| if (argument == null) { |
| throw new IOException("Null argument at position " + position); |
| } |
| return argument; |
| } |
| |
| /** |
| * Returns the children of this expression. |
| * |
| * @return list of child expressions |
| */ |
| protected List<Expression> getChildren() { |
| return this.children; |
| } |
| |
| @Override |
| public int getPrecedence() { |
| return 0; |
| } |
| |
| @Override |
| public void addChildren(Deque<Expression> exprs) { |
| // no children by default, will be overridden by specific expressions. |
| } |
| |
| /** |
| * Add a specific number of children to this expression. The children are |
| * popped off the head of the expressions. |
| * |
| * @param exprs |
| * deque of expressions from which to take the children |
| * @param count |
| * number of children to be added |
| */ |
| protected void addChildren(Deque<Expression> exprs, int count) { |
| for (int i = 0; i < count; i++) { |
| addChild(exprs.pop()); |
| } |
| } |
| |
| /** |
| * Add a single argument to this expression. The argument is popped off the |
| * head of the expressions. |
| * |
| * @param expr |
| * child to add to the expression |
| */ |
| private void addChild(Expression expr) { |
| children.push(expr); |
| } |
| |
| @Override |
| public void addArguments(Deque<String> args) { |
| // no children by default, will be overridden by specific expressions. |
| } |
| |
| /** |
| * Add a specific number of arguments to this expression. The children are |
| * popped off the head of the expressions. |
| * |
| * @param args |
| * deque of arguments from which to take the argument |
| * @param count |
| * number of children to be added |
| */ |
| protected void addArguments(Deque<String> args, int count) { |
| for (int i = 0; i < count; i++) { |
| addArgument(args.pop()); |
| } |
| } |
| |
| /** |
| * Add a single argument to this expression. The argument is popped off the |
| * head of the expressions. |
| * |
| * @param arg |
| * argument to add to the expression |
| */ |
| protected void addArgument(String arg) { |
| arguments.add(arg); |
| } |
| |
| /** |
| * Returns the {@link FileStatus} from the {@link PathData} item. If the |
| * current options require links to be followed then the returned file status |
| * is that of the linked file. |
| * |
| * @param item |
| * PathData |
| * @param depth |
| * current depth in the process directories |
| * @return FileStatus |
| */ |
| protected FileStatus getFileStatus(PathData item, int depth) |
| throws IOException { |
| FileStatus fileStatus = item.stat; |
| if (fileStatus.isSymlink()) { |
| if (options.isFollowLink() || (options.isFollowArgLink() && |
| (depth == 0))) { |
| Path linkedFile = item.fs.resolvePath(fileStatus.getSymlink()); |
| fileStatus = getFileSystem(item).getFileStatus(linkedFile); |
| } |
| } |
| return fileStatus; |
| } |
| |
| /** |
| * Returns the {@link Path} from the {@link PathData} item. |
| * |
| * @param item |
| * PathData |
| * @return Path |
| */ |
| protected Path getPath(PathData item) throws IOException { |
| return item.path; |
| } |
| |
| /** |
| * Returns the {@link FileSystem} associated with the {@link PathData} item. |
| * |
| * @param item PathData |
| * @return FileSystem |
| */ |
| protected FileSystem getFileSystem(PathData item) throws IOException { |
| return item.fs; |
| } |
| } |