package org.agnitas.emm.core.validator;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import org.agnitas.emm.core.validator.annotation.Validate;
import org.apache.commons.validator.Arg;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.Validator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorException;
import org.apache.commons.validator.ValidatorResources;
import org.apache.commons.validator.ValidatorResult;
import org.apache.commons.validator.ValidatorResults;
import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.xml.sax.SAXException;
@Aspect
public class ModelValidator {
private final static Logger log = Logger.getLogger(ModelValidator.class);
private ResourceBundle messagesBundle;
private ValidatorResources resources;
public ModelValidator(String validationFile, String propertiesFile) throws IOException, SAXException {
InputStream in = this.getClass().getClassLoader().getResourceAsStream(validationFile);
resources = new ValidatorResources(in);
messagesBundle = ResourceBundle.getBundle(propertiesFile);
}
@Before("@annotation(annotation) && args(model)")
public void validate(Validate annotation, Object model) throws ValidatorException {
log.debug("formName:"+annotation.value()+", model:"+model.getClass().getName());
Validator validator = new Validator(resources, annotation.value());
validator.setParameter(Validator.BEAN_PARAM, model);
ValidatorResults results = validator.validate();
checkResults(results);
}
@SuppressWarnings("unchecked")
private void checkResults(ValidatorResults results) throws IllegalArgumentException {
Iterator<String> fieldNames = results.getPropertyNames().iterator();
while (fieldNames.hasNext()) {
ValidatorResult result = results.getValidatorResult(fieldNames.next());
List<String> actions = result.getField().getDependencyList();
for (int i = 0; i < actions.size(); ++ i) {
if (!result.isValid(actions.get(i))) {
ValidatorAction action = resources.getValidatorAction(actions.get(i));
Field field = result.getField();
throw new IllegalArgumentException(getErrorMessage(field, action));
}
}
}
}
private String getErrorMessage(Field field, ValidatorAction action) {
// TODO: add processing of an alternative message
// that can be associated with a Field and configured with a <msg> xml element.
// See Resources.getActionMessage(validator, request, va, field)) for references.
String args[] = getArgs(action.getName(), messagesBundle, field);
String msg = field.getMsg(action.getName()) != null ? field.getMsg(action.getName()) : action.getMsg();
return MessageFormat.format(getMessage(messagesBundle, msg), (Object[]) args);
}
public static String[] getArgs(String actionName, ResourceBundle messages, Field field) {
String[] argMessages = new String[4];
Arg[] args = new Arg[] {
field.getArg(actionName, 0),
field.getArg(actionName, 1),
field.getArg(actionName, 2),
field.getArg(actionName, 3) };
for (int i = 0; i < args.length; i++) {
if (args[i] == null) {
continue;
}
if (args[i].isResource()) {
argMessages[i] = getMessage(messages, args[i].getKey());
} else {
argMessages[i] = args[i].getKey();
}
}
return argMessages;
}
public static String getMessage(ResourceBundle messages, String key) {
String message = null;
if (messages != null) {
message = messages.getString(key);
}
return (message == null) ? "" : message;
}
}