Programiranje

Obdelava argumentov ukazne vrstice v Javi: Zadeva zaprta

Številne aplikacije Java, zaženene iz ukazne vrstice, jemljejo argumente za nadzor svojega vedenja. Ti argumenti so na voljo v argumentu niza nizov, ki se prenese v statični del aplikacije glavni () metoda. Običajno obstajata dve vrsti argumentov: možnosti (ali stikala) in dejanski argumenti podatkov. Aplikacija Java mora te argumente obdelati in izvesti dve osnovni nalogi:

  1. Preverite, ali je uporabljena sintaksa veljavna in podprta
  2. Pridobite dejanske podatke, ki jih aplikacija potrebuje za izvajanje svojih operacij

Koda, ki izvaja te naloge, je pogosto narejena po meri za vsako aplikacijo in zato zahteva znaten napor pri ustvarjanju in vzdrževanju, še posebej, če zahteve presegajo preproste primere z eno ali dvema možnostma. The Opcije razred, opisan v tem članku, izvaja generični pristop za enostavno obvladovanje najbolj zapletenih situacij. Razred omogoča preprosto opredelitev zahtevanih možnosti in podatkovnih argumentov ter zagotavlja temeljita preverjanja skladnje in enostaven dostop do rezultatov teh preverjanj. Za ta projekt so bile uporabljene tudi nove funkcije Java 5, kot so generiki in napisi za varno uporabo.

Vrste argumentov ukazne vrstice

V preteklih letih sem napisal več orodij Java, ki uporabljajo argumente ukazne vrstice za nadzor njihovega vedenja. Že na začetku se mi je zdelo nadležno ročno ustvarjanje in vzdrževanje kode za obdelavo različnih možnosti. To je privedlo do razvoja prototipa razreda, ki je olajšal to nalogo, vendar je imel ta razred svoje omejitve, saj se je ob natančnem pregledu izkazalo, da je število možnih različnih sort za argumente ukazne vrstice pomembno. Sčasoma sem se odločil razviti splošno rešitev tega problema.

Pri razvoju te rešitve sem moral rešiti dva glavna problema:

  1. Ugotovite vse sorte, v katerih se lahko pojavijo možnosti ukazne vrstice
  2. Poiščite preprost način, kako uporabnikom omogočiti, da izrazijo te sorte pri uporabi še nerazvitega razreda

Analiza problema 1 je privedla do naslednjih opažanj:

  • Možnosti ukazne vrstice v nasprotju z argumenti podatkov ukazne vrstice - začnite s predpono, ki jih enolično identificira. Primeri predpone vključujejo pomišljaj (-) na platformah Unix za možnosti, kot so -a ali poševnica (/) na platformah Windows.
  • Možnosti so lahko preprosta stikala (tj. -a lahko prisoten ali ne) ali vzame vrednost. Primer je:

    java MyTool -a -b logfile.inp 
  • Možnosti, ki sprejmejo vrednost, imajo lahko različna ločila med dejanskim ključem možnosti in vrednostjo. Takšna ločila so lahko prazen prostor, dvopičje (:) ali znak enakosti (=):

    java MyTool -a -b logfile.inp java MyTool -a -b: logfile.inp java MyTool -a -b = logfile.inp 
  • Možnosti, ki imajo vrednost, lahko dodajo še eno stopnjo zapletenosti. Za primer si oglejmo, kako Java podpira opredelitev lastnosti okolja:

    java -Djava.library.path = / usr / lib ... 
  • Torej, poleg dejanske tipke možnosti (D), ločilo (=) in dejansko vrednost opcije (/ usr / lib), dodatni parameter (java.library.path) lahko prevzame poljubno število vrednosti (v zgornjem primeru lahko s to sintakso podate številne lastnosti okolja). V tem članku se ta parameter imenuje "podrobnost".
  • Možnosti imajo tudi lastnost večkratnosti: lahko so obvezne ali neobvezne, število dovoljenih sprememb pa se lahko razlikuje (na primer natančno enkrat, enkrat ali več ali druge možnosti).
  • Argumenti podatkov so vsi argumenti ukazne vrstice, ki se ne začnejo s predpono. Tu se lahko sprejemljivo število takih podatkovnih argumentov razlikuje med najmanjšim in največjim številom (ki pa ni nujno enako). Poleg tega aplikacija običajno zahteva, da so ti argumenti podatkov zadnji v ukazni vrstici, vendar ni nujno, da je tako. Na primer:

    java MyTool -a -b = logfile.inp data1 data2 data3 // Vsi podatki na koncu 

    ali

    java MyTool -a data1 data2 -b = logfile.inp data3 // Lahko je sprejemljivo za aplikacijo 
  • Bolj zapletene aplikacije lahko podpirajo več možnosti:

    java MyTool -a -b datafile.inp java MyTool -k [-verbose] foo bar duh java MyTool -preveri -verify logfile.out 
  • Nazadnje se lahko aplikacija odloči, da bo prezrla neznane možnosti ali pa bo takšne možnosti štela za napako.

Torej, ko sem zasnoval način, kako uporabnikom omogočiti, da izrazijo vse te sorte, sem pripravil naslednji splošni obrazec, ki je podlaga za ta članek:

[[]] 

Ta obrazec je treba kombinirati z lastnostjo množitve, kot je opisano zgoraj.

Znotraj omejitev splošne oblike zgoraj opisane možnosti Opcije razred, opisan v tem članku, je zasnovan kot splošna rešitev za vse potrebe obdelave ukazne vrstice, ki jih ima aplikacija Java.

Razredi pomočnikov

The Opcije class, ki je osnovni razred za rešitev, opisano v tem članku, ima dva pomožna razreda:

  1. OptionData: Ta razred vsebuje vse informacije za eno določeno možnost
  2. OptionSet: Ta razred vsebuje nabor možnosti. Opcije sam lahko vsebuje poljubno število takih sklopov

Pred opisom podrobnosti teh razredov so bili predstavljeni še drugi pomembni koncepti Opcije razred je treba uvesti.

Varno naštevanje

Predpono, ločilo in lastnost množitve so zajeli enumi, funkcija, ki jo je Java 5 prvič zagotovila:

predpona za javno naštevanje {DASH ('-'), SLASH ('/'); zasebni znak c; zasebna predpona (char c) {this.c = c; } char getName () {return c; }} javni ločevalnik naštevanja {COLON (':'), EQUALS ('='), BLANK (''), NONE ('D'); zasebni znak c; zasebni ločevalnik (char c) {this.c = c; } char getName () {return c; }} množičnost javnega števila {ENKRAT, ENKRAT_OR_MORE, ZERO_OR_ONE, ZERO_OR_MORE; } 

Uporaba enumov ima nekaj prednosti: večja varnost tipa in tesen nadzor nad naborom dovoljenih vrednosti brez napora. Enume je mogoče priročno uporabljati tudi z generiziranimi zbirkami.

Upoštevajte, da Predpona in Ločilo enumi imajo svoje konstruktorje, ki omogočajo opredelitev dejanskega znak predstavlja ta primerek enum (v primerjavi z ime uporablja za sklicevanje na določen primerek enum). Te znake je mogoče pridobiti s pomočjo teh naštevanj ' getName () metode, znaki pa se uporabljajo za java.util.regex sintaksa vzorca paketa. Ta paket se uporablja za preverjanje skladnje v Opcije razred, podrobnosti o tem bodo sledile.

The Množičnost enum trenutno podpira štiri različne vrednosti:

  1. ENKRAT: Možnost se mora pojaviti natanko enkrat
  2. ONCE_OR_MORE: Možnost se mora pojaviti vsaj enkrat
  3. ZERO_OR_ONCE: Možnost je lahko odsotna ali pa je prisotna natančno enkrat
  4. ZERO_OR_MORE: Možnost je lahko odsotna ali prisotna poljubno številokrat

