Menghuraikan baris arahan dengan Apache Commons CLI

Dari semasa ke semasa, saya merasa perlu menangani argumen baris perintah di Java baik untuk aplikasi berbasis Java atau untuk implementasi fungsi utama () yang menyediakan mekanisme pengujian mudah langsung di dalam kelas yang sedang diuji. Pembangun Java mempunyai banyak pilihan untuk menguraikan baris perintah. Apabila hanya ada satu, dua, atau sebilangan kecil argumen baris perintah (terutamanya jika kehadiran atau ketiadaan bendera adalah semua yang diperlukan daripada nilai yang menyertainya), tulis beberapa baris kod untuk memproses perintah ini- pilihan garis bukan masalah besar. Apabila terdapat lebih banyak pilihan dan / atau beberapa pilihan mempunyai nilai, ada baiknya mengakses sokongan yang lebih canggih untuk menguraikan baris perintah.

Dalam entri blog ini, saya akan melihat penggunaan perpustakaan Apache Commons CLI, tetapi terdapat banyak pilihan lain seperti args4j, penghuraian baris perintah TE-Code, CLAJR (Argumen Baris Perintah dengan Refleksi Java), JArgs, JSAP (Java Simple Pemproses Argumen), dan beberapa yang lain (lebih banyak lagi di sini).

Walaupun perpustakaan Apache Commons CLI adalah sebahagian daripada Apache Commons, ia adalah muat turun berasingan (JAR) dari muat turun JAR untuk Apache Commons Modeler dan dari muat turun JAR untuk Apache Commons Lang yang saya bicarakan dalam entri blog sebelumnya yang terdapat di sini dan di sini. Untuk entri blog ini, saya menggunakan CLI 1.1 kerana tidak ada pelepasan yang dijangkakan untuk CLI 2.0 (keterangan lebih lanjut mengenai ini pada akhir entri ini).

Saya akan menunjukkan beberapa contoh ringkas Apache Common CLI dan memasukkan beberapa pautan ke sumber lain semasa penggunaan perpustakaan ini.

Dua kelas penting dalam penggunaan Apache Common CLI adalah kelas org.apache.commons.cli.Option dan org.apache.commons.cli.Options yang berkait rapat (mengandungi beberapa contoh Optionkelas). Kelas-kelas ini digunakan untuk mewakili pilihan baris perintah yang diharapkan. Dua coretan kod berikut menunjukkan penyediaan kelas Pilihan untuk pilihan gaya Posix dan pilihan gaya GNU.

Menggunakan Kelas Pilihan dengan Contoh Pilihan Berganda

 /** * 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; } 

Perhatikan dalam contoh pengaturan Pilihan yang belum ada perbedaan dalam menangani pilihan gaya Posix berbanding gaya GNU. Setakat ini, pilihan boleh diperlakukan sama.

Sebelum beralih ke demonstrasi penghuraian argumen baris perintah CLI berdasarkan pilihan yang dijangkakan ini, perlu diperhatikan sokongan CLI untuk maklumat penggunaan dan maklumat bantuan melalui kelas org.apache.commons.cli.HelpFormatter. Kelas utiliti berguna ini mengandungi kaedah seperti versi PrintHelp yang terlalu banyak, versi printUsage yang terlalu banyak, dan beberapa output lain dan kaedah yang berkaitan.

Coretan kod berikut menunjukkan kaedah yang menggunakan salah satu kaedah printUsage HelpFormatter dan salah satu kaedah printHelp kelas itu.

printUsage () dan 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(); } 

Coretan kod seterusnya menunjukkan beberapa panggilan ke kaedah printHelp () dan printUsage () yang ditunjukkan di atas dan diikuti oleh snapshot skrin yang menunjukkan output dari menjalankannya.

 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); 

Cuplikan skrin pertama menunjukkan hasil ketika kod di atas dijalankan persis seperti yang ditunjukkan (dengan truediteruskan ke kedua penggunaan printHelpmetode untuk menunjukkan bahawa pilihan harus disertakan dalam bahagian penggunaan). Cuplikan skrin kedua menunjukkan apa yang berlaku apabila panggilan kedua printHelptidak diserahkan kepadanya sehingga pilihan tidak ditampilkan.

printUsage dan printHelp

printUsage dan printHelp with One printHelp Tidak Memaparkan Pilihan

Walaupun penggunaan dan pertolongan mengenai pilihan adalah, seperti namanya, bermanfaat dan berguna, alasan sebenarnya untuk menggunakan argumen baris perintah biasanya untuk mengawal tingkah laku aplikasi. Penyenaraian kod seterusnya menunjukkan dua kaedah untuk menghuraikan argumen baris perintah gaya GNU dan gaya Posix. Walaupun pengaturan Pilihan tidak mementingkan gaya tertentu selain menentukan pilihan itu sendiri, jenis pilihan penting sekarang untuk menentukan penghurai yang sesuai untuk digunakan.

usePosixParser () dan 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() ); } } 

Apabila kod di atas dijalankan, outputnya seperti yang ditunjukkan dalam dua tangkapan skrin berikutnya:

Keputusan PosixParser

Hasil Penyusun GNU

Contoh Lengkap

Kod lengkap untuk aplikasi contoh dari mana bahagian ditunjukkan di atas kini disenaraikan untuk kemudahan.