/*********************************************************************************
* The contents of this file are subject to the Common Public Attribution
* License Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.openemm.org/cpal1.html. The License is based on the Mozilla
* Public License Version 1.1 but Sections 14 and 15 have been added to cover
* use of software over a computer network and provide for limited attribution
* for the Original Developer. In addition, Exhibit A has been modified to be
* consistent with Exhibit B.
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is OpenEMM.
* The Original Developer is the Initial Developer.
* The Initial Developer of the Original Code is AGNITAS AG. All portions of
* the code written by AGNITAS AG are Copyright (c) 2009 AGNITAS AG. All Rights
* Reserved.
*
* Contributor(s): AGNITAS AG.
********************************************************************************/
package org.agnitas.service.csv.validator;
import java.io.UnsupportedEncodingException;
import org.agnitas.beans.ColumnMapping;
import org.agnitas.beans.ImportProfile;
import org.agnitas.beans.Recipient;
import org.agnitas.service.NewImportWizardService;
import org.agnitas.util.AgnUtils;
import org.agnitas.util.ImportUtils;
import org.agnitas.util.importvalues.DateFormat;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.util.ValidatorUtils;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
/**
* @author Viktor Gema
*/
public class FieldsValidator {
private static final transient Logger logger = Logger.getLogger(FieldsValidator.class);
public static final String DB_CHARSET = "UTF-8";
/**
* Checks if the field is mandatory.
*
* @return boolean If the field isn't <code>null</code> and
* has a length greater than zero, <code>true</code> is returned.
* Otherwise <code>false</code>.
*/
public static boolean validateMandatoryField(Object bean, Field field, Validator validator) {
String value = getValueAsString(bean, field);
final ImportProfile profile = (ImportProfile) validator.getParameterValue("org.agnitas.beans.ImportProfile");
final ColumnMapping currentColumn = getColumnMappingForCurentField(field, profile);
return !(currentColumn != null && currentColumn.getMandatory()) || !GenericValidator.isBlankOrNull(value);
}
private static String getValueAsString(Object bean, Field field) {
String value = null;
final String varValue = field.getVarValue("customField");
if (Boolean.valueOf(varValue)) {
try {
Object property = PropertyUtils.getProperty(bean, "customFields");
if (property instanceof Map) {
value = ((Map<String, String>) property).get(field.getProperty());
}
} catch (Exception e) {
AgnUtils.logger().warn(MessageFormat.format("Failed to get bean ({0}) property ({1})as string", bean, varValue), e);
}
} else {
value = ValidatorUtils.getValueAsString(bean, field.getProperty());
}
return value;
}
private static ColumnMapping getColumnMappingForCurentField(Field field, ImportProfile profile) {
ColumnMapping currentColumn = null;
final List<ColumnMapping> columnMapping = profile.getColumnMapping();
for (ColumnMapping column : columnMapping) {
if (column.getDatabaseColumn().equals(field.getProperty())) {
currentColumn = column;
break;
}
}
return currentColumn;
}
/**
* Checks if the field is an e-mail address.
*
* @param value The value validation is being performed on.
* @return boolean If the field is an e-mail address
* <code>true</code> is returned.
* Otherwise <code>false</code>.
*/
public static boolean validateEmail(Object bean, Field field, Validator validator) {
String value = getValueAsString(bean, field);
final ImportProfile profile = (ImportProfile) validator.getParameterValue("org.agnitas.beans.ImportProfile");
final ColumnMapping currentColumn = getColumnMappingForCurentField(field, profile);
if (currentColumn != null && currentColumn.getMandatory()) {
return !GenericValidator.isBlankOrNull(value) && GenericValidator.isEmail(value);
} else {
return currentColumn == null || GenericValidator.isEmail(value);
}
}
/**
* Checks if the field is an e-mail address.
*
* @param value The value validation is being performed on.
* @return boolean If the field is an e-mail address
* <code>true</code> is returned.
* Otherwise <code>false</code>.
*/
public static boolean validateGender(Object bean, Field field, Validator validator) {
String value = getValueAsString(bean, field);
final ImportProfile profile = (ImportProfile) validator.getParameterValue("org.agnitas.beans.ImportProfile");
Integer maxGenderValue = (Integer) validator.getParameterValue("java.lang.Integer");
if(maxGenderValue == null || maxGenderValue == 0){
maxGenderValue = NewImportWizardService.MAX_GENDER_VALUE_BASIC;
}
final ColumnMapping currentColumn = getColumnMappingForCurentField(field, profile);
if (currentColumn != null && currentColumn.getMandatory()) {
return !GenericValidator.isBlankOrNull(value) && genderMappingValidation(value, profile, maxGenderValue);
} else {
return currentColumn == null || genderMappingValidation(value, profile, maxGenderValue);
}
}
private static boolean genderMappingValidation(String value, ImportProfile profile, Integer maxGenderValue) {
final Map<String, Integer> genderMap = profile.getGenderMapping();
return GenericValidator.isInt(value) && Integer.valueOf(value) <= maxGenderValue && Integer.valueOf(value) >= 0 || genderMap.keySet().contains(value);
}
/**
* Checks if the field can be successfully converted to a <code>int</code>.
*
* @param value The value validation is being performed on.
* @return boolean If the field can be successfully converted
* to a <code>int</code> <code>true</code> is returned.
* Otherwise <code>false</code>.
*/
public static boolean validateInt(Object bean, Field field, Validator validator) {
String value = getValueAsString(bean, field);
final ImportProfile profile = (ImportProfile) validator.getParameterValue("org.agnitas.beans.ImportProfile");
final ColumnMapping currentColumn = getColumnMappingForCurentField(field, profile);
if (currentColumn != null && currentColumn.getMandatory()) {
return !GenericValidator.isBlankOrNull(value) && GenericValidator.isInt(value);
} else {
return currentColumn == null || GenericValidator.isInt(value);
}
}
/**
* Checks the mailtype value
*
* @param mailtype the mailtype value
* @return true if mailtype is a number from 0 to 2 or mailtype is one
* of the strings: "txt", "text", "html" (the letter case is not important). False otherwise
*/
private static boolean isValidMailTypeValue(String mailtype) {
if(GenericValidator.isInt(mailtype)) {
int mailTypeInt = Integer.valueOf(mailtype);
return mailTypeInt == Recipient.MAILTYPE_TEXT || mailTypeInt == Recipient.MAILTYPE_HTML ||
mailTypeInt == Recipient.MAILTYPE_HTML_OFFLINE || mailTypeInt == Recipient.MAILTYPE_MHTML;
} else {
String mailtypeLower = mailtype.toLowerCase();
return (mailtypeLower.equals(ImportUtils.MAIL_TYPE_HTML) ||
mailtypeLower.equals(ImportUtils.MAIL_TYPE_TEXT)
|| mailtypeLower.equals(ImportUtils.MAIL_TYPE_TEXT_ALT));
}
}
/**
* Checks if the field can be successfully converted to a <code>int</code>.
*
* @param value The value validation is being performed on.
* @return boolean If the field can be successfully converted
* to a <code>int</code> <code>true</code> is returned.
* Otherwise <code>false</code>.
*/
public static boolean validateMailType(Object bean, Field field, Validator validator) {
String value = getValueAsString(bean, field);
final ImportProfile profile = (ImportProfile) validator.getParameterValue("org.agnitas.beans.ImportProfile");
final ColumnMapping currentColumn = getColumnMappingForCurentField(field, profile);
if (currentColumn != null && currentColumn.getMandatory()) {
return !GenericValidator.isBlankOrNull(value) && isValidMailTypeValue(value);
} else {
return currentColumn == null || isValidMailTypeValue(value);
}
}
public static boolean checkRange(Object bean, Field field, Validator validator) {
final String value = getValueAsString(bean, field);
final ImportProfile profile = (ImportProfile) validator.getParameterValue("org.agnitas.beans.ImportProfile");
final ColumnMapping currentColumn = getColumnMappingForCurentField(field, profile);
final Integer length = Integer.valueOf(field.getVarValue("maxLength"));
if (currentColumn != null && currentColumn.getMandatory()) {
return !GenericValidator.isBlankOrNull(value) && checkMaxStringLength(value, length);
} else {
return currentColumn == null || checkMaxStringLength(value, length);
}
}
private static boolean checkMaxStringLength(String value, int length) {
boolean dbEncodingLengthOk = true;
if (value != null) {
try {
dbEncodingLengthOk = value.getBytes(DB_CHARSET).length <= length;
} catch (UnsupportedEncodingException e) {
logger.error("Error during import maxlength validation (encoding not supported): " + e + "\n" + AgnUtils.getStackTrace(e));
}
}
return GenericValidator.maxLength(value, length) && dbEncodingLengthOk;
}
/**
* Checks if the field can be successfully converted to a <code>double</code>.
*
* @param value The value validation is being performed on.
* @return boolean If the field can be successfully converted
* to a <code>double</code> <code>true</code> is returned.
* Otherwise <code>false</code>.
*/
public static boolean validateDouble(Object bean, Field field, Validator validator) {
String value = getValueAsString(bean, field);
final ImportProfile profile = (ImportProfile) validator.getParameterValue("org.agnitas.beans.ImportProfile");
final ColumnMapping currentColumn = getColumnMappingForCurentField(field, profile);
if (currentColumn != null && currentColumn.getMandatory()) {
return !GenericValidator.isBlankOrNull(value) && GenericValidator.isDouble(value);
} else {
return currentColumn == null || GenericValidator.isDouble(value);
}
}
/**
* Checks if the field can be successfully converted to a <code>date</code>.
*
* @param value The value validation is being performed on.
* @return boolean If the field can be successfully converted
* to a <code>date</code> <code>true</code> is returned.
* Otherwise <code>false</code>.
*/
public static boolean validateDate(Object bean, Field field, Validator validator) {
String value = getValueAsString(bean, field);
final ImportProfile profile = (ImportProfile) validator.getParameterValue("org.agnitas.beans.ImportProfile");
final ColumnMapping currentColumn = getColumnMappingForCurentField(field, profile);
if (currentColumn != null && currentColumn.getMandatory()) {
return !GenericValidator.isBlankOrNull(value) && GenericValidator.isDate(value, DateFormat.getValue(profile.getDateFormat()), true);
} else {
return currentColumn == null || GenericValidator.isDate(value, DateFormat.getValue(profile.getDateFormat()), true);
}
}
}