1 /***
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.cli;
18
19 import java.io.PrintWriter;
20
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.Iterator;
26 import java.util.List;
27
28 /***
29 * A formatter of help messages for the current command line options
30 *
31 * @author Slawek Zachcial
32 * @author John Keyes (john at integralsource.com)
33 **/
34 public class HelpFormatter {
35
36
37 /*** default number of characters per line */
38 public static final int DEFAULT_WIDTH = 74;
39
40 /*** default padding to the left of each line */
41 public static final int DEFAULT_LEFT_PAD = 1;
42
43 /***
44 * the number of characters of padding to be prefixed
45 * to each description line
46 */
47 public static final int DEFAULT_DESC_PAD = 3;
48
49 /*** the string to display at the begining of the usage statement */
50 public static final String DEFAULT_SYNTAX_PREFIX = "usage: ";
51
52 /*** default prefix for shortOpts */
53 public static final String DEFAULT_OPT_PREFIX = "-";
54
55 /*** default prefix for long Option */
56 public static final String DEFAULT_LONG_OPT_PREFIX = "--";
57
58 /*** default name for an argument */
59 public static final String DEFAULT_ARG_NAME = "arg";
60
61
62
63 /***
64 * number of characters per line
65 *
66 * @deprecated Scope will be made private for next major version
67 * - use get/setWidth methods instead.
68 */
69 public int defaultWidth = DEFAULT_WIDTH;
70
71 /***
72 * amount of padding to the left of each line
73 *
74 * @deprecated Scope will be made private for next major version
75 * - use get/setLeftPadding methods instead.
76 */
77 public int defaultLeftPad = DEFAULT_LEFT_PAD;
78
79 /***
80 * the number of characters of padding to be prefixed
81 * to each description line
82 *
83 * @deprecated Scope will be made private for next major version
84 * - use get/setDescPadding methods instead.
85 */
86 public int defaultDescPad = DEFAULT_DESC_PAD;
87
88 /***
89 * the string to display at the begining of the usage statement
90 *
91 * @deprecated Scope will be made private for next major version
92 * - use get/setSyntaxPrefix methods instead.
93 */
94 public String defaultSyntaxPrefix = DEFAULT_SYNTAX_PREFIX;
95
96 /***
97 * the new line string
98 *
99 * @deprecated Scope will be made private for next major version
100 * - use get/setNewLine methods instead.
101 */
102 public String defaultNewLine = System.getProperty("line.separator");
103
104 /***
105 * the shortOpt prefix
106 *
107 * @deprecated Scope will be made private for next major version
108 * - use get/setOptPrefix methods instead.
109 */
110 public String defaultOptPrefix = DEFAULT_OPT_PREFIX;
111
112 /***
113 * the long Opt prefix
114 *
115 * @deprecated Scope will be made private for next major version
116 * - use get/setLongOptPrefix methods instead.
117 */
118 public String defaultLongOptPrefix = DEFAULT_LONG_OPT_PREFIX;
119
120 /***
121 * the name of the argument
122 *
123 * @deprecated Scope will be made private for next major version
124 * - use get/setArgName methods instead.
125 */
126 public String defaultArgName = DEFAULT_ARG_NAME;
127
128 /***
129 * Sets the 'width'.
130 *
131 * @param width the new value of 'width'
132 */
133 public void setWidth(int width)
134 {
135 this.defaultWidth = width;
136 }
137
138 /***
139 * Returns the 'width'.
140 *
141 * @return the 'width'
142 */
143 public int getWidth()
144 {
145 return this.defaultWidth;
146 }
147
148 /***
149 * Sets the 'leftPadding'.
150 *
151 * @param padding the new value of 'leftPadding'
152 */
153 public void setLeftPadding(int padding)
154 {
155 this.defaultLeftPad = padding;
156 }
157
158 /***
159 * Returns the 'leftPadding'.
160 *
161 * @return the 'leftPadding'
162 */
163 public int getLeftPadding()
164 {
165 return this.defaultLeftPad;
166 }
167
168 /***
169 * Sets the 'descPadding'.
170 *
171 * @param padding the new value of 'descPadding'
172 */
173 public void setDescPadding(int padding)
174 {
175 this.defaultDescPad = padding;
176 }
177
178 /***
179 * Returns the 'descPadding'.
180 *
181 * @return the 'descPadding'
182 */
183 public int getDescPadding()
184 {
185 return this.defaultDescPad;
186 }
187
188 /***
189 * Sets the 'syntaxPrefix'.
190 *
191 * @param prefix the new value of 'syntaxPrefix'
192 */
193 public void setSyntaxPrefix(String prefix)
194 {
195 this.defaultSyntaxPrefix = prefix;
196 }
197
198 /***
199 * Returns the 'syntaxPrefix'.
200 *
201 * @return the 'syntaxPrefix'
202 */
203 public String getSyntaxPrefix()
204 {
205 return this.defaultSyntaxPrefix;
206 }
207
208 /***
209 * Sets the 'newLine'.
210 *
211 * @param newline the new value of 'newLine'
212 */
213 public void setNewLine(String newline)
214 {
215 this.defaultNewLine = newline;
216 }
217
218 /***
219 * Returns the 'newLine'.
220 *
221 * @return the 'newLine'
222 */
223 public String getNewLine()
224 {
225 return this.defaultNewLine;
226 }
227
228 /***
229 * Sets the 'optPrefix'.
230 *
231 * @param prefix the new value of 'optPrefix'
232 */
233 public void setOptPrefix(String prefix)
234 {
235 this.defaultOptPrefix = prefix;
236 }
237
238 /***
239 * Returns the 'optPrefix'.
240 *
241 * @return the 'optPrefix'
242 */
243 public String getOptPrefix()
244 {
245 return this.defaultOptPrefix;
246 }
247
248 /***
249 * Sets the 'longOptPrefix'.
250 *
251 * @param prefix the new value of 'longOptPrefix'
252 */
253 public void setLongOptPrefix(String prefix)
254 {
255 this.defaultLongOptPrefix = prefix;
256 }
257
258 /***
259 * Returns the 'longOptPrefix'.
260 *
261 * @return the 'longOptPrefix'
262 */
263 public String getLongOptPrefix()
264 {
265 return this.defaultLongOptPrefix;
266 }
267
268 /***
269 * Sets the 'argName'.
270 *
271 * @param name the new value of 'argName'
272 */
273 public void setArgName(String name)
274 {
275 this.defaultArgName = name;
276 }
277
278 /***
279 * Returns the 'argName'.
280 *
281 * @return the 'argName'
282 */
283 public String getArgName()
284 {
285 return this.defaultArgName;
286 }
287
288
289
290
291 /***
292 * <p>Print the help for <code>options</code> with the specified
293 * command line syntax. This method prints help information to
294 * System.out.</p>
295 *
296 * @param cmdLineSyntax the syntax for this application
297 * @param options the Options instance
298 */
299 public void printHelp(String cmdLineSyntax, Options options)
300 {
301 printHelp(defaultWidth, cmdLineSyntax, null, options, null, false);
302 }
303
304 /***
305 * <p>Print the help for <code>options</code> with the specified
306 * command line syntax. This method prints help information to
307 * System.out.</p>
308 *
309 * @param cmdLineSyntax the syntax for this application
310 * @param options the Options instance
311 * @param autoUsage whether to print an automatically generated
312 * usage statement
313 */
314 public void printHelp(String cmdLineSyntax, Options options,
315 boolean autoUsage)
316 {
317 printHelp(defaultWidth, cmdLineSyntax, null, options, null, autoUsage);
318 }
319
320 /***
321 * <p>Print the help for <code>options</code> with the specified
322 * command line syntax. This method prints help information to
323 * System.out.</p>
324 *
325 * @param cmdLineSyntax the syntax for this application
326 * @param header the banner to display at the begining of the help
327 * @param options the Options instance
328 * @param footer the banner to display at the end of the help
329 */
330 public void printHelp(String cmdLineSyntax, String header, Options options,
331 String footer)
332 {
333 printHelp(cmdLineSyntax, header, options, footer, false);
334 }
335
336 /***
337 * <p>Print the help for <code>options</code> with the specified
338 * command line syntax. This method prints help information to
339 * System.out.</p>
340 *
341 * @param cmdLineSyntax the syntax for this application
342 * @param header the banner to display at the begining of the help
343 * @param options the Options instance
344 * @param footer the banner to display at the end of the help
345 * @param autoUsage whether to print an automatically generated
346 * usage statement
347 */
348 public void printHelp(String cmdLineSyntax, String header, Options options,
349 String footer, boolean autoUsage)
350 {
351 printHelp(defaultWidth, cmdLineSyntax, header, options, footer,
352 autoUsage);
353 }
354
355 /***
356 * <p>Print the help for <code>options</code> with the specified
357 * command line syntax. This method prints help information to
358 * System.out.</p>
359 *
360 * @param width the number of characters to be displayed on each line
361 * @param cmdLineSyntax the syntax for this application
362 * @param header the banner to display at the begining of the help
363 * @param options the Options instance
364 * @param footer the banner to display at the end of the help
365 */
366 public void printHelp(int width, String cmdLineSyntax, String header,
367 Options options, String footer)
368 {
369 printHelp(width, cmdLineSyntax, header, options, footer, false);
370 }
371
372 /***
373 * <p>Print the help for <code>options</code> with the specified
374 * command line syntax. This method prints help information to
375 * System.out.</p>
376 *
377 * @param width the number of characters to be displayed on each line
378 * @param cmdLineSyntax the syntax for this application
379 * @param header the banner to display at the begining of the help
380 * @param options the Options instance
381 * @param footer the banner to display at the end of the help
382 * @param autoUsage whether to print an automatically generated
383 * usage statement
384 */
385 public void printHelp(int width, String cmdLineSyntax, String header,
386 Options options, String footer, boolean autoUsage)
387 {
388 PrintWriter pw = new PrintWriter(System.out);
389
390 printHelp(pw, width, cmdLineSyntax, header, options, defaultLeftPad,
391 defaultDescPad, footer, autoUsage);
392 pw.flush();
393 }
394
395 /***
396 * <p>Print the help for <code>options</code> with the specified
397 * command line syntax.</p>
398 *
399 * @param pw the writer to which the help will be written
400 * @param width the number of characters to be displayed on each line
401 * @param cmdLineSyntax the syntax for this application
402 * @param header the banner to display at the begining of the help
403 * @param options the Options instance
404 * @param leftPad the number of characters of padding to be prefixed
405 * to each line
406 * @param descPad the number of characters of padding to be prefixed
407 * to each description line
408 * @param footer the banner to display at the end of the help
409 */
410 public void printHelp(PrintWriter pw, int width, String cmdLineSyntax,
411 String header, Options options, int leftPad,
412 int descPad, String footer)
413 {
414 printHelp(pw, width, cmdLineSyntax, header, options, leftPad, descPad,
415 footer, false);
416 }
417
418
419 /***
420 * <p>Print the help for <code>options</code> with the specified
421 * command line syntax.</p>
422 *
423 * @param pw the writer to which the help will be written
424 * @param width the number of characters to be displayed on each line
425 * @param cmdLineSyntax the syntax for this application
426 * @param header the banner to display at the begining of the help
427 * @param options the Options instance
428 * @param leftPad the number of characters of padding to be prefixed
429 * to each line
430 * @param descPad the number of characters of padding to be prefixed
431 * to each description line
432 * @param footer the banner to display at the end of the help
433 * @param autoUsage whether to print an automatically generated
434 * usage statement
435 */
436 public void printHelp(PrintWriter pw, int width, String cmdLineSyntax,
437 String header, Options options, int leftPad,
438 int descPad, String footer, boolean autoUsage)
439 {
440 if ((cmdLineSyntax == null) || (cmdLineSyntax.length() == 0))
441 {
442 throw new IllegalArgumentException("cmdLineSyntax not provided");
443 }
444
445 if (autoUsage)
446 {
447 printUsage(pw, width, cmdLineSyntax, options);
448 }
449 else
450 {
451 printUsage(pw, width, cmdLineSyntax);
452 }
453
454 if ((header != null) && (header.trim().length() > 0))
455 {
456 printWrapped(pw, width, header);
457 }
458
459 printOptions(pw, width, options, leftPad, descPad);
460
461 if ((footer != null) && (footer.trim().length() > 0))
462 {
463 printWrapped(pw, width, footer);
464 }
465 }
466
467 /***
468 * <p>Prints the usage statement for the specified application.</p>
469 *
470 * @param pw The PrintWriter to print the usage statement
471 * @param width The number of characters to display per line
472 * @param app The application name
473 * @param options The command line Options
474 *
475 */
476 public void printUsage(PrintWriter pw, int width, String app,
477 Options options)
478 {
479
480 StringBuffer buff = new StringBuffer(defaultSyntaxPrefix).append(app)
481 .append(" ");
482
483
484 final Collection processedGroups = new ArrayList();
485
486
487 Option option;
488
489 List optList = new ArrayList(options.getOptions());
490 Collections.sort(optList, new OptionComparator());
491
492 for (Iterator i = optList.iterator(); i.hasNext();)
493 {
494
495 option = (Option) i.next();
496
497
498 OptionGroup group = options.getOptionGroup(option);
499
500
501 if (group != null)
502 {
503
504 if (!processedGroups.contains(group))
505 {
506
507 processedGroups.add(group);
508
509
510
511 appendOptionGroup(buff, group);
512 }
513
514
515
516 }
517
518
519 else
520 {
521 appendOption(buff, option, option.isRequired());
522 }
523
524 if (i.hasNext())
525 {
526 buff.append(" ");
527 }
528 }
529
530
531
532 printWrapped(pw, width, buff.toString().indexOf(' ') + 1,
533 buff.toString());
534 }
535
536 /***
537 * Appends the usage clause for an OptionGroup to a StringBuffer.
538 * The clause is wrapped in square brackets if the group is required.
539 * The display of the options is handled by appendOption
540 * @param buff the StringBuffer to append to
541 * @param group the group to append
542 * @see #appendOption(StringBuffer,Option,boolean)
543 */
544 private static void appendOptionGroup(final StringBuffer buff,
545 final OptionGroup group)
546 {
547 if (!group.isRequired())
548 {
549 buff.append("[");
550 }
551
552 List optList = new ArrayList(group.getOptions());
553 Collections.sort(optList, new OptionComparator());
554
555 for (Iterator i = optList.iterator(); i.hasNext();)
556 {
557
558 appendOption(buff, (Option) i.next(), true);
559
560 if (i.hasNext())
561 {
562 buff.append(" | ");
563 }
564 }
565
566 if (!group.isRequired())
567 {
568 buff.append("]");
569 }
570 }
571
572 /***
573 * Appends the usage clause for an Option to a StringBuffer.
574 *
575 * @param buff the StringBuffer to append to
576 * @param option the Option to append
577 * @param required whether the Option is required or not
578 */
579 private static void appendOption(final StringBuffer buff,
580 final Option option,
581 final boolean required)
582 {
583 if (!required)
584 {
585 buff.append("[");
586 }
587
588 if (option.getOpt() != null)
589 {
590 buff.append("-").append(option.getOpt());
591 }
592 else
593 {
594 buff.append("--").append(option.getLongOpt());
595 }
596
597
598 if (option.hasArg() && (option.getArgName() != null))
599 {
600 buff.append(" <").append(option.getArgName()).append(">");
601 }
602
603
604 if (!required)
605 {
606 buff.append("]");
607 }
608 }
609
610 /***
611 * <p>Print the cmdLineSyntax to the specified writer, using the
612 * specified width.</p>
613 *
614 * @param pw The printWriter to write the help to
615 * @param width The number of characters per line for the usage statement.
616 * @param cmdLineSyntax The usage statement.
617 */
618 public void printUsage(PrintWriter pw, int width, String cmdLineSyntax)
619 {
620 int argPos = cmdLineSyntax.indexOf(' ') + 1;
621
622 printWrapped(pw, width, defaultSyntaxPrefix.length() + argPos,
623 defaultSyntaxPrefix + cmdLineSyntax);
624 }
625
626 /***
627 * <p>Print the help for the specified Options to the specified writer,
628 * using the specified width, left padding and description padding.</p>
629 *
630 * @param pw The printWriter to write the help to
631 * @param width The number of characters to display per line
632 * @param options The command line Options
633 * @param leftPad the number of characters of padding to be prefixed
634 * to each line
635 * @param descPad the number of characters of padding to be prefixed
636 * to each description line
637 */
638 public void printOptions(PrintWriter pw, int width, Options options,
639 int leftPad, int descPad)
640 {
641 StringBuffer sb = new StringBuffer();
642
643 renderOptions(sb, width, options, leftPad, descPad);
644 pw.println(sb.toString());
645 }
646
647 /***
648 * <p>Print the specified text to the specified PrintWriter.</p>
649 *
650 * @param pw The printWriter to write the help to
651 * @param width The number of characters to display per line
652 * @param text The text to be written to the PrintWriter
653 */
654 public void printWrapped(PrintWriter pw, int width, String text)
655 {
656 printWrapped(pw, width, 0, text);
657 }
658
659 /***
660 * <p>Print the specified text to the specified PrintWriter.</p>
661 *
662 * @param pw The printWriter to write the help to
663 * @param width The number of characters to display per line
664 * @param nextLineTabStop The position on the next line for the first tab.
665 * @param text The text to be written to the PrintWriter
666 */
667 public void printWrapped(PrintWriter pw, int width, int nextLineTabStop,
668 String text)
669 {
670 StringBuffer sb = new StringBuffer(text.length());
671
672 renderWrappedText(sb, width, nextLineTabStop, text);
673 pw.println(sb.toString());
674 }
675
676
677
678 /***
679 * <p>Render the specified Options and return the rendered Options
680 * in a StringBuffer.</p>
681 *
682 * @param sb The StringBuffer to place the rendered Options into.
683 * @param width The number of characters to display per line
684 * @param options The command line Options
685 * @param leftPad the number of characters of padding to be prefixed
686 * to each line
687 * @param descPad the number of characters of padding to be prefixed
688 * to each description line
689 *
690 * @return the StringBuffer with the rendered Options contents.
691 */
692 protected StringBuffer renderOptions(StringBuffer sb, int width,
693 Options options, int leftPad,
694 int descPad)
695 {
696 final String lpad = createPadding(leftPad);
697 final String dpad = createPadding(descPad);
698
699
700
701
702
703 int max = 0;
704 StringBuffer optBuf;
705 List prefixList = new ArrayList();
706 Option option;
707 List optList = options.helpOptions();
708
709 Collections.sort(optList, new OptionComparator());
710
711 for (Iterator i = optList.iterator(); i.hasNext();)
712 {
713 option = (Option) i.next();
714 optBuf = new StringBuffer(8);
715
716 if (option.getOpt() == null)
717 {
718 optBuf.append(lpad).append(" " + defaultLongOptPrefix)
719 .append(option.getLongOpt());
720 }
721 else
722 {
723 optBuf.append(lpad).append(defaultOptPrefix)
724 .append(option.getOpt());
725
726 if (option.hasLongOpt())
727 {
728 optBuf.append(',').append(defaultLongOptPrefix)
729 .append(option.getLongOpt());
730 }
731 }
732
733 if (option.hasArg())
734 {
735 if (option.hasArgName())
736 {
737 optBuf.append(" <").append(option.getArgName()).append(">");
738 }
739 else
740 {
741 optBuf.append(' ');
742 }
743 }
744
745 prefixList.add(optBuf);
746 max = (optBuf.length() > max) ? optBuf.length() : max;
747 }
748
749 int x = 0;
750
751 for (Iterator i = optList.iterator(); i.hasNext();)
752 {
753 option = (Option) i.next();
754 optBuf = new StringBuffer(prefixList.get(x++).toString());
755
756 if (optBuf.length() < max)
757 {
758 optBuf.append(createPadding(max - optBuf.length()));
759 }
760
761 optBuf.append(dpad);
762
763 int nextLineTabStop = max + descPad;
764
765 if (option.getDescription() != null)
766 {
767 optBuf.append(option.getDescription());
768 }
769
770 renderWrappedText(sb, width, nextLineTabStop, optBuf.toString());
771
772 if (i.hasNext())
773 {
774 sb.append(defaultNewLine);
775 }
776 }
777
778 return sb;
779 }
780
781 /***
782 * <p>Render the specified text and return the rendered Options
783 * in a StringBuffer.</p>
784 *
785 * @param sb The StringBuffer to place the rendered text into.
786 * @param width The number of characters to display per line
787 * @param nextLineTabStop The position on the next line for the first tab.
788 * @param text The text to be rendered.
789 *
790 * @return the StringBuffer with the rendered Options contents.
791 */
792 protected StringBuffer renderWrappedText(StringBuffer sb, int width,
793 int nextLineTabStop, String text)
794 {
795 int pos = findWrapPos(text, width, 0);
796
797 if (pos == -1)
798 {
799 sb.append(rtrim(text));
800
801 return sb;
802 }
803 sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
804
805
806
807 final String padding = createPadding(nextLineTabStop);
808
809 while (true)
810 {
811 text = padding + text.substring(pos).trim();
812 pos = findWrapPos(text, width, nextLineTabStop);
813
814 if (pos == -1)
815 {
816 sb.append(text);
817
818 return sb;
819 }
820
821 sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
822 }
823 }
824
825 /***
826 * Finds the next text wrap position after <code>startPos</code> for the
827 * text in <code>text</code> with the column width <code>width</code>.
828 * The wrap point is the last postion before startPos+width having a
829 * whitespace character (space, \n, \r).
830 *
831 * @param text The text being searched for the wrap position
832 * @param width width of the wrapped text
833 * @param startPos position from which to start the lookup whitespace
834 * character
835 * @return postion on which the text must be wrapped or -1 if the wrap
836 * position is at the end of the text
837 */
838 protected int findWrapPos(String text, int width, int startPos)
839 {
840 int pos = -1;
841
842
843 if (((pos = text.indexOf('\n', startPos)) != -1 && pos <= width)
844 || ((pos = text.indexOf('\t', startPos)) != -1 && pos <= width))
845 {
846 return pos+1;
847 }
848 else if ((startPos + width) >= text.length())
849 {
850 return -1;
851 }
852
853
854
855 pos = startPos + width;
856
857 char c;
858
859 while ((pos >= startPos) && ((c = text.charAt(pos)) != ' ')
860 && (c != '\n') && (c != '\r'))
861 {
862 --pos;
863 }
864
865
866 if (pos > startPos)
867 {
868 return pos;
869 }
870
871
872
873 pos = startPos + width;
874
875 while ((pos <= text.length()) && ((c = text.charAt(pos)) != ' ')
876 && (c != '\n') && (c != '\r'))
877 {
878 ++pos;
879 }
880
881 return (pos == text.length()) ? (-1) : pos;
882 }
883
884 /***
885 * <p>Return a String of padding of length <code>len</code>.</p>
886 *
887 * @param len The length of the String of padding to create.
888 *
889 * @return The String of padding
890 */
891 protected String createPadding(int len)
892 {
893 StringBuffer sb = new StringBuffer(len);
894
895 for (int i = 0; i < len; ++i)
896 {
897 sb.append(' ');
898 }
899
900 return sb.toString();
901 }
902
903 /***
904 * <p>Remove the trailing whitespace from the specified String.</p>
905 *
906 * @param s The String to remove the trailing padding from.
907 *
908 * @return The String of without the trailing padding
909 */
910 protected String rtrim(String s)
911 {
912 if ((s == null) || (s.length() == 0))
913 {
914 return s;
915 }
916
917 int pos = s.length();
918
919 while ((pos > 0) && Character.isWhitespace(s.charAt(pos - 1)))
920 {
921 --pos;
922 }
923
924 return s.substring(0, pos);
925 }
926
927
928
929
930 /***
931 * <p>This class implements the <code>Comparator</code> interface
932 * for comparing Options.</p>
933 */
934 private static class OptionComparator
935 implements Comparator {
936
937 /***
938 * <p>Compares its two arguments for order. Returns a negative
939 * integer, zero, or a positive integer as the first argument
940 * is less than, equal to, or greater than the second.</p>
941 *
942 * @param o1 The first Option to be compared.
943 * @param o2 The second Option to be compared.
944 *
945 * @return a negative integer, zero, or a positive integer as
946 * the first argument is less than, equal to, or greater than the
947 * second.
948 */
949 public int compare(Object o1, Object o2)
950 {
951 Option opt1 = (Option)o1;
952 Option opt2 = (Option)o2;
953
954 return opt1.getKey().compareToIgnoreCase(opt2.getKey());
955 }
956 }
957 }