001/*
002 * Copyright 2012-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.cli.command.core;
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.List;
023import java.util.Set;
024
025import org.springframework.boot.cli.command.AbstractCommand;
026import org.springframework.boot.cli.command.Command;
027import org.springframework.boot.cli.command.CommandRunner;
028import org.springframework.boot.cli.command.HelpExample;
029import org.springframework.boot.cli.command.NoHelpCommandArgumentsException;
030import org.springframework.boot.cli.command.NoSuchCommandException;
031import org.springframework.boot.cli.command.options.OptionHelp;
032import org.springframework.boot.cli.command.status.ExitStatus;
033import org.springframework.boot.cli.util.Log;
034
035/**
036 * Internal {@link Command} used for 'help' requests.
037 *
038 * @author Phillip Webb
039 */
040public class HelpCommand extends AbstractCommand {
041
042        private final CommandRunner commandRunner;
043
044        public HelpCommand(CommandRunner commandRunner) {
045                super("help", "Get help on commands");
046                this.commandRunner = commandRunner;
047        }
048
049        @Override
050        public String getUsageHelp() {
051                return "command";
052        }
053
054        @Override
055        public String getHelp() {
056                return null;
057        }
058
059        @Override
060        public Collection<OptionHelp> getOptionsHelp() {
061                List<OptionHelp> help = new ArrayList<OptionHelp>();
062                for (final Command command : this.commandRunner) {
063                        if (isHelpShown(command)) {
064                                help.add(new OptionHelp() {
065
066                                        @Override
067                                        public Set<String> getOptions() {
068                                                return Collections.singleton(command.getName());
069                                        }
070
071                                        @Override
072                                        public String getUsageHelp() {
073                                                return command.getDescription();
074                                        }
075
076                                });
077                        }
078                }
079                return help;
080        }
081
082        private boolean isHelpShown(Command command) {
083                if (command instanceof HelpCommand || command instanceof HintCommand) {
084                        return false;
085                }
086                return true;
087        }
088
089        @Override
090        public ExitStatus run(String... args) throws Exception {
091                if (args.length == 0) {
092                        throw new NoHelpCommandArgumentsException();
093                }
094                String commandName = args[0];
095                for (Command command : this.commandRunner) {
096                        if (command.getName().equals(commandName)) {
097                                Log.info(this.commandRunner.getName() + command.getName() + " - "
098                                                + command.getDescription());
099                                Log.info("");
100                                if (command.getUsageHelp() != null) {
101                                        Log.info("usage: " + this.commandRunner.getName() + command.getName()
102                                                        + " " + command.getUsageHelp());
103                                        Log.info("");
104                                }
105                                if (command.getHelp() != null) {
106                                        Log.info(command.getHelp());
107                                }
108                                Collection<HelpExample> examples = command.getExamples();
109                                if (examples != null) {
110                                        Log.info(examples.size() == 1 ? "example:" : "examples:");
111                                        Log.info("");
112                                        for (HelpExample example : examples) {
113                                                Log.info("    " + example.getDescription() + ":");
114                                                Log.info("        $ " + example.getExample());
115                                                Log.info("");
116                                        }
117                                        Log.info("");
118                                }
119                                return ExitStatus.OK;
120                        }
121                }
122                throw new NoSuchCommandException(commandName);
123        }
124
125}