Author: alexsmirnov
Date: 2009-01-06 20:12:00 -0500 (Tue, 06 Jan 2009)
New Revision: 12144
Modified:
trunk/ui/beanValidator/src/main/java/org/richfaces/validator/BeanValidator.java
trunk/ui/beanValidator/src/test/java/org/richfaces/validator/BeanValidatorTest.java
trunk/ui/beanValidator/src/test/java/org/richfaces/validator/ValidableBean.java
Log:
Append collection-like properties support.
Modified: trunk/ui/beanValidator/src/main/java/org/richfaces/validator/BeanValidator.java
===================================================================
---
trunk/ui/beanValidator/src/main/java/org/richfaces/validator/BeanValidator.java 2009-01-06
19:45:51 UTC (rev 12143)
+++
trunk/ui/beanValidator/src/main/java/org/richfaces/validator/BeanValidator.java 2009-01-07
01:12:00 UTC (rev 12144)
@@ -21,11 +21,14 @@
package org.richfaces.validator;
import java.beans.FeatureDescriptor;
+import java.util.Collection;
+import java.util.EmptyStackException;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
+import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;
import javax.el.ELContext;
@@ -128,7 +131,7 @@
String[] validationMessages = null;
if (null != target) {
ELContext elContext = context.getELContext();
- ValidationResolver validationResolver = new ValidationResolver(
+ ValidationResolver validationResolver = createValidationResolver(
elContext.getELResolver(), calculateLocale(context));
ELContextWrapper wrappedElContext = new ELContextWrapper(elContext,
validationResolver);
@@ -159,7 +162,7 @@
// Method for checking input parameters for prevent NPE
private void checkInputParameters(FacesContext context,
ValueExpression target) {
- if (null == context || null == target ) {
+ if (null == context || null == target) {
throw new FacesException(INPUT_PARAMETERS_IS_NOT_CORRECT);
}
}
@@ -274,7 +277,7 @@
* This method determine ResourceBundle, used in current request @param
* locale - user locale @return ResourceBundle instance
*/
- private ResourceBundle getCurrentResourceBundle(Locale locale) {
+ protected ResourceBundle getCurrentResourceBundle(Locale locale) {
if (null == FacesContext.getCurrentInstance()
|| null == FacesContext.getCurrentInstance().getApplication()) {
throw new FacesException(FACES_CONTEXT_IS_NULL);
@@ -284,16 +287,17 @@
if (null == appBundle || null == locale) {
return null;
}
-
+
ResourceBundle bundle;
-
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+ ClassLoader classLoader = Thread.currentThread()
+ .getContextClassLoader();
if (classLoader != null) {
bundle = ResourceBundle.getBundle(appBundle, locale, classLoader);
} else {
bundle = ResourceBundle.getBundle(appBundle, locale);
}
-
+
return bundle;
}
@@ -304,13 +308,17 @@
* during validation process @return ClassValidator instance
*/
@SuppressWarnings("unchecked")
- private ClassValidator<? extends Object> createValidator(
+ protected ClassValidator<? extends Object> createValidator(
Class<? extends Object> beanClass, Locale locale) {
ResourceBundle bundle = getCurrentResourceBundle(locale);
return bundle == null ? new ClassValidator(beanClass)
: new ClassValidator(beanClass, bundle);
}
+
+ protected ValidationResolver createValidationResolver(ELResolver parent, Locale locale)
{
+ return new ValidationResolver(parent,locale);
+ }
/**
* Wrapper class for a {@link ELResolver}. For a setValue method, perform
* validation instead of real assignment.
@@ -330,13 +338,16 @@
private String[] validationMessages = null;
private Locale locale = null;
-
+
+ private Stack<BasePropertyPair> valuesStack;
+
/**
* @param parent
*/
public ValidationResolver(ELResolver parent, Locale locale) {
this.parent = parent;
this.locale = locale;
+ this.valuesStack = new Stack<BasePropertyPair>();
}
public boolean isValid() {
@@ -388,7 +399,9 @@
* java.lang.Object, java.lang.Object)
*/
public Object getValue(ELContext context, Object base, Object property) {
- return parent.getValue(context, base, property);
+ Object value = parent.getValue(context, base, property);
+ valuesStack.push(new BasePropertyPair(base, property));
+ return value;
}
/**
@@ -416,15 +429,39 @@
Object value) {
if (null != base && null != property) {
context.setPropertyResolved(true);
- //https://jira.jboss.org/jira/browse/RF-4034
- //apache el looses locale information during value resolution,
- //so we use our own
- validationMessages = validate(base, property.toString(), value, locale);
- valid = null == validationMessages
- || 0 == validationMessages.length;
+ // For Arrays, Collection or Map use parent base and property.
+ BasePropertyPair basePropertyPair = lookupBeanProperty(new BasePropertyPair(
+ base, property));
+ base = basePropertyPair.getBase();
+ property = basePropertyPair.getProperty();
+ if (null != base && null != property) {
+ //
https://jira.jboss.org/jira/browse/RF-4034
+ // apache el looses locale information during value
+ // resolution,
+ // so we use our own
+ validationMessages = validate(base, property.toString(),
+ value, locale);
+ valid = null == validationMessages
+ || 0 == validationMessages.length;
+
+ }
}
}
+ private BasePropertyPair lookupBeanProperty(BasePropertyPair pair) {
+ Object base = pair.getBase();
+ if (null != base
+ && (base instanceof Collection || base instanceof Map || base
+ .getClass().isArray())) {
+ try {
+ pair = lookupBeanProperty(valuesStack.pop());
+ } catch (EmptyStackException e) {
+ // Do nothing, this is a first item.
+ }
+ }
+ return pair;
+ }
+
/**
* @return the validationMessages
*/
@@ -435,6 +472,39 @@
}
/**
+ * @author asmirnov
+ *
+ */
+ static class BasePropertyPair {
+ private final Object base;
+ private final Object property;
+
+ /**
+ * @param base
+ * @param property
+ */
+ public BasePropertyPair(Object base, Object property) {
+ this.base = base;
+ this.property = property;
+ }
+
+ /**
+ * @return the base
+ */
+ public Object getBase() {
+ return base;
+ }
+
+ /**
+ * @return the property
+ */
+ public Object getProperty() {
+ return property;
+ }
+
+ }
+
+ /**
* Class for identify validator instance by locale
*
* @author amarkhel
Modified:
trunk/ui/beanValidator/src/test/java/org/richfaces/validator/BeanValidatorTest.java
===================================================================
---
trunk/ui/beanValidator/src/test/java/org/richfaces/validator/BeanValidatorTest.java 2009-01-06
19:45:51 UTC (rev 12143)
+++
trunk/ui/beanValidator/src/test/java/org/richfaces/validator/BeanValidatorTest.java 2009-01-07
01:12:00 UTC (rev 12144)
@@ -20,12 +20,16 @@
*/
package org.richfaces.validator;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.ResourceBundle;
+import org.ajax4jsf.el.ELContextWrapper;
import org.ajax4jsf.tests.AbstractAjax4JsfTestCase;
import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;
+import org.richfaces.validator.BeanValidator.ValidationResolver;
public class BeanValidatorTest extends AbstractAjax4JsfTestCase {
@@ -78,4 +82,51 @@
assertNotNull(invalidValues);
assertEquals(1, invalidValues.length);
}
+
+ public void testValidateArray() throws Exception {
+ BeanValidator beanValidator = BeanValidator.createInstance();
+ InvalidValue[] invalidValues = beanValidator.validateBean(new ValidableBean(),
"array", "",Locale.getDefault());
+ assertNotNull(invalidValues);
+ assertEquals(2, invalidValues.length);
+ System.out.println(invalidValues[0].getMessage());
+ System.out.println(invalidValues[1].getMessage());
+ }
+
+ public void testValidateList() throws Exception {
+ BeanValidator beanValidator = BeanValidator.createInstance();
+ InvalidValue[] invalidValues = beanValidator.validateBean(new ValidableBean(),
"list", "",Locale.getDefault());
+ assertNotNull(invalidValues);
+ assertEquals(1, invalidValues.length);
+ System.out.println(invalidValues[0].getMessage());
+ }
+ public void testValidateMap() throws Exception {
+ BeanValidator beanValidator = BeanValidator.createInstance();
+ InvalidValue[] invalidValues = beanValidator.validateBean(new ValidableBean(),
"map", "",Locale.getDefault());
+ assertNotNull(invalidValues);
+ assertEquals(1, invalidValues.length);
+ System.out.println(invalidValues[0].getMessage());
+ }
+
+ public void testValidationResolver() throws Exception {
+ ValidableBean bean = new ValidableBean();
+ BeanValidator beanValidator = BeanValidator.createInstance();
+ ValidationResolver validationResolver =
beanValidator.createValidationResolver(facesContext.getELContext().getELResolver(),
Locale.US);
+ Object list = validationResolver.getValue(elContext, bean, "list");
+ assertNotNull(list);
+ assertTrue(list instanceof List);
+ validationResolver.setValue(elContext, list, new Integer(0), "");
+ assertFalse(validationResolver.isValid());
+ assertEquals(1, validationResolver.getValidationMessages().length);
+ }
+ public void testValidationResolverMap() throws Exception {
+ ValidableBean bean = new ValidableBean();
+ BeanValidator beanValidator = BeanValidator.createInstance();
+ ValidationResolver validationResolver =
beanValidator.createValidationResolver(facesContext.getELContext().getELResolver(),
Locale.US);
+ Object list = validationResolver.getValue(elContext, bean, "map");
+ assertNotNull(list);
+ assertTrue(list instanceof Map);
+ validationResolver.setValue(elContext, list, new Integer(0), "");
+ assertFalse(validationResolver.isValid());
+ assertEquals(1, validationResolver.getValidationMessages().length);
+ }
}
Modified: trunk/ui/beanValidator/src/test/java/org/richfaces/validator/ValidableBean.java
===================================================================
---
trunk/ui/beanValidator/src/test/java/org/richfaces/validator/ValidableBean.java 2009-01-06
19:45:51 UTC (rev 12143)
+++
trunk/ui/beanValidator/src/test/java/org/richfaces/validator/ValidableBean.java 2009-01-07
01:12:00 UTC (rev 12144)
@@ -20,9 +20,15 @@
*/
package org.richfaces.validator;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import org.hibernate.validator.Length;
import org.hibernate.validator.Max;
import org.hibernate.validator.Min;
+import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
/**
@@ -38,8 +44,60 @@
private String text;
private Object foo;
+
+ @NotEmpty
+ private List<String> list = new ArrayList<String>();
+
+ private String[] array = new String[1];
+
+ private Map<String, String> map = new HashMap<String, String>();
/**
+ * @return the list
+ */
+ public List<String> getList() {
+ return list;
+ }
+
+ /**
+ * @param list the list to set
+ */
+ public void setList(List<String> list) {
+ this.list = list;
+ }
+
+ /**
+ * @return the array
+ */
+ @NotEmpty
+ @Length(min=2,max=5)
+ public String[] getArray() {
+ return array;
+ }
+
+ /**
+ * @param array the array to set
+ */
+ public void setArray(String[] array) {
+ this.array = array;
+ }
+
+ /**
+ * @return the map
+ */
+ @Length(min=2,max=5)
+ public Map<String, String> getMap() {
+ return map;
+ }
+
+ /**
+ * @param map the map to set
+ */
+ public void setMap(Map<String, String> map) {
+ this.map = map;
+ }
+
+ /**
* @return the integerProperty
*/
public int getIntegerProperty() {