[richfaces-svn-commits] JBoss Rich Faces SVN: r12144 - in trunk/ui/beanValidator/src: test/java/org/richfaces/validator and 1 other directory.

richfaces-svn-commits at lists.jboss.org richfaces-svn-commits at lists.jboss.org
Tue Jan 6 20:12:01 EST 2009


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() {




More information about the richfaces-svn-commits mailing list