View Javadoc

1   /*
2   Karma CLI - Command Line Interface for the Karma application
3   Copyright (C) 2004  Toolforge <www.toolforge.nl>
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19  package nl.toolforge.karma.console;
20  
21  import nl.toolforge.core.util.lang.NiftyStringUtils;
22  import nl.toolforge.karma.core.cmd.CommandDescriptor;
23  import nl.toolforge.karma.core.cmd.CommandException;
24  import nl.toolforge.karma.core.cmd.CommandFactory;
25  import nl.toolforge.karma.core.cmd.CommandLoadException;
26  import org.apache.commons.cli.Option;
27  import org.apache.commons.lang.StringUtils;
28  
29  import java.util.Collection;
30  import java.util.Hashtable;
31  import java.util.Iterator;
32  import java.util.Map;
33  
34  public final class CommandRenderer {
35  
36    public static final int COMMAND_FILL = 40;
37    public static final int OPTION_FILL = 50;
38  
39    public static String commands = null;
40  
41    private static Map helpCache = null;
42  
43    private CommandRenderer() {}
44  
45    /***
46     * Provides a <code>String</code> view on <code>command</code>.
47     *
48     * @param commandName The name (or an alias) for the command.
49     * @return A <code>String</code> with help info for the command.
50     */
51    public static String renderCommand(String commandName) throws CommandLoadException, CommandException {
52  
53      if (helpCache == null) {
54        helpCache = new Hashtable();
55      } else {
56        if (helpCache.containsKey(commandName)) {
57          return (String) helpCache.get(commandName);
58        }
59      }
60  
61      CommandDescriptor descriptor = CommandFactory.getInstance().getCommandDescriptor(commandName);
62  
63      if (descriptor == null) {
64        throw new CommandException(CommandException.UNKNOWN_COMMAND, new Object[]{commandName});
65      }
66  
67      Collection optionsCollection = descriptor.getOptions().getOptions();
68      Option[] options = (Option[]) optionsCollection.toArray(new Option[optionsCollection.size()]);
69  
70      String cachedItem = printCommand(descriptor, options, true, true).toString();
71      helpCache.put(commandName, cachedItem);
72  
73      return cachedItem;
74    }
75  
76    /***
77     * Provides a <code>String</code> view on all commands, nicely rendered.
78     *
79     * @param commandDescriptors
80     *   A <code>Collection</code> with all command descriptors for the commands applicable to the Karma runtime.
81     *
82     * @return
83     *   A <code>String</code> with all command usages, rendered much like what a shell (like <code>sh</code>) would
84     *   provide.
85     */
86    public static String renderedCommands(Collection commandDescriptors) {
87  
88      if (commands == null) {
89  
90        StringBuffer buffer = new StringBuffer();
91  
92        for (Iterator i = commandDescriptors.iterator(); i.hasNext();) {
93  
94          CommandDescriptor descriptor = (CommandDescriptor) i.next();
95  
96          Collection optionsCollection = descriptor.getOptions().getOptions();
97          Option[] options = (Option[]) optionsCollection.toArray(new Option[optionsCollection.size()]);
98  
99          buffer.append(printCommand(descriptor, options, false, false));
100       }
101       commands = buffer.toString();
102     }
103 
104     return commands;
105   }
106 
107   private static StringBuffer printCommand(CommandDescriptor descriptor, Option[] options, boolean showOptions, boolean showHelp) {
108 
109     StringBuffer buffer = new StringBuffer();
110     String commandNameAlias = descriptor.getName()+" ("+descriptor.getAlias()+")";
111 
112     buffer.
113         append( commandNameAlias ).
114         append( StringUtils.repeat(" ", COMMAND_FILL - commandNameAlias.length()) );
115     if (!showOptions) {
116       buffer.append( descriptor.getDescription() );
117     }
118     buffer.append( "\n" );
119 
120     if (showOptions) {
121       for (int j = 0; j < options.length; j++) {
122 
123         Option o = options[j];
124 
125         String leftPadding = "   ";
126 
127         buffer.
128             append(leftPadding).
129             append("-" + o.getOpt()).
130             append(", --" + o.getLongOpt());
131 
132         String args = "";
133         if (o.hasArg()) {
134           args = " <".concat(o.getArgName()).concat(">");
135         }
136 
137         // todo when the commands are described with too much of text, then FILL will run out of count ...
138         //
139         buffer.append(args.concat(StringUtils.repeat(" ", OPTION_FILL - (o.getLongOpt() + args).length())));
140         buffer.append(leftPadding);
141         if (!o.isRequired()) {
142           buffer.append("(Optional) ");
143         }
144         buffer.append(o.getDescription());
145         buffer.append("\n");
146       }
147     }
148 
149     if (showHelp) {
150       buffer.append("\n");
151 
152       String trimmed = NiftyStringUtils.deleteWhiteSpaceExceptOne(descriptor.getHelp());
153       String[] split = NiftyStringUtils.split(trimmed, " ", 120);
154       String joined = StringUtils.join(split, "\n");
155 
156       buffer.append(joined);
157       buffer.append("\n");
158     }
159 
160     return buffer;
161   }
162 }