This project has retired. For details please refer to its
Attic page.
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.oozie.cli;
019
020 import org.apache.commons.cli.Options;
021 import org.apache.commons.cli.GnuParser;
022 import org.apache.commons.cli.ParseException;
023 import org.apache.commons.cli.CommandLine;
024 import org.apache.commons.cli.HelpFormatter;
025
026 import java.util.Map;
027 import java.util.LinkedHashMap;
028 import java.text.MessageFormat;
029 import java.io.PrintWriter;
030
031 /**
032 * Command line parser based on Apache common-cli 1.x that supports subcommands.
033 */
034 public class CLIParser {
035 private static final String LEFT_PADDING = " ";
036
037 private String cliName;
038 private String[] cliHelp;
039 private Map<String, Options> commands = new LinkedHashMap<String, Options>();
040 private Map<String, Boolean> commandWithArgs = new LinkedHashMap<String, Boolean>();
041 private Map<String, String> commandsHelp = new LinkedHashMap<String, String>();
042
043 /**
044 * Create a parser.
045 *
046 * @param cliName name of the parser, for help purposes.
047 * @param cliHelp help for the CLI.
048 */
049 public CLIParser(String cliName, String[] cliHelp) {
050 this.cliName = cliName;
051 this.cliHelp = cliHelp;
052 }
053
054 /**
055 * Add a command to the parser.
056 *
057 * @param command comand name.
058 * @param argsHelp command arguments help.
059 * @param commandHelp command description.
060 * @param commandOptions command options.
061 * @param hasArguments
062 */
063 public void addCommand(String command, String argsHelp, String commandHelp, Options commandOptions,
064 boolean hasArguments) {
065 String helpMsg = argsHelp + ((hasArguments) ? "<ARGS> " : "") + ": " + commandHelp;
066 commandsHelp.put(command, helpMsg);
067 commands.put(command, commandOptions);
068 commandWithArgs.put(command, hasArguments);
069 }
070
071 /**
072 * Bean that represents a parsed command.
073 */
074 public class Command {
075 private String name;
076 private CommandLine commandLine;
077
078 private Command(String name, CommandLine commandLine) {
079 this.name = name;
080 this.commandLine = commandLine;
081 }
082
083 /**
084 * Return the command name.
085 *
086 * @return the command name.
087 */
088 public String getName() {
089 return name;
090 }
091
092 /**
093 * Return the command line.
094 *
095 * @return the command line.
096 */
097 public CommandLine getCommandLine() {
098 return commandLine;
099 }
100 }
101
102 /**
103 * Parse a array of arguments into a command.
104 *
105 * @param args array of arguments.
106 * @return the parsed Command.
107 * @throws ParseException thrown if the arguments could not be parsed.
108 */
109 public Command parse(String[] args) throws ParseException {
110 if (args.length == 0) {
111 throw new ParseException("missing sub-command");
112 }
113 else {
114 if (commands.containsKey(args[0])) {
115 GnuParser parser = new GnuParser();
116 String[] minusCommand = new String[args.length - 1];
117 System.arraycopy(args, 1, minusCommand, 0, minusCommand.length);
118 return new Command(args[0], parser.parse(commands.get(args[0]), minusCommand,
119 commandWithArgs.get(args[0])));
120 }
121 else {
122 throw new ParseException(MessageFormat.format("invalid sub-command [{0}]", args[0]));
123 }
124 }
125 }
126
127 public String shortHelp() {
128 return "use 'help' sub-command for help details";
129 }
130
131 /**
132 * Print the help for the parser to standard output.
133 */
134 public void showHelp() {
135 PrintWriter pw = new PrintWriter(System.out);
136 pw.println("usage: ");
137 for (String s : cliHelp) {
138 pw.println(LEFT_PADDING + s);
139 }
140 pw.println();
141 HelpFormatter formatter = new HelpFormatter();
142 for (Map.Entry<String, Options> entry : commands.entrySet()) {
143 String s = LEFT_PADDING + cliName + " " + entry.getKey() + " ";
144 if (entry.getValue().getOptions().size() > 0) {
145 pw.println(s + "<OPTIONS> " + commandsHelp.get(entry.getKey()));
146 formatter.printOptions(pw, 100, entry.getValue(), s.length(), 3);
147 }
148 else {
149 pw.println(s + commandsHelp.get(entry.getKey()));
150 }
151 pw.println();
152 }
153 pw.flush();
154 }
155
156 }
157