package es.ejie.frmk.presentacion.validacion;

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

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.validator.Arg;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericTypeValidator;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorUtil;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.validator.Resources;

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

/**
 * @version 1.0
 * Fecha: 05-feb-04
 */
public class Q70ValidacionesCampo 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();
	
	public static final String FIELD_TEST_NULL = "NULL";
	public static final String FIELD_TEST_NOTNULL = "NOTNULL";
	public static final String FIELD_TEST_EQUAL = "EQUAL";

	/**
	 * 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) {

		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}
        
		if (GenericValidator.isBlankOrNull(value)) {
			errors.add(field.getKey(), getActionError(request, va, field));
			return false;
		} else {
			return true;
		}

	}

	/**
	 * 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) {
                                                 
		Object form = validator.getResource(org.apache.commons.validator.Validator.BEAN_KEY);
		String value = null;
		boolean required = false;
        
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}
        
		int i = 0;
		String fieldJoin = "AND";
		if (!GenericValidator.isBlankOrNull(field.getVarValue("fieldJoin"))) {
			fieldJoin = field.getVarValue("fieldJoin");
		}
        
		if (fieldJoin.equalsIgnoreCase("AND")) {
			required = true;
		}
        
		while (!GenericValidator.isBlankOrNull(field.getVarValue("field[" + i + "]"))) {
			String dependProp = field.getVarValue("field[" + i + "]");
			String dependTest = field.getVarValue("fieldTest[" + i + "]");
			String dependTestValue = field.getVarValue("fieldValue[" + i + "]");
			String dependIndexed = field.getVarValue("fieldIndexed[" + i + "]");
            
			if (dependIndexed == null) {
				dependIndexed = "false";
			}
            
			String dependVal = null;
			boolean thisRequired = false;
			if (field.isIndexed() && dependIndexed.equalsIgnoreCase("true")) {
				String key = field.getKey();
				if ((key.indexOf("[") > -1) && (key.indexOf("]") > -1)) {
					String ind = key.substring(0, key.indexOf(".") + 1);
					dependProp = ind + dependProp;
				}
			}
            
			dependVal = ValidatorUtil.getValueAsString(form, dependProp);
			if (dependTest.equals(FIELD_TEST_NULL)) {
				if ((dependVal != null) && (dependVal.length() > 0)) {
					thisRequired = false;
				} else {
					thisRequired = true;
				}
			}
            
			if (dependTest.equals(FIELD_TEST_NOTNULL)) {
				if ((dependVal != null) && (dependVal.length() > 0)) {
					thisRequired = true;
				} else {
					thisRequired = false;
				}
			}
            
			if (dependTest.equals(FIELD_TEST_EQUAL)) {
				thisRequired = dependTestValue.equalsIgnoreCase(dependVal);
			}
            
			if (fieldJoin.equalsIgnoreCase("AND")) {
				required = required && thisRequired;
			} else {
				required = required || thisRequired;
			}
            
			i++;
		}
        
		if (required) {
			if (GenericValidator.isBlankOrNull(value)) {
				errors.add(
					field.getKey(),
					getActionError(request, va, field));
				
				return false;

			} else {
				return true;
			}
		}
		return true;
	}

	/**
	 * 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) {

		String mask = field.getVarValue("mask");
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}
        
		try {
			if (!GenericValidator.isBlankOrNull(value)
				&& !GenericValidator.matchRegexp(value, mask)) {
                    
				errors.add(
					field.getKey(),
					getActionError(request, va, field));

				return false;
			} else {
				return true;
			}
		} catch (Exception e) {
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Excepción en el método validateMask");
			}
			if (logInc.isEnabled())
			{
				Q70ValidacionGenericaException validacionGenericaException = new Q70ValidacionGenericaException(Q70ValidacionesCampo.class.toString(), "validateMask", "Excepción en el método validateMask", e);
				logInc.log(validacionGenericaException, COMPONENTE, "ERROR");
			}
		}
		return true;
	}


	/**
	 * 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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			result = GenericTypeValidator.formatByte(value);

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
			}
		}

		return result;
	}


	/**
	 * 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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			result = GenericTypeValidator.formatShort(value);

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
			}
		}

		return result;
	}


	/**
	 * 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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			result = GenericTypeValidator.formatInt(value);

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
			}
		}

		return result;
	}

	/**
	 * 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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			result = GenericTypeValidator.formatInt(value);

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
				//tracear y registrar la validación rechazada en el log de incidencias.
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Validación rechazada para el campo "+field);
				}
				if (logInc.isEnabled())
				{
					Q70ValidacionGenericaException validacionGenericaException = new Q70ValidacionGenericaException(Q70ValidacionesCampo.class.toString(), "validateIntegerOrNull", "Validación rechazada para el campo "+field, null);
					logInc.log(validacionGenericaException, COMPONENTE, "WARN");
				}
			}
		}

		return result;
	}

	/**
	 * 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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			result = GenericTypeValidator.formatLong(value);

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
			}
		}

		return result;
	}


	/**
	 * 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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			result = GenericTypeValidator.formatFloat(value);

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
			}
		}

		return result;
	}


	/**
	 *  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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			result = GenericTypeValidator.formatDouble(value);

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
			}
		}

		return result;
	}


	/**
	 *  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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}
		String datePattern = field.getVarValue("datePattern");
		String datePatternStrict = field.getVarValue("datePatternStrict");
		Locale locale = Resources.getLocale(request);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				if (datePattern != null && datePattern.length() > 0) {
					result = GenericTypeValidator.formatDate(value, datePattern, false);
				} else if (datePatternStrict != null && datePatternStrict.length() > 0) {
					result = GenericTypeValidator.formatDate(value, datePatternStrict, true);
				} else {
					result = GenericTypeValidator.formatDate(value, locale);
				}
			} catch (Exception e) {
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Excepción en el método validateDate");
				}
				if (logInc.isEnabled())
				{
					Q70ValidacionGenericaException validacionGenericaException = new Q70ValidacionGenericaException(Q70ValidacionesCampo.class.toString(), "validateDate", "Excepción en el método validateDate", e);
					logInc.log(validacionGenericaException, COMPONENTE, "ERROR");
				}
			}

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
			}
		}

		return result;
	}

	/**
	 * 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) {
		return validateIntRange(bean, va, field, errors, request);
	}

	/**
	 * 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) {

		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				int intValue = Integer.parseInt(value);
				int min = Integer.parseInt(field.getVarValue("min"));
				int max = Integer.parseInt(field.getVarValue("max"));

				if (!GenericValidator.isInRange(intValue, min, max)) {
					errors.add(field.getKey(), getActionError(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(), getActionError(request, va, field));
				return false;
			}
		}

		return true;
	}

	/**
	 *  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) {

		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				double doubleValue = Double.parseDouble(value);
				double min = Double.parseDouble(field.getVarValue("min"));
				double max = Double.parseDouble(field.getVarValue("max"));

				if (!GenericValidator.isInRange(doubleValue, min, max)) {
					errors.add(field.getKey(), getActionError(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(), getActionError(request, va, field));
				return false;
			}
		}

		return true;
	}

	/**
	 *  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) {

		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				float floatValue = Float.parseFloat(value);
				float min = Float.parseFloat(field.getVarValue("min"));
				float max = Float.parseFloat(field.getVarValue("max"));

				if (!GenericValidator.isInRange(floatValue, min, max)) {
					errors.add(field.getKey(), getActionError(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(), getActionError(request, va, field));
				return false;
			}
		}

		return true;
	}


	/**
	 *  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 result = null;
		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			result = GenericTypeValidator.formatCreditCard(value);

			if (result == null) {
				errors.add(field.getKey(), getActionError(request, va, field));
			}
		}

		return result;
	}


	/**
	 *  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) {

		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value) && !GenericValidator.isEmail(value)) {
			errors.add(field.getKey(), getActionError(request, va, field));
			return false;
		} else {
			return true;
		}
	}


	/**
	 *  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) {

		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (value != null) {
			try {
				int max = Integer.parseInt(field.getVarValue("maxlength"));

				if (!GenericValidator.maxLength(value, max)) {
					errors.add(field.getKey(), getActionError(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(), getActionError(request, va, field));
				return false;
			}
		}

		return true;
	}


	/**
	 * 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) {

		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				int min = Integer.parseInt(field.getVarValue("minlength"));

				if (!GenericValidator.minLength(value, min)) {
					errors.add(field.getKey(), getActionError(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(), getActionError(request, va, field));
				return false;
			}
		}

		return true;
	}
	
	/**
	*  Return <code>true</code> if the specified object is a String or a <code>null</code>
	*  value.
	*
	* @param o Object to be tested
	* @return The string value
	*/
   protected static boolean isString(Object o) {
	   return (o == null) ? true : String.class.isInstance(o);
   }

/*------------------------------------------*/	

	/**
	 * Genera el error correspondiente para que Struts lo muestre en pantalla.
	 * El error se crea con key y no con literales, ya que estos seran investigados por los custom Tags, 
	 * mediante colaboracion con el componente Gestor de Mensajes de Internacionalizacion i18nkey.
	 * 
	 * @param  request  Current request object.
	 * @param  va       The <code>ValidatorAction</code> that is currently being performed.
	 * @param  field    The <code>Field</code> object associated with the current
	 * 
	 * @return Error devuelto en forma de <code>ActionError</code> de Geremua 
	 */	
	public static ActionError getActionError(HttpServletRequest request, ValidatorAction va, Field field) {
		Q70ValidacionesGenericasPlugIn plugIn = null;
		try {
			ModuleConfig config = (ModuleConfig)request.getAttribute(Globals.MODULE_KEY);
			
			PlugIn[] plugInList = (PlugIn[])request.getSession().getServletContext().getAttribute(Globals.PLUG_INS_KEY+config.getPrefix());
			for (int i = 0; i<plugInList.length; i++)
			{
				if (plugInList[i] instanceof Q70ValidacionesGenericasPlugIn)
					plugIn = (Q70ValidacionesGenericasPlugIn)plugInList[i];	
			}
			
			
			//se construye un object array de argumentos con el ámbito y los keys
			Arg arg0 = field.getArg0(va.getName());
			Arg arg1 = field.getArg1(va.getName());
			Arg arg2 = field.getArg2(va.getName());
			Arg arg3 = field.getArg3(va.getName());
			Object arg[] = new Object[] { plugIn, arg0==null?null:arg0.getKey(), arg1==null?null:arg1.getKey(), arg2==null?null:arg2.getKey(), arg3==null?null:arg3.getKey() };
			String msg = (field.getMsg(va.getName()) != null ? field.getMsg(va.getName()) : va.getMsg());
			
			return new ActionError(msg, arg);
			//return new ActionError(msg, arg[0], arg[1], arg[2], arg[3]);
		} catch (Exception e) {
			if (null == plugIn)
			{
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "No se ha encontrado un plugin de la clase Q70ValidacionesGenericasPlugIn en el fichero de configuración.");
				}
				if (logInc.isEnabled())
				{
					Q70ValidacionGenericaException validacionGenericaException = new Q70ValidacionGenericaException(Q70ValidacionesCampo.class.toString(), "getActionError", "No se ha encontrado un plugin de la clase Q70ValidacionesGenericasPlugIn en el fichero de configuración.", e);
					logInc.log(validacionGenericaException, COMPONENTE, "ERROR");
				}
			}
			else
			{
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "No se ha encontrado la propiedad i18nKey en el plugin de validación del fichero de configuración.");
				}
				if (logInc.isEnabled())
				{
					Q70ValidacionGenericaException validacionGenericaException = new Q70ValidacionGenericaException(Q70ValidacionesCampo.class.toString(), "getActionError", "No se ha encontrado la propiedad i18nKey en el plugin de validación del fichero de configuración.", e);
					logInc.log(validacionGenericaException, COMPONENTE, "ERROR");
				}
			}
			return null;
		}
	}
}
