DBVIEW
src/org/dbview/utils/args4j/OptionContainer.java
00001 /*
00002         DbView - Graph Visualization
00003     Copyright (C) 2012  Denis BEURIVE
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 /**
00020  * @author Denis Beurive
00021  */
00022 package org.dbview.utils.args4j;
00023 
00024 import java.lang.reflect.Field;
00025 import java.util.Enumeration;
00026 import java.util.Hashtable;
00027 import java.util.ArrayList;
00028 
00029 import org.kohsuke.args4j.Option;
00030 
00031 /**
00032  * This class is a parent class for all command line options' containers.
00033  * @remark See Args4j. The command line options are declared in a class. We call this class the <i>command line options container</i>
00034  *
00035  * @author Denis BEURIVE
00036  */
00037 public class OptionContainer
00038 {
00039     /**
00040      * Each time an option is parsed, then the associated command line arguments are removed from the list of command line argument.
00041      * This attribute contains the remaining arguments in the command line.
00042      */
00043     private ArrayList<String> __shrinked_argv = new ArrayList<String>();
00044 
00045     /**
00046      * This method returns the list of command line option strings ("-host", "-user", ...).
00047      * For each command line option string, the list contains a flag that indicates whether the option takes an argument or not.
00048      * @return The method returns a hash.
00049      *         <ul>
00050      *              <li>Key:   The command option string.</li>
00051      *              <li>Value: A boolean value that indicates whether the option takes an argument or not.</li>
00052      *         </ul>
00053      */
00054     public Hashtable<String, Boolean> options()
00055     {
00056         Hashtable<String, Boolean> options = new Hashtable<String, Boolean>();
00057         Field[] fields = this.getClass().getDeclaredFields();
00058         for (Field field: fields)
00059         {
00060             Option o = null;
00061             o = field.getAnnotation(Option.class);
00062             if (null == o) { continue; }
00063 
00064             String   option_class_name = field.getType().getName();
00065             String[] option_aliases    = o.aliases();
00066             String   option_name       = o.name();
00067             Boolean  take_args         = 0 == option_class_name.compareTo("boolean") ? Boolean.FALSE : Boolean.TRUE;
00068 
00069             options.put(option_name, take_args);
00070 
00071             // System.out.println("OPT> " + option_name);
00072 
00073             for (String alias: option_aliases) { options.put(alias, take_args); }
00074         }
00075         return options;
00076     }
00077 
00078     /**
00079      * This method is mainly used for debugging.
00080      * @return The method returns a string that represents the container's state.
00081      */
00082     @Override
00083     public String toString()
00084     {
00085         String result = "";
00086 
00087         Hashtable<String, Boolean> o = this.options();
00088         Enumeration<String> keys     = o.keys();
00089 
00090         while (keys.hasMoreElements())
00091         {
00092             String key  = keys.nextElement();
00093             Boolean arg = o.get(key);
00094             result += key + " => " + (arg ? "TRUE" : "FALSE") + System.getProperty("line.separator");
00095         }
00096 
00097         return result;
00098     }
00099 
00100     /**
00101      * This method extracts the command line arguments that apply to <i>these</i> options, from a given list of arguments.
00102      * @remark This method is used to implement a 2 stages command line parsing. Sometimes, it is necessary to extract a part of information from the command line in order to parse the all arguments.
00103      * @param in_argv List of arguments.
00104      * @return The method returns the list of command line arguments that applies to this options' container.
00105      */
00106     public String[] extractArgvForThisSet(String[] in_argv)
00107     {
00108         // System.out.println("> Given: " + org.dbview.utils.Strings.join(Arrays.asList(in_argv), ", "));
00109 
00110         ArrayList<String> result           = new ArrayList<String>();
00111         Hashtable<String, Boolean> options = this.options();
00112         int removed                        = 0;
00113 
00114         this.__shrinked_argv = new ArrayList<String>();
00115         for (String arg: in_argv) { this.__shrinked_argv.add(arg); }
00116 
00117         // System.out.println(">>> " + this.__shrinked_argv.size());
00118         // Enumeration<String> e = options.keys();
00119         // while (e.hasMoreElements()) { System.out.println("HASH(" + e.nextElement() + ")"); }
00120 
00121         for (int i=0; i<in_argv.length; i++)
00122         {
00123             String arg = in_argv[i];
00124             // System.out.println("CLI(" + arg + ")");
00125 
00126             if (options.containsKey(arg))
00127             {
00128                 result.add(arg);
00129                 this.__shrinked_argv.remove(i - removed);
00130                 removed++;
00131                 if (! options.get(arg))        { continue; }
00132                 if (i == (in_argv.length - 1)) { break; }
00133                 i += 1;
00134                 result.add(in_argv[i]);
00135                 this.__shrinked_argv.remove(i - removed);
00136                 removed++;
00137             }
00138         }
00139 
00140         // System.out.println("> Left: " + org.dbview.utils.Strings.join(this.__shrinked_argv, ", "));
00141         return result.toArray(new String[result.size()]);
00142     }
00143 
00144     /**
00145      * This method returns the list of command line arguments that remains after the command line parsing.
00146      * @return The method returns the list of command line arguments that remains after the command line parsing.
00147      */
00148     public String[] shrink()
00149     {
00150         return this.__shrinked_argv.toArray(new String[this.__shrinked_argv.size()]);
00151     }
00152 }