Po potrebi je mogoče enostavno dodati več opredelitev.

Razred OptionData

The OptionData class je v bistvu vsebnik podatkov: prvič za podatke, ki opisujejo samo možnost, in drugič, za dejanske podatke, ki jih najdete v ukazni vrstici za to možnost. Ta zasnova se že odraža v konstruktorju:

OptionData (Predpona Options.Prefix, String key, logična podrobnost, Options.Separator separator, boolean value, Options.Multiplicity multiplicity) 

Ključ se uporablja kot enolični identifikator za to možnost. Upoštevajte, da ti argumenti neposredno odražajo prej opisane ugotovitve: celoten opis možnosti mora imeti vsaj predpono, ključ in večkratnost. Možnosti, ki imajo vrednost, imajo tudi ločilo in lahko sprejmejo podrobnosti. Upoštevajte tudi, da ima ta konstruktor dostop do paketov, zato ga aplikacije ne morejo neposredno uporabljati. Razred OptionSetje addOption () metoda dodaja možnosti. To načelo oblikovanja ima to prednost, da imamo veliko boljši nadzor nad dejanskimi možnimi kombinacijami argumentov, uporabljenih za ustvarjanje OptionData primerov. Če bi bil na primer ta konstruktor javen, lahko ustvarite primerek s podrobnostmi, nastavljenimi na prav in vrednost nastavljena na napačno, kar je seveda nesmisel. Namesto da bi imel v konstruktorju natančne preglede, sem se odločil, da ponudim nadzorovan nabor addOption () metode.

Konstruktor ustvari tudi primerek java.util.regex.Pattern, ki se uporablja za postopek ujemanja vzorcev te možnosti. En primer bi bil vzorec za možnost, ki ima vrednost, brez podrobnosti in neprazno ločilo:

pattern = java.util.regex.Pattern.compile (prefix.getName () + ključ + separator.getName () + "(. +) $"); 

The OptionData razred, kot smo že omenili, vsebuje tudi rezultate preverjanj, ki jih je opravil Opcije razred. Zagotavlja naslednje javne metode za dostop do teh rezultatov:

int getResultCount () String getResultValue (int indeks) String getResultDetail (int indeks) 

Prva metoda, getResultCount (), vrne, kolikokrat je bila možnost najdena. Ta zasnova metode je neposredno povezana z množico, opredeljeno za možnost. Za možnosti, ki imajo vrednost, je to vrednost mogoče pridobiti s pomočjo getResultValue (indeks int) metoda, pri kateri se indeks lahko giblje med 0 in getResultCount () - 1. Za možnosti vrednosti, ki sprejemajo tudi podrobnosti, je do njih mogoče podobno dostopati s pomočjo getResultDetail (indeks int) metoda.

Razred OptionSet

The OptionSet class je v bistvu vsebnik za nabor OptionData primerke in tudi argumente podatkov, najdene v ukazni vrstici.

Konstruktor ima obliko:

OptionSet (predpona Options.Prefix, Options.Multiplicity defaultMultiplicity, String setName, int minData, int maxData) 

Tudi ta konstruktor ima dostop do paketov. Nabore možnosti je mogoče ustvariti samo z Opcije razred je drugačen addSet () metode. Pri dodajanju možnosti v nabor lahko privzeto množico za tukaj določene možnosti preglasite. Tu določeno ime niza je enolični identifikator, ki se uporablja za sklicevanje na niz. minData in maxData sta najmanjše in največje število sprejemljivih podatkovnih argumentov za ta niz.

Javni API za OptionSet vsebuje naslednje metode:

Splošni načini dostopa:

Niz getSetName () int getMinData () int getMaxData () 

Metode za dodajanje možnosti:

