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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
038     */
039    public class DeployerCLParser extends BaseCLParser implements ConnectionParams {
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 static String ARGUMENT_SECURE_SHORTFORM = "secure";
067        private final static String ARGUMENT_SECURE = "secure";
068    
069        private final Collection<CommandMetaData> commandMetaData;
070    
071        private CommandArgs commandArgs;
072        private CommandMetaData metaData;
073        
074        public DeployerCLParser(OutputStream out) {
075            super(out);
076            
077            commandMetaData = new ArrayList<CommandMetaData>();
078            commandMetaData.add(LoginCommandMetaData.META_DATA);
079            commandMetaData.add(DeployCommandMetaData.META_DATA);
080            commandMetaData.add(DistributeCommandMetaData.META_DATA);
081            commandMetaData.add(ListModulesCommandMetaData.META_DATA);
082            commandMetaData.add(ListTargetsCommandMetaData.META_DATA);
083            commandMetaData.add(RedeployCommandMetaData.META_DATA);
084            commandMetaData.add(StartCommandMetaData.META_DATA);
085            commandMetaData.add(StopCommandMetaData.META_DATA);
086            commandMetaData.add(RestartCommandMetaData.META_DATA);
087            commandMetaData.add(UndeployCommandMetaData.META_DATA);
088            commandMetaData.add(SearchPluginsCommandMetaData.META_DATA);
089            commandMetaData.add(InstallPluginCommandMetaData.META_DATA);
090            commandMetaData.add(HelpCommandMetaData.META_DATA);
091            commandMetaData.add(InstallLibraryCommandMetaData.META_DATA);
092    
093            addURI();
094            addHost();
095            addPort();
096            addDriver();
097            addUser();
098            addPassword();
099            addSyserr();
100            addVerbose();
101            addOffline();
102            addSecure();
103        }
104        
105        public CommandMetaData getCommandMetaData() {
106            return metaData;
107        }
108    
109        public CommandArgs getCommandArgs() {
110            return commandArgs;
111        }
112        
113        public String getURI() {
114            return commandLine.getOptionValue(ARGUMENT_URI_SHORTFORM);
115        }
116        
117        public String getHost() {
118            return commandLine.getOptionValue(ARGUMENT_HOST_SHORTFORM);
119        }
120        
121        public Integer getPort() {
122            String port = commandLine.getOptionValue(ARGUMENT_PORT_SHORTFORM);
123            if (null == port) {
124                return null;
125            }
126            return new Integer(port);
127        }
128    
129        public String getDriver() {
130            return commandLine.getOptionValue(ARGUMENT_DRIVER_SHORTFORM);
131        }
132        
133        public String getUser() {
134            return commandLine.getOptionValue(ARGUMENT_USER_SHORTFORM);
135        }
136        
137        public String getPassword() {
138            return commandLine.getOptionValue(ARGUMENT_PASSWORD_SHORTFORM);
139        }
140        
141        public boolean isSyserr() {
142            return commandLine.hasOption(ARGUMENT_SYSERR_SHORTFORM);
143        }
144        
145        public boolean isVerbose() {
146            return commandLine.hasOption(ARGUMENT_VERBOSE_SHORTFORM);
147        }
148        
149        public boolean isOffline() {
150            return commandLine.hasOption(ARGUMENT_OFFLINE_SHORTFORM);
151        }
152        
153        public boolean isSecure() {
154            return commandLine.hasOption(ARGUMENT_SECURE_SHORTFORM);
155        }
156        
157        @Override
158        public void displayHelp() {
159            String[] args = new String[0];
160            if (null != commandArgs) {
161                args = commandArgs.getArgs();
162            } else if (null != metaData) {
163                args = new String[] {metaData.getCommandName()};
164            }
165            displayHelp(args);
166        }
167    
168        @Override
169        protected void displayHelp(String[] args) {
170            PrintHelper printHelper = new PrintHelper(System.out);
171            PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out), true);
172    
173            out.println();
174            if(args.length > 0) {
175                CommandMetaData commandLine = getCommandMetaData(args[0]);
176                if(commandLine != null) {
177                    out.println("Help for command: "+commandLine.getCommandName());
178                    out.println("    "+hangingIndent(commandLine.getCommandName()+" "+commandLine.getHelpArgumentList(), 4));
179                    out.println();
180                    out.print(PrintHelper.reformat(commandLine.getHelpText(), 8, 72));
181                    out.println();
182                    return;
183                } else if(args[0].equals("options")) {
184                    out.println("Help on general options:");
185                    printHelper.printOptions(out, options);
186                    out.println();
187                    return;
188                } else if(args[0].equals("all")) {
189                    out.println();
190                    out.println("All commands");
191                    out.println();
192                    for (CommandMetaData commandLine2 : commandMetaData) {
193                        out.println("    "+hangingIndent(commandLine2.getCommandName()+" "+commandLine2.getHelpArgumentList(), 4));
194                        out.print(PrintHelper.reformat(commandLine2.getHelpText(), 8, 72));
195                        out.println();
196                    }
197                    out.println();
198                    return;
199                }
200            }
201    
202            out.println("usage: java -jar bin/deployer.jar [general options] command [command options]");
203            out.println();
204            out.println("The general options are:");
205            printHelper.printOptionsNoDesc(out, options);
206            out.println();
207            out.println("The available commands are:");
208            renderCommandList(out);
209            out.println();
210            out.println("For more information about a specific command, run");
211            out.println("    java -jar bin/deployer.jar help [command name]");
212            out.println();
213            out.println("For more information about all commands, run");
214            out.println("    java -jar bin/deployer.jar help all");
215            out.println();
216            out.println("For more information about general options, run");
217            out.println("    java -jar bin/deployer.jar help options");
218            out.println();
219        }
220    
221        private void renderCommandList(PrintWriter out) {
222            Map temp = new HashMap();
223            for (CommandMetaData commandLine : commandMetaData) {
224                List list = (List) temp.get(commandLine.getCommandGroup());
225                if(list == null) {
226                    list = new ArrayList();
227                    temp.put(commandLine.getCommandGroup(), list);
228                }
229                list.add(commandLine.getCommandName());
230            }
231            List groups = new ArrayList(temp.keySet());
232            Collections.sort(groups);
233            for (int i = 0; i < groups.size(); i++) {
234                String name = (String) groups.get(i);
235                out.println("    "+name);
236                List list = (List) temp.get(name);
237                Collections.sort(list);
238                for (int j = 0; j < list.size(); j++) {
239                    String cmd = (String) list.get(j);
240                    out.println("        "+cmd);
241                }
242            }
243        }
244        
245        protected CommandMetaData getCommandMetaData(String commandName) {
246            for (CommandMetaData commandLine : commandMetaData) {
247                if (commandLine.getCommandName().equals(commandName)) {
248                    return commandLine;
249                }
250            }
251            return null;
252        }
253    
254        protected String hangingIndent(String source, int cols) {
255            String s = PrintHelper.reformat(source, cols, 72);
256            return s.substring(cols);
257        }
258        
259        @Override
260        protected void validateOptions() throws CLParserException {
261            try {
262                getPort();
263            } catch (NumberFormatException e) {
264                throw new CLParserException("Port [" + commandLine.getOptionValue(ARGUMENT_PORT_SHORTFORM) + "] is not an integer.", e);
265            }
266        }
267    
268        @Override
269        protected void validateRemainingArgs() throws CLParserException {
270            String[] args = commandLine.getArgs();
271            if (0 == args.length) {
272                throw new CLParserException("No command has been provided.");
273            }
274            
275            String command = args[0];
276            metaData = getCommandMetaData(command);
277            if (null == metaData) {
278                throw new CLParserException("Command [" + command + "] is undefined.");
279            }
280            
281            String[] newArgs = new String[args.length - 1];
282            System.arraycopy(args, 1, newArgs, 0, newArgs.length);
283            commandArgs = metaData.parse(newArgs);
284        }
285        
286        protected void addOffline() {
287            options.addOption(ARGUMENT_OFFLINE_SHORTFORM,
288                    ARGUMENT_OFFLINE,
289                    false,
290                    "Deploy offline to a local server, using whatever deployers are available in the local server");
291        }
292        
293        protected void addSecure() {
294            options.addOption(ARGUMENT_SECURE_SHORTFORM,
295                    ARGUMENT_SECURE,
296                    false,
297                    "Use secure channel to communicate with the server.  Unsecured channel is used by default.");
298        }
299    
300        protected void addVerbose() {
301            options.addOption(ARGUMENT_VERBOSE_SHORTFORM,
302                    ARGUMENT_VERBOSE,
303                    false,
304                    "Enables verbose execution mode.  Disabled by default.");
305        }
306    
307        protected void addSyserr() {
308            options.addOption(ARGUMENT_SYSERR_SHORTFORM,
309                    ARGUMENT_SYSERR,
310                    false,
311                    "Enables error logging to syserr.  Disabled by default.");
312        }
313    
314        protected void addPassword() {
315            addOptionWithParam(ARGUMENT_PASSWORD,
316                    ARGUMENT_PASSWORD_SHORTFORM,
317                    "password",
318                    "Specifies a password to use to authenticate to the server.");
319        }
320    
321        protected void addUser() {
322            addOptionWithParam(ARGUMENT_USER,
323                    ARGUMENT_USER_SHORTFORM,
324                    "username",
325                    "If the deployment operation requires authentication, then you can "
326                            + "specify the username to use to connect.  If no password is specified, the "
327                            + "deployer will attempt to connect to the server with no password, and if "
328                            + "that fails, will prompt you for a password.");
329        }
330    
331        protected void addDriver() {
332            addOptionWithParam(ARGUMENT_DRIVER,
333                    ARGUMENT_DRIVER_SHORTFORM,
334                    "driver.jar",
335                    "If you want to use this tool with a server other than Geronimo, "
336                            + "then you must provide the path to its driver JAR.  Currently, manifest "
337                            + "Class-Path entries in that JAR are ignored.");
338        }
339    
340        protected void addPort() {
341            addOptionWithParam(ARGUMENT_PORT,
342                    ARGUMENT_PORT_SHORTFORM,
343                    "port",
344                    "The RMI listen port of a Geronimo server to deploy to.  This option is "
345                            + "not compatible with --uri, but is often used with --host.  The default port is 1099.");
346        }
347    
348        protected void addHost() {
349            addOptionWithParam(ARGUMENT_HOST_SHORTFORM,
350                    ARGUMENT_HOST_SHORTFORM,
351                    "hostname",
352                    "The host name of a Geronimo server to deploy to.  This option is "
353                            + "not compatible with --uri, but is often used with --port.");
354        }
355    
356        protected void addURI() {
357            addOptionWithParam(ARGUMENT_URI,
358                    ARGUMENT_URI_SHORTFORM,
359                    "uri",
360                    "A URI to contact the server.  If not specified, the deployer defaults to "
361                            + "operating on a Geronimo server running on the standard port on localhost.\n"
362                            + "A URI to connect to Geronimo (including optional host and port parameters) has the form: "
363                            + "deployer:geronimo:jmx[://host[:port]] (though you could also just use --host and --port instead).");
364        }
365    
366        protected void addOptionWithParam(String longOption, String shortOption, String argName, String desc) {
367            OptionBuilder optionBuilder = OptionBuilder.hasArg().withArgName(argName);
368            optionBuilder = optionBuilder.withLongOpt(longOption);
369            optionBuilder = optionBuilder.withDescription(desc);
370            Option option = optionBuilder.create(shortOption);
371            options.addOption(option);
372        }
373    
374    }