Programmering

Kommandolinjeparsing med Apache Commons CLI

Fra tid til anden finder jeg mig selv nødt til at håndtere kommandolinjeargumenter i Java enten til Java-baserede applikationer eller til hoved () -funktionsimplementeringer, der giver en simpel testmekanisme direkte inden for den klasse, der testes. Java-udvikleren har mange valg til kommandolinjeparsing. Når der kun er et, to eller et lille antal kommandolinjeargumenter (især hvis tilstedeværelsen eller fraværet af et flag er alt, hvad der er nødvendigt snarere end en ledsagende værdi), skal du skrive et par linier kode for at behandle disse kommandoer - linjemuligheder er ikke en big deal. Når der er flere muligheder og / eller nogle indstillinger har værdier, er det rart at få adgang til mere sofistikeret support til kommandolinjeparsing.

I dette blogindlæg vil jeg se på brugen af ​​Apache Commons CLI-biblioteket, men der er mange andre valg såsom args4j, TE-Code kommandolinjeparsing, CLAJR (Kommandolinjeargumenter med Java-refleksion), JArgs, JSAP (Java Simple Argument Processor) og flere andre (endnu mere her).

Selvom Apache Commons CLI-bibliotek er en del af Apache Commons, er det en separat (JAR) download fra JAR-download til Apache Commons Modeler og fra JAR-download til Apache Commons Lang, som jeg talte om i tidligere blogindgange, der var tilgængelige her og her. Til dette blogindlæg bruger jeg CLI 1.1, fordi der ikke er nogen forventet frigivelse af CLI 2.0 (flere detaljer om dette i slutningen af ​​denne post).

Jeg vil demonstrere nogle meget enkle eksempler på Apache Common CLI og inkludere nogle links til andre ressourcer ved brug af dette bibliotek.

To vigtige klasser ved brug af Apache Common CLI er org.apache.commons.cli.Option-klassen og den nært beslægtede org.apache.commons.cli.Options (indeholder flere forekomster af Mulighed klasse). Disse klasser bruges til at repræsentere de forventede kommandolinjemuligheder. De følgende to kodestykker viser opsætning af en Options-klasse til Posix-stilindstillinger og GNU-stilindstillinger.

Brug af indstillingsklassen med flere indstillinger

 / ** * Konstruer og lever Posix-kompatible indstillinger. * * @returneringsmuligheder forventes fra kommandolinjen i Posix-formularen. * / public static Options constructPosixOptions () {final Options posixOptions = new Options (); posixOptions.addOption ("display", false, "Vis tilstanden."); returner posixMuligheder; } / ** * Konstruer og lever GNU-kompatible indstillinger. * * @return-indstillinger forventes fra kommandolinjen i GNU-formularen. * / 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, "Antal kopier "); returner gnuOptions; } 

Bemærk i eksemplerne med opsætning af indstillinger, at der endnu ikke er nogen forskel i håndteringen af ​​Posix-stil versus GNU-stilindstillinger. Indtil videre kan mulighederne behandles ens.

Inden vi går videre til demonstration af CLI's parsing af kommandolinjeargumenter baseret på disse forventede muligheder, er det værd at bemærke CLIs understøttelse af brugsinformation og hjælpinformation via org.apache.commons.cli.HelpFormatter-klassen. Denne nyttige hjælpeklasse indeholder metoder såsom overbelastede versioner af printHelp, overbelastede versioner af printUsage og flere andre output og relaterede metoder.

Følgende kodestykke demonstrerer en metode, der gør brug af en af ​​HelpFormatter's printUsage-metoder og en af ​​denne klasses printHelp-metoder.

printUsage () og printHelp ()

 / ** * Udskriv oplysninger om brug til den leverede OutputStream. * * @param applicationName Navn på applikation, der skal vises i brug. * @param optioner Kommandolinjemuligheder for at være en del af brugen. * @param ud OutputStream, som brugsoplysningerne skal skrives til. * / public static void printUsage (final String applicationName, final Options options, final OutputStream out) {final PrintWriter writer = new PrintWriter (out); endelig HelpFormatter useFormatter = ny HelpFormatter (); usageFormatter.printUsage (forfatter, 80, applikationsnavn, indstillinger); writer.close (); } / ** * Skriv "hjælp" til den leverede OutputStream. * / public static void printHjælp (endelige valgmuligheder, endelig int udskrevetRowWidth, final String header, final String footer, final int spacesBeforeOption, final int spacesBeforeOptionDescription, final boolean displayUsage, final OutputStream out) {final String commandLineSyntax = "java -cpIpacheCommCons. krukke"; endelig PrintWriter-forfatter = ny PrintWriter (ud); endelig HelpFormatter helpFormatter = ny HelpFormatter (); helpFormatter.printHelp (skribent, tryktRowWidth, commandLineSyntax, header, optioner, mellemrumBeforeOption, mellemrumBeforeOptionDescription, sidefod, displayUsage); writer.close (); } 

Det næste kodestykke viser nogle opkald til metoderne printHelp () og printUsage () vist ovenfor og efterfølges af et skærmbillede, der viser output fra at køre dem.

 System.out.println ("- BRUG -"); printUsage (applicationName + "(Posix)", constructPosixOptions (), System.out); displayBlankLines (1, System.out); printUsage (applicationName + "(Gnu)", constructGnuOptions (), System.out); displayBlankLines (4, System.out); System.out.println ("- HJÆLP -"); 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); 

Det første skærmbillede viser resultaterne, når koden ovenfor udføres nøjagtigt som vist (med rigtigt videregivet til begge anvendelser af printHjælp metode til at angive, at indstillinger skal inkluderes i brugsdelen). Det andet skærmbillede snapshot viser, hvad der sker, når det andet opkald til printHjælp har falsk sendt til det, så indstillingerne ikke vises.

printUsage and printHelp

printUsage and printHelp with One printHelp viser ikke indstillinger

Mens brugs- og hjælpoplysningerne om indstillingerne, som deres navne antyder, er nyttige og nyttige, er den virkelige grund til at bruge kommandolinjeargumenter normalt at kontrollere applikationens opførsel. Den næste kodeliste viser to metoder til parsing af GNU-stil og Posix-stil kommandolinjeargumenter. Mens opsætningen af ​​indstillingerne ikke bekymrede sig om den specifikke stil bortset fra at specificere selve indstillingerne, er typen af ​​indstilling vigtig nu for at bestemme den relevante parser, der skal bruges.

usePosixParser () og useGnuParser ()

 / ** * Anvend Apache Commons CLI PosixParser på kommandolinjeargumenter. * * @param commandLineArguments Kommandolinjeargumenter, der skal behandles med * Posix-stil parser. * / public static void usePosixParser (final String [] commandLineArguments) {final CommandLineParser cmdLinePosixParser = ny PosixParser (); endelige indstillinger posixOptions = constructPosixOptions (); CommandLine commandLine; prøv {commandLine = cmdLinePosixParser.parse (posixOptions, commandLineArguments); hvis (commandLine.hasOption ("display")) {System.out.println ("Du vil have en skærm!"); }} fange (ParseException parseException) // markeret undtagelse {System.err.println ("Mødte undtagelse under parsing ved hjælp af PosixParser: \ n" + parseException.getMessage ()); }} / ** * Anvend Apache Commons CLI GnuParser på kommandolinjeargumenter. * * @param commandLineArguments Kommandolinjeargumenter, der skal behandles med * Gnu-stil parser. * / public static void useGnuParser (final String [] commandLineArguments) {final CommandLineParser cmdLineGnuParser = new GnuParser (); final Options gnuOptions = constructGnuOptions (); CommandLine commandLine; prøv {commandLine = cmdLineGnuParser.parse (gnuOptions, commandLineArguments); hvis (commandLine.hasOption ("p")) {System.out.println ("Du vil udskrive (p valgt)!"); } hvis (commandLine.hasOption ("print")) {System.out.println ("Du vil udskrive (valgt udskrift)!"); } hvis (commandLine.hasOption ('g')) {System.out.println ("Du vil have en GUI!"); } hvis (commandLine.hasOption ("n")) {System.out.println ("Du valgte nummeret" + commandLine.getOptionValue ("n")); }} fangst (ParseException parseException) // kontrolleret undtagelse {System.err.println ("Opstod undtagelse under parsing ved hjælp af GnuParser: \ n" + parseException.getMessage ()); }} 

Når ovenstående kode udføres, ser dens output ud som den, der vises i de næste to skærmbillede:

PosixParser-resultater

GNU Parser-resultater

Det komplette eksempel

Den komplette kode for eksempelapplikationen, hvorfra dele blev vist ovenfor, er nu angivet for nemheds skyld.

$config[zx-auto] not found$config[zx-overlay] not found