OptionSet addOption (String key) OptionSet addOption (String key, Multiplicity multiplicity) OptionSet addOption (String key, Separator separator) OptionSet addOption (String key, Separator separator, Multiplicity multiplicity) OptionSet addOption (String key, boolean details OptionSeparator Separator separator) (Ključ niza, logične podrobnosti, ločilo ločevalnika, večkratnost) 

Metode za dostop do podatkov o rezultatih preverjanja:

java.util.ArrayList getOptionData () OptionData getOption (String key) boolean isSet (String key) java.util.ArrayList getData () java.util.ArrayList getUnmatched () 

Upoštevajte, da so metode za dodajanje možnosti, ki uporabljajo a Ločilo argument ustvari OptionData primer sprejema vrednost. The addOption () metode vrnejo primerek samega, ki omogoča verigiranje klicev:

Možnosti možnosti = nove možnosti (argumenti); options.addSet ("MySet"). addOption ("a"). addOption ("b"); 

Po opravljenih pregledih so njihovi rezultati na voljo prek preostalih metod. getOptionData () vrne seznam vseh OptionData primerov, medtem ko getOption () omogoča neposreden dostop do določene možnosti. isSet (tipka String) je priročna metoda, ki preverja, ali je bila možnost vsaj enkrat najdena v ukazni vrstici. getData () omogoča dostop do najdenih argumentov podatkov, medtem ko getUnmatched () seznam vseh možnosti, najdenih v ukazni vrstici, za katere ni ujemanja OptionData primerov.

Razred Možnosti

Opcije je osnovni razred, s katerim bodo aplikacije sodelovale. Ponuja več konstruktorjev, ki zavzamejo niz nizov argumentov ukazne vrstice, ki je glavni () metoda kot prvi argument določa:

Možnosti (String args []) Možnosti (String args [], int data) Options (String args [], int defMinData, int defMaxData) Options (String args [], Multiplicity defaultMultiplicity) Options (String args [], Multiplicity defaultMultiplicity, int data) Možnosti (String args [], Multiplicity defaultMultiplicity, int defMinData, int defMaxData) Options (String args [], Predpona predpone) Options (String args [], Predpona predpone, int data) Options (String args [], Prefix predpona, int defMinData, int defMaxData) Možnosti (niz argumenti [], predpona predpona, Multiplicity defaultMultiplicity) Možnosti (niz argumenti [], predpona predpona, Multiplicity defaultMultiplicity, int podatki) Možnosti (niz argumenti [], predpona predpona, Multiplicity defaultMultiplicity, int defMinData, int defMaxData) 

Prvi konstruktor na tem seznamu je najpreprostejši z uporabo vseh privzetih vrednosti, zadnji pa je najbolj splošen.

Tabela 1: Argumenti za konstruktorje Options () in njihov pomen

Vrednost Opis Privzeto
predponoTa argument konstruktorja je edino mesto, kjer je mogoče določiti predpono. Ta vrednost se prenese na kateri koli nabor možnosti in katero koli možnost, ki se ustvari pozneje. Zamisel tega pristopa je, da se v dani aplikaciji ne zdi verjetno, da bi bilo treba uporabiti različne predpone.Predpona.DASH
defaultMultiplicityTa privzeta večkratnost se posreduje vsakemu naboru možnosti in se uporablja kot privzeta za možnosti, dodane naboru, ne da bi določili večkratnost. Seveda lahko to množico preglasimo za vsako dodano možnost.Množnost.KRAT
defMinDatadefMinData je privzeto najmanjše število podprtih podatkovnih argumentov, posredovanih vsakemu naboru možnosti, vendar ga je seveda mogoče dodati pri dodajanju nabora.0
defMaxDatadefMaxData je privzeto največje število podprtih podatkovnih argumentov, posredovanih vsakemu naboru možnosti, vendar ga je seveda mogoče dodati pri dodajanju nabora.0
$config[zx-auto] not found$config[zx-overlay] not found