DBVIEW
src/org/dbview/runtime/cli/CliParser.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 
00023 package org.dbview.runtime.cli;
00024 
00025 import java.util.Arrays;
00026 import java.util.Hashtable;
00027 import org.jdom.JDOMException;
00028 import java.util.ArrayList;
00029 import java.lang.reflect.Method;
00030 import org.dbview.adapter.*;
00031 import org.dbview.addons.AddOnCatalogException;
00032 import org.dbview.addons.input.utils.mysql.CliOptions;
00033 import org.dbview.input_addons.*;
00034 import org.dbview.output_addons.*;
00035 import org.dbview.utils.args4j.CommaSeparatedStripedListOptionHandler;
00036 import org.dbview.utils.args4j.OptionContainer;
00037 import org.dbview.utils.args4j.SpecialStringOptionHandler;
00038 import org.jdom.Element;
00039 import org.kohsuke.args4j.*;
00040 
00041 
00042 /**
00043  * This class handles the process of parsing the command line, which is not a trivial action.
00044  *
00045  * @author Denis BEURIVE
00046  */
00047 public class CliParser
00048 {
00049     /**
00050      * Command line.
00051      */
00052     private static String[]      __vargs               = null;
00053 
00054     /**
00055      * This is the catalogue of all available input add-ons.
00056      * This object is used to instantiate input add-ons.
00057      */
00058     private static InputCatalog  __catalog             = null;
00059 
00060     /**
00061      * This is a command line option.
00062      * It represents an input add-on (used to load a specific database).
00063      */
00064     public static final String   CLI_INPUT_ADDON      = "db-adaptor";
00065 
00066     /**
00067      * This is a command line option.
00068      * It represents an output add-on.
00069      * The output add-on defines the output's format.
00070      */
00071     public static final String   CLI_OUTPUT_ADDON     = "exporter";
00072 
00073     /**
00074      * This is a command line option.
00075      * It represents the name of a profile.
00076      */
00077     public static final String   CLI_PROFILE           = "profile";
00078 
00079     /**
00080      * This is a command line option.
00081      * It represents the two extremities of a path.
00082      */
00083     public static final String   CLI_BETWEEN          = "between";
00084 
00085     /**
00086      * This is a command line option.
00087      * It represents a list of tables to zoom in.
00088      */
00089     public static final String   CLI_ZOOM          = "zoom";
00090 
00091     /**
00092      * This is a command line option.
00093      * If a list of tables to zoom in is defined, then this value represents a zoom level.
00094      */
00095     public static final String   CLI_ZOOM_LEVEL          = "zoom-level";
00096 
00097     /**
00098      * This is a command line option.
00099      * This option is used when the user wants to calculate the path(s) between two tables.
00100      * it represents the maximum number of paths to show.
00101      */
00102     public static final String   CLI_LIMIT             = "limit";
00103 
00104     /**
00105      * This is a command selector.
00106      * The user requests the print of the general help message.
00107      */
00108     public static final String   CS_HELP               = "help";
00109 
00110     /**
00111      * This is a command selector.
00112      * The user requests the list of all available input add-ons.
00113      */
00114     public static final String   CS_LIST_INPUT         = "list-db-adaptors";
00115 
00116     /**
00117      * This is a command selector.
00118      * VThe user requests the list of all available output add-ons for tables.
00119      */
00120     public static final String   CS_LIST_OUTPUT_TABLE        = "list-table-exporters";
00121 
00122     /**
00123      * This is a command selector.
00124      * The user requests the print of the help message for a specific input add-on.
00125      */
00126     public static final String   CS_INPUT_ADDON_HELP  = "help-db-adaptor";
00127 
00128     /**
00129      * This is a command selector.
00130      * The user requests the print of the help message for a specific output add-on.
00131      */
00132     public static final String   CS_OUTPUT_ADDON_HELP = "help-table-exporter";
00133 
00134     /**
00135      * This is a command selector.
00136      * The user wants to add a new profile to the profiles' repository.
00137      */
00138     public static final String   CS_PROFILE_ADD        = "profile-add";
00139 
00140     /**
00141      * This is a command selector.
00142      * The user wants to remove a profile from the profiles' repository.
00143      */
00144     public static final String   CS_PROFILE_DELETE     = "profile-delete";
00145 
00146     /**
00147      * This is a command selector.
00148      * The user wants to print a given profile.
00149      */
00150     public static final String   CS_PROFILE_SHOW       = "profile-show";
00151 
00152     /**
00153      * This is a command selector.
00154      * The user wants to update a given profile.
00155      */
00156     public static final String   CS_PROFILE_UPDATE     = "profile-update";
00157 
00158     /**
00159      * This is a command selector.
00160      * The user wants to print all profiles in the profiles' repository.
00161      */
00162     public static final String   CS_PROFILE_LIST       = "profile-list";
00163 
00164     /**
00165      * This is a command selector.
00166      * The user wants to export a database.
00167      */
00168     public static final String   CS_EXPORT             = "export";
00169 
00170     /**
00171      * This is a command selector.
00172      * The user wants to print the list of all available soft foreign key detectors.
00173      */
00174     public static final String   CS_LIST_SFK_DETECTOR    = "list-soft-key-detectors";
00175 
00176     /**
00177      * Initialize the class.
00178      *
00179      * @throws Exception
00180      */
00181     private static void __init() throws Exception
00182     {
00183         if (null == CliParser.__catalog)
00184             CliParser.__catalog = new InputCatalog();
00185     }
00186 
00187     /**
00188      * This method prints the software' usage.
00189      * @return This method returns a string that represents the help message.
00190      */
00191     public static String help()
00192     {
00193         ArrayList<String> lines = new ArrayList<String>();
00194 
00195         String program_name = System.getProperty("program.name");
00196         program_name = null == program_name ? "DEBUG MESSAGE: Set the program's name in the launcher!" : program_name;
00197 
00198         lines.add(program_name + ":");
00199         lines.add(CliParser.CS_HELP);
00200         lines.add("");
00201         lines.add(CliParser.CS_LIST_INPUT);
00202         lines.add("");
00203         lines.add(CliParser.CS_LIST_OUTPUT_TABLE);
00204         lines.add("");
00205         lines.add(CliParser.CS_LIST_SFK_DETECTOR);
00206         lines.add("");
00207         lines.add(CliParser.CS_INPUT_ADDON_HELP      + " <name of the add-on to which you need help>");
00208         lines.add("");
00209         lines.add(CliParser.CS_OUTPUT_ADDON_HELP     + " <name of the add-on to which you need help>");
00210         lines.add("");
00211         lines.add(CliParser.CS_PROFILE_LIST);
00212         lines.add("");
00213         lines.add(CliParser.CS_PROFILE_DELETE        + " <name of the profile to delete>");
00214         lines.add("");
00215         lines.add(CliParser.CS_PROFILE_SHOW          + " <name of the profile to show>");
00216         lines.add("");
00217         lines.add(CliParser.CS_PROFILE_ADD           + " <name of the profile to add> "
00218                                                      + "-" + CliParser.CLI_INPUT_ADDON + " <name of the database adaptor> /profile's configuration/");
00219         lines.add("");
00220         lines.add(CliParser.CS_PROFILE_UPDATE        + " <name of the profile to update> /One, or more, profile's parameter(s)/");
00221         lines.add("");
00222         lines.add(CliParser.CS_EXPORT                + " -" + CliParser.CLI_OUTPUT_ADDON + " <name of the exporter> /exporter's configuration/"
00223                                                      + " [-" + CliParser.CLI_BETWEEN + " <name of a table>,<name of a table> [-"  + CliParser.CLI_LIMIT + " <maximum number of pathes to calculate>]"
00224                                                      + " | -" + CliParser.CLI_ZOOM + " <comma separated list of tables> [-" + CliParser.CLI_ZOOM_LEVEL + " <value>]]"
00225                                                      + " (-" + CliParser.CLI_PROFILE + " <profile's name> | -" + CliParser.CLI_INPUT_ADDON + " <name of the adaptor> /adaptor's configuration/)");
00226         lines.add("");
00227         return org.dbview.utils.Strings.joinWithNewLines(lines);
00228     }
00229 
00230     /**
00231      * Parse the command line. Please not that this method will try all the
00232      * specialized command line parsers.
00233      *
00234      * @note Specialized parsers are private methods that start with the string
00235      *       of characters "__try", followed by an uppercase letter. Specialized
00236      *       command line parsers take no argument, at return an instance of
00237      *       CliData.
00238      * @param in_vargs
00239      *            Array of strings that represent the command line.
00240      * @return The parser returns an instance of CliData.
00241      * @throws Exception
00242      */
00243     public static CliData parse(String[] in_vargs)
00244     {
00245         CliData data = null;
00246         CliParser.__vargs = in_vargs;
00247 
00248         if (0 == CliParser.__vargs.length)
00249         {
00250             return new CliData(CliActionSelector.CLI_HELP);
00251         }
00252 
00253         Method[] methods = CliParser.class.getDeclaredMethods();
00254 
00255         for (int i = 0; i < methods.length; i++)
00256         {
00257             if (!methods[i].getName().matches("^__try[A-Z].+$"))
00258             {
00259                 continue;
00260             }
00261             try
00262             {
00263                 // System.out.println(methods[i].getName());
00264                 data = (CliData) methods[i].invoke(null, new Object[0]);
00265             }
00266             catch (Exception e)
00267             {
00268                 System.out.println("Unexpected error: " + e.getMessage() + " " + e.getClass().getName());
00269             }
00270             if (null != data)
00271             {
00272                 return data;
00273             }
00274         }
00275 
00276         return new CliData(CliActionSelector.CLI_UNKNOWN);
00277     }
00278 
00279     /**
00280      * Test if the user asks for help.
00281      *
00282      * @return <ul>
00283      *              <li>If the user asks for help, then the method returns an instance of CliData. The value of the member "type" of the returned object is
00284      *                  CliConstantes.CLI_HELP.</li>
00285      *              <li>Otherwise, the method returns the value null.</li>
00286      *         </ul>
00287      */
00288     @SuppressWarnings("unused")
00289     private static CliData __tryHelp() throws Exception
00290     {
00291         if (0 == CliParser.__vargs[0].compareTo(CliParser.CS_HELP))
00292         {
00293             String message = CliParser.__checkCliEmpty();
00294             if (null != message) { return new CliData(CliActionSelector.CLI_HELP, message); }
00295             return new CliData(CliActionSelector.CLI_HELP);
00296         }
00297         return null;
00298     }
00299 
00300     /**
00301      * Test if the user wants to print the help for a specific input add-on.
00302      *
00303      * @return <ul>
00304      *              <li>If the user asks for help, then the method returns an instance of CliData.
00305      *                  The value of the member "type" of the returned object is CliConstantes.CLI_INPUT_HELP.</li>
00306      *              <li>Otherwise, the method returns the value null.</li>
00307      *         </ul>
00308      * @throws Exception
00309      */
00310     @SuppressWarnings("unused")
00311     private static CliData __tryInputHelp() throws Exception
00312     {
00313         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_INPUT_ADDON_HELP)) { return null; }
00314         if (2 != CliParser.__vargs.length) { return new CliData(CliActionSelector.CLI_INPUT_HELP, "In order to print the usage for a specific input add-on, you must specify the name of the requested add-on. "); }
00315 
00316         // Check the argument's value.
00317         String target_name = CliParser.__vargs[1];
00318         if (target_name.startsWith("-")) { return new CliData(CliActionSelector.CLI_INPUT_HELP, "Arguments must not start with a dash (-). If an argument starts with a dash, then you should escape it. For example, \"-foo\" becomes \"\\-foo\"."); }
00319         target_name = target_name.replaceFirst("^\\\\", "");
00320 
00321         Hashtable<String, Object> data = new Hashtable<String, Object>();
00322         data.put("name", target_name);
00323         return new CliData(CliActionSelector.CLI_INPUT_HELP, data);
00324     }
00325 
00326     /**
00327      * Test if the user wants to print the help for a specific output add-on.
00328      *
00329      * @return <ul>
00330      *              <li>If the user asks for help, then the method returns an instance of CliData.
00331      *                  The value of the member "type" of the returned object is CliConstantes.CLI_OUTPUT_HELP.</li>
00332      *              <li>Otherwise, the method returns the value null.</li>
00333      *         </ul>
00334      * @throws Exception
00335      */
00336     @SuppressWarnings("unused")
00337     private static CliData __tryOutputHelp() throws Exception
00338     {
00339         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_OUTPUT_ADDON_HELP)) { return null; }
00340         if (2 != CliParser.__vargs.length) { return new CliData(CliActionSelector.CLI_OUTPUT_HELP, "In order to print the usage for a specific output add-on, you must specify the name of the requested add-on."); }
00341 
00342         // Check the argument's value.
00343         String target_name = CliParser.__vargs[1];
00344         if (target_name.startsWith("-"))
00345         { return new CliData(CliActionSelector.CLI_OUTPUT_HELP, "Arguments must not start with a dash (-). If an argument starts with a dash, then you should escape it. For example, \"-foo\" becomes \"\\-foo\"."); }
00346         target_name = target_name.replaceFirst("^\\\\", "");
00347 
00348         Hashtable<String, Object> data = new Hashtable<String, Object>();
00349         data.put("name", target_name);
00350         return new CliData(CliActionSelector.CLI_OUTPUT_HELP, data);
00351     }
00352 
00353     /**
00354      * Test if the user asks for the list of available input add-ons.
00355      *
00356      * @return <ul>
00357      *              <li>If the user asks for the list of available input add-ons, then the method returns an instance of CliData.
00358      *                  The value of the member "type" of the returned object is CliConstantes.CLI_LIST_INPUT_TARGETS.</li>
00359      *              <li>Otherwise, the method returns the value null.</li>
00360      *         </ul>
00361      */
00362     @SuppressWarnings("unused")
00363     private static CliData __tryTargetInput()
00364     {
00365         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_LIST_INPUT)) return null;
00366         String message = CliParser.__checkCliEmpty();
00367         if (null != message) return new CliData(CliActionSelector.CLI_LIST_INPUT_ADDONS, message);
00368         return new CliData(CliActionSelector.CLI_LIST_INPUT_ADDONS);
00369     }
00370 
00371     /**
00372      * Test if the user asks for the list of available soft foreign key matchers.
00373      * @return <ul>
00374      *              <li>If the user asks for the list of available soft foreign key matchers, then the method returns an instance of CliData.
00375      *                  The value of the member "type" of the returned object is CliConstantes.CLI_LIST_FK_MATCHER.</li>
00376      *              <li> Otherwise, the method returns the value null.</li>
00377      *         </ul>
00378      */
00379     @SuppressWarnings("unused")
00380     private static CliData __tryListFkMatcher()
00381     {
00382         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_LIST_SFK_DETECTOR)) return null;
00383         String message = CliParser.__checkCliEmpty();
00384         if (null != message) return new CliData(CliActionSelector.CLI_LIST_SFK_DETECTOR, message);
00385         return new CliData(CliActionSelector.CLI_LIST_SFK_DETECTOR);
00386     }
00387 
00388     /**
00389      * Test if the user asks for the list of available output add-ons for tables.
00390      *
00391      * @return <ul>
00392      *              <li>If the user asks for the list of available output add-ons, then the method returns an instance of CliData.
00393      *                  The value of the member "type" of the returned object is CliConstantes.CLI_LIST_OUTPUT_TARGETS.</li>
00394      *              <li>Otherwise, the method returns the value null.</li>
00395      *         </ul>
00396      */
00397     @SuppressWarnings("unused")
00398     private static CliData __tryAddOnOutputTable()
00399     {
00400         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_LIST_OUTPUT_TABLE)) return null;
00401         String message = CliParser.__checkCliEmpty();
00402         if (null != message) return new CliData(CliActionSelector.CLI_HELP, message);
00403         return new CliData(CliActionSelector.CLI_LIST_OUTPUT_TABLE_ADDONS);
00404     }
00405 
00406     /**
00407      * Test if the user wants to add a new profile to the profiles' repository.
00408      *
00409      * @return <ul>
00410      *              <li>If the user wants to add a new profile, then the method returns an instance of CliData.
00411      *                  <ul>
00412      *                      <li>The value of the member "type" of the returned object is CliConstantes.CLI_PROFILE_ADD.</li>
00413      *                      <li>The member "data" of the returned object contains the following keys:
00414      *                          <ul>
00415      *                              <li>"name": The name of the profile to add.</li>
00416      *                              <li>"input-target": The add-on's name.</li>
00417      *                              <li>"input-target-configuration": the profile's configuration (XML element).</li>
00418      *                          </ul>
00419      *                      </li>
00420      *                  </ul>
00421      *              </li>
00422      *              <li>Otherwise, the method returns the value null.</li>
00423      *         </ul>
00424      */
00425     @SuppressWarnings("unused")
00426     private static CliData __tryProfileAdd()
00427     {
00428         /**
00429          * This class contains the CLI options needed to add a new profile into the profiles' repository.
00430          * @author Denis Beurive
00431          */
00432         class CliOptionsProfileAdd extends OptionContainer
00433         {
00434             @Option(name = "-" + CliParser.CLI_INPUT_ADDON, handler = SpecialStringOptionHandler.class)
00435             private String __target = null;
00436 
00437             public String getTarget() { return this.__target; }
00438         }
00439 
00440         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_PROFILE_ADD)) return null;
00441 
00442         String profile_name            = null;
00443         String profile_target          = null;
00444         CliOptionsProfileAdd options   = new CliOptionsProfileAdd();
00445         OptionContainer options_target = null;
00446 
00447         // CliParser.__debug(CliParser.__vargs);
00448 
00449         // ------------------------------------------------------------------------
00450         // First, get the name of the new profile.
00451         // ------------------------------------------------------------------------
00452 
00453         if (CliParser.__vargs.length < 2)
00454         { return new CliData(CliActionSelector.CLI_PROFILE_ADD, "To add a new profile, you must specify the profile's name."); }
00455         profile_name = CliParser.__vargs[1];
00456 
00457         // Check the argument's value.
00458         if (profile_name.startsWith("-"))
00459         {
00460             return new CliData(CliActionSelector.CLI_PROFILE_ADD, "Arguments must not start with a dash (-). If an argument starts with a dash, then you should escape it. For example, \"-foo\" becomes \"\\-foo\".");
00461         }
00462         profile_name = profile_name.replaceFirst("^\\\\", "");
00463 
00464         // ------------------------------------------------------------------------
00465         // Then, find out the target.
00466         // ------------------------------------------------------------------------
00467 
00468         try
00469         {
00470             CmdLineParser parser = new CmdLineParser(options);
00471             parser.parseArgument(options.extractArgvForThisSet(CliParser.__vargs));
00472 
00473             // System.out.println("-");
00474             // CliParser.__debug(options.extractArgvForThisSet(CliParser.__vargs));
00475             // System.out.println("-");
00476 
00477             profile_target = options.getTarget();
00478 
00479             // Detect the lack of add-on's name.
00480             if (null == profile_target)
00481             return new CliData(CliActionSelector.CLI_PROFILE_ADD, "To add a new profile, you must specify the profile's add-on (-" + CliParser.CLI_INPUT_ADDON + " <add-on's name>).");
00482         }
00483         catch (CmdLineException e)
00484         {
00485             // Please note that this bloc should never be executed since we use
00486             // string options (which accepts any kind of characters' sequence).
00487             return new CliData(CliActionSelector.CLI_PROFILE_ADD, "It seems that you want to add a new profile. But something os wrong with the way you specify your request: " + e.getMessage());
00488         }
00489 
00490         // ------------------------------------------------------------------------
00491         // Now that we know the profile's add-on, we parse the command line
00492         // arguments for this specific add-on.
00493         // ------------------------------------------------------------------------
00494 
00495         try
00496         {
00497             CliParser.__init();
00498             Hashtable<String, Object> data = new Hashtable<String, Object>();
00499             Element configuration = null;
00500 
00501             // Get a CLI adapter for the requested add-on.
00502             AbstractCli cli = (AbstractCli) CliParser.__catalog.getAdaptor(profile_target, "Cli");
00503 
00504             options_target = cli.getOptionsContainer();
00505 
00506             // Parse the command line and extract the new profile's
00507             // configuration.
00508             configuration = cli.getConf(CliParser.__vargs, Boolean.TRUE, Boolean.TRUE);
00509 
00510             // Check for unexpected arguments.
00511             ArrayList<OptionContainer> olist = new ArrayList<OptionContainer>();
00512             olist.add(options);
00513             olist.add(options_target);
00514             ArrayList<String> shrinked_list = CliParser.__shrinkArgv(olist);
00515             if (0 != shrinked_list.size())
00516             { return new CliData(CliActionSelector.CLI_PROFILE_ADD, "Unexpected atgument(s): " + org.dbview.utils.Strings.join(shrinked_list, ", ") + "."); }
00517 
00518             // OK
00519             data.put("name", profile_name);
00520             data.put("input-target", profile_target);
00521             data.put("input-target-configuration", configuration);
00522             return new CliData(CliActionSelector.CLI_PROFILE_ADD, data);
00523         }
00524         catch (AddOnCatalogException e)
00525         {
00526             return new CliData(CliActionSelector.CLI_PROFILE_ADD, "An error occurred while processing the target's name \"" + profile_target + "\". The given name (" + profile_target + ") is probably not recognized. " + e.getMessage());
00527         }
00528         catch (Exception e)
00529         {
00530             return new CliData(CliActionSelector.CLI_PROFILE_ADD, e.getMessage());
00531         }
00532     }
00533 
00534     /**
00535      * Test if the user wants to delete a profile.
00536      *
00537      * @return <ul>
00538      *              <li>If the user wants to delete a profile, then the method returns an instance of CliData.
00539      *                  <ul>
00540      *                      <li>The value of the member "type" of the returned object is CliConstantes.CLI_PROFILE_REMOVE.</li>
00541      *                      <li>The member "data" of the returned object contains the following keys:
00542      *                          <ul>
00543      *                              <li>"name": The name of the profile to add.</li>
00544      *                          </ul>
00545      *                      </li>
00546      *                  </ul>
00547      *              </li>
00548      *              <li>Otherwise, the method returns the value null.</li>
00549      *         </ul>
00550      */
00551     @SuppressWarnings("unused")
00552     private static CliData __tryProfileDelete()
00553     {
00554         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_PROFILE_DELETE)) return null;
00555         if (2 != CliParser.__vargs.length) return new CliData(CliActionSelector.CLI_PROFILE_REMOVE, "In order to delete a profile, you must specify the name of the profile to delete.");
00556 
00557         String profile_name = CliParser.__vargs[1];
00558 
00559         // Check the argument's value.
00560         if (profile_name.startsWith("-")) { return new CliData(CliActionSelector.CLI_PROFILE_REMOVE, "Arguments must not start with a dash (-). If an argument starts with a dash, then you should escape it. For example, \"-foo\" becomes \"\\-foo\"."); }
00561         profile_name = profile_name.replaceFirst("^\\\\", "");
00562 
00563         Hashtable<String, Object> data = new Hashtable<String, Object>();
00564         data.put("name", profile_name);
00565         return new CliData(CliActionSelector.CLI_PROFILE_REMOVE, data);
00566     }
00567 
00568     /**
00569      * Test if the user wants to print a profile.
00570      *
00571      * @return <ul>
00572      *            <li>If the user wants to print a profile, then the method returns an instance of CliData.
00573      *                <ul>
00574      *                    <li>The value of the member "type" of the returned object is CliConstantes.CLI_PROFILE_SHOW.</li>
00575      *                    <li>The member "data" of the returned object contains the following keys:
00576      *                        <ul>
00577      *                           <li>"name": The name of the profile to add.</li>
00578      *                        </ul>
00579      *                    </li>
00580      *                </ul>
00581      *            </li>
00582      *            <li>Otherwise, the method returns the value null.</li>
00583      *         </ul>
00584      */
00585     @SuppressWarnings("unused")
00586     private static CliData __tryProfileShow()
00587     {
00588         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_PROFILE_SHOW)) return null;
00589         if (2 != CliParser.__vargs.length) return new CliData(CliActionSelector.CLI_PROFILE_SHOW, "In order to diplay a profile, you must specify the name of the profile to display.");
00590 
00591         String profile_name = CliParser.__vargs[1];
00592 
00593         // Check the argument's value.
00594         if (profile_name.startsWith("-")) { return new CliData(CliActionSelector.CLI_PROFILE_SHOW, "Arguments must not start with a dash (-). If an argument starts with a dash, then you should escape it. For example, \"-foo\" becomes \"\\-foo\"."); }
00595         profile_name = profile_name.replaceFirst("^\\\\", "");
00596 
00597         Hashtable<String, Object> data = new Hashtable<String, Object>();
00598         data.put("name", profile_name);
00599         return new CliData(CliActionSelector.CLI_PROFILE_SHOW, data);
00600     }
00601 
00602     /**
00603      * Test if the user wants to update a given profile.
00604      *
00605      * @return <ul>
00606      *             <li>If the user wants to update a profile, then the method returns an instance of CliData.
00607      *                 <ul>
00608      *                     <li>The value of the member "type" of the returned object is CliConstantes.CLI_PROFILE_UPDATE.</li>
00609      *                     <li>The member "data" of the returned object contains the following keys:
00610      *                         <ul>
00611      *                             <li>"name": The name of the profile to add.</li>
00612      *                             <li>"target"; The add-on's name.</li>
00613      *                             <li>"new_configuration": the new profile's configuration (XML element).</li>
00614      *                             <li>"old_configuration": the old profile's configuration (XML element).</li>
00615      *                         </ul>
00616      *                      </li>
00617      *                 </ul>
00618      *             </li>
00619      *             <li>Otherwise, the method returns the value null.</li>
00620      *         </ul>
00621      */
00622     @SuppressWarnings("unused")
00623     private static CliData __tryProfileUpdate()
00624     {
00625         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_PROFILE_UPDATE)) { return null; }
00626 
00627         String profile_target = null;
00628         String profile_name   = null;
00629 
00630         // ------------------------------------------------------------------------
00631         // First, extract the name of the profile to update.
00632         // ------------------------------------------------------------------------
00633 
00634         if (CliParser.__vargs.length < 2) { return new CliData(CliActionSelector.CLI_PROFILE_UPDATE, "To update a rofile, you must specify the profile's name."); }
00635         profile_name = CliParser.__vargs[1];
00636 
00637         // Check the argument's value.
00638         if (profile_name.startsWith("-")) { return new CliData(CliActionSelector.CLI_PROFILE_UPDATE, "Arguments must not start with a dash (-). If an argument starts with a dash, then you should escape it. For example, \"-foo\" becomes \"\\-foo\"."); }
00639         profile_name = profile_name.replaceFirst("^\\\\", "");
00640 
00641         // ------------------------------------------------------------------------
00642         // Now get the profile's add-on.
00643         // ------------------------------------------------------------------------
00644 
00645         AbstractConfiguration profile_conf = null;
00646         try
00647         {
00648             profile_conf = ProfilesRepository.getProfileInstance(profile_name);
00649             if (null == profile_conf) { return new CliData(CliActionSelector.CLI_PROFILE_UPDATE, "The profile's name you specified (" + profile_name + ") can not be found in the profiles' repository."); }
00650             profile_target = profile_conf.getAddOnName();
00651         }
00652         catch (Exception e)
00653         {
00654             return new CliData(CliActionSelector.CLI_PROFILE_UPDATE, "Can not get the current profile's data from the profiles' repository. The profiles' repository may be screwed up! " + e.getMessage());
00655         }
00656 
00657         // ------------------------------------------------------------------------
00658         // Now that we know the profile's add-on, we find out the list of
00659         // command
00660         // line arguments for this add-on.
00661         // ------------------------------------------------------------------------
00662 
00663         try
00664         {
00665             CliParser.__init();
00666             Element configuration = null;
00667 
00668             // Get a CLI adapter for the add-on.
00669             AbstractCli cli = (AbstractCli) CliParser.__catalog.getAdaptor(profile_target, "Cli");
00670 
00671             // Parse the command line and extract the new profile's
00672             // configuration.
00673             // Parsing, in this case, is not strict.
00674             configuration = cli.getConf(CliParser.__vargs, Boolean.FALSE, Boolean.FALSE);
00675 
00676             // Check for unexpected arguments.
00677             OptionContainer options_target = cli.getOptionsContainer();
00678             ArrayList<OptionContainer> olist = new ArrayList<OptionContainer>();
00679             olist.add(options_target);
00680             ArrayList<String> shrinked_list = CliParser.__shrinkArgv(olist);
00681             if (0 != shrinked_list.size())
00682             { return new CliData(CliActionSelector.CLI_PROFILE_UPDATE, "Unexpected atgument(s): " + org.dbview.utils.Strings.join(shrinked_list, ", ") + "."); }
00683 
00684             // OK
00685             Hashtable<String, Object> data = new Hashtable<String, Object>();
00686             data.put("name", profile_name);
00687             data.put("target", profile_target);
00688             data.put("new_configuration", configuration);
00689             data.put("old_configuration", profile_conf.toXml());
00690             return new CliData(CliActionSelector.CLI_PROFILE_UPDATE, data);
00691         }
00692         catch (AddOnCatalogException e)
00693         {
00694             return new CliData(CliActionSelector.CLI_PROFILE_UPDATE, "An error occurred while processing the profile's which name \"" + profile_name + "\". The profile's add-on (" + profile_target + ") is probably not recognized anymore!. " + e.getMessage());
00695         }
00696         catch (Exception e)
00697         {
00698             return new CliData(CliActionSelector.CLI_PROFILE_UPDATE, e.getMessage());
00699         }
00700     }
00701 
00702     /**
00703      * This method tests if the user wants to list all the profiles stored in
00704      * the repository.
00705      *
00706      * @return <ul>
00707      *              <li>If the user wants to list all the profiles, then the method returns an instance of CliData.
00708      *                  <ul>
00709      *                      <li>The value of the member "type" of the returned object is CliConstantes.CLI_PROFILE_LIST.</li>
00710      *                  </ul>
00711      *              </li>
00712      *              <li>Otherwise, the method returns the value null.</li>
00713      *         </ul>
00714      */
00715     @SuppressWarnings("unused")
00716     private static CliData __tryProfileList()
00717     {
00718         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_PROFILE_LIST)) return null;
00719         return new CliData(CliActionSelector.CLI_PROFILE_LIST);
00720     }
00721 
00722     /**
00723      * This method tests if the user wants to process a given database.
00724      *
00725      * @return <ul>
00726      *            <li>If the user wants to process a given database, then the method returns an instance of CliData.
00727      *                <ul>
00728      *                    <li>The value of the member "type" of the returned object is CliConstantes.CLI_EXPORT.</li>
00729      *                </ul>
00730      *            </li>
00731      *            <li>Otherwise, the method returns thevalue null</li>
00732      *         </ul>
00733      */
00734     @SuppressWarnings("unused")
00735     private static CliData __tryExport()
00736     {
00737         /**
00738          * This class contains the required configuration used to parse the options that represents the list of tables to zoom in.
00739          * @author Denis BEURIVE
00740          */
00741         class ZoomOptions extends OptionContainer
00742         {
00743             /**
00744              * List of tables to zoom at.
00745              */
00746             @Option(name= "-" + CliParser.CLI_ZOOM, handler=CommaSeparatedStripedListOptionHandler.class)
00747             private String __zoom = null;
00748 
00749             /**
00750              * Zoom lebel.
00751              */
00752             @Option(name= "-" + CliParser.CLI_ZOOM_LEVEL)
00753             private Integer __zoom_level = null;
00754 
00755             /**
00756              * This method returns the list of tables to zoom in.
00757              * @return The method returns the list of tables to zoom in.
00758              */
00759             public ArrayList<String> getZoom()
00760             {
00761                 if (null == this.__zoom) { return null; }
00762 
00763                 String[] values = this.__zoom.split(",");
00764                 ArrayList<String> result = new ArrayList<String>();
00765                 for (String s: values) { result.add(s); }
00766                 return result;
00767             }
00768 
00769             /**
00770              * This method returns the zoom level to apply (to a list of tables).
00771              * @return The method returns the zoom level to apply (to a list of tables).
00772              */
00773             public Integer getZoomLevel()
00774             {
00775                 return this.__zoom_level;
00776             }
00777         }
00778 
00779         /**
00780          * This class represents the required configuration used to parse the options that defined a path.
00781          * @author Denis Beurive
00782          */
00783         class PathOptions extends OptionContainer
00784         {
00785             /**
00786              * This option represents the two extremities of the path.
00787              */
00788             @Option(name= "-" + CliParser.CLI_BETWEEN, handler=CommaSeparatedStripedListOptionHandler.class)
00789             private String __between = null;
00790 
00791             /**
00792              * This option represents the maximum number of path to calculate.
00793              */
00794             @Option(name= "-" + CliParser.CLI_LIMIT)
00795             private Integer __limit = null;
00796 
00797             /**
00798              * Return the two extremities of the path to calculate.
00799              * @return Return the two extremities of the path to calculate.
00800              */
00801             public ArrayList<String> getBetween()
00802             {
00803                 if (null == this.__between) { return null; }
00804 
00805                 String[] values = this.__between.split(",");
00806                 ArrayList<String> result = new ArrayList<String>();
00807                 for (String s: values) { result.add(s); }
00808                 return result;
00809             }
00810 
00811             /**
00812              * Return the maximum number of paths to calculate.
00813              * @return Return the maximum number of paths to calculate.
00814              */
00815             public Integer getLimit()
00816             { return this.__limit; }
00817         }
00818 
00819         if (0 != CliParser.__vargs[0].compareTo(CliParser.CS_EXPORT)) return null;
00820 
00821         String profile_name                                 = null; // May be null, if the connection's profile is included within the command line.
00822         String input_addon_name                             = null; // May be null (if a profile's name is specified).
00823         String output_addon_name                            = null;
00824         Element xml_input_configuration                     = null;
00825         Element xml_output_configuration                    = null;
00826         ArrayList<String> zoom_list                         = null;
00827         Integer zoom_level                                  = null;
00828         ArrayList<String> between                           = null;
00829         String path_from                                    = null;
00830         String path_to                                      = null;
00831         Integer path_limit                                  = null;
00832         Hashtable<String, Object> data                      = new Hashtable<String, Object>();
00833         CliOptionsIOTargets options_targets                 = new CliOptionsIOTargets();
00834         CliOptionsProfileName options_profile_name          = new CliOptionsProfileName();
00835         OptionContainer options_input_cli                   = new OptionContainer();
00836         OptionContainer options_output_cli                  = new OptionContainer();
00837 
00838         // ------------------------------------------------------------------------
00839         // First, extract the name of the input and output add-ons.
00840         // SET input_target_name:
00841         // output_target_name: Necessarily set.
00842         // ------------------------------------------------------------------------
00843 
00844         try
00845         {
00846             CmdLineParser parser = new CmdLineParser(options_targets);
00847             parser.parseArgument(options_targets.extractArgvForThisSet(CliParser.__vargs));
00848 
00849             input_addon_name  = options_targets.getInputTarget();
00850             output_addon_name = options_targets.getOutputTarget();
00851 
00852             // Make sure that the mandatory option is set.
00853             if (null == output_addon_name) { return new CliData(CliActionSelector.CLI_EXPORT, "In order to process a database, you must, at least, indicate the name of the output add-on's adaptor (-" + CliParser.CLI_OUTPUT_ADDON + " <add-on's name>). And, optionally, you may specify the name of an input add-on (-" + CliParser.CLI_INPUT_ADDON + " <add-on's name>)."); }
00854         }
00855         catch (CmdLineException e)
00856         {
00857             // Please note that this bloc should never be executed since we use
00858             // string options (which accepts any kind of characters' sequence).
00859             return new CliData(CliActionSelector.CLI_EXPORT, "It seems that you want to export a database. But something is wrong with the way you specify your request: " + e.getMessage());
00860         }
00861 
00862         // ------------------------------------------------------------------------
00863         // Get the input add-on's configuration from a profile or from the
00864         // command line.
00865         // ------------------------------------------------------------------------
00866 
00867         if (null == input_addon_name)
00868         {
00869             // No input add-on name is specified. I assume that a profile's name is given.
00870             try
00871             {
00872                 CmdLineParser parser = new CmdLineParser(options_profile_name);
00873                 parser.parseArgument(options_profile_name.extractArgvForThisSet(CliParser.__vargs));
00874 
00875                 profile_name = options_profile_name.getProfileName();
00876 
00877                 if (null == profile_name)
00878                 return new CliData(CliActionSelector.CLI_EXPORT, "In order to process a given database, you must specify a profile's name (-" + CliParser.CLI_PROFILE + " <name of the profile>), or a set of input adaptor configurations's parameters (-" + CliParser.CLI_INPUT_ADDON + " <...> ...). ");
00879 
00880                 // Get the configuration for the requested profile's name.
00881                 ProfilesRepository.init();
00882                 AbstractConfiguration conf = ProfilesRepository.getProfileInstance(profile_name);
00883                 if (null == conf)
00884                 {
00885                     return new CliData(CliActionSelector.CLI_EXPORT, "The profile's name you specified (" + profile_name + ") can not be found in the profiles' repository.");
00886                 }
00887 
00888                 xml_input_configuration = conf.toXml().getChild("data");
00889                 if (null == xml_input_configuration)
00890                 {
00891                     return new CliData(CliActionSelector.CLI_EXPORT, "The profile's you specified (" + profile_name + ") is not valid. It does not contain any \"data\" tag!");
00892                 }
00893 
00894                 input_addon_name = conf.getAddOnName();
00895             }
00896             catch (CmdLineException e)
00897             {
00898                 // Please note that this bloc should never be executed since we
00899                 // use string options (which accepts any kind of characters'
00900                 // sequence).
00901                 return new CliData(CliActionSelector.CLI_EXPORT, "It seems that you want to export a database. But something is wrong with the way you specify your request: " + e.getMessage());
00902             }
00903             catch (JDOMException e)
00904             {
00905                 return new CliData(CliActionSelector.CLI_EXPORT, "It seems that you want to export a database. But it seems that your profiles' repository is screwed up: " + e.getMessage());
00906             }
00907             catch (Exception e)
00908             {
00909                 return new CliData(CliActionSelector.CLI_EXPORT, "It seems that you want to export a database. An unexpected error occured: " + e.getMessage());
00910             }
00911         }
00912         else
00913         {
00914             // A add-on name is given. I assume that an input add-on
00915             // configuration is given through the command line.
00916             try
00917             {
00918                 CliParser.__init();
00919 
00920                 // Get a CLI adapter for the add-on.
00921                 AbstractCli cli = (AbstractCli) CliParser.__catalog.getAdaptor(input_addon_name, "Cli");
00922 
00923                 // Get the options' container, that will be used later (to look for unexpected arguments).
00924                 options_input_cli = cli.getOptionsContainer();
00925 
00926                 // Parse the command line and extract the new profile's
00927                 // configuration.
00928                 xml_input_configuration = cli.getConf(CliParser.__vargs, Boolean.TRUE, Boolean.TRUE);
00929             }
00930             catch (AddOnCatalogException e)
00931             {
00932                 return new CliData(CliActionSelector.CLI_EXPORT, "An error occurred while extracting input add-on's configuration from the command line. " + e.getMessage());
00933             }
00934             catch (Exception e)
00935             {
00936                 return new CliData(CliActionSelector.CLI_EXPORT, e.getMessage());
00937             }
00938         }
00939 
00940         // ------------------------------------------------------------------------
00941         // Now, get the configuration for the output add-on.
00942         // ------------------------------------------------------------------------
00943 
00944         try
00945         {
00946             OutputCatalog out = new OutputCatalog();
00947             AbstractCli cli = (AbstractCli) out.getAdaptor(output_addon_name, "Cli");
00948 
00949             // Get the options' container, that will be used later (to look for unexpected arguments).
00950             options_output_cli = cli.getOptionsContainer();
00951 
00952             xml_output_configuration = cli.getConf(CliParser.__vargs, Boolean.TRUE, Boolean.TRUE);
00953             // System.out.println(org.dbview.utils.Jdom.print(output_configuration));
00954         }
00955         catch (CliException e)
00956         {
00957             return new CliData(CliActionSelector.CLI_EXPORT, "It seems that you want to export a database. But something is wrong with the way you specify the output add-on's adaptor configuration : " + e.getMessage());
00958         }
00959         catch (AddOnCatalogException e)
00960         {
00961             return new CliData(CliActionSelector.CLI_EXPORT, "It seems that you want to export a database. An error occurred while using the exporter \"" + output_addon_name + "\" : " + e.getMessage());
00962         }
00963         catch (Exception e)
00964         {
00965             return new CliData(CliActionSelector.CLI_EXPORT, e.getMessage());
00966         }
00967 
00968         // ------------------------------------------------------------------------
00969         // OK... Shall we zoom?
00970         // ------------------------------------------------------------------------
00971 
00972         ZoomOptions options_zoom  = new ZoomOptions();
00973         CmdLineParser zoom_parser = new CmdLineParser(options_zoom);
00974 
00975         try
00976         {
00977             zoom_parser.parseArgument(options_zoom.extractArgvForThisSet(CliParser.__vargs));
00978         }
00979         catch (CmdLineException e)
00980         {
00981             return new CliData(CliActionSelector.CLI_EXPORT, e.getMessage());
00982         }
00983 
00984         zoom_list  = options_zoom.getZoom();
00985         zoom_level = options_zoom.getZoomLevel();
00986 
00987         if (null == zoom_list)
00988         if (null != zoom_level)
00989         { return new CliData(CliActionSelector.CLI_EXPORT, "Option -" + CliParser.CLI_ZOOM_LEVEL + " can not be used alone. You must specify a list of tables to zoom in."); }
00990 
00991         // ------------------------------------------------------------------------
00992         // OK... Shall calculate a path?
00993         // ------------------------------------------------------------------------
00994 
00995         PathOptions options_path  = new PathOptions();
00996         CmdLineParser path_parser = new CmdLineParser(options_path);
00997 
00998         try
00999         {
01000             path_parser.parseArgument(options_path.extractArgvForThisSet(CliParser.__vargs));
01001         }
01002         catch (CmdLineException e)
01003         {
01004             return new CliData(CliActionSelector.CLI_EXPORT, e.getMessage());
01005         }
01006 
01007         between    = options_path.getBetween();
01008         path_limit = options_path.getLimit();
01009 
01010         if (null == between)
01011         if (null != path_limit)
01012         { return new CliData(CliActionSelector.CLI_EXPORT, "Option -" + CliParser.CLI_LIMIT + " can not be used alone. You must specify a path to calculate."); }
01013 
01014         if (null != between)
01015         if (between.size() != 2)
01016         { return new CliData(CliActionSelector.CLI_EXPORT, "Option -" + CliParser.CLI_BETWEEN + " defines two table (<name of a table>,<name of a table>)."); }
01017 
01018         // ------------------------------------------------------------------------
01019         // Make sure that the "zoom" option and the "path" option are not defined
01020         // simultaneously.
01021         // ------------------------------------------------------------------------
01022 
01023         if ((null != zoom_list) && (null != between))
01024         { return new CliData(CliActionSelector.CLI_EXPORT, "You can not define simultaneously a list of tables to zoom in and a path to calculate."); }
01025 
01026         // Check for unexpected arguments.
01027         ArrayList<OptionContainer> olist = new ArrayList<OptionContainer>();
01028         olist.add(options_targets);
01029         olist.add(options_profile_name);
01030         olist.add(options_input_cli);
01031         olist.add(options_output_cli);
01032         olist.add(options_path);
01033         olist.add(options_zoom);
01034 
01035         ArrayList<String> shrinked_list = CliParser.__shrinkArgv(olist);
01036         if (0 != shrinked_list.size())
01037         { return new CliData(CliActionSelector.CLI_EXPORT, "Unexpected atgument(s): " + org.dbview.utils.Strings.join(shrinked_list, ", ") + "."); }
01038 
01039         // ------------------------------------------------------------------------
01040         // OK, we have everything. Let's return.
01041         // ------------------------------------------------------------------------
01042 
01043         if (null != between)
01044         {
01045             data.put("path-between", between);
01046             data.put("path-limit",   null == path_limit ? 1 : path_limit);
01047         }
01048 
01049         if (null != zoom_list)
01050         {
01051             data.put("zoom-list",  zoom_list);
01052             data.put("zoom-level", null == zoom_level ? 0 : zoom_level);
01053         }
01054 
01055         data.put("input-target-name",    input_addon_name);          // String
01056         data.put("output-target-name",   output_addon_name);         // String
01057         data.put("input-configuration",  xml_input_configuration);   // Element
01058         data.put("output-configuration", xml_output_configuration);  // Element
01059 
01060         // DEBUG
01061         // System.out.println("__tryExport done");
01062 
01063         return new CliData(CliActionSelector.CLI_EXPORT, data);
01064     }
01065 
01066     /**
01067      * This method makes sure that the command line does not contain any command line parameter after the command selector.
01068      *
01069      * @return <ul>
01070      *             <li>If the command line does not contain any command line parameter after the command selector, then the method returns the value null.</li>
01071      *             <li>Otherwise, the method returns a string that represents the error message.</li>
01072      *         </ul>
01073      * @throws Exception
01074      */
01075     private static String __checkCliEmpty()
01076     {
01077         if (1 < CliParser.__vargs.length)
01078         {
01079             ArrayList<String> m = new ArrayList<String>();
01080             for (int i = 1; i < CliParser.__vargs.length; i++)
01081             {
01082                 m.add(CliParser.__vargs[i]);
01083             }
01084             return "Unexpected command line arguments (" + org.dbview.utils.Strings.join(m, ", ") + ").";
01085         }
01086         return null;
01087     }
01088 
01089     /**
01090      * This method extracts the following argument from the command line:
01091      * <ul>
01092      *      <li>The command selector.</li>
01093      *      <li>The non option argument that may follow the command selector (until the first option is reached)</li>
01094      *      <li>The option's arguments given by the list of given options' containers.</li>
01095      * </ul>
01096      * @param in_options The list of options' containers.
01097      * @return The method returns an array of command line arguments.
01098      */
01099     private static ArrayList<String> __shrinkArgv(ArrayList<OptionContainer> in_options)
01100     {
01101         ArrayList<String> res = new ArrayList<String>(Arrays.asList(CliParser.__vargs));
01102 
01103         // First, remove all non option's argument at the beginning of the command line.
01104         // System.out.println(res.size());
01105         for (String arg: CliParser.__vargs)
01106         {
01107             // System.out.println("\t> " + arg);
01108             if (arg.startsWith("-")) { break; }
01109             res.remove(0);
01110         }
01111         // System.out.println(res.size());
01112 
01113         // Then, remove all *required* options.
01114         for (OptionContainer option: in_options)
01115         {
01116             option.extractArgvForThisSet(res.toArray(new String[res.size()]));
01117 
01118             // String[] os = option.shrink();
01119             // System.out.println("> " + os.length);
01120 
01121             res = new ArrayList<String>( Arrays.asList(option.shrink()));
01122 
01123         }
01124 
01125         return res;
01126     }
01127 
01128     /**
01129      * Print the command line.
01130      * @param in_argv The command line.
01131      * @remark This method is used for debug only.
01132      */
01133     @SuppressWarnings("unused")
01134     private static void __debug(String in_argv[])
01135     {
01136         for (String arg: in_argv)
01137         {
01138             System.out.println("\t> " + arg);
01139         }
01140     }
01141 }
01142 
01143 // ---------------------------------------------------------------------------------
01144 // The following classes define generic option's classes.
01145 // These options may be used by several parsing routines.
01146 //----------------------------------------------------------------------------------
01147 
01148 /**
01149  * This class contains the CLI option used to extract a profile's name from the command line.
01150  * @remark This class is designed to be used with the library Args4j.
01151  * @remark This class is not public.
01152  * @author Denis Beurive
01153  */
01154 class CliOptionsProfileName extends OptionContainer
01155 {
01156     /** Name of the profile. */
01157     @Option(name = "-" + CliParser.CLI_PROFILE, handler = SpecialStringOptionHandler.class)
01158     private String __name = null;
01159 
01160     /**
01161      * Returns the name of the profile.
01162      * @return Returns the name of the profile.
01163      */
01164     public String getProfileName()
01165     {
01166         return this.__name;
01167     }
01168 }
01169 
01170 /**
01171  * This class contains the CLI options needed to proceed to an export.
01172  * It defines options for an input and an output add-on.
01173  * @remark This class is designed to be used with the library Args4j.
01174  * @remark This class is not public.
01175  * @author Denis Beurive
01176  */
01177 class CliOptionsIOTargets extends OptionContainer
01178 {
01179     /** Name of the input add-on. */
01180     @Option(name = "-" + CliParser.CLI_INPUT_ADDON, handler = SpecialStringOptionHandler.class)
01181     private String __input_target  = null;
01182 
01183     /** Name of the output add-on. */
01184     @Option(name = "-" + CliParser.CLI_OUTPUT_ADDON, handler = SpecialStringOptionHandler.class)
01185     private String __output_target = null;
01186 
01187     /**
01188      * Returns the name of the input add-on.
01189      * @return Returns the name of the input add-on.
01190      */
01191     public String getInputTarget() { return this.__input_target; }
01192 
01193     /**
01194      * Returns the name of the output add-on.
01195      * @return Returns the name of the output add-on.
01196      */
01197     public String getOutputTarget() { return this.__output_target; }
01198 }
01199 
01200 
01201 
01202 
01203