jaxx.runtime.validator.XWorkBeanValidator Maven / Gradle / Ivy
/*
* *##%
* JAXX Runtime
* Copyright (C) 2008 - 2009 CodeLutin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* ##%*
*/
package jaxx.runtime.validator;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ValidationAwareSupport;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.validator.ActionValidatorManager;
import com.opensymphony.xwork2.validator.DelegatingValidatorContext;
import com.opensymphony.xwork2.validator.FieldValidator;
import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.Validator;
import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* A customized validator for a given bean.
*
* Use the method {@link #validate(java.lang.Object)} to obtain the messages
* detected by the validator for the given bean.
*
* @param type of the bean to validate.
*
* @author chemit
* @since 1.3
*/
public class XWorkBeanValidator {
/** to use log facility, just put in your code: log.info(\"...\"); */
private static final Log log = LogFactory.getLog(XWorkBeanValidator.class);
protected final static Map> EMPTY_RESULT = Collections.unmodifiableMap(new HashMap>());
/** the type of bean to validate */
protected final Class beanClass;
/** the validation named context (can be null) */
protected String contextName;
/** the list of field names detected for this validator */
protected Set fieldNames;
/** a flag to include or not the default context validators */
protected boolean includeDefaultContext;
// --
// XWorks fields
// --
protected ValidationAwareSupport validationSupport;
protected DelegatingValidatorContext validationContext;
protected transient ActionValidatorManager validator;
protected ActionContext context;
public XWorkBeanValidator(Class beanClass, String contextName) {
this(beanClass, contextName, true, BeanValidatorUtil.getSharedValueStack());
}
public XWorkBeanValidator(Class beanClass, String contextName, ValueStack vs) {
this(beanClass, contextName, true, vs);
}
public XWorkBeanValidator(Class beanClass, String contextName, boolean includeDefaultContext) {
this(beanClass, contextName, includeDefaultContext, BeanValidatorUtil.getSharedValueStack());
}
public XWorkBeanValidator(Class beanClass, String contextName, boolean includeDefaultContext, ValueStack vs) {
this.beanClass = beanClass;
this.includeDefaultContext = includeDefaultContext;
validationSupport = new ValidationAwareSupport();
validationContext = new DelegatingValidatorContext(validationSupport);
if (vs == null) {
// create a standalone value stack
ConfigurationManager confManager = new ConfigurationManager();
Configuration conf = confManager.getConfiguration();
vs = conf.getContainer().getInstance(ValueStackFactory.class).createValueStack();
if (log.isDebugEnabled()) {
log.info("create a standalone value stack " + vs);
}
} else {
if (log.isDebugEnabled()) {
log.debug("use given value stack " + vs);
}
}
context = new ActionContext(vs.getContext());
ActionContext.setContext(context);
// init validator
validator = context.getContainer().getInstance(ActionValidatorManager.class, "no-annotations");
// init context
setContextName(contextName);
}
public boolean isIncludeDefaultContext() {
return includeDefaultContext;
}
public Class getBeanClass() {
return beanClass;
}
public String getContextName() {
return contextName;
}
public Set getFieldNames() {
return fieldNames;
}
public ActionValidatorManager getValidator() {
return validator;
}
/**
* Test a the validator contains the field given his name
*
* @param fieldName the name of the searched field
* @return true
if validator contaisn this field, false
otherwise
*/
public boolean containsField(String fieldName) {
return fieldNames.contains(fieldName);
}
public void setIncludeDefaultContext(boolean includeDefaultContext) {
this.includeDefaultContext = includeDefaultContext;
if (contextName != null) {
// reload context
setContextName(contextName);
}
}
public void setContextName(String contextName) {
this.contextName = contextName;
// changing contextName may change fields definition
// so reload fields
initFields();
}
/**
* Valide le bean donné et retourne les messages produits.
*
* @param bean le bean a valider (il doit etre non null)
*
* @return le dictionnaire des messages produits par la validation indexées
* par le nom du champs du bean impacté.
*/
public Map> validate(B bean) {
if (bean == null) {
throw new NullPointerException("bean can not be null in method validate");
}
Map> result = EMPTY_RESULT;
// on lance la validation uniquement si des champs sont a valider
if (!fieldNames.isEmpty()) {
try {
//TC - 20081024 : since context is in a ThreadLocal variable, we must do the check
if (ActionContext.getContext() == null) {
ActionContext.setContext(context);
}
validator.validate(bean, contextName, validationContext);
if (log.isTraceEnabled()) {
log.trace("Action errors: " + validationContext.getActionErrors());
log.trace("Action messages: " + validationContext.getActionMessages());
log.trace("Field errors: " + validationContext.getFieldErrors());
}
if (log.isDebugEnabled()) {
log.debug(this + " : " + validationContext.getFieldErrors());
}
if (validationContext.hasFieldErrors()) {
Map,?> messages = validationContext.getFieldErrors();
result = new HashMap>(messages.size());
for (Object fieldName : messages.keySet()) {
Collection> c = (Collection>) messages.get(fieldName);
List mm = new java.util.ArrayList(c.size());
for (Object message : c) {
mm.add(message + "");
}
result.put(fieldName + "", mm);
}
}
} catch (ValidationException eee) {
log.warn("Error during validation on " + beanClass + " for reason : " + eee.getMessage(), eee);
} finally {
// on nettoye toujours le validateur apres operation
validationSupport.clearErrorsAndMessages();
}
}
return result;
}
@Override
public String toString() {
return super.toString() + "";
}
/**
* update the property {@link #fieldNames}, says search in XWorks
*/
protected synchronized void initFields() {
if (fieldNames != null) {
fieldNames = null;
}
Set detectedFieldNames = new java.util.HashSet();
int skip = 0;
if (contextName != null && !includeDefaultContext) {
// count the number of validator to skip
for (Validator> v : validator.getValidators(beanClass, null)) {
// we only work on FieldValidator at the moment
if (v instanceof FieldValidator) {
skip++;
}
}
}
for (Validator> v : validator.getValidators(beanClass, contextName)) {
// we only work on FieldValidator at the moment
if (v instanceof FieldValidator) {
if (skip > 0) {
skip--;
continue;
}
FieldValidator fieldValidator = (FieldValidator) v;
log.debug("context " + contextName + " - field " + fieldValidator.getFieldName());
String fName = fieldValidator.getFieldName();
detectedFieldNames.add(fName);
}
}
fieldNames = Collections.unmodifiableSet(detectedFieldNames);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy