jaxx.runtime.validator.BeanValidatorUtil 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 jaxx.runtime.*;
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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
/**
* The helper class for validation module.
*
* @author chemit
*/
public class BeanValidatorUtil {
/** to use log facility, just put in your code: log.info(\"...\"); */
static private final Log log = LogFactory.getLog(BeanValidatorUtil.class);
/**
* a shared value stack to allow external operations on it (for example
* add some datas in stack to be usedby validators
*/
static private ValueStack sharedValueStack;
public static synchronized ValueStack getSharedValueStack() {
if (sharedValueStack == null) {
// init context
ConfigurationManager confManager = new ConfigurationManager();
Configuration conf = confManager.getConfiguration();
sharedValueStack = conf.getContainer().getInstance(ValueStackFactory.class).createValueStack();
if (log.isDebugEnabled()) {
log.debug("init shared value stack " + sharedValueStack);
}
}
return sharedValueStack;
}
protected BeanValidatorUtil() {
// no instance
}
/**
* Convinient method to attach a bean to all validators of an JAXXObject.
*
* It is possible to exclude some validator to be treated.
*
* @param ui the ui containing the validatros to treate
* @param bean the bean to attach in validators (can be null)
* @param excludeIds the list of validator id to exclude
*/
@SuppressWarnings({"unchecked"})
public static void setValidatorBean(JAXXObject ui, Object bean, String... excludeIds) {
if (!JAXXValidator.class.isAssignableFrom(ui.getClass())) {
return;
}
JAXXValidator jaxxValidator = (JAXXValidator) ui;
List validatorIds = jaxxValidator.getValidatorIds();
if (excludeIds.length > 0) {
validatorIds = new ArrayList(validatorIds);
for (String excludeId : excludeIds) {
validatorIds.remove(excludeId);
}
}
for (String validatorId : validatorIds) {
BeanValidator beanValidator = jaxxValidator.getValidator(validatorId);
if (bean == null || beanValidator.getBeanClass().isAssignableFrom(bean.getClass())) {
// touch validator, only if fits the bean type (or bean is null)
beanValidator.setBean(bean);
}
}
}
/**
* Convinient method to set the changed property to all validators of an JAXXObject.
*
* It is possible to exclude some validator to be treated.
*
* @param ui the ui containing the validatros to treate
* @param newValue the new value to set in changed validator property
* @param excludeIds the list of validator id to exclude
*/
@SuppressWarnings({"unchecked"})
public static void setValidatorChanged(JAXXObject ui, boolean newValue, String... excludeIds) {
if (!JAXXValidator.class.isAssignableFrom(ui.getClass())) {
return;
}
JAXXValidator jaxxValidator = (JAXXValidator) ui;
List validatorIds = jaxxValidator.getValidatorIds();
if (excludeIds.length > 0) {
validatorIds = new ArrayList(validatorIds);
for (String excludeId : excludeIds) {
validatorIds.remove(excludeId);
}
}
for (String validatorId : validatorIds) {
BeanValidator beanValidator = jaxxValidator.getValidator(validatorId);
beanValidator.setChanged(newValue);
}
}
/**
* Convert a value to a given type and then if was succesffull try to set it in the bean manage by the validator.
*
* @param validator validator to be involved
* @param fieldName the name of the bean property
* @param value the actual value to convert
* @param valueClass the type of the conversion
*/
public static void convert(BeanValidator> validator, String fieldName, String value, Class> valueClass) {
Object result = validator.convert(fieldName, value, valueClass);
if (result != null) {
try {
BeanInfo info = Introspector.getBeanInfo(validator.getBean().getClass());
for (PropertyDescriptor descriptor : info.getPropertyDescriptors()) {
if (fieldName.equals(descriptor.getName()) && descriptor.getWriteMethod() != null) {
descriptor.getWriteMethod().invoke(validator.getBean(), result);
break;
}
}
} catch (IntrospectionException e) {
log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e);
} catch (InvocationTargetException e) {
log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e);
} catch (IllegalAccessException e) {
log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e);
}
} else {
//fixme : conversion failed, we should be able to notify ui that values has changed ?
// otherwise, bean value has not changed,...
}
}
public static EventSetDescriptor getPropertyChangeListenerDescriptor(Class beanClass) {
try {
// check that the bean is listenable, otherwise, can't use
// the validator on it
BeanInfo infos = Introspector.getBeanInfo(beanClass);
EventSetDescriptor[] events = infos.getEventSetDescriptors();
for (EventSetDescriptor event : events) {
if ("propertyChange".equals(event.getName())) {
if (event.getAddListenerMethod() == null) {
// no property event listener, so can not use the validator
throw new IllegalStateException("no addPropertyChangeListener method found for " + beanClass);
}
if (event.getRemoveListenerMethod() == null) {
// no property event listener, so can not use the validator
throw new IllegalStateException("no removePropertyChangeListener method found for " + beanClass);
}
return event;
}
}
// no property event listener, so can not use the validator
throw new IllegalStateException("no PropertyChangeListener access method found for " + beanClass);
} catch (IntrospectionException ex) {
throw new IllegalStateException("could not acquire PropertyChangeListener bean info for " + beanClass + " for reason " + ex.getMessage(), ex);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy