001: /*
002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: *
005: * File:CLIPParser.java
006: *
007: * Date - Dec/15/2001
008: * @author - alejandro.abdelnur@sun.com
009: * @author Raja Nagendra Kumar, Nagendra.Raja@sun.com *
010: */
011: package com.sun.portal.rewriter.util.clip;
012:
013: import java.util.ArrayList;
014: import java.util.HashMap;
015: import java.util.Iterator;
016: import java.util.List;
017: import java.util.Map;
018: import java.util.StringTokenizer;
019:
020: public class CLIPParser {
021: private String toolHelpMessageID;
022: private final Map subCommandsList = new HashMap();
023: private final List orderedSubCommandsList = new ArrayList();
024:
025: /**
026: * Creates a CLIP parser instance with a set of sub commands.
027: * @param aSubCommands array of sub commands for the CLIPParser.
028: * @param aToolHelpMessage message for the command.
029: * @throws IllegalArgumentException if invalid information is passed.
030: */
031: public CLIPParser(final CLIPSubCommand[] aSubCommands,
032: final String aToolHelpMessage)
033: throws IllegalArgumentException {
034: toolHelpMessageID = aToolHelpMessage;
035:
036: if (aSubCommands == null || aSubCommands.length == 0) {
037: throw new IllegalArgumentException(
038: "CLIPParser - sub command array can not be null or empty");
039: }
040:
041: for (int i = 0; i < aSubCommands.length; i++) {
042: if (aSubCommands[i].getSubCommandName() == null) {
043: throw new IllegalArgumentException(
044: "CLIPSubCommand can not be null");
045: }
046: addSubCommand(aSubCommands[i]);
047: }//for loop
048: }//constructor
049:
050: /**
051: * Creates a CLIP parser instance with no sub commands.
052: * @param options array with all the valid options for the sub command,
053: * or NULL if the sub command expects no options.
054: * @param minOperands minimum number of operands the sub command expects.
055: * @param maxOperands maximum number of operands the sub command expects.
056: * @param aCommandHelpMessage help message for the command.
057: * @param operandsHelp help message for the operands.
058: * @throws IllegalArgumentException if invalid information is passed.
059: */
060: public CLIPParser(final CLIPOption[] options,
061: final int minOperands, final int maxOperands,
062: final String aCommandHelpMessage, final String operandsHelp)
063: throws IllegalArgumentException {
064: final CLIPSubCommand subCommand = new CLIPSubCommand(null,
065: options, minOperands, maxOperands, operandsHelp,
066: aCommandHelpMessage);
067: addSubCommand(subCommand);
068: }//constructor
069:
070: private void addSubCommand(final CLIPSubCommand subCommand)
071: throws IllegalArgumentException {
072: if (subCommand.getSubCommandName() != null) {
073: verifyName(subCommand.getSubCommandName(), "CLIPSubCommand");
074: }
075:
076: if (subCommandsList.containsKey(subCommand.getSubCommandName())) {
077: throw new IllegalArgumentException("CLIPSubCommand '"
078: + subCommand.getSubCommandName()
079: + "', sub command already defined");
080: }
081:
082: subCommandsList.put(subCommand.getSubCommandName(), subCommand);
083: orderedSubCommandsList.add(subCommand);
084: }//addSubCommand()
085:
086: public String getToolHelp() {
087: return CLIPSpec.getLocaleHelper().getLocalizedString(
088: toolHelpMessageID);
089: }//getToolHelp()
090:
091: /**
092: * Verifies the argument array is valid for the CLIP parser definition.
093: * @param args argument array to verify.
094: * processed successfuly.
095: */
096: public void verifyArguments(final String[] args) {
097: try {
098: //do't check if args contain one of the std options
099: if (scanForStdExitOptions(args) != null) {
100: return;
101: }
102:
103: getSubCommand(args);
104: getOptions(args);
105: getOperands(args);
106: } catch (CLIPException e) {
107: System.err.println(e);
108: System.out.println(getHelp(args));
109: System.exit(0);
110: }//try/catch
111: }//verifyArgments()
112:
113: /**
114: * Returns the sub command from the argument array.
115: * @param args argument array to parse for sub command.
116: * @return the entered sub command or NULL if no sub command was found.
117: * @throws CLIPException thrown if the sub command is invalid.
118: */
119: public String getSubCommand(final String[] args)
120: throws CLIPException {
121: final boolean hasSubCommands = !subCommandsList
122: .containsKey(null);
123: final String firstArgument = (args.length > 0 && hasSubCommands) ? args[0]
124: : null;
125: final CLIPSubCommand subCommand = (CLIPSubCommand) subCommandsList
126: .get(firstArgument);
127:
128: if (subCommand == null) {
129: throw new CLIPException(CLIPSpec.getLocaleHelper()
130: .getLocalizedString("errorInvalidSubCmd",
131: new Object[] { firstArgument }), 0);
132: }
133:
134: return firstArgument;
135: }//getSubCommand();
136:
137: /**
138: * Returns a Map with all the (key,value) for all the options.
139: * <P>
140: * The key is the option long name.
141: * <P>
142: * The value is always a String array, it's length is always one except if
143: * it's a collection option, then the
144: * length is the number of collection values in the option.
145: * <P>
146: * If the option is a boolean option (not option value or it a negated option
147: * "--no-<OPTION>") the value will be
148: * <B>true</B> or <B>false</B>.
149: * <P>
150: *
151: * @param args argument array to parse for options.
152: *
153: * @return a Map instance with all the options of the argument array.
154: *
155: * @throws CLIPException thrown if there are invalid or incorrect options
156: * in the argument array or if mandatory options are missing from the
157: * argument array.
158: */
159: public Map getOptions(final String[] args) throws CLIPException {
160: final CLIPSubCommand subCommand = (CLIPSubCommand) subCommandsList
161: .get(getSubCommand(args));
162: final Map map = new HashMap();
163:
164: Iterator i = ((subCommand.getDefaultOptionValues()).keySet())
165: .iterator();
166: while (i.hasNext()) {
167: String optionName = (String) i.next();
168: List optionValues = (List) subCommand
169: .getDefaultOptionValues().get(optionName);
170: map.put(optionName, ((ArrayList) optionValues).clone());
171: }
172:
173: final int argumentIndex = processOptions(args, map);
174: i = subCommand.getValidOptions().keySet().iterator();
175: while (i.hasNext()) {
176: String optionName = (String) i.next();
177: CLIPOption option = (CLIPOption) subCommand
178: .getValidOptions().get(optionName);
179:
180: if (option.getDefaultValues() == null
181: && !map.containsKey(option.getLongName())) {
182: throw new CLIPException(CLIPSpec.getLocaleHelper()
183: .getLocalizedString(
184: "errorMissingMandatoryOption",
185: new Object[] { option.getLongName() }),
186: argumentIndex);
187: }
188: }
189: return massageOptions(map);
190: }//getOptions()
191:
192: /**
193: * Returns a String array with all the operands of the argument array.
194: * <P>
195: * All the operands after the options end or after the operand demarcator "--".
196: * <P>
197: *
198: * @param args argument array to parse for operands.
199: * @return all the operands from the argument array, if the argument array has no operands it returns an empty array.
200: * @throws CLIPException thrown if the operands can not be process because errors in the options or if the number
201: * of operands in the argument array is outside of the minimum and maximum operand boundaries.
202: */
203: public String[] getOperands(final String[] args)
204: throws CLIPException {
205: final CLIPSubCommand subCommand = (CLIPSubCommand) subCommandsList
206: .get(getSubCommand(args));
207: final int i = processOptions(args, new HashMap());
208: final int numberOfOperands = args.length - i;
209:
210: if (subCommand.getMinOperands() > numberOfOperands
211: || numberOfOperands > subCommand.getMaxOperands()) {
212: throw new CLIPException(CLIPSpec.getLocaleHelper()
213: .getLocalizedString("errorInvalidOperandsCount"), i);
214: }
215:
216: for (int j = i; j < args.length; j++) {
217: if (args[j].equals("--")) {
218: throw new CLIPException(CLIPSpec.getLocaleHelper()
219: .getLocalizedString(
220: "errorDashDashCantBeOperand"), j);
221: }
222: }
223:
224: String[] operands = new String[numberOfOperands];
225: if (args.length > 0) {
226: System.arraycopy(args, i, operands, 0, numberOfOperands);
227: }
228: return operands;
229: }//getOpterands()
230:
231: /**
232: * Process options and returns index where operands start.
233: * Used by getOptions and getOperands.
234: */
235: private int processOptions(final String[] args, final Map map)
236: throws CLIPException {
237: final CLIPSubCommand subCommand = (CLIPSubCommand) subCommandsList
238: .get(getSubCommand(args));
239: boolean allOptionsProcessed = false;
240: int i = (subCommand.getSubCommandName() != null) ? 1 : 0;
241: while (!allOptionsProcessed && i < args.length) {
242: if (args[i]
243: .startsWith(CLIPConstants.ADD_TO_COLLECTION_OPTION)) {
244: String optionName = args[i]
245: .substring(CLIPConstants.ADD_TO_COLLECTION_OPTION
246: .length());
247: CLIPOption option = (CLIPOption) subCommand
248: .getValidOptions().get(optionName);
249:
250: if (optionName.length() < 2 || option == null) {
251: throw new CLIPException(CLIPSpec.getLocaleHelper()
252: .getLocalizedString("errorInvalidOption",
253: new Object[] { optionName }), i);
254: }
255:
256: if (option.getType() != CLIPConstants.COLLECTION) {
257: throw new CLIPException(CLIPSpec.getLocaleHelper()
258: .getLocalizedString("errorNotACollection",
259: new Object[] { optionName }), i);
260: }
261:
262: List values = getOptionValues(subCommand, map,
263: optionName);
264: if ((i + 1) == args.length) {
265: throw new CLIPException(
266: CLIPSpec
267: .getLocaleHelper()
268: .getLocalizedString(
269: "errorMissingCollectionValuesToAdd",
270: new Object[] { optionName }),
271: i);
272: } else {
273: i++;
274: String optionValue = args[i];
275: StringTokenizer tokens = new StringTokenizer(
276: optionValue,
277: (optionValue.indexOf(" ") > -1) ? " " : ",");
278:
279: while (tokens.hasMoreTokens()) {
280: String token = tokens.nextToken();
281: values.add(token);
282: }
283: }
284: } else if (args[i]
285: .startsWith(CLIPConstants.REMOVE_FROM_COLLECTION_OPTION)) {
286: String optionName = args[i]
287: .substring(CLIPConstants.REMOVE_FROM_COLLECTION_OPTION
288: .length());
289: CLIPOption option = (CLIPOption) subCommand
290: .getValidOptions().get(optionName);
291:
292: if (optionName.length() < 2 || option == null) {
293: throw new CLIPException(CLIPSpec.getLocaleHelper()
294: .getLocalizedString("errorInvalidOption",
295: new Object[] { optionName }), i);
296: }
297:
298: if (option.getType() != CLIPConstants.COLLECTION) {
299: throw new CLIPException(CLIPSpec.getLocaleHelper()
300: .getLocalizedString("errorNotACollection",
301: new Object[] { optionName }), i);
302: }
303:
304: if ((i + 1) == args.length) {
305: throw new CLIPException(
306: CLIPSpec
307: .getLocaleHelper()
308: .getLocalizedString(
309: "errorMissingCollectionValuesToDelete",
310: new Object[] { optionName }),
311: i);
312: } else {
313: i++;
314: List values = getOptionValues(subCommand, map,
315: optionName);
316: String optionValue = args[i];
317: StringTokenizer tokens = new StringTokenizer(
318: optionValue,
319: (optionValue.indexOf(" ") > -1) ? " " : ",");
320:
321: while (tokens.hasMoreTokens()) {
322: String token = tokens.nextToken();
323:
324: if (values.contains(token)) {
325: values.remove(token);
326: } else { // if the option value is name/value pair, removes if name is specified
327: for (int j = 0; j < values.size(); j++) {
328: String v = (String) values.get(j);
329: if (v.startsWith(token + "=")) {
330: values.remove(j);
331: }
332: }
333: }
334: }
335: }
336: } else if (args[i].equals(CLIPConstants.NO_MORE_OPTIONS)) { // only operands follow, stop processing options
337: i++;
338: allOptionsProcessed = true;
339: } else if (args[i].startsWith(CLIPConstants.NEGATE_OPTION)) {
340: String optionName = args[i]
341: .substring(CLIPConstants.NEGATE_OPTION.length());
342: CLIPOption option = (CLIPOption) subCommand
343: .getValidOptions().get(optionName);
344: if (option == null) {
345: throw new CLIPException(CLIPSpec.getLocaleHelper()
346: .getLocalizedString("errorInvalidOption",
347: new Object[] { optionName }), i);
348: }
349: if (option.getType() != CLIPConstants.BOOLEAN) {
350: throw new CLIPException(CLIPSpec.getLocaleHelper()
351: .getLocalizedString("errorNotABoolean",
352: new Object[] { optionName }), i);
353: }
354: String optionValue = "false";
355: List values = getOptionValues(subCommand, map,
356: optionName);
357: values.clear();
358: values.add(optionValue);
359: } else if (args[i].startsWith(CLIPConstants.LONG_OPTION)) {
360: String optionName = args[i]
361: .substring(CLIPConstants.LONG_OPTION.length());
362: CLIPOption option = (CLIPOption) subCommand
363: .getValidOptions().get(optionName);
364: if (option == null) {
365: throw new CLIPException(CLIPSpec.getLocaleHelper()
366: .getLocalizedString("errorInvalidOption",
367: new Object[] { optionName }), i);
368: } else if (option.getType() == CLIPConstants.COLLECTION) {
369: if ((i + 1) == args.length) {
370: throw new CLIPException(
371: CLIPSpec
372: .getLocaleHelper()
373: .getLocalizedString(
374: "errorMissingCollectionOptionValue",
375: new Object[] { optionName }),
376: i);
377: } else {
378: i++;
379: String optionValue = args[i];
380: List values = getOptionValues(subCommand, map,
381: optionName);
382: values.clear();
383: StringTokenizer tokens = new StringTokenizer(
384: optionValue,
385: (optionValue.indexOf(" ") > -1) ? " "
386: : ",");
387: while (tokens.hasMoreTokens()) {
388: String token = tokens.nextToken();
389: values.add(token);
390: }
391: }
392: } else {
393: i = handleRest(args, subCommand, option,
394: optionName, map, i);
395: }
396: } else if (args[i].startsWith(CLIPConstants.SHORT_OPTION)) {
397: String optionName = args[i]
398: .substring(CLIPConstants.SHORT_OPTION.length());
399:
400: // process a set of short options within a single -, all but the last have to be of boolean type
401: for (int j = 0; j < optionName.length() - 1; j++) {
402: String shortOptionName = "" + optionName.charAt(j);
403: CLIPOption option = (CLIPOption) subCommand
404: .getValidOptions().get(shortOptionName);
405: if (option == null) {
406: throw new CLIPException(
407: CLIPSpec
408: .getLocaleHelper()
409: .getLocalizedString(
410: "errorInvalidOption",
411: new Object[] { shortOptionName }),
412: i);
413: } else if (option.getType() == CLIPConstants.BOOLEAN) {
414: String optionValue = "true";
415: List values = getOptionValues(subCommand, map,
416: shortOptionName);
417: values.clear();
418: values.add(optionValue);
419: } else {
420: throw new CLIPException(
421: CLIPSpec
422: .getLocaleHelper()
423: .getLocalizedString(
424: "errorNotABooleanOption",
425: new Object[] { shortOptionName }),
426: i);
427: }
428: }
429: optionName = ""
430: + optionName.charAt(optionName.length() - 1);
431:
432: CLIPOption option = (CLIPOption) subCommand
433: .getValidOptions().get(optionName);
434: i = checkBoolAndRegular(args, subCommand, optionName,
435: option, i, map);
436: } else {
437: allOptionsProcessed = true;
438: }
439: i++;
440: }
441:
442: if (allOptionsProcessed) {
443: i--;
444: }
445:
446: return i;
447: }//processOptions()
448:
449: private int checkBoolAndRegular(final String[] args,
450: final CLIPSubCommand aSubCommand, String aOptionName,
451: CLIPOption aOption, int aI, final Map map)
452: throws CLIPException {
453: if (aOption == null) {
454: throw new CLIPException(CLIPSpec.getLocaleHelper()
455: .getLocalizedString("errorInvalidOption",
456: new Object[] { aOptionName }), aI);
457: } else {
458: return handleRest(args, aSubCommand, aOption, aOptionName,
459: map, aI);
460: }
461: }//checkBoolAndRegular()
462:
463: private int handleRest(final String[] aArgs,
464: final CLIPSubCommand aSubCommand, CLIPOption aOption,
465: String aOptionName, final Map aMap, int aIndex)
466: throws CLIPException {
467: if (aOption.getType() == CLIPConstants.BOOLEAN) {
468: String optionValue = "true";
469: List values = getOptionValues(aSubCommand, aMap,
470: aOptionName);
471: values.clear();
472: values.add(optionValue);
473: } else if (aOption.getType() == CLIPConstants.REGULAR) {
474: if ((aIndex + 1) == aArgs.length) {
475: throw new CLIPException(CLIPSpec.getLocaleHelper()
476: .getLocalizedString(
477: "errorMissingRegularOptionValue",
478: new Object[] { aOptionName }), aIndex);
479: } else {
480: aIndex++;
481: String optionValue = aArgs[aIndex];
482: List values = getOptionValues(aSubCommand, aMap,
483: aOptionName);
484: values.clear();
485: values.add(optionValue);
486: }
487: }
488:
489: else {
490: throw new CLIPException(CLIPSpec.getLocaleHelper()
491: .getLocalizedString("clipInternalError"), aIndex);
492: }
493: return aIndex;
494: }
495:
496: /**
497: * Maps from short to long options and creates option value list.
498: */
499: private static List getOptionValues(
500: final CLIPSubCommand subCommand, final Map map,
501: final String optionName) {
502: final CLIPOption option = (CLIPOption) subCommand
503: .getValidOptions().get(optionName);
504: final String longName = option.getLongName();
505:
506: List list = (List) map.get(longName);
507: if (list == null) {
508: list = new ArrayList();
509: map.put(longName, list);
510: }
511: return list;
512: }//getOptionValues()
513:
514: /**
515: * Converts Map entries from List to String[].
516: *
517: */
518: private static Map massageOptions(final Map map) {
519: final Iterator i = map.keySet().iterator();
520: while (i.hasNext()) {
521: String option = (String) i.next();
522: List values = (List) map.get(option);
523: String[] arrayValues = new String[values.size()];
524: values.toArray(arrayValues);
525: map.put(option, arrayValues);
526: }
527:
528: return map;
529: }//messageOptions()
530:
531: /**
532: * Returns the name part of a name/value pair element.
533: * <P>
534: * It uses '=' as the name/value separator.
535: * <P>
536: * @param element the option or operand name/value pair element.
537: * @return the name portion of the name/value pair or the complete
538: * element if there is no value.
539: */
540: public static String getName(final String element) {
541: String name = element;
542:
543: final int index = element.indexOf("=");
544: if (index > -1) {
545: name = element.substring(0, index);
546: }
547:
548: return name;
549: }//getName()
550:
551: /**
552: * Returns the value part of a name/value pair element.
553: * <P>
554: * It uses '=' as the name/value separator.
555: * <P>
556: *
557: * @param element the option or operand name/value pair element.
558: * @return the value portion of the name/value pair or <B>null</B>
559: * if there is not value in the element.
560: */
561: public static String getValue(final String element) {
562: String value = null;
563:
564: final int index = element.indexOf("=");
565: if (index > -1) {
566: value = element.substring(index + 1);
567: }
568:
569: return value;
570: }//getValue()
571:
572: /**
573: * String representation of the processed command arguments.
574: * <P>
575: *
576: * @param args argument array
577: * @return String representation.
578: * @throws CLIPException thrown if the argument array could not be processed successfuly.
579: */
580: public String toString(final String[] args) throws CLIPException {
581: final StringBuffer sb = new StringBuffer(2048);
582: final String subCmd = getSubCommand(args);
583: final Map options = getOptions(args);
584: final String[] operands = getOperands(args);
585: sb.append("\n").append("Sub-command: ").append(subCmd).append(
586: "\n").append("\n").append("Options: ").append("\n");
587:
588: final Iterator i = options.keySet().iterator();
589: while (i.hasNext()) {
590: String option = (String) i.next();
591: String[] values = (String[]) options.get(option);
592: sb.append((" " + option + " ").substring(0,
593: 12)
594: + ": ");
595: for (int j = 0; j < values.length; j++) {
596: sb.append(values[j]).append(" ");
597: }
598: sb.append("\n");
599: }
600:
601: sb.append("\n").append("Operands: ").append("\n");
602:
603: for (int j = 0; j < operands.length; j++) {
604: sb.append(" ").append(operands[j]).append("\n");
605: }
606:
607: sb.append("\n");
608: return sb.toString();
609: }//toString()
610:
611: /**
612: * Returns if the command invocation needs help or not.
613: * <P>
614: * It may be an exlicit request for help, using the --help option,
615: * or because an invalid argument set has been given.
616: * <P>
617: *
618: * @param args the array argument.
619: * @return <B>true</B> if help is needed, <B>false</B> otherwise.
620: */
621: public boolean needsHelp(final String[] args) {
622: boolean help = false;
623: try {
624: verifyArguments(args);
625: Map options = getOptions(args);
626: help = options.containsKey("help")
627: && ((String[]) options.get("help"))[0]
628: .equals("true");
629: } catch (CLIPException ex) {
630: help = true;
631: }
632: return help;
633: }//needsHelp()
634:
635: /**
636: * Returns the Help for the command.
637: * <P>
638: * Using the current arguments determines if a full help or a sub command help
639: * should be returned.
640: * <P>
641: *
642: * @param args the current argument array, to determine the type of help to return.
643: * @return the help for the command.
644: */
645: public String getHelp(final String[] args) {
646: boolean fullHelp = false;
647: final String firstArgument = (args.length > 0) ? args[0] : null;
648: fullHelp = !subCommandsList.containsKey(firstArgument);
649: CLIPSubCommand subCommand;
650:
651: if (!fullHelp) {
652: subCommand = (CLIPSubCommand) subCommandsList
653: .get(firstArgument);
654: } else {
655: subCommand = (CLIPSubCommand) subCommandsList.get(null);
656: fullHelp = ((subCommand == null) || (subCommand
657: .getSubCommandName() != null));
658: }
659:
660: final StringBuffer sb = new StringBuffer(2048);
661: if (fullHelp) {
662: sb.append(getToolHelp()).append("\n\n");
663: sb.append("SUBCOMMANDS\n");
664: int size = orderedSubCommandsList.size();
665: for (int i = 0; i < size; i++) {
666: subCommand = (CLIPSubCommand) orderedSubCommandsList
667: .get(i);
668: String name = subCommand.getSubCommandName();
669: if (name == null) {
670: name = "<NO SUB COMMAND> ";
671: } else {
672: name = name + " ";
673: }
674:
675: sb.append(" ").append(name).append(
676: subCommand.getSubCommandHelp()).append(".\n");
677: printOptionsHelp(sb, " ", subCommand
678: .getOrderedOptions());
679:
680: if (subCommand.getMaxOperands() > 0) {
681: if (subCommand.getMaxOperands() == 1) {
682: sb.append(" <OPERAND> ");
683: } else {
684: sb.append(" <OPERANDS> ");
685: }
686: sb.append(subCommand.getOperandsHelp())
687: .append("\n");
688: }//if
689: }//for loop
690: } else {
691: sb.append(subCommand.getSubCommandHelp()).append(".\n\n");
692: sb.append("OPTIONS\n");
693: printOptionsHelp(sb, " ", subCommand.getOrderedOptions());
694:
695: if (subCommand.getMaxOperands() > 0) {
696: if (subCommand.getMaxOperands() == 1) {
697: sb.append("\nOPERAND\n");
698: } else {
699: sb.append("\nOPERANDS\n");
700: }
701: sb.append(" ").append(subCommand.getOperandsHelp())
702: .append("\n");
703: }//if
704: }//if/else
705: return sb.toString();
706: }//getHelp()
707:
708: /**
709: * Renders the help for a seto of options, used by getHelp.
710: */
711: private static void printOptionsHelp(final StringBuffer sb,
712: final String padding, final List options) {
713: final int size = options.size();
714: for (int i = 0; i < size; i++) {
715: CLIPOption option = (CLIPOption) options.get(i);
716: sb.append(padding);
717:
718: //Bug ID: 4661414
719: if (option.getShortName() == null
720: || option.getShortName().length() == 0) {
721: sb.append(" ");
722: } else {
723: sb.append('-').append(option.getShortName())
724: .append(' ');
725: }
726:
727: sb.append("--").append(option.getLongName()).append(' ');
728: sb.append(option.getHelpMessage()).append(" (");
729:
730: if (option.getDefaultValues() == null) {
731: sb.append("none");
732: } else {
733: for (int j = 0; j < option.getDefaultValues().length; j++) {
734: if (j > 0) {
735: sb.append(' ');
736: }
737: sb.append(option.getDefaultValues()[j]);
738: }
739: }
740:
741: sb.append(")\n");
742: }
743: }//printOptionsHelp()
744:
745: static String scanForStdExitOptions(final String[] args) {
746: //don't check the options if the user has asked for help/version
747: final String stdHelpOption = CLIPConstants.LONG_OPTION
748: + CLIPConstants.OPTION_HELP;
749:
750: final String stdVersionOption = CLIPConstants.LONG_OPTION
751: + CLIPConstants.OPTION_VERSION;
752:
753: for (int i = 0; i < args.length; i++) {
754: if (args[i].equals(stdHelpOption)) {
755: return stdHelpOption;
756: }
757:
758: if (args[i].equals(stdVersionOption)) {
759: return stdVersionOption;
760: }
761: }//for loop
762: return null;
763: }//scanForStdOption()
764:
765: /**
766: * Verifies a name (sub command or long option name ) is well formed.
767: */
768: static void verifyName(final String name,
769: final String exceptionMsgPrefix) {
770: if (name == null || name.length() < 2) {
771: throw new IllegalArgumentException(exceptionMsgPrefix
772: + " has to be at least 2 chars long");
773: }
774:
775: if (name.equals("--")) {
776: throw new IllegalArgumentException(exceptionMsgPrefix
777: + " can not be '--'");
778: }
779:
780: if (name.startsWith("-") || name.endsWith("-")) {
781: throw new IllegalArgumentException(exceptionMsgPrefix
782: + " can not start or end with '-'");
783: }
784:
785: if (!name.equals(name.toLowerCase())) {
786: throw new IllegalArgumentException(exceptionMsgPrefix
787: + " has to be in lower case");
788: }
789: }//verifyName()
790:
791: public String toString() {
792: return "Tool Help Message: " + getToolHelp() + "\n"
793: + "\nSub Command List: " + subCommandsList + "\n";
794: }//toString()
795:
796: }//class CLIPParser
|