Author: amarkhel
Date: 2008-07-08 10:38:17 -0400 (Tue, 08 Jul 2008)
New Revision: 9451
Modified:
trunk/sandbox/ui/beanValidator/src/main/java/org/richfaces/validator/BeanValidator.java
trunk/sandbox/ui/beanValidator/src/main/java/org/richfaces/validator/FacesBeanValidator.java
Log:
Implement some TODO tasks in beanValidator project
Modified:
trunk/sandbox/ui/beanValidator/src/main/java/org/richfaces/validator/BeanValidator.java
===================================================================
---
trunk/sandbox/ui/beanValidator/src/main/java/org/richfaces/validator/BeanValidator.java 2008-07-08
14:02:15 UTC (rev 9450)
+++
trunk/sandbox/ui/beanValidator/src/main/java/org/richfaces/validator/BeanValidator.java 2008-07-08
14:38:17 UTC (rev 9451)
@@ -7,10 +7,14 @@
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.concurrent.ConcurrentHashMap;
import javax.el.ELContext;
+import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.ValueExpression;
+import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
@@ -19,30 +23,42 @@
/**
* Perform validation by Hibernate Validator annotations
+ *
* @author asmirnov
- *
+ *
*/
public class BeanValidator {
-
+
+ private static final String INPUT_PARAMETERS_IS_NOT_CORRECT = "Input parameters is
not correct.";
+
+ private static final String LOCALE_IS_NOT_SET = "Locale is not set";
+
+ private static final String VIEW_ROOT_IS_NOT_INITIALIZED = "ViewRoot is not
initialized";
+
public static final String VALIDATOR_PARAM = BeanValidator.class.getName();
- private BeanValidator(){
+ private Map<ValidatorKey, ClassValidator<? extends Object>> classValidators
= new ConcurrentHashMap<ValidatorKey, ClassValidator<? extends Object>>();
+
+ private BeanValidator() {
// This is a "singleton"-like class. Only factory methods allowed.
}
-
+
/**
* Create BeanValidator instance. For a Junit tests only.
+ *
* @return
*/
- static BeanValidator createInstance(){
+ static BeanValidator createInstance() {
// TODO - get instance class name from a "META-INF/service"
- // If the Seam framework is active, use org.jboss.seam.core.Validators component should
be used.
+ // If the Seam framework is active, use org.jboss.seam.core.Validators
+ // component should be used.
return new BeanValidator();
}
-
+
/**
- * Return BeanValidator object from a ServletContext attribute.
- * Create new instance if noone is defined.
+ * Return BeanValidator object from a ServletContext attribute. Create new
+ * instance if none is defined.
+ *
* @param context
* @return
*/
@@ -52,9 +68,10 @@
BeanValidator instance;
// TODO - use properly synchronization mutex ?
synchronized (context) {
- Map<String, Object> applicationMap = externalContext.getApplicationMap();
+ Map<String, Object> applicationMap = externalContext
+ .getApplicationMap();
instance = (BeanValidator) applicationMap.get(VALIDATOR_PARAM);
- if(null == instance){
+ if (null == instance) {
// Vaildator not initialized - create and store new instance.
instance = createInstance();
applicationMap.put(VALIDATOR_PARAM, instance);
@@ -62,41 +79,75 @@
}
return instance;
}
-
+
/**
* Perform Validation for a new value.
- * @param context current faces context.
- * @param target {@link ValueExpression} for a value assigement.
- * @param value new value for validation
- * @return null if no validation errors. Array of the validation messages othervise.
+ *
+ * @param context
+ * current faces context.
+ * @param target
+ * {@link ValueExpression} for a value assignment.
+ * @param value
+ * new value for validation
+ * @return null if no validation errors. Array of the validation messages
+ * otherwise.
+ * @throws FacesException
+ * if locale or context not properly initialized
*/
- public String[] validate(FacesContext context, ValueExpression target, Object value) {
- // TODO -check null parameters.
+ public String[] validate(FacesContext context, ValueExpression target,
+ Object value) {
+ // TODO - check null parameters.
+ checkInputParameters(context, target, value);
ELContext elContext = context.getELContext();
- ValidationResolver validationResolver = new
ValidationResolver(elContext.getELResolver());
- ELContextWrapper wrappedElContext = new
ELContextWrapper(elContext,validationResolver);
+ ValidationResolver validationResolver = new ValidationResolver(
+ elContext.getELResolver());
+ ELContextWrapper wrappedElContext = new ELContextWrapper(elContext,
+ validationResolver);
// TODO - check null viewRoot and null Locale.
+ if (null == context.getViewRoot()) {
+ throw new FacesException(VIEW_ROOT_IS_NOT_INITIALIZED);
+ } else if (null == context.getViewRoot().getLocale()) {
+ throw new FacesException(LOCALE_IS_NOT_SET);
+ }
wrappedElContext.setLocale(context.getViewRoot().getLocale());
// TODO - handle ELExceptions ?
- target.setValue(wrappedElContext, value);
- if(validationResolver.isValid()){
+ try {
+ target.setValue(wrappedElContext, value);
+ } catch (ELException e) {
+ throw new FacesException(e);
+ }
+ if (validationResolver.isValid()) {
return null;
} else {
return validationResolver.getValidationMessages();
}
}
-
+
+ // Method for checking input parameters for prevent NPE
+ private void checkInputParameters(FacesContext context,
+ ValueExpression target, Object value) {
+ if (null == context || null == target || null == value) {
+ throw new FacesException(INPUT_PARAMETERS_IS_NOT_CORRECT);
+ }
+ }
+
/**
- * Validate bean property for a new value.
- * TODO - localisation ?
- * @param base - bean
- * @param property - bean property name.
- * @param value new value.
- * @return null for a valid value, array of the validation messages othervise.
+ * Validate bean property for a new value. TODO - localization ?
+ *
+ * @param base -
+ * bean
+ * @param property -
+ * bean property name.
+ * @param value
+ * new value.
+ * @return null for a valid value, array of the validation messages
+ * othervise.
*/
- public String[] validate(Object base, String property, Object value, Locale locale) {
- InvalidValue[] invalidValues = validateBean(base, property, value, locale);
- if(null == invalidValues){
+ public String[] validate(Object base, String property, Object value,
+ Locale locale) {
+ InvalidValue[] invalidValues = validateBean(base, property, value,
+ locale);
+ if (null == invalidValues) {
return null;
} else {
String[] result = new String[invalidValues.length];
@@ -110,6 +161,7 @@
/**
* Validate bean property of the base object aganist new value
+ *
* @param base
* @param property
* @param value
@@ -118,12 +170,14 @@
protected InvalidValue[] validateBean(Object base, String property,
Object value, Locale locale) {
Class<? extends Object> beanClass = base.getClass();
- InvalidValue[] invalidValues = validateClass(beanClass, property, value, locale);
+ InvalidValue[] invalidValues = validateClass(beanClass, property,
+ value, locale);
return invalidValues;
}
/**
* Validate bean property in the base class aganist new value.
+ *
* @param beanClass
* @param property
* @param value
@@ -131,37 +185,73 @@
*/
protected InvalidValue[] validateClass(Class<? extends Object> beanClass,
String property, Object value, Locale locale) {
- ClassValidator<? extends Object> classValidator = getValidator(beanClass,
locale);
- InvalidValue[] invalidValues = classValidator.getPotentialInvalidValues( property,
value );
+ ClassValidator<? extends Object> classValidator = getValidator(
+ beanClass, locale);
+ InvalidValue[] invalidValues = classValidator
+ .getPotentialInvalidValues(property, value);
return invalidValues;
}
/**
* Get ( or create ) {@link ClassValidator} for a given bean class.
+ *
* @param beanClass
* @return
*/
@SuppressWarnings("unchecked")
- protected ClassValidator<? extends Object> getValidator(Class<? extends
Object> beanClass, Locale locale) {
+ protected ClassValidator<? extends Object> getValidator(
+ Class<? extends Object> beanClass, Locale locale) {
// TODO - cache validator instances.
// TODO - localization support.
- return new ClassValidator(beanClass);
+ ResourceBundle bundle = getCurrentResourceBundle(locale);
+ ValidatorKey key = new ValidatorKey(beanClass, bundle);
+ ClassValidator result = classValidators.get(key);
+ if (null == result) {
+ result = createValidator(beanClass, bundle);
+ classValidators.put(key, result);
+ }
+ return result;
}
+ /*
+ * This method determine ResourceBundle, used in current request @param
+ * locale - user locale @return ResourceBundle instance
+ */
+ private ResourceBundle getCurrentResourceBundle(Locale locale) {
+ String appBundle = FacesContext.getCurrentInstance().getApplication()
+ .getMessageBundle();
+ ResourceBundle bundle = ResourceBundle.getBundle(appBundle, locale);
+ return bundle;
+ }
+
+ /*
+ * Method for create new instance of ClassValidator, if same not in cache.
+ * @param beanClass - Class to validate @param bundle - Resource bundle,
+ * used during validation process @return ClassValidator instance
+ */
+ @SuppressWarnings("unchecked")
+ private ClassValidator<? extends Object> createValidator(
+ Class<? extends Object> beanClass, ResourceBundle bundle) {
+ return bundle == null ? new ClassValidator(beanClass)
+ : new ClassValidator(beanClass, bundle);
+ }
+
/**
- * Wrapper class for a {@link ELResolver}. For a setValue method, perform validation
instead of real assigement.
+ * Wrapper class for a {@link ELResolver}. For a setValue method, perform
+ * validation instead of real assignment.
+ *
* @author asmirnov
- *
+ *
*/
final class ValidationResolver extends ELResolver {
-
+
/**
* Original resolver.
*/
private final ELResolver parent;
-
+
private boolean valid = true;
-
+
private String[] validationMessages = null;
/**
@@ -180,7 +270,8 @@
* @param context
* @param base
* @return
- * @see javax.el.ELResolver#getCommonPropertyType(javax.el.ELContext,
java.lang.Object)
+ * @see javax.el.ELResolver#getCommonPropertyType(javax.el.ELContext,
+ * java.lang.Object)
*/
public Class<?> getCommonPropertyType(ELContext context, Object base) {
return parent.getCommonPropertyType(context, base);
@@ -190,7 +281,8 @@
* @param context
* @param base
* @return
- * @see javax.el.ELResolver#getFeatureDescriptors(javax.el.ELContext,
java.lang.Object)
+ * @see javax.el.ELResolver#getFeatureDescriptors(javax.el.ELContext,
+ * java.lang.Object)
*/
public Iterator<FeatureDescriptor> getFeatureDescriptors(
ELContext context, Object base) {
@@ -202,7 +294,8 @@
* @param base
* @param property
* @return
- * @see javax.el.ELResolver#getType(javax.el.ELContext, java.lang.Object,
java.lang.Object)
+ * @see javax.el.ELResolver#getType(javax.el.ELContext,
+ * java.lang.Object, java.lang.Object)
*/
public Class<?> getType(ELContext context, Object base, Object property) {
return parent.getType(context, base, property);
@@ -213,7 +306,8 @@
* @param base
* @param property
* @return
- * @see javax.el.ELResolver#getValue(javax.el.ELContext, java.lang.Object,
java.lang.Object)
+ * @see javax.el.ELResolver#getValue(javax.el.ELContext,
+ * java.lang.Object, java.lang.Object)
*/
public Object getValue(ELContext context, Object base, Object property) {
return parent.getValue(context, base, property);
@@ -224,7 +318,8 @@
* @param base
* @param property
* @return
- * @see javax.el.ELResolver#isReadOnly(javax.el.ELContext, java.lang.Object,
java.lang.Object)
+ * @see javax.el.ELResolver#isReadOnly(javax.el.ELContext,
+ * java.lang.Object, java.lang.Object)
*/
public boolean isReadOnly(ELContext context, Object base,
Object property) {
@@ -236,14 +331,17 @@
* @param base
* @param property
* @param value
- * @see javax.el.ELResolver#setValue(javax.el.ELContext, java.lang.Object,
java.lang.Object, java.lang.Object)
+ * @see javax.el.ELResolver#setValue(javax.el.ELContext,
+ * java.lang.Object, java.lang.Object, java.lang.Object)
*/
public void setValue(ELContext context, Object base, Object property,
Object value) {
- if(null != base && null != property){
- context.setPropertyResolved(true);
- validationMessages = validate(base,property.toString(),value,
context.getLocale());
- valid = null == validationMessages || 0 == validationMessages.length;
+ if (null != base && null != property) {
+ context.setPropertyResolved(true);
+ validationMessages = validate(base, property.toString(), value,
+ context.getLocale());
+ valid = null == validationMessages
+ || 0 == validationMessages.length;
}
}
@@ -253,6 +351,43 @@
public String[] getValidationMessages() {
return validationMessages;
}
-
+
}
+
+ /**
+ * Class for identify validator instance by resource bundle
+ *
+ * @author amarkhel
+ *
+ */
+ class ValidatorKey {
+ private Class<? extends Object> validatableClass;
+ private ResourceBundle bundle;
+
+ /**
+ * Constructor for ValidatorKey object
+ *
+ * @param validatableClass -
+ * class to validate
+ * @param bundle -
+ * Resource bundle, used during validation process
+ */
+ public ValidatorKey(Class<? extends Object> validatableClass,
+ ResourceBundle bundle) {
+ this.validatableClass = validatableClass;
+ this.bundle = bundle;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ ValidatorKey key = (ValidatorKey) other;
+ return key.validatableClass.equals(validatableClass)
+ && key.bundle.equals(bundle);
+ }
+
+ @Override
+ public int hashCode() {
+ return validatableClass.hashCode() + bundle.hashCode();
+ }
+ }
}
Modified:
trunk/sandbox/ui/beanValidator/src/main/java/org/richfaces/validator/FacesBeanValidator.java
===================================================================
---
trunk/sandbox/ui/beanValidator/src/main/java/org/richfaces/validator/FacesBeanValidator.java 2008-07-08
14:02:15 UTC (rev 9450)
+++
trunk/sandbox/ui/beanValidator/src/main/java/org/richfaces/validator/FacesBeanValidator.java 2008-07-08
14:38:17 UTC (rev 9451)
@@ -3,7 +3,9 @@
*/
package org.richfaces.validator;
+import javax.el.ELException;
import javax.el.ValueExpression;
+import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
@@ -12,34 +14,44 @@
import javax.faces.validator.ValidatorException;
/**
- * Implementation of the JSF validator to use with Bean Validation / Hibernate validator
+ * Implementation of the JSF validator to use with Bean Validation / Hibernate
+ * validator
+ *
* @author asmirnov
- *
+ *
*/
public class FacesBeanValidator implements Validator {
- /* (non-Javadoc)
- * @see javax.faces.validator.Validator#validate(javax.faces.context.FacesContext,
javax.faces.component.UIComponent, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.faces.validator.Validator#validate(javax.faces.context.FacesContext,
+ * javax.faces.component.UIComponent, java.lang.Object)
*/
- public void validate(FacesContext context, UIComponent component, Object
convertedValue)
- throws ValidatorException {
+ public void validate(FacesContext context, UIComponent component,
+ Object convertedValue) throws ValidatorException {
if (component instanceof UIInput) {
// Validate input component
UIInput input = (UIInput) component;
- ValueExpression valueExpression = input.getValueExpression("value");
- if(null != valueExpression){
- // TODO - check EL Exceptions ?
- String[] messages = BeanValidator.getInstance(context).validate(context,
valueExpression, convertedValue);
- if(null != messages){
- input.setValid(false);
- // TODO - send all validation messages.
- for (String msg : messages) {
- context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
msg,""));
- }
+ try {
+ ValueExpression valueExpression = input
+ .getValueExpression("value");
+ if (null != valueExpression) {
+ // TODO - check EL Exceptions ?
+ String[] messages = BeanValidator.getInstance(context)
+ .validate(context, valueExpression, convertedValue);
+ if (null != messages) {
+ input.setValid(false);
+ // TODO - send all validation messages.
+ for (String msg : messages) {
+ context.addMessage(input.getClientId(context), new FacesMessage(
+ FacesMessage.SEVERITY_ERROR, msg, ""));
+ }
+ }
}
+ } catch (ELException e) {
+ throw new FacesException(e);
}
}
-
}
-
}