KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > cli > framework > CommandLineParser


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.cli.framework;
24
25 import java.io.File JavaDoc;
26 import java.io.FileInputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Vector JavaDoc;
30 import java.util.Properties JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.ListIterator JavaDoc;
33 import java.util.Arrays JavaDoc;
34 import java.util.NoSuchElementException JavaDoc;
35
36 /**
37  * The <code>CommandLineParser</code> object is used to parse the
38  * command line and verify that the command line is CLIP compliant.
39  * @version $Revision: 1.6 $
40  */

41 public class CommandLineParser
42 {
43     
44     // Name of Command
45
private String JavaDoc commandName = null;
46     
47     // List of Short Options from command-line argument
48
private HashMap JavaDoc optionsList = new HashMap JavaDoc();
49     
50     // Array of Operands from command-line argument
51
private Vector JavaDoc Operands = new Vector JavaDoc();
52     
53     //Valid Command object
54
private ValidCommand validCommand = null;
55     
56     //Any short option
57
private static final String JavaDoc ANY_SHORT_OPTION_REGEXP = "^-[^-.*]+";
58
59     // Regular expression for short options
60
private static final String JavaDoc SHORT_OPTION_REGEXP = "^-[\\w?]+";
61     
62     // Regular expression for short option and argument
63
private static final String JavaDoc SHORT_OPTION_ARGUMENT_REGEXP = "^-[\\w?](=.*)";
64     
65     // Regular expression for long option
66
// private static final String LONG_OPTION_REGEXP = "^--.+(=.*)*";
67
private final String JavaDoc LONG_OPTION_REGEXP = "^--\\w[-\\w]*(=.*)*";
68     
69     // Regular expression for command name
70
private static final String JavaDoc COMMAND_NAME_REGEXP = "^[a-z\\-][a-z0-9\\-\\_\\ ]*$";
71
72     // Regular expression of help short option.
73
//help short option can either be -h or -?
74
private static final String JavaDoc SHORT_OPTION_HELP_REGEXP = "-\\w*[?]\\w*";
75
76     // HELP OPTION STRING
77
private static final String JavaDoc HELP_OPTION = "--help";
78
79     //Boolean --no- optoin
80
private static final String JavaDoc BOOLEAN_NO_OPTION = "--no-";
81     
82     // BOOLEAN STRING
83
private static final String JavaDoc BOOLEAN = "boolean";
84     
85     // TRUE STRING
86
private static final String JavaDoc TRUE = "true";
87     
88     // FALSE STRING
89
private static final String JavaDoc FALSE = "false";
90
91     
92     /** Creates new CommandLineParser */
93     public CommandLineParser()
94     {
95     }
96     
97     
98     /** Create new CommandLineParser with the given argument
99      * @param validCommand - ValidCommand object containing the specification
100      * for the command
101      */

102     public CommandLineParser(ValidCommand validCommand)
103     {
104         this.validCommand = validCommand;
105     }
106     
107         
108     /** Creates new CommandLineParser with the given argument
109      * @param args - command line arguments
110      * @param validCommand - ValidCommand object containing the specification
111      * for the command
112      * @throws CommandValidationException if command name is invalid
113      */

114     public CommandLineParser(String JavaDoc[] args, ValidCommand validCommand)
115         throws CommandValidationException, HelpException
116     {
117         this.validCommand = validCommand;
118         if (validCommand != null)
119         {
120             parseCommandLine(args);
121         }
122         
123     }
124     
125     
126     
127     /** Parse the command line arguments accordingly to CLIP
128      * @param args - command line arguments
129      * @throws CommandValidationException if command name is invalid
130      */

131     public void parseCommandLine(final String JavaDoc[] args)
132         throws CommandValidationException, HelpException
133     {
134         commandName = args[0];
135
136
137         if (this.validCommand == null)
138         {
139             throw new CommandValidationException(getLocalizedString("InvalidCommand",
140                                                  new Object JavaDoc[] {commandName} ));
141         }
142         
143         //get all options
144
for (int ii=1; ii<args.length; ii++)
145         {
146             //figure out if this is a help option then throw a HelpException
147
//so that manpage or usage text gets displayed
148
if (args[ii].equals(HELP_OPTION) ||
149                 args[ii].matches(SHORT_OPTION_HELP_REGEXP))
150                 throw new HelpException(commandName);
151
152
153             //verify and get short options
154
if (args[ii].matches(ANY_SHORT_OPTION_REGEXP) )
155             {
156                 ii = verifyShortOptions(args, ii);
157             }
158             
159             //get long options
160
//long option can be of the following:
161
// --<alphanumeric chars>
162
// --<alphanumeric chars>-<alphnumeric chars>
163
// --<alphanumeric chars>=<option_argument>
164
else if (args[ii].matches(LONG_OPTION_REGEXP))
165             {
166                 ii = insertLongOption(args, ii);
167             }
168             
169             //get operands
170
else
171             {
172                 ii = insertOperands(Arrays.asList(args).listIterator(ii));
173             }
174         }
175         //insertEnvironmentOptions();
176
insertPrefFileOptions();
177         insertDefaultOptions();
178         replaceAlternativeOptions();
179     }
180
181     
182     /** Checks if the short option is valid.
183      * If valid, then call insertShortOption() to insert
184      * the short options to the HashMap.
185      * According to CLIP, short option consist of a hyphen
186      * followed a single letter or digit,
187      * @params ii - index in the arguments
188      * @return the index of the next argument
189      * @throws CommandValidationException
190
191      */

192     private int verifyShortOptions(final String JavaDoc[] args, int ii)
193         throws CommandValidationException
194     {
195         int index;
196         if (args[ii].matches(SHORT_OPTION_REGEXP) ||
197             args[ii].matches(SHORT_OPTION_ARGUMENT_REGEXP)) {
198             index = insertShortOption(args, ii);
199         } else {
200             throw new CommandValidationException(getLocalizedString("NoSuchOption",
201                                                  new Object JavaDoc[] {args[ii]}));
202         }
203         return index;
204     }
205     
206     
207     /** Insert short options group to the shot options list
208      * @param sOption - group of short options
209      *
210      */

211     private void insertShortOptionsGroup(final String JavaDoc sOptions)
212         throws CommandValidationException
213     {
214         for (int ii=1; ii<sOptions.length(); ii++)
215         {
216             final String JavaDoc optionName = findOptionName(sOptions.charAt(ii));
217             insertBooleanOption(optionName);
218         }
219     }
220     
221     
222     /** call this method only if there is no option argument
223      * The assumption is that if there are no option argument
224      * then the option is of type boolean.
225      * @param optionName - name of option
226      * @throws CommandValidationException if option is not boolean
227      */

228     private void insertBooleanOption(String JavaDoc optionName)
229         throws CommandValidationException
230     {
231         if (checkOptionIsBoolean(optionName))
232         {
233             //optionsList.put(optionName, getDefaultBooleanValue(optionName));
234
//Bug #6296862, same as long option, boolean option without argument is always TRUE
235
optionsList.put(optionName, TRUE);
236         }
237         else
238         {
239             optionsList.put(optionName, null);
240         }
241     }
242
243     
244     /** Insert short option to the short options list
245      * @params args - arguments of options
246      * @params ii - index in the arguments
247      * @return the index of the next argument
248      * @throws CommandValidationException
249      */

250     private int insertShortOption(final String JavaDoc[] args, int ii)
251         throws CommandValidationException
252     {
253
254         //if short option length is greater than 2 then it is a
255
//short options group
256
if (args[ii].length() > 2)
257         {
258             final int index = args[ii].indexOf('=');
259             //if the long option and option argument is delimited by a space
260
if (index == -1)
261             {
262                 insertShortOptionsGroup(args[ii]);
263             }
264             else
265             {
266                 insertOptionWithEqualSign(findOptionName(args[ii].charAt(1)),
267                                           args[ii].substring(index+1));
268             }
269         }
270         else
271         {
272             //make sure that the next argument is valid
273
if (ii+1 < args.length)
274             {
275                 final String JavaDoc optionName = findOptionName(args[ii].charAt(1));
276                 
277                 //if the next argument starts with "-" then it's not
278
//an option argument
279
//if argument is a boolean option then next argument
280
//is not an option argument
281
if (args[ii+1].startsWith("-") ||
282                     checkOptionIsBoolean(optionName) )
283                 {
284                     insertBooleanOption(optionName);
285                 }
286                 else
287                 {
288                     optionsList.put(findOptionName(args[ii].charAt(1)), args[ii+1]);
289                     ii++;
290                 }
291             }
292             else
293             {
294                 insertBooleanOption(findOptionName(args[ii].charAt(1)));
295             }
296         }
297         return ii;
298     }
299     
300     
301     /** Insert long option to the long options list
302      * @params args - arguments of options
303      * @params ii - index in the arguments
304      * @return the index of the next argument
305      * @throws CommandValidationException
306      */

307     private int insertLongOption(final String JavaDoc[] args, int ii)
308         throws CommandValidationException
309     {
310         final int index = args[ii].indexOf('=');
311         //if the long option and option argument is delimited by a space
312
if (index == -1)
313         {
314             //boolean option with "--no-" always means false
315
if (args[ii].startsWith(BOOLEAN_NO_OPTION) &&
316                 checkOptionIsBoolean(args[ii].substring(BOOLEAN_NO_OPTION.length())) )
317             {
318                 optionsList.put(args[ii].substring(BOOLEAN_NO_OPTION.length()), FALSE);
319             }
320             else if (checkOptionIsBoolean(args[ii].substring(2)))
321             {
322                 //long boolean option is always true
323
optionsList.put(args[ii].substring(2), TRUE);
324             }
325             else if (ii+1<args.length)
326             {
327                 //if the next argument starts with "-" then it's missing an option value
328
if (args[ii+1].startsWith("-") )
329                 {
330                     optionsList.put(args[ii].substring(2), null);
331                 }
332                 else
333                 {
334                     optionsList.put(args[ii].substring(2), args[ii+1]);
335                     ii++;
336                 }
337             }
338             else
339                 optionsList.put(args[ii].substring(2), null);
340         }
341         //if the long option and option argument is delimited by '='
342
else
343         {
344             insertOptionWithEqualSign(args[ii].substring(2, index),
345                                       args[ii].substring(index+1));
346         }
347         return ii;
348     }
349
350
351     /**
352      * This method inserts the optionName and optionValue to optionsList
353      * @param optionName - name of option
354      * @param optoinValue - value of option
355      * @throws CommandValidationException if invalid boolean value to insert
356      */

357     private void insertOptionWithEqualSign(String JavaDoc optionName, String JavaDoc optionValue)
358         throws CommandValidationException
359     {
360         if (checkOptionIsBoolean(optionName))
361         {
362             //if option is a boolean then the value must be true or false
363
if (optionValue!=null &&
364                 (optionValue.compareToIgnoreCase(TRUE)==0 ||
365                  optionValue.compareToIgnoreCase(FALSE)==0))
366             {
367                 optionsList.put(optionName, optionValue);
368             }
369             else
370                 throw new CommandValidationException(getLocalizedString("OptionIsBoolean",
371                                                      new Object JavaDoc[] {optionName} ));
372         }
373         else
374             optionsList.put(optionName, optionValue);
375     }
376
377     
378     /**
379      * Insert default option to the long options list
380      */

381     private void insertDefaultOptions()
382     {
383         final Vector JavaDoc allOptions = validCommand.getOptions();
384         if (allOptions != null)
385         {
386             for (int ii=0; ii<allOptions.size(); ii++)
387             {
388                 final ValidOption currentOption = (ValidOption)allOptions.get(ii);
389                 if (currentOption != null &&
390                     !optionsList.containsKey(currentOption.getName()) &&
391                     !isEnvironmentOptionExists(currentOption.getName()) &&
392                     !validCommand.hasDeprecatedOption(currentOption) &&
393                     currentOption.getDefaultValue()!=null)
394                 {
395                     CLILogger.getInstance().printDebugMessage(
396                         "**** insert Default Options " +
397                         currentOption.getName() + " " +
398                         currentOption.getDefaultValue());
399                     optionsList.put(currentOption.getName(),
400                                     currentOption.getDefaultValue());
401                 }
402             }
403         }
404     }
405
406
407     /**
408      *
409      */

410     private void insertPrefFileOptions()
411     {
412         try{
413             String JavaDoc homedir = System.getProperty("user.home");
414             CLIDescriptorsReader cdr = CLIDescriptorsReader.getInstance();
415             String JavaDoc filename = cdr.getEnvironmentFileName();
416             String JavaDoc envPrefix = cdr.getEnvironmentPrefix();
417             FileInputStream JavaDoc prefsFile = new
418                             FileInputStream JavaDoc(homedir+File.separator+filename);
419             Properties JavaDoc p = new Properties JavaDoc();
420             p.load(prefsFile);
421             final Vector JavaDoc allOptions = validCommand.getOptions();
422             for (int ii=0; ii<allOptions.size(); ii++)
423             {
424                 final ValidOption currentOption = (ValidOption)allOptions.get(ii);
425                 final String JavaDoc optionName = currentOption.getName();
426                 String JavaDoc envVarName = envPrefix+optionName.toUpperCase();
427                 String JavaDoc value = p.getProperty(envVarName);
428                 if(!optionsList.containsKey(optionName) &&
429                     !isEnvironmentOptionExists(currentOption.getName()) &&
430                     (value != null))
431                 {
432                     optionsList.put(optionName, value);
433                 }
434             }
435         }
436         catch(IOException JavaDoc e){
437                 //ignore
438
}
439     }
440     
441     
442     /**
443      * Insert environment option to the long options list
444      */

445     private void insertEnvironmentOptions()
446     {
447         final HashMap JavaDoc envOptions = CommandEnvironment.getInstance().getEnvironments();
448         final Vector JavaDoc allOptions = validCommand.getOptions();
449         if (envOptions != null)
450         {
451             for (int ii=0; ii<allOptions.size(); ii++)
452             {
453                 final ValidOption currentOption = (ValidOption)allOptions.get(ii);
454                 final String JavaDoc optionName = currentOption.getName();
455                 if (currentOption != null &&
456                     !optionsList.containsKey(currentOption.getName()) &&
457                     envOptions.containsKey(optionName))
458                 {
459                     CLILogger.getInstance().printDebugMessage(
460                         "**** insert Environment Options " +
461                         optionName + " " +
462                         (String JavaDoc)envOptions.get(optionName) );
463                     optionsList.put(optionName, (String JavaDoc)envOptions.get(optionName));
464                 }
465             }
466         }
467     }
468
469
470     /**
471      * Gets all the valid options which are set in the environment for a given
472      * ValidCommand
473      */

474     public HashMap JavaDoc getValidEnvironmentOptions()
475     {
476         final HashMap JavaDoc envOptions = CommandEnvironment.getInstance().getEnvironments();
477         HashMap JavaDoc validEnvOptions = new HashMap JavaDoc();
478         final Vector JavaDoc allOptions = validCommand.getOptions();
479         if (envOptions != null)
480         {
481             for (int ii=0; ii<allOptions.size(); ii++)
482             {
483                 final ValidOption currentOption = (ValidOption)allOptions.get(ii);
484                 final String JavaDoc optionName = currentOption.getName();
485                 if (currentOption != null &&
486                     envOptions.containsKey(optionName))
487                 {
488                     CLILogger.getInstance().printDebugMessage(
489                         "**** valid Environment Options " +
490                         optionName + " " +
491                         (String JavaDoc)envOptions.get(optionName) );
492                     validEnvOptions.put(optionName, (String JavaDoc)envOptions.get(optionName));
493                 }
494             }
495         }
496         return validEnvOptions;
497     }
498
499
500     /**
501      * Checks to see if the value for this environment option is set
502      * Used in insertDefaultOptions(), dont want to insert default if the env.
503      * is set.
504      */

505     public boolean isEnvironmentOptionExists(String JavaDoc optionName)
506     {
507         final HashMap JavaDoc envOptions = CommandEnvironment.getInstance().getEnvironments();
508         if (envOptions.containsKey(optionName))
509             return true;
510         else
511             return false;
512     }
513
514
515     /**
516      * This method search for the alternative options and replace it with the
517      * actual option name.
518      */

519     private void replaceAlternativeOptions()
520     {
521         final Vector JavaDoc optionNames = new Vector JavaDoc(optionsList.keySet());
522         
523         for (int ii=0; ii<optionNames.size(); ii++)
524         {
525             final String JavaDoc optionName = (String JavaDoc)optionNames.get(ii);
526             if (validCommand.hasAlternateDeprecatedOption(optionName))
527             {
528                 //set the value of actual option and remove the alternate option
529
//from the options list.
530

531                 final String JavaDoc alternateOptionName =
532                 validCommand.getAlternateDeprecatedOption(optionName).getName();
533  
534                 optionsList.put(alternateOptionName,(String JavaDoc)optionsList.get(optionName));
535
536                 CLILogger.getInstance().printWarning(getLocalizedString("OptionDeprecatedUseNew",
537                                                      new Object JavaDoc[] {optionName, alternateOptionName}));
538                 optionsList.remove(optionName);
539             }
540         }
541
542     }
543     
544     
545     /** Insert the list of operand and the Operand variable
546      * @param operandIter - list of operand
547      * @return last index of the list
548      */

549     private int insertOperands(final ListIterator JavaDoc operandIter)
550         throws CommandValidationException
551     {
552         try
553         {
554             //check if the first element is a "--"
555
if (!((String JavaDoc)operandIter.next()).equals("--"))
556             {
557                 Operands.add((String JavaDoc)operandIter.previous());
558                 //call next to advance to the next element
559
operandIter.next();
560             }
561             
562             while (operandIter.hasNext())
563             {
564                 Operands.add((String JavaDoc)operandIter.next());
565             }
566         }
567         catch (NoSuchElementException JavaDoc nsee)
568         {
569             throw new CommandValidationException(nsee);
570         }
571         return operandIter.nextIndex();
572     }
573     
574     
575     /** find long option name from short option
576      * @param ValidCommand object
577      * @param shortoption string
578      * @return the long option string
579      */

580     private String JavaDoc findOptionName(final char shortOption)
581         throws CommandValidationException
582     {
583         //search in required and valid options list
584
final Vector JavaDoc allOptions = validCommand.getOptions();
585         if (allOptions != null)
586         {
587             for (int ii=0; ii<allOptions.size(); ii++)
588             {
589                 Vector JavaDoc shortOptions =
590                 ((ValidOption)allOptions.get(ii)).getShortNames();
591                 
592                 if (shortOptions.contains(String.valueOf(shortOption)))
593                 {
594                     return ((ValidOption)allOptions.get(ii)).getName();
595                 }
596             }
597         }
598         throw new CommandValidationException(getLocalizedString("NoSuchOption",
599                                              new Object JavaDoc[] {String.valueOf(shortOption)} ));
600     }
601     
602     
603     /** check if the option is a boolean value
604      * @param optionName - name of option
605      * @return true if this option is a boolean value
606      */

607     private boolean checkOptionIsBoolean(final String JavaDoc optionName)
608     {
609         final ValidOption option = validCommand.getOption(optionName);
610         if (option != null)
611         {
612             if ((option.getType().compareToIgnoreCase(BOOLEAN)) == 0)
613                 return true;
614             else
615                 return false;
616         }
617         else
618         {
619             return false;
620         }
621     }
622     
623     /** return the opposite of the default value for boolean type
624      * @param optionName - name of option
625      * @return the opposite of the default value for boolean type
626      */

627     /* // Due to the bug #6296862, this method is not being used.
628     private String getDefaultBooleanValue(final String optionName)
629     {
630         final ValidOption option = validCommand.getOption(optionName);
631         if (option != null)
632         {
633             if (option.getDefaultValue() !=null &&
634                 option.getDefaultValue().compareToIgnoreCase(TRUE)==0)
635                 return FALSE;
636         }
637         //should an exception be thrown here if there is no default
638         //value for boolean option?
639         return TRUE;
640     }
641     */

642     
643     /** gets the optionsList
644      * @return optionsList
645      */

646     public HashMap JavaDoc getOptionsList()
647     {
648         return optionsList;
649     }
650     
651     
652     /** gets the operandsList
653      * @return operadsList
654      */

655     public Vector JavaDoc getOperands()
656     {
657         return Operands;
658     }
659
660     /**
661      * returns the localized string from framework's LocalStrings.properties.
662      * Calls the LocalStringsManagerFactory.getFrameworkLocalStringsManager()
663      * method, returns "Key not found" if it cannot find the key
664      * @param key, the string to be localized
665      * @param toInsert, the strings to be inserted in the placeholders
666      */

667     protected String JavaDoc getLocalizedString(String JavaDoc key, Object JavaDoc[] toInsert)
668     {
669         try
670         {
671             final LocalStringsManager lsm =
672             LocalStringsManagerFactory.getFrameworkLocalStringsManager();
673             return lsm.getString(key, toInsert);
674         }
675         catch (CommandValidationException cve)
676         {
677             return LocalStringsManager.DEFAULT_STRING_VALUE;
678         }
679     }
680     
681     
682     public String JavaDoc toString()
683     {
684         return "\n**********\nname = " + commandName +
685         "\nOptions = " + optionsList +
686         "\nOperands = " + Operands + "\n**********\n";
687     }
688     
689 }
690
Popular Tags