Analyse en ligne de commande avec la CLI Apache Commons

De temps en temps, j'ai besoin de gérer des arguments de ligne de commande en Java soit pour les applications basées sur Java, soit pour les implémentations de la fonction main () qui fournissent un mécanisme de test simple directement dans la classe testée. Le développeur Java a de nombreux choix pour l'analyse de la ligne de commande. Lorsqu'il n'y a qu'un, deux ou un petit nombre d'arguments de ligne de commande (surtout si la présence ou l'absence d'un indicateur est tout ce qui est nécessaire plutôt qu'une valeur d'accompagnement), écrivez quelques lignes de code pour traiter ces commandes. les options de ligne ne sont pas un gros problème. Quand il y a plus d'options et / ou que certaines options ont des valeurs, il est agréable d'accéder à un support plus sophistiqué pour l'analyse de ligne de commande.

Dans cette entrée de blog, je vais examiner l'utilisation de la bibliothèque CLI Apache Commons, mais il existe de nombreux autres choix tels que args4j, l'analyse de ligne de commande TE-Code, CLAJR (Arguments de ligne de commande avec réflexion Java), JArgs, JSAP (Java Simple Argument Processor), et plusieurs autres (encore plus ici).

Bien que la bibliothèque CLI d'Apache Commons fasse partie d'Apache Commons, il s'agit d'un téléchargement (JAR) séparé du téléchargement JAR pour Apache Commons Modeler et du téléchargement JAR pour Apache Commons Lang dont j'ai parlé dans les entrées de blog précédentes disponibles ici et ici. Pour cette entrée de blog, j'utilise CLI 1.1 car il n'y a pas de version prévue pour CLI 2.0 (plus de détails à ce sujet à la fin de cette entrée).

Je vais démontrer quelques exemples très simples d'Apache Common CLI et inclure des liens vers d'autres ressources sur l'utilisation de cette bibliothèque.

Deux classes importantes dans l'utilisation d'Apache Common CLI sont la classe org.apache.commons.cli.Option et la classe org.apache.commons.cli.Options étroitement liée (contient plusieurs instances de la Optionclasse). Ces classes sont utilisées pour représenter les options de ligne de commande attendues. Les deux extraits de code suivants illustrent la configuration d'une classe Options pour les options de style Posix et les options de style GNU.

Utilisation de la classe d'options avec plusieurs instances d'option

 /** * Construct and provide Posix-compatible Options. * * @return Options expected from command-line of Posix form. */ public static Options constructPosixOptions() { final Options posixOptions = new Options(); posixOptions.addOption("display", false, "Display the state."); return posixOptions; } /** * Construct and provide GNU-compatible Options. * * @return Options expected from command-line of GNU form. */ public static Options constructGnuOptions() { final Options gnuOptions = new Options(); gnuOptions.addOption("p", "print", false, "Option for printing") .addOption("g", "gui", false, "HMI option") .addOption("n", true, "Number of copies"); return gnuOptions; } 

Notez dans les exemples de configuration des options qu'il n'y a pas encore de différence dans la gestion des options de style Posix et de style GNU. Jusqu'à présent, les options peuvent être traitées de la même manière.

Avant de passer à la démonstration de l'analyse par la CLI des arguments de ligne de commande en fonction de ces options anticipées, il convient de noter la prise en charge par la CLI des informations d'utilisation et des informations d'aide via la classe org.apache.commons.cli.HelpFormatter. Cette classe utilitaire utile contient des méthodes telles que les versions surchargées de printHelp, les versions surchargées de printUsage et plusieurs autres méthodes de sortie et associées.

L'extrait de code suivant illustre une méthode qui utilise l'une des méthodes printUsage de HelpFormatter et l'une des méthodes printHelp de cette classe.

printUsage () et printHelp ()

 /** * Print usage information to provided OutputStream. * * @param applicationName Name of application to list in usage. * @param options Command-line options to be part of usage. * @param out OutputStream to which to write the usage information. */ public static void printUsage( final String applicationName, final Options options, final OutputStream out) { final PrintWriter writer = new PrintWriter(out); final HelpFormatter usageFormatter = new HelpFormatter(); usageFormatter.printUsage(writer, 80, applicationName, options); writer.close(); } /** * Write "help" to the provided OutputStream. */ public static void printHelp( final Options options, final int printedRowWidth, final String header, final String footer, final int spacesBeforeOption, final int spacesBeforeOptionDescription, final boolean displayUsage, final OutputStream out) { final String commandLineSyntax = "java -cp ApacheCommonsCLI.jar"; final PrintWriter writer = new PrintWriter(out); final HelpFormatter helpFormatter = new HelpFormatter(); helpFormatter.printHelp( writer, printedRowWidth, commandLineSyntax, header, options, spacesBeforeOption, spacesBeforeOptionDescription, footer, displayUsage); writer.close(); } 

L'extrait de code suivant montre quelques appels aux méthodes printHelp () et printUsage () illustrées ci-dessus et est suivi d'un instantané d'écran montrant la sortie de ces méthodes.

 System.out.println("-- USAGE --"); printUsage(applicationName + " (Posix)", constructPosixOptions(), System.out); displayBlankLines(1, System.out); printUsage(applicationName + " (Gnu)", constructGnuOptions(), System.out); displayBlankLines(4, System.out); System.out.println("-- HELP --"); printHelp( constructPosixOptions(), 80, "POSIX HELP", "End of POSIX Help", 3, 5, true, System.out); displayBlankLines(1, System.out); printHelp( constructGnuOptions(), 80, "GNU HELP", "End of GNU Help", 5, 3, true, System.out); 

Le premier instantané d'écran montre les résultats lorsque le code ci-dessus est exécuté exactement comme indiqué (avec truepassé aux deux utilisations de la printHelpméthode pour indiquer que les options doivent être incluses dans la partie d'utilisation). Le deuxième instantané d'écran montre ce qui se passe lorsque le deuxième appel à lui printHelpa été transmis par false afin que les options ne soient pas affichées.

printUtilisation et impressionAide

printUtilisation et impressionAide avec une impressionAide ne pas afficher les options

Bien que l'utilisation et les informations d'aide sur les options soient, comme leur nom l'indique, utiles et utiles, la vraie raison d'utiliser des arguments de ligne de commande est généralement de contrôler le comportement de l'application. La liste de code suivante montre deux méthodes pour analyser les arguments de ligne de commande de style GNU et de style Posix. Alors que la configuration des options ne se souciait pas du style spécifique autre que la spécification des options elles-mêmes, le type d'option est important maintenant pour déterminer l'analyseur approprié à utiliser.

usePosixParser () et useGnuParser ()

 /** * Apply Apache Commons CLI PosixParser to command-line arguments. * * @param commandLineArguments Command-line arguments to be processed with * Posix-style parser. */ public static void usePosixParser(final String[] commandLineArguments) { final CommandLineParser cmdLinePosixParser = new PosixParser(); final Options posixOptions = constructPosixOptions(); CommandLine commandLine; try { commandLine = cmdLinePosixParser.parse(posixOptions, commandLineArguments); if ( commandLine.hasOption("display") ) { System.out.println("You want a display!"); } } catch (ParseException parseException) // checked exception { System.err.println( "Encountered exception while parsing using PosixParser:\n" + parseException.getMessage() ); } } /** * Apply Apache Commons CLI GnuParser to command-line arguments. * * @param commandLineArguments Command-line arguments to be processed with * Gnu-style parser. */ public static void useGnuParser(final String[] commandLineArguments) { final CommandLineParser cmdLineGnuParser = new GnuParser(); final Options gnuOptions = constructGnuOptions(); CommandLine commandLine; try { commandLine = cmdLineGnuParser.parse(gnuOptions, commandLineArguments); if ( commandLine.hasOption("p") ) { System.out.println("You want to print (p chosen)!"); } if ( commandLine.hasOption("print") ) { System.out.println("You want to print (print chosen)!"); } if ( commandLine.hasOption('g') ) { System.out.println("You want a GUI!"); } if ( commandLine.hasOption("n") ) { System.out.println( "You selected the number " + commandLine.getOptionValue("n")); } } catch (ParseException parseException) // checked exception { System.err.println( "Encountered exception while parsing using GnuParser:\n" + parseException.getMessage() ); } } 

Lorsque le code ci-dessus est exécuté, sa sortie ressemble à celle affichée dans les deux instantanés d'écran suivants:

Résultats PosixParser

Résultats de l'analyseur GNU

L'exemple complet

Le code complet de l'exemple d'application à partir duquel des parties ont été affichées ci-dessus est maintenant répertorié pour plus de commodité.