001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.cli.deployer;
018    
019    import java.io.OutputStream;
020    import java.io.OutputStreamWriter;
021    import java.io.PrintWriter;
022    import java.util.ArrayList;
023    import java.util.Collection;
024    import java.util.Collections;
025    import java.util.HashMap;
026    import java.util.List;
027    import java.util.Map;
028    
029    import org.apache.commons.cli.Option;
030    import org.apache.commons.cli.OptionBuilder;
031    import org.apache.geronimo.cli.BaseCLParser;
032    import org.apache.geronimo.cli.CLParserException;
033    import org.apache.geronimo.cli.PrintHelper;
034    
035    
036    /**
037     * @version $Rev: 476049 $ $Date: 2006-11-17 15:35:17 +1100 (Fri, 17 Nov 2006) $
038     */
039    public class DeployerCLParser extends BaseCLParser {
040        private final static String ARGUMENT_URI_SHORTFORM = "U";
041        private final static String ARGUMENT_URI = "uri";
042        
043        private final static String ARGUMENT_HOST_SHORTFORM = "host";
044        
045        private final static String ARGUMENT_PORT_SHORTFORM = "port";
046        private final static String ARGUMENT_PORT = "port";
047    
048        private final static String ARGUMENT_DRIVER_SHORTFORM = "d";
049        private final static String ARGUMENT_DRIVER = "driver";
050    
051        private final static String ARGUMENT_USER_SHORTFORM = "u";
052        private final static String ARGUMENT_USER = "user";
053    
054        private final static String ARGUMENT_PASSWORD_SHORTFORM = "p";
055        private final static String ARGUMENT_PASSWORD = "password";
056    
057        private final static String ARGUMENT_SYSERR_SHORTFORM = "s";
058        private final static String ARGUMENT_SYSERR = "syserr";
059    
060        private final static String ARGUMENT_VERBOSE_SHORTFORM = "v";
061        private final static String ARGUMENT_VERBOSE = "verbose";
062    
063        private final static String ARGUMENT_OFFLINE_SHORTFORM = "o";
064        private final static String ARGUMENT_OFFLINE = "offline";
065    
066        private final Collection<CommandMetaData> commandMetaData;
067    
068        private CommandArgs commandArgs;
069        private CommandMetaData metaData;
070        
071        public DeployerCLParser(OutputStream out) {
072            super(out);
073            
074            commandMetaData = new ArrayList<CommandMetaData>();
075            commandMetaData.add(LoginCommandMetaData.META_DATA);
076            commandMetaData.add(DeployCommandMetaData.META_DATA);
077            commandMetaData.add(DistributeCommandMetaData.META_DATA);
078            commandMetaData.add(ListModulesCommandMetaData.META_DATA);
079            commandMetaData.add(ListTargetsCommandMetaData.META_DATA);
080            commandMetaData.add(RedeployCommandMetaData.META_DATA);
081            commandMetaData.add(StartCommandMetaData.META_DATA);
082            commandMetaData.add(StopCommandMetaData.META_DATA);
083            commandMetaData.add(RestartCommandMetaData.META_DATA);
084            commandMetaData.add(UndeployCommandMetaData.META_DATA);
085            commandMetaData.add(SearchPluginsCommandMetaData.META_DATA);
086            commandMetaData.add(InstallPluginCommandMetaData.META_DATA);
087            commandMetaData.add(HelpCommandMetaData.META_DATA);
088    
089            addURI();
090            addHost();
091            addPort();
092            addDriver();
093            addUser();
094            addPassword();
095            addSyserr();
096            addVerbose();
097            addOffline();
098        }
099        
100        public CommandMetaData getCommandMetaData() {
101            return metaData;
102        }
103    
104        public CommandArgs getCommandArgs() {
105            return commandArgs;
106        }
107        
108        public String getURI() {
109            return commandLine.getOptionValue(ARGUMENT_URI_SHORTFORM);
110        }
111        
112        public String getHost() {
113            return commandLine.getOptionValue(ARGUMENT_HOST_SHORTFORM);
114        }
115        
116        public Integer getPort() {
117            String port = commandLine.getOptionValue(ARGUMENT_PORT_SHORTFORM);
118            if (null == port) {
119                return null;
120            }
121            return new Integer(port);
122        }
123    
124        public String getDriver() {
125            return commandLine.getOptionValue(ARGUMENT_DRIVER_SHORTFORM);
126        }
127        
128        public String getUser() {
129            return commandLine.getOptionValue(ARGUMENT_USER_SHORTFORM);
130        }
131        
132        public String getPassword() {
133            return commandLine.getOptionValue(ARGUMENT_PASSWORD_SHORTFORM);
134        }
135        
136        public boolean isSyserr() {
137            return commandLine.hasOption(ARGUMENT_SYSERR_SHORTFORM);
138        }
139        
140        public boolean isVerbose() {
141            return commandLine.hasOption(ARGUMENT_VERBOSE_SHORTFORM);
142        }
143        
144        public boolean isOffline() {
145            return commandLine.hasOption(ARGUMENT_OFFLINE_SHORTFORM);
146        }
147        
148        @Override
149        public void displayHelp() {
150            String[] args = new String[0];
151            if (null != commandArgs) {
152                args = commandArgs.getArgs();
153            } else if (null != metaData) {
154                args = new String[] {metaData.getCommandName()};
155            }
156            displayHelp(args);
157        }
158    
159        @Override
160        protected void displayHelp(String[] args) {
161            PrintHelper printHelper = new PrintHelper(System.out);
162            PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out), true);
163    
164            out.println();
165            if(args.length > 0) {
166                CommandMetaData commandLine = getCommandMetaData(args[0]);
167                if(commandLine != null) {
168                    out.println("Help for command: "+commandLine.getCommandName());
169                    out.println("    "+hangingIndent(commandLine.getCommandName()+" "+commandLine.getHelpArgumentList(), 4));
170                    out.println();
171                    out.print(PrintHelper.reformat(commandLine.getHelpText(), 8, 72));
172                    out.println();
173                    return;
174                } else if(args[0].equals("options")) {
175                    out.println("Help on general options:");
176                    printHelper.printOptions(out, options);
177                    out.println();
178                    return;
179                } else if(args[0].equals("all")) {
180                    out.println();
181                    out.println("All commands");
182                    out.println();
183                    for (CommandMetaData commandLine2 : commandMetaData) {
184                        out.println("    "+hangingIndent(commandLine2.getCommandName()+" "+commandLine2.getHelpArgumentList(), 4));
185                        out.print(PrintHelper.reformat(commandLine2.getHelpText(), 8, 72));
186                        out.println();
187                    }
188                    out.println();
189                    return;
190                }
191            }
192    
193            out.println("usage: java -jar bin/deployer.jar [general options] command [command options]");
194            out.println();
195            out.println("The general options are:");
196            printHelper.printOptionsNoDesc(out, options);
197            out.println();
198            out.println("The available commands are:");
199            renderCommandList(out);
200            out.println();
201            out.println("For more information about a specific command, run");
202            out.println("    java -jar bin/deployer.jar help [command name]");
203            out.println();
204            out.println("For more information about all commands, run");
205            out.println("    java -jar bin/deployer.jar help all");
206            out.println();
207            out.println("For more information about general options, run");
208            out.println("    java -jar bin/deployer.jar help options");
209            out.println();
210        }
211    
212        private void renderCommandList(PrintWriter out) {
213            Map temp = new HashMap();
214            for (CommandMetaData commandLine : commandMetaData) {
215                List list = (List) temp.get(commandLine.getCommandGroup());
216                if(list == null) {
217                    list = new ArrayList();
218                    temp.put(commandLine.getCommandGroup(), list);
219                }
220                list.add(commandLine.getCommandName());
221            }
222            List groups = new ArrayList(temp.keySet());
223            Collections.sort(groups);
224            for (int i = 0; i < groups.size(); i++) {
225                String name = (String) groups.get(i);
226                out.println("    "+name);
227                List list = (List) temp.get(name);
228                Collections.sort(list);
229                for (int j = 0; j < list.size(); j++) {
230                    String cmd = (String) list.get(j);
231                    out.println("        "+cmd);
232                }
233            }
234        }
235        
236        protected CommandMetaData getCommandMetaData(String commandName) {
237            for (CommandMetaData commandLine : commandMetaData) {
238                if (commandLine.getCommandName().equals(commandName)) {
239                    return commandLine;
240                }
241            }
242            return null;
243        }
244    
245        protected String hangingIndent(String source, int cols) {
246            String s = PrintHelper.reformat(source, cols, 72);
247            return s.substring(cols);
248        }
249        
250        @Override
251        protected void validateOptions() throws CLParserException {
252            try {
253                getPort();
254            } catch (NumberFormatException e) {
255                throw new CLParserException("Port [" + commandLine.getOptionValue(ARGUMENT_PORT_SHORTFORM) + "] is not an integer.", e);
256            }
257        }
258    
259        @Override
260        protected void validateRemainingArgs() throws CLParserException {
261            String[] args = commandLine.getArgs();
262            if (0 == args.length) {
263                throw new CLParserException("No command has been provided.");
264            }
265            
266            String command = args[0];
267            metaData = getCommandMetaData(command);
268            if (null == metaData) {
269                throw new CLParserException("Command [" + command + "] is undefined.");
270            }
271            
272            String[] newArgs = new String[args.length - 1];
273            System.arraycopy(args, 1, newArgs, 0, newArgs.length);
274            commandArgs = metaData.parse(newArgs);
275        }
276        
277        protected void addOffline() {
278            options.addOption(ARGUMENT_OFFLINE_SHORTFORM,
279                    ARGUMENT_OFFLINE,
280                    false,
281                    "Deploy offline to a local server, using whatever deployers are available in the local server");
282        }
283    
284        protected void addVerbose() {
285            options.addOption(ARGUMENT_VERBOSE_SHORTFORM,
286                    ARGUMENT_VERBOSE,
287                    false,
288                    "Enables verbose execution mode.  Disabled by default.");
289        }
290    
291        protected void addSyserr() {
292            options.addOption(ARGUMENT_SYSERR_SHORTFORM,
293                    ARGUMENT_SYSERR,
294                    false,
295                    "Enables error logging to syserr.  Disabled by default.");
296        }
297    
298        protected void addPassword() {
299            addOptionWithParam(ARGUMENT_PASSWORD,
300                    ARGUMENT_PASSWORD_SHORTFORM,
301                    "password",
302                    "Specifies a password to use to authenticate to the server.");
303        }
304    
305        protected void addUser() {
306            addOptionWithParam(ARGUMENT_USER,
307                    ARGUMENT_USER_SHORTFORM,
308                    "username",
309                    "If the deployment operation requires authentication, then you can "
310                            + "specify the username to use to connect.  If no password is specified, the "
311                            + "deployer will attempt to connect to the server with no password, and if "
312                            + "that fails, will prompt you for a password.");
313        }
314    
315        protected void addDriver() {
316            addOptionWithParam(ARGUMENT_DRIVER,
317                    ARGUMENT_DRIVER_SHORTFORM,
318                    "driver.jar",
319                    "If you want to use this tool with a server other than Geronimo, "
320                            + "then you must provide the path to its driver JAR.  Currently, manifest "
321                            + "Class-Path entries in that JAR are ignored.");
322        }
323    
324        protected void addPort() {
325            addOptionWithParam(ARGUMENT_PORT,
326                    ARGUMENT_PORT_SHORTFORM,
327                    "port",
328                    "The RMI listen port of a Geronimo server to deploy to.  This option is "
329                            + "not compatible with --uri, but is often used with --host.  The default port is 1099.");
330        }
331    
332        protected void addHost() {
333            addOptionWithParam(ARGUMENT_HOST_SHORTFORM,
334                    ARGUMENT_HOST_SHORTFORM,
335                    "hostname",
336                    "The host name of a Geronimo server to deploy to.  This option is "
337                            + "not compatible with --uri, but is often used with --port.");
338        }
339    
340        protected void addURI() {
341            addOptionWithParam(ARGUMENT_URI,
342                    ARGUMENT_URI_SHORTFORM,
343                    "uri",
344                    "A URI to contact the server.  If not specified, the deployer defaults to "
345                            + "operating on a Geronimo server running on the standard port on localhost.\n"
346                            + "A URI to connect to Geronimo (including optional host and port parameters) has the form: "
347                            + "deployer:geronimo:jmx[://host[:port]] (though you could also just use --host and --port instead).");
348        }
349    
350        protected void addOptionWithParam(String longOption, String shortOption, String argName, String desc) {
351            OptionBuilder optionBuilder = OptionBuilder.hasArg().withArgName(argName);
352            optionBuilder = optionBuilder.withLongOpt(longOption);
353            optionBuilder = optionBuilder.withDescription(desc);
354            Option option = optionBuilder.create(shortOption);
355            options.addOption(option);
356        }
357    
358    }