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