Está en: Inicio >> ISValidator >> Ejemplos >> CommandLineMartes 20 de Mayo de 2025
SourceForge Logo
ISValidator
Presentacion
Arquitectura
Download
Ejemplos
To-Do
Cambios
Más información
ISDirValidator
Presentacion
En SF.net
Resumen
Download
Noticias
In English
ISValidator

Página... CommandLine

Ejemplos de ISValidator

Esta página recoge uno de los ejemplos de uso de las rutinas ISValidator. Puede así mismo ver los ejemplos que se incluyen en el paquete para descargar.

Situación

Supongamos que queremos realizar un programa que funcione bajo la línea de comandos del Sistema Operativo para mandar emails y registrarlos en una base de datos. A este programa se le deben pasar cuatro parámetros:

  • Email de destino, como primer argumento. Se impone por restricciones de la base de datos donde se van a almacenar los datos a introducir, que la longitud de este campo no sea superior a 100 caracteres, y por supuesto sea un email válido.
  • Asunto, como segundo argumento. Las restricciones para este campo son que no sea nulo y tenga una longitud máxima de 255 caracteres.
  • Fecha de envío, como tercer argumento. Este campo tiene como restricción que sea una fecha válida (dd/mm/aaaa).
  • Cuerpo del mensaje, como cuarto argumento. Se impone una restricción de tamaño máximo de 1000 caracteres

Si alguna de estas restricciones no se cumpliese se deberá mostrar un mensaje por pantalla indicando todas las condiciones incumplidas.

Código del ejemplo

Este ejemplo está hecho para la versión 0.0.10 de las rutinas ISValidator

Vamos a ver este ejemplo que hemos puesto en código Java. Algunas partes carentes de interés se han suprimido para no enturbiar el objeto, que es el comprender el funcionamiento de ISValidator

public static void main(java.lang.String[] args) {
	// this can be read from a properties file, but in this example is in the code for simplicity
	errorMessages.put("EmailConstraint", "The argument $argumentName; with value \"$valueToCheck;\" is not a valid email");
	errorMessages.put("DateConstraint", "The argument $argumentName; with value \"$valueToCheck;\" is not a valid date");
	errorMessages.put("NotNullConstraint", "You haven´t put all the parameters");

	try {
		//The meta container
		CommandLineMetaContainer inputParameters = new CommandLineMetaContainer(4, args);

		//For the email
		CommandLineArgumentConstraintContainer theEmail = new CommandLineArgumentConstraintContainer(0, "email", inputParameters);
		theEmail.addConstraint(new EmailConstraint());
		theEmail.addConstraint(new RegularExpresionConstraint(".{1,100}"));

		//For the Body
		//In this parameter we use a diferente constructor, without the metacontainer.
		//If we use the default constructor (without arguments) in the metacontainer this is the only way to add
		//constraintContainers, because the metacontainer dosen´t know the arguments
		CommandLineArgumentConstraintContainer theBody = new CommandLineArgumentConstraintContainer(3, "body", args);
		theBody.addConstraint(new RegularExpresionConstraint(".{1,1000}"));
		//we have use the constructor without the metacontainer so we must add the constraint container to it. It is a diferent way to do.
		inputParameters.addContainer(theBody);

		//here we are using the metacontainer to check the data and like a model of it.
		if (inputParameters.checkConstraint()) {
			//in this case the processor for the correct and incorrect is the same, paint it
			paintData(inputParameters);
		} else {
			//in this case the processor for the correct and incorrect is the same, paint it
			paintData(inputParameters);
		}
	} catch (CommandLineMetaContainerException e) {
		System.out.println("Error in the number of parameters, you have introduced " + e.getIntroducedArguments() + " and this program requires " + e.getRequiredArguments() + " arguments.");
		System.out.println("Usage:");
		System.out.println("java com.inigoserrano.isvalidator.examples.exampleCommandLineMetaContainer email subject date body");
	} catch (Exception e) {
		e.printStackTrace(System.out);
	}
}
/**
 * Method to paint the data
 */
private static void paintData(CommandLineMetaContainer data) throws InValidConstraintProcesorInternalException, ValidConstraintProcesorInternalException {
	//here we are using the metacontainer like a model of the data
	//if the constraints dosen´t match the i must initialitate the invalidConstraintProcessor
	if (!data.match()) {
		data.setInValidConstraintProcesor(new SimpleInValidConstraintProcesor(errorMessages), new SimpleInValidConstraintProcesorContainer());
	}

	//print the email
	if (data.getConstraintContainer("email").match()) {
		paintValidData(data.getConstraintContainer("email"));
	} else {
		paintInValidData(data.getConstraintContainer("email"));
	}

}
/**
 * Method to paint the invalid data
 */
private static void paintInValidData(ConstraintContainer data) throws InValidConstraintProcesorInternalException {
	//here we are using the metacontainer to help us to paint the data, in this case when it is invalid
	InValidConstraintProcesorContainer errorContainer = null;

	// get all the error messages
	errorContainer = data.getInvalidConstraintProcesorContainer();
	Enumeration iterator = errorContainer.elements();
	// and print it
	while (iterator.hasMoreElements()) {
		System.out.println(((InValidConstraintProcesor) iterator.nextElement()).getMessage());
	}
}
/**
 * Method to paint the valid data
 */
private static void paintValidData(ConstraintContainer data) {
	//here we are using the metacontainer to help us to paint the data, in this case when it is valid
	try {
		System.out.println(data.executeValidConstraintProcesor(new SimpleValidConstraintProcesor()));
	} catch (Exception e) {
		e.printStackTrace(System.out);
	}
}
                        

Descripción del Código

El código como se puede apreciar es muy sistemático.

Inicialmente se crea el metacontenedor que contendrá los contenedores de Restricciones. En este caso se utiliza el CommandLineMetaContainer, que sirve para recoger y modelar los datos provinientes de la linea de comandos, en otras situaciones se podrían utilizar otros metaContenedores.

//The meta container
CommandLineMetaContainer inputParameters = new CommandLineMetaContainer(4, args);

                        

Seguidamente se crean los Contenedores de Restricciones (ConstraintContainer) , uno por campo a validar. En este ejemplo se utiliza el CommandLineArgumentConstraintContainer que es el adecuado para los argumentos de la línea de comandos, aunque se podría utilizar otro, como se verá en el ejemplo del Servlet (también se pueden crear nuevos contenedores).

Al contenedor se le añaden las restricciones. Se puede comprobar que el campo email tiene dos restricciones y el resto tiene solo una. Utilizando esta forma el constraintContainer se añade directamente al metacontenedor, lo que facilita el trabajo

//For the email
CommandLineArgumentConstraintContainer theEmail = new CommandLineArgumentConstraintContainer(0, "email", inputParameters);
theEmail.addConstraint(new EmailConstraint());
theEmail.addConstraint(new RegularExpresionConstraint(".{1,100}"));
                        

Con esta información ya se puede comprobar si son todos válidos

		if (inputParameters.checkConstraint()) {

                        

En este caso tanto si los datos son correctos como si no se realiza el mismo proceso y se muestran por consola.

Para ello debemos indicarle al metacontenedor que procesador de restricciones invalidas queremos utilizar, en este caso utilizamos SimpleInValidConstraintProcesor pasandole como parámetro la hashtable que contiene los mensajes parametrizados de error y como segundo parámetro el tipo de objeto que queremos que recoja todos los errores. Esta modificación se ha realizado para aportar mayor flexibilidad y poder trabajar con otros productos como el Struts de Apache

En la Hashtable se le pasa un mensaje parametrizado para cada tipo de restricción. Los parámetros se marcan en el mensaje iniciándolos con un $ y terminándolos con un ; . Este procesador realiza una sustitución de los parámetros del mensaje por el valor que le ha dado la restricción a esos parámetros

	if (!data.match()) {
		data.setInValidConstraintProcesor(new SimpleInValidConstraintProcesor(errorMessages), new SimpleInValidConstraintProcesorContainer());
	}
                        
//print the email
if (data.getConstraintContainer("email").match()) {
	paintValidData(data.getConstraintContainer("email"));
} else {
        paintInValidData(data.getConstraintContainer("email"));
}
                        

En este código superior lo que se hace es obtener el dato en forma de CosntraintContainer y comprobar si es válido o no, y llamar a la función de pintado dependiendo de ello

	// get all the error messages
	errorContainer = data.getInvalidConstraintProcesorContainer();
	Enumeration iterator = errorContainer.elements();
	// and print it
	while (iterator.hasMoreElements()) {
		System.out.println(((InValidConstraintProcesor) iterator.nextElement()).getMessage());
	}
                        

Para pintar los datos erroneos lo que se hace es pedirle al contenedor de restricciones que nos devuelva el contenedor de procesadores de restricciones invalidas, que es el que , en este caso, dispone de los mensajes de error con las substituciones de las variables. Como un dato puede tener más de una restricción incumplida, y cada restricción tiene su mensaje debemos recorrer la enumeración para mostrarlas todas.

System.out.println(data.executeValidConstraintProcesor(new SimpleValidConstraintProcesor()));
                        

El pintado de los datos validos es más simple, ya que solo hay que darle el procesador que queremos utilizar.

Variante 1

Existe una variante general a este funcionamiento y es la de que ante el incumplimiento de una determinada restricción se lance una excepción para romper el flujo del programa. Esta modalidad es útil si ante un error no se va a realizar ningún tratamiento, y con que uno falle ya se da todo por inválido. Realmente el no indicar nada en el valor booleano de lanzar excepción, como en el ejemplo principal es lo mismo que indicar que el valor es false.

//For the email
CommandLineArgumentConstraintContainer theEmail = new CommandLineArgumentConstraintContainer(0, "email", inputParameters, true);
theEmail.addConstraint(new EmailConstraint());
theEmail.addConstraint(new RegularExpresionConstraint(".{1,100}",false));

                        

En este caso se indica a nivel de contenedor que se quiere lanzar una excepción cuando no se satisfaga una condición. Si se indica una opción a nivel de restricción esta tiene prevalencia sobre la del contenedor. En ejemplo anterior en el caso de que no se cumpliese la segunda restricción no se lanzaría una excepción, porque explícitamente se ha dicho que no se quiere que el incumplimiento de esa restricción lance excepciones.

Variante 2

Otra de las variante que se pueden utilizar es la de que el contenedor no se añada directamente al metacontenedor, y realizarlo manualmente.

//For the Body
//In this parameter we use a diferente constructor, without the metacontainer.
//If we use the default constructor (without arguments) in the metacontainer this is the only way to add
//constraintContainers, because the metacontainer dosen´t know the arguments
CommandLineArgumentConstraintContainer theBody = new CommandLineArgumentConstraintContainer(3, "body", args);
theBody.addConstraint(new RegularExpresionConstraint(".{1,1000}"));
//we have use the constructor without the metacontainer so we must add the constraint container to it. It is a diferent way to do.
inputParameters.addContainer(theBody);
                        

Para ello hay que utilizar el constructor del contenedor de la esta manera manera. En los ejemplos del paquete para descargar se puede ver el ejemplo completo.




Iñigo Serrano todos los derechos reservados.
Queda prohibida la reproducción total o parcial del contenido aquí expuesto.