001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.hadoop.util;
019
020 import java.io.IOException;
021 import java.io.PrintStream;
022
023 import org.apache.hadoop.classification.InterfaceAudience;
024 import org.apache.hadoop.classification.InterfaceStability;
025 import org.apache.hadoop.conf.Configuration;
026
027 /**
028 * A utility to help run {@link Tool}s.
029 *
030 * <p><code>ToolRunner</code> can be used to run classes implementing
031 * <code>Tool</code> interface. It works in conjunction with
032 * {@link GenericOptionsParser} to parse the
033 * <a href="{@docRoot}/../hadoop-project-dist/hadoop-common/CommandsManual.html#Generic_Options">
034 * generic hadoop command line arguments</a> and modifies the
035 * <code>Configuration</code> of the <code>Tool</code>. The
036 * application-specific options are passed along without being modified.
037 * </p>
038 *
039 * @see Tool
040 * @see GenericOptionsParser
041 */
042 @InterfaceAudience.Public
043 @InterfaceStability.Stable
044 public class ToolRunner {
045
046 /**
047 * Runs the given <code>Tool</code> by {@link Tool#run(String[])}, after
048 * parsing with the given generic arguments. Uses the given
049 * <code>Configuration</code>, or builds one if null.
050 *
051 * Sets the <code>Tool</code>'s configuration with the possibly modified
052 * version of the <code>conf</code>.
053 *
054 * @param conf <code>Configuration</code> for the <code>Tool</code>.
055 * @param tool <code>Tool</code> to run.
056 * @param args command-line arguments to the tool.
057 * @return exit code of the {@link Tool#run(String[])} method.
058 */
059 public static int run(Configuration conf, Tool tool, String[] args)
060 throws Exception{
061 if(conf == null) {
062 conf = new Configuration();
063 }
064 GenericOptionsParser parser = new GenericOptionsParser(conf, args);
065 //set the configuration back, so that Tool can configure itself
066 tool.setConf(conf);
067
068 //get the args w/o generic hadoop args
069 String[] toolArgs = parser.getRemainingArgs();
070 return tool.run(toolArgs);
071 }
072
073 /**
074 * Runs the <code>Tool</code> with its <code>Configuration</code>.
075 *
076 * Equivalent to <code>run(tool.getConf(), tool, args)</code>.
077 *
078 * @param tool <code>Tool</code> to run.
079 * @param args command-line arguments to the tool.
080 * @return exit code of the {@link Tool#run(String[])} method.
081 */
082 public static int run(Tool tool, String[] args)
083 throws Exception{
084 return run(tool.getConf(), tool, args);
085 }
086
087 /**
088 * Prints generic command-line argurments and usage information.
089 *
090 * @param out stream to write usage information to.
091 */
092 public static void printGenericCommandUsage(PrintStream out) {
093 GenericOptionsParser.printGenericCommandUsage(out);
094 }
095
096
097 /**
098 * Print out a prompt to the user, and return true if the user
099 * responds with "y" or "yes". (case insensitive)
100 */
101 public static boolean confirmPrompt(String prompt) throws IOException {
102 while (true) {
103 System.err.print(prompt + " (Y or N) ");
104 StringBuilder responseBuilder = new StringBuilder();
105 while (true) {
106 int c = System.in.read();
107 if (c == -1 || c == '\r' || c == '\n') {
108 break;
109 }
110 responseBuilder.append((char)c);
111 }
112
113 String response = responseBuilder.toString();
114 if (response.equalsIgnoreCase("y") ||
115 response.equalsIgnoreCase("yes")) {
116 return true;
117 } else if (response.equalsIgnoreCase("n") ||
118 response.equalsIgnoreCase("no")) {
119 return false;
120 }
121 System.err.println("Invalid input: " + response);
122 // else ask them again
123 }
124 }
125 }