Programmering

Kommandolinjeparsing med Apache Commons CLI

Innimellom finner jeg meg selv nødt til å håndtere kommandolinjeargumenter i Java, enten for Java-baserte applikasjoner eller for hoved () funksjonsimplementeringer som gir en enkel testmekanisme direkte innenfor klassen som testes. Java-utvikleren har mange valg for kommandolinjeparsering. Når det bare er ett, to eller et lite antall kommandolinjeargumenter (spesielt hvis tilstedeværelsen eller fraværet av et flagg er alt som trengs i stedet for en tilhørende verdi), skriv noen få kodelinjer for å behandle disse kommandoene. linjealternativer er ikke så farlig. Når det er flere alternativer og / eller noen alternativer har verdier, er det hyggelig å få tilgang til mer sofistikert støtte for kommandolinjeparsering.

I denne blogginnlegget vil jeg se på bruk av Apache Commons CLI-biblioteket, men det er mange andre valg som args4j, TE-Code kommandolinjeparsering, CLAJR (Command Line Arguments with Java Reflection), JArgs, JSAP (Java Simple Argument Processor), og flere andre (enda mer her).

Selv om Apache Commons CLI-bibliotek er en del av Apache Commons, er det en separat (JAR) nedlasting fra JAR-nedlastingen for Apache Commons Modeler og fra JAR-nedlastingen for Apache Commons Lang som jeg snakket om i tidligere blogginnlegg som var tilgjengelig her og her. For dette blogginnlegget bruker jeg CLI 1.1 fordi det ikke er forventet utgivelse for CLI 2.0 (mer informasjon om dette på slutten av denne oppføringen).

Jeg vil demonstrere noen veldig enkle eksempler på Apache Common CLI og inkludere noen lenker til andre ressurser ved bruk av dette biblioteket.

To viktige klasser ved bruk av Apache Common CLI er org.apache.commons.cli.Option-klassen og den nært beslektede org.apache.commons.cli.Options (inneholder flere forekomster av Alternativ klasse). Disse klassene brukes til å representere de forventede kommandolinjealternativene. De følgende to kodebitene viser hvordan du konfigurerer en alternativklasse for Posix-stil og GNU-stil.

Bruke alternativklassen med flere alternativstilfeller

 / ** * Konstruer og gi Posix-kompatible alternativer. * * @returnalternativer forventet fra kommandolinjen i Posix-skjemaet. * / public static Options constructPosixOptions () {final Options posixOptions = new Options (); posixOptions.addOption ("display", false, "Display the state."); returner posixOptions; } / ** * Konstruer og gi GNU-kompatible alternativer. * * @returnalternativer forventet fra kommandolinjen i GNU-skjemaet. * / 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 kopier "); returnere gnuOptions; } 

Merk deg i eksemplene på å sette opp Alternativer at det ennå ikke er noen forskjell i håndteringen av Posix-stil versus GNU-stil. Så langt kan alternativene behandles likt.

Før du går videre til å demonstrere CLIs analyse av kommandolinjeargumenter basert på disse forventede alternativene, er det verdt å merke seg CLIs støtte for bruksinformasjon og hjelpinformasjon via org.apache.commons.cli.HelpFormatter-klassen. Denne nyttige verktøyklassen inneholder metoder som overbelastede versjoner av printHelp, overbelastede versjoner av printUsage og flere andre utdata og relaterte metoder.

Følgende kodebit demonstrerer en metode som bruker en av HelpFormatter's printUsage-metoder og en av denne klassens printHelp-metoder.

printUsage () og printHelp ()

 / ** * Skriv ut bruksinformasjon til gitt OutputStream. * * @param applicationName Navnet på applikasjonen som skal vises i bruk. * @param options Kommandolinjealternativer for å være en del av bruken. * @param ut OutputStream som brukerinformasjonen 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 (skribent, 80, applikasjonsnavn, alternativer); writer.close (); } / ** * Skriv "hjelp" til den medfølgende OutputStream. * / public static void printHelp (final Options options, final int PrintRowWidth, final String header, final String footer, final int spacesBeforeOption, final int spacesBeforeOptionDescription, final boolean displayUsage, final OutputStream out) {final String commandLineSyntax = "java -cpIpacheCommons. krukke"; endelig PrintWriter-forfatter = ny PrintWriter (ut); endelig HelpFormatter helpFormatter = ny HelpFormatter (); helpFormatter.printHelp (skribent, tryktRowWidth, commandLineSyntax, topptekst, alternativer, mellomromForOption, mellomromBeforeOptionBeskrivelse, bunntekst, displayUsage); writer.close (); } 

Neste kodebit viser noen anrop til utskriftHelp () og utskriftsbruk () -metodene som er vist ovenfor, og etterfølges av et øyeblikksbilde av skjermen som viser utdataene fra å kjøre disse.

 System.out.println ("- BRUK -"); printUsage (applicationName + "(Posix)", constructPosixOptions (), System.out); displayBlankLines (1, System.out); printUsage (applicationName + "(Gnu)", constructGnuOptions (), System.out); displayBlankLines (4, System.out); System.out.println ("- HJELP -"); 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 skjermbildet viser resultatene når koden ovenfor kjøres nøyaktig som vist (med ekte overført til begge bruksområder av printHjelp metode for å indikere at opsjoner skal inkluderes i bruksdelen). Det andre skjermbildet viser hva som skjer når det andre kalles til printHjelp har falsk overført til den slik at alternativene ikke vises.

printBruk og printHelp

printBruk og printHelp med One printHelp viser ikke alternativer

Mens bruks- og hjelpinformasjonen om alternativene, som navnene antyder, er nyttige og nyttige, er den virkelige grunnen til å bruke kommandolinjeargumenter vanligvis for å kontrollere applikasjonens oppførsel. Den neste kodelisten viser to metoder for å analysere kommandolinjeargumenter i GNU-stil og Posix-stil. Selv om oppsettet av alternativene ikke brydde seg om den spesifikke stilen annet enn å spesifisere alternativene selv, er typen alternativ nå viktig for å bestemme den aktuelle parseren som skal brukes.

usePosixParser () og useGnuParser ()

 / ** * Bruk Apache Commons CLI PosixParser på kommandolinjeargumenter. * * @param commandLineArguments Kommandolinjeargumenter som skal behandles med * Posix-stil parser. * / public static void usePosixParser (final String [] commandLineArguments) {final CommandLineParser cmdLinePosixParser = new PosixParser (); final Options posixOptions = constructPosixOptions (); CommandLine commandLine; prøv {commandLine = cmdLinePosixParser.parse (posixOptions, commandLineArguments); hvis (commandLine.hasOption ("display")) {System.out.println ("You want a display!"); }} catch (ParseException parseException) // sjekket unntak {System.err.println ("Møtte på unntak under parsing ved bruk av PosixParser: \ n" + parseException.getMessage ()); }} / ** * Bruk Apache Commons CLI GnuParser på kommandolinjeargumenter. * * @param commandLineArguments Kommandolinjeargumenter som skal behandles med * parser i GNU-stil. * / 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 skrive ut (p valgt)!"); } if (commandLine.hasOption ("print")) {System.out.println ("Du vil skrive ut (valgt utskrift)!"); } hvis (commandLine.hasOption ('g')) {System.out.println ("Du vil ha en GUI!"); } hvis (commandLine.hasOption ("n")) {System.out.println ("Du valgte nummeret" + commandLine.getOptionValue ("n")); }} catch (ParseException parseException) // sjekket unntak {System.err.println ("Møtte unntak mens du analyserte ved hjelp av GnuParser: \ n" + parseException.getMessage ()); }} 

Når koden ovenfor kjøres, ser utgangen ut som den som vises i de neste to skjermbildene:

PosixParser-resultater

GNU Parser-resultater

Det komplette eksemplet

Den komplette koden for eksempelapplikasjonen der deler ble vist ovenfor er nå oppført for enkelhets skyld.

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