View Javadoc

1   package org.lsst.ccs.command;
2   
3   import java.io.PrintWriter;
4   import java.util.ArrayList;
5   import java.util.Collections;
6   import java.util.Comparator;
7   import java.util.List;
8   import org.lsst.ccs.command.annotations.Argument;
9   import org.lsst.ccs.command.annotations.Command;
10  
11  /**
12   * Provides help based on information from a command dictionary.
13   *
14   * @author tonyj
15   */
16  public class HelpGenerator {
17  
18      private final Dictionary dict;
19      private final PrintWriter out;
20  
21      /**
22       * Create a HelpGenerator
23       *
24       * @param out Where the output of the help commands should be sent
25       * @param dict The dictionary used to provide help
26       */
27      public HelpGenerator(PrintWriter out, Dictionary dict) {
28          this.out = out;
29          this.dict = dict;
30      }
31  
32      @Command(description = "List available commands")
33      public void help() {
34          List<DictionaryCommand> sorted = new ArrayList<>();
35          for (DictionaryCommand def : dict) {
36              sorted.add(def);
37          }
38          Collections.sort(sorted, new CommandDefinitionComparator());
39          for (DictionaryCommand def : sorted) {
40              helpForCommand(def);
41          }
42      }
43  
44      @Command(description = "Show help for a single command")
45      public void help(@Argument(name = "command") String command) {
46          boolean foundCommand = false;
47          for (DictionaryCommand def : dict) {
48              if (def.getCommandName().equals(command)) {
49                  foundCommand = true;
50                  helpForCommand(def);
51                  int maxNameLeng = 0, maxTypeLeng = 0;
52                  for (DictionaryArgument param : def.getArguments()) {
53                      int leng = param.getName().length();
54                      maxNameLeng = (leng > maxNameLeng) ? leng : maxNameLeng;
55                      leng = param.getSimpleType().length();
56                      maxTypeLeng = (leng > maxTypeLeng) ? leng : maxTypeLeng;
57                  }
58                  String spaces = String.format("%80s", "");
59                  for (DictionaryArgument param : def.getArguments()) {
60                      String name = param.getName(), type = param.getSimpleType();
61                      out.printf("    %s%s   %s%s   %s\n", name,
62                                 spaces.substring(0, maxNameLeng - name.length()),
63                                 type,
64                                 spaces.substring(0, maxTypeLeng - type.length()),
65                                 param.getDescription());
66                  }
67              }
68          }
69          if (!foundCommand) throw new IllegalArgumentException("No help found for "+command);
70      }
71  
72      private void helpForCommand(DictionaryCommand def) {
73          StringBuilder builder = new StringBuilder();
74          builder.append(def.getCommandName());
75          for (DictionaryArgument param : def.getArguments()) {
76              builder.append(' ').append(param.getName());
77          }
78          if (def.isVarArgs()) {
79              builder.append("...");
80          }
81          out.printf(builder.length()<=30 ? "%-30s %s\n" : "%s\n                               %s\n", 
82                  builder, def.getDescription());
83          if (def.getAliases().length>0) {
84              out.printf("    aliases:");
85              for (String alias : def.getAliases()) out.printf(" %s",alias);
86              out.println();
87          }
88      }
89  
90      /**
91       * A comparator used for putting commands into alphabetical order
92       */
93      private static class CommandDefinitionComparator implements Comparator<DictionaryCommand> {
94  
95          @Override
96          public int compare(DictionaryCommand o1, DictionaryCommand o2) {
97              return o1.getCommandName().compareTo(o2.getCommandName());
98          }
99      }
100 }