Tratamiento de líneas de comando mediante «Commons CLI»
Una tarea que inicialmente suelen realizar la gran mayoría de las aplicaciones es el
análisis de los parámetros con los que el usuario ha invocado la aplicación.
Es este tutorial voy a realizar una presentación de una librería que nos facilitar enormemente esta tarea.
Apache Commons CLI
Apache Commons CLI (Command Line Interface) es una de las útiles librerías que forman parte de Apache Commons.
Esta librería es bastante ligera, unos 35Kb, por lo que no es descartable a pesar de que el análisis de los parámetros se suela realizar únicamente una vez al inicio de la aplicación.
Modo de empleo general
Normalmente el tratamiento de la línea de comandos se realiza en tres pasos:
- Definición
- Parseo
- Análisis del parseo
Definición
En esta etápa se define como será la línea de comando que acepte nuestra aplicación. Esta definición se realiza a través de las clases org.apache.commons.cli.Options
y org.apache.commons.cli.Option
de la librería
Por ejemplo, en el siguiente fragmento de código, definimos dos parámetros ip
y h
.
Options options = new Options(); options.addOption("ip", true, "IP de destino"); // Nombre del parámetro, ¿tiene que tener un valor asociado?, Descripción options.addOption("h", false, "Imprime el mensaje de ayuda");
Parseo
En esta etapa la librería analizará automáticamente la línea de comandos según lo definido en la clase Options
Análisis del parseo
En esta etapa, debemos verificar que los valores de los parámetros son correctos, por ejemplo, que un parámetro requerido esté presente y tenga un valor válido.
Un ejemplo
En el siguiente fragmento de código (autocomentado), mostramos una pequeña aplicación cuya línea de comando se compone
de los siguientes parámetros:
-ip address [-port puerto] [err|console] [-help | -h]
En donde el único parámetro requerido es el parámetro ip
y en donde no pueden aparecer a la misma vez los parámetros console
y error
import org.apache.commons.cli.*; import java.io.OutputStream; /** * Ejemplos del uso de la librería "Apache Commons CLI" * @author Carlos García. Autentia. */ public class CommonsCliApp { /** * -ip address [-port puerto] [err|console] [-help | -h] */ public static void main(String[] args) { final int DEF_PORT = 60001; // Puerto por defecto int port = 0; String ip = null; OutputStream output = null; CommandLineParser parser = null; CommandLine cmdLine = null; /////////////////////////////////////////////////////////////////////// // Fase 1: Configuramos las opciones de validación de entrada. /////////////////////////////////////////////////////////////////////// Options options = new Options(); options.addOption("ip", true, "IP de destino"); options.addOption("port", true, "Puerto destino"); options.addOption("h", "help", false, "Imprime el mensaje de ayuda"); // No pueden aparecen las dos opciones simultáneamente. OptionGroup group = new OptionGroup(); group.addOption(new Option("err", "Salida estándar de errores")); group.addOption(new Option("console", "Salida estándar")); options.addOptionGroup(group); try { /////////////////////////////////////////////////////////////////////// // Fase 2: Parseamos la entrada con la configuración establecida /////////////////////////////////////////////////////////////////////// parser = new BasicParser(); cmdLine = parser.parse(options, args); /////////////////////////////////////////////////////////////////////// // Fase 3: Analizamos los resultados y realizamos las tareas pertinentes /////////////////////////////////////////////////////////////////////// // Si está la opcion de ayuda, la imprimimos y salimos. if (cmdLine.hasOption("h")){ // No hace falta preguntar por el parámetro "help". Ambos son sinónimos new HelpFormatter().printHelp(CommonsCliApp.class.getCanonicalName(), options ); return; } // Si el usuario ha especificado el puerto lo leemos if (cmdLine.hasOption("port")){ port = Integer.parseInt( cmdLine.getOptionValue("port") ); } else { port = DEF_PORT; } // Leemos la dirección IP. Sino existe generamos un error pues es un parámetro requerido. ip = cmdLine.getOptionValue("ip"); if (ip == null){ throw new org.apache.commons.cli.ParseException("La direccion IP es requerida"); } if (cmdLine.hasOption("console")){ output = System.out; } else if (cmdLine.hasOption("err")){ output = System.err; } else { output = null; } // .............................................................. // Aquí irían las tareas que tuviera que realizar la aplicación // .............................................................. System.out.println("OK"); } catch (org.apache.commons.cli.ParseException ex){ System.out.println(ex.getMessage()); new HelpFormatter().printHelp(CommonsCliApp.class.getCanonicalName(), options ); // Error, imprimimos la ayuda } catch (java.lang.NumberFormatException ex){ new HelpFormatter().printHelp(CommonsCliApp.class.getCanonicalName(), options ); // Error, imprimimos la ayuda } } }
Algunos ejemplos de invocació a la aplicación para ver la salida
(Suponemos que la librería commons cli
está en el CLASSPATH
)
Bueno, para terminar, recordaros que esto no es más que un tutorial introductorio a la librería. Si necesitais más información podeis dirigiros a la página oficial del proyecto.
Carlos García Pérez. Creador de MobileTest, un complemento educativo para los profesores y sus alumnos.
cgpcosmad@gmail.com
Muy bueno, práctico, conciso, y bien comentado. Muchas gracias.