package es.ejie.frmk.presentacion.validacion;

import java.io.Serializable;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.validator.Field;
import org.apache.commons.validator.ValidatorAction;
import org.apache.struts.action.ActionErrors;

import es.ejie.frmk.infraestructura.logs.incidencias.Q70LogIncidencias;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70Traza;


/**
 * Clase que implementa la funcionalidad del componente <b>Gestor de Validaciones Genéricas</b> de Geremua.
 * <p>
 * Se trata de una adaptación del <b>Validator-Framework de Jakarta</b> para que colabore con el componente
 * de <b>Gestor de Internacionalización</b>.
 * <p>
 * Implementa las reglas indicadas en los ficheros de reglas de validación que presentan las web-applications
 * en la carpeta de configuración de su directorio /WEB-INF (por ejemplo: 
 * <code>\WEB-INF\validators-config\validator-rules.xml</code>)
 * 
 */
public class Q70ValidacionesGenericas
	implements  Serializable {
	
	/**
	 * Constante que indica el componente al que pertenece dicha clase. Es
	 * necesario para el uso del log de trazas.
	 */
	private static final String COMPONENTE = "VALIDACIONES_GEN";

	/**
	 * Instancia del log de trazas
	 */
	private static Q70Traza tr = Q70Traza.getSingleton();
	
	/**
	 * Instancia del log de incidencias.
	 */
	private static Q70LogIncidencias logInc = Q70LogIncidencias.getSingleton();

	/**
	 * Checks if the field isn't null and length of the field is greater than zero not 
	 * including whitespace.
	 *
	 * @param bean The bean validation is being performed on.
	 * @param va The <code>ValidatorAction</code> that is currently being performed.
	 * @param field The <code>Field</code> object associated with the current 
	 * field being validated.
	 * @param errors The <code>ActionErrors</code> object to add errors to if 
	 * any validation errors occur.
	 * @param request Current request object.
	 * @return true if meets stated requirements, false otherwise.
	 */
	public static boolean validateRequired(Object bean,
										   ValidatorAction va, Field field,
										   ActionErrors errors,
										   HttpServletRequest request) {										   	
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateRequired(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateRequired",field.getKey());
		return bResultado;
	}

	/**
	 * Checks if the field isn't null based on the values of other fields.
	 *
	 * @param bean The bean validation is being performed on.
	 * @param va The <code>ValidatorAction</code> that is currently being 
	 * performed.
	 * @param field The <code>Field</code> object associated with the current 
	 * field being validated.
	 * @param errors The <code>ActionErrors</code> object to add errors to if 
	 * any validation errors occur.
	 * @param validator The <code>Validator</code> instance, used to access 
	 * other field values.
	 * @param request Current request object.
	 * @return true if meets stated requirements, false otherwise.
	 */
	public static boolean validateRequiredIf(Object bean,
											 ValidatorAction va, Field field,
											 ActionErrors errors,
											 org.apache.commons.validator.Validator validator,
											 HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateRequiredIf(bean, va, field, errors, validator, request);
		if (!bResultado)
			writeIncLog("validateRequiredIf",field.getKey());
		return bResultado;
	}

	/**
	 * Checks if the field matches the regular expression in the field's mask attribute.
	 *
	 * @param bean The bean validation is being performed on.
	 * @param va The <code>ValidatorAction</code> that is currently being 
	 * performed.
	 * @param field The <code>Field</code> object associated with the current 
	 * field being validated.
	 * @param errors   The <code>ActionErrors</code> object to add errors to if 
	 * any validation errors occur.
	 * @param request Current request object.
	 * @return true if field matches mask, false otherwise.
	 */
	public static boolean validateMask(Object bean,
									   ValidatorAction va, Field field,
									   ActionErrors errors,
									   HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateMask(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateMask",field.getKey());
		return bResultado;		
	}


	/**
	 * Checks if the field can safely be converted to a byte primitive.
	 *
	 *@param bean The bean validation is being performed on.
	 *@param va The <code>ValidatorAction</code> that is currently being performed.
	 *@param field The <code>Field</code> object associated with the current 
	 *field being validated.
	 *@param errors The <code>ActionErrors</code> object to add errors to if 
	 *any validation errors occur.
	 *@param request Current request object.
	 *@return A Byte if valid, null otherwise.
	 */
	public static Byte validateByte(Object bean,
									ValidatorAction va, Field field,
									ActionErrors errors,
									HttpServletRequest request) {
		Byte bResultado = null;
		bResultado = Q70ValidacionesCampo.validateByte(bean, va, field, errors, request);
		if (bResultado == null)
			writeIncLog("validateByte",field.getKey());
		return bResultado;		
	}


	/**
	 * Checks if the field can safely be converted to a short primitive.
	 *
	 * @param bean The bean validation is being performed on.
	 * @param va The <code>ValidatorAction</code> that is currently being performed.
	 * @param field The <code>Field</code> object associated with the current 
	 * field being validated.
	 * @param errors The <code>ActionErrors</code> object to add errors to if 
	 * any validation errors occur.
	 * @param request Current request object.
	 * @return A Short if valid, otherwise null.
	 */
	public static Short validateShort(Object bean,
									  ValidatorAction va, Field field,
									  ActionErrors errors,
									  HttpServletRequest request) {
		Short bResultado = null;
		bResultado = Q70ValidacionesCampo.validateShort(bean, va, field, errors, request);
		if (bResultado == null)
			writeIncLog("validateShort",field.getKey());
		return bResultado;		
	}


	/**
	 * Checks if the field can safely be converted to an int primitive.
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return          An Integer if valid, a null otherwise.
	 */
	public static Integer validateInteger(Object bean,
										  ValidatorAction va, Field field,
										  ActionErrors errors,
										  HttpServletRequest request) {										   	
		Integer bResultado = null;
		bResultado = Q70ValidacionesCampo.validateInteger(bean, va, field, errors, request);
		if (bResultado == null)
			writeIncLog("validateInteger",field.getKey());
		return bResultado;
	}


	/**
	 * Chequea que el campo sea null o un entero en caso de no ser nulo
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return          An Integer if valid, a null otherwise.
	 */
	public static Integer validateIntegerOrNull(Object bean,
										  ValidatorAction va, Field field,
										  ActionErrors errors,
										  HttpServletRequest request) {										   	
		Integer bResultado = null;
		bResultado = Q70ValidacionesCampo.validateIntegerOrNull(bean, va, field, errors, request);
		return bResultado;
	}


	/**
	 * Checks if the field can safely be converted to a long primitive.
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return          A Long if valid, a null otherwise.
	 */
	public static Long validateLong(Object bean,
									ValidatorAction va, Field field,
									ActionErrors errors,
									HttpServletRequest request) {
		Long bResultado = null;
		bResultado = Q70ValidacionesCampo.validateLong(bean, va, field, errors, request);
		if (bResultado == null)
			writeIncLog("validateLong",field.getKey());
		return bResultado;
	}


	/**
	 * Checks if the field can safely be converted to a float primitive.
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return A Float if valid, a null otherwise.
	 */
	public static Float validateFloat(Object bean,
									  ValidatorAction va, Field field,
									  ActionErrors errors,
									  HttpServletRequest request) {
		Float bResultado = null;
		bResultado = Q70ValidacionesCampo.validateFloat(bean, va, field, errors, request);
		if (bResultado == null)
			writeIncLog("validateFloat",field.getKey());
		return bResultado;
	}


	/**
	 *  Checks if the field can safely be converted to a double primitive.
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return A Double if valid, a null otherwise.
	 */
	public static Double validateDouble(Object bean,
										ValidatorAction va, Field field,
										ActionErrors errors,
										HttpServletRequest request) {
		Double bResultado = null;
		bResultado = Q70ValidacionesCampo.validateDouble(bean, va, field, errors, request);
		if (bResultado == null)
			writeIncLog("validateDouble",field.getKey());
		return bResultado;
	}


	/**
	 *  Checks if the field is a valid date. If the field has a datePattern variable,
	 *  that will be used to format <code>java.text.SimpleDateFormat</code>. If the
	 *  field has a datePatternStrict variable, that will be used to format <code>java.text.SimpleDateFormat</code>
	 *  and the length will be checked so '2/12/1999' will not pass validation with
	 *  the format 'MM/dd/yyyy' because the month isn't two digits. If no datePattern
	 *  variable is specified, then the field gets the DateFormat.SHORT format for
	 *  the locale. The setLenient method is set to <code>false</code> for all variations.
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return A Date if valid, a null if blank or invalid.
	 */
	public static Date validateDate(Object bean,
									ValidatorAction va, Field field,
									ActionErrors errors,
									HttpServletRequest request) {
		Date bResultado = null;
		bResultado = Q70ValidacionesCampo.validateDate(bean, va, field, errors, request);
		if (bResultado == null)
			writeIncLog("validateDate",field.getKey());
		return bResultado;
	}

	/**
	 * Checks if a fields value is within a range (min &amp; max specified in the
	 * vars attribute).
	 * 
	 *@deprecated  As of Struts 1.1, replaced by {@link #validateIntRange(java.lang.Object,org.apache.commons.validator.ValidatorAction,org.apache.commons.validator.Field,org.apache.struts.action.ActionErrors,javax.servlet.http.HttpServletRequest)}
	 *@param  bean     The bean validation is being performed on.
	 *@param  va       The <code>ValidatorAction</code> that is currently being performed.
	 *@param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 *@param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 *@param  request  Current request object.
	 *@return          True if in range, false otherwise.
	 */
	public static boolean validateRange(Object bean,
										ValidatorAction va, Field field,
										ActionErrors errors,
										HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateRange(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateRange",field.getKey());
		return bResultado;
	}

	/**
	 * Checks if a fields value is within a range (min &amp; max specified in the
	 * vars attribute).
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return True if in range, false otherwise.
	 */
	public static boolean validateIntRange(Object bean,
										   ValidatorAction va, Field field,
										   ActionErrors errors,
										   HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateIntRange(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateIntRange",field.getKey());
		return bResultado;
	}

	/**
	 *  Checks if a fields value is within a range (min &amp; max specified in the
	 *  vars attribute).
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return          True if in range, false otherwise.
	 */
	public static boolean validateDoubleRange(Object bean,
											  ValidatorAction va, Field field,
											  ActionErrors errors,
											  HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateDoubleRange(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateDoubleRange",field.getKey());
		return bResultado;
	}

	/**
	 *  Checks if a fields value is within a range (min &amp; max specified in the
	 *  vars attribute).
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return True if in range, false otherwise.
	 */
	public static boolean validateFloatRange(Object bean,
											 ValidatorAction va, Field field,
											 ActionErrors errors,
											 HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateFloatRange(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateFloatRange",field.getKey());
		return bResultado;
	}


	/**
	 *  Checks if the field is a valid credit card number.
	 * 
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return The credit card as a Long, a null if invalid, blank, or null.
	 */
	public static Long validateCreditCard(Object bean,
										  ValidatorAction va, Field field,
										  ActionErrors errors,
										  HttpServletRequest request) {
		Long bResultado = null;
		bResultado = Q70ValidacionesCampo.validateCreditCard(bean, va, field, errors, request);
		if (bResultado == null)
			writeIncLog("validateCreditCard",field.getKey());
		return bResultado;
	}


	/**
	 *  Checks if a field has a valid e-mail address.
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return True if valid, false otherwise.
	 */
	public static boolean validateEmail(Object bean,
										ValidatorAction va, Field field,
										ActionErrors errors,
										HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateEmail(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateEmail",field.getKey());
		return bResultado;
	}


	/**
	 *  Checks if the field's length is less than or equal to the maximum value.
	 *  A <code>Null</code> will be considered an error.
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return True if stated conditions met.
	 */
	public static boolean validateMaxLength(Object bean,
											ValidatorAction va, Field field,
											ActionErrors errors,
											HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateMaxLength(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateMaxLength",field.getKey());
		return bResultado;
	}


	/**
	 * Checks if the field's length is greater than or equal to the minimum value.
	 * A <code>Null</code> will be considered an error.
	 *
	 * @param  bean     The bean validation is being performed on.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 *      field being validated.
	 * @param  errors   The <code>ActionErrors</code> object to add errors to if any
	 *      validation errors occur.
	 * @param  request  Current request object.
	 * @return True if stated conditions met.
	 */
	public static boolean validateMinLength(Object bean,
											ValidatorAction va, Field field,
											ActionErrors errors,
											HttpServletRequest request) {
		boolean bResultado = false;
		bResultado = Q70ValidacionesCampo.validateMinLength(bean, va, field, errors, request);
		if (!bResultado)
			writeIncLog("validateMinLength",field.getKey());
		return bResultado;
	}
	
	
	/**
	 * Método que registra una validación rechazada en el log de incidencias.
	 * 
	 * @param metodo Método que ha rechazado la validación.
	 * @param field Campo cuya validación ha sido rechada y queremos que sea
	 * registrado en el log de incidencias.
	 */
	private static void writeIncLog(String metodo, String field)
	{
		if (tr.isTraceActive())
		{
			tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Validación rechazada para el campo "+field);
		}
		if (logInc.isEnabled())
		{
			Q70ValidacionGenericaException validacionGenericaException = new Q70ValidacionGenericaException(Q70ValidacionesGenericas.class.toString(), metodo, "Validación rechazada para el campo "+field, null);
			logInc.log(validacionGenericaException, COMPONENTE, "WARN");
		}
	}
}
