[jboss-cvs] jboss-seam/src/main/org/jboss/seam/core ...
Gavin King
gavin.king at jboss.com
Sun Jun 24 18:24:50 EDT 2007
User: gavin
Date: 07/06/24 18:24:50
Modified: src/main/org/jboss/seam/core Expressions.java
Validators.java
Log:
redesign model-based validation, according to advice of Jacob
JBSEAM-1593
Revision Changes Path
1.38 +25 -68 jboss-seam/src/main/org/jboss/seam/core/Expressions.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: Expressions.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Expressions.java,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -b -r1.37 -r1.38
--- Expressions.java 22 Jun 2007 15:28:56 -0000 1.37
+++ Expressions.java 24 Jun 2007 22:24:50 -0000 1.38
@@ -1,4 +1,4 @@
-//$Id: Expressions.java,v 1.37 2007/06/22 15:28:56 gavin Exp $
+//$Id: Expressions.java,v 1.38 2007/06/24 22:24:50 gavin Exp $
package org.jboss.seam.core;
import static org.jboss.seam.annotations.Install.BUILT_IN;
@@ -9,10 +9,7 @@
import javax.el.ELContext;
import javax.el.ExpressionFactory;
-import org.hibernate.validator.ClassValidator;
-import org.hibernate.validator.InvalidValue;
import org.jboss.seam.Component;
-import org.jboss.seam.Model;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
@@ -85,7 +82,7 @@
private javax.el.ValueExpression facesValueExpression;
private javax.el.ValueExpression seamValueExpression;
- private javax.el.ValueExpression getExpression()
+ public javax.el.ValueExpression toUnifiedValueExpression()
{
if ( isFacesContextActive() )
{
@@ -112,12 +109,12 @@
public T getValue()
{
- return (T) getExpression().getValue( getELContext() );
+ return (T) toUnifiedValueExpression().getValue( getELContext() );
}
public void setValue(T value)
{
- getExpression().setValue( getELContext(), value );
+ toUnifiedValueExpression().setValue( getELContext(), value );
}
public String getExpressionString()
@@ -127,7 +124,7 @@
public Class<T> getType()
{
- return (Class<T>) getExpression().getType( getELContext() );
+ return (Class<T>) toUnifiedValueExpression().getType( getELContext() );
}
};
@@ -147,7 +144,7 @@
private javax.el.MethodExpression facesMethodExpression;
private javax.el.MethodExpression seamMethodExpression;
- private javax.el.MethodExpression getExpression()
+ public javax.el.MethodExpression toUnifiedMethodExpression()
{
if ( isFacesContextActive() )
{
@@ -174,7 +171,7 @@
public T invoke(Object... args)
{
- return (T) getExpression().invoke( getELContext(), args );
+ return (T) toUnifiedMethodExpression().invoke( getELContext(), args );
}
public String getExpressionString()
@@ -186,8 +183,10 @@
}
/**
- * A value expression, an EL expression that evaluates to
- * an attribute getter or get/set pair.
+ * A value expression - an EL expression that evaluates to
+ * an attribute getter or get/set pair. This interface
+ * is just a genericized version of the Unified EL ValueExpression
+ * interface.
*
* @author Gavin King
*
@@ -199,11 +198,16 @@
public void setValue(T value);
public String getExpressionString();
public Class<T> getType();
+ /**
+ * @return the underlying Unified EL ValueExpression
+ */
+ public javax.el.ValueExpression toUnifiedValueExpression();
}
/**
- * A method expression, an EL expression that evaluates to
- * a method.
+ * A method expression - an EL expression that evaluates to
+ * a method. This interface is just a genericized version of
+ * the Unified EL ValueExpression interface.
*
* @author Gavin King
*
@@ -213,6 +217,10 @@
{
public T invoke(Object... args);
public String getExpressionString();
+ /**
+ * @return the underlying Unified EL MethodExpression
+ */
+ public javax.el.MethodExpression toUnifiedMethodExpression();
}
protected boolean isFacesContextActive()
@@ -220,58 +228,7 @@
return false;
}
- /**
- * Validate that a value can be assigned to the property
- * identified by a value expression.
- *
- * @param propertyExpression a value expression
- * @param value the value that is to be assigned
- *
- * @return the validation failures, as InvalidValues
- */
- public InvalidValue[] getInvalidValues(String propertyExpression, Object value)
- {
- if (propertyExpression == null)
- {
- return new InvalidValue[0];
- }
- int dot = propertyExpression.lastIndexOf('.');
- int bracket = propertyExpression.lastIndexOf('[');
- if (dot<=0 && bracket<=0)
- {
- return new InvalidValue[0];
- }
- String componentName;
- String propertyName;
- String modelExpression;
- if (dot>bracket)
- {
- componentName = propertyExpression.substring(2, dot).trim();
- propertyName = propertyExpression.substring( dot+1, propertyExpression.length()-1 ).trim();
- modelExpression = propertyExpression.substring(0, dot).trim() + '}';
- }
- else
- {
- componentName = propertyExpression.substring(2, bracket).trim();
- propertyName = propertyExpression.substring( bracket+1, propertyExpression.length()-2 ).trim();
- if ( propertyName.startsWith("'") && propertyName.endsWith("'") )
- {
- propertyName = propertyName.substring( 1, propertyName.length()-1 );
- //TODO: handle meaningless property names here!
- }
- else
- {
- return new InvalidValue[0];
- }
- modelExpression = propertyExpression.substring(0, bracket).trim() + '}';
- }
-
- Object modelInstance = getExpressionFactory().createValueExpression( getELContext(), modelExpression, Object.class)
- .getValue( getELContext() ); //TODO: cache the ValueExpression object!
- return getValidator(modelInstance, componentName).getPotentialInvalidValues(propertyName, value);
- }
-
- /**
+ /*
* Gets the validator from the Component object (if this is a Seam
* component, we need to use the validator for the bean class, not
* the proxy class) or from a Model object (if it is not a Seam
@@ -281,7 +238,7 @@
* @param componentName the name of the context variable, which might be a component name
* @return a ClassValidator object
*/
- private static ClassValidator getValidator(Object instance, String componentName)
+ /*private static ClassValidator getValidator(Object instance, String componentName)
{
if (instance==null || componentName==null )
{
@@ -289,7 +246,7 @@
}
Component component = Component.forName(componentName);
return ( component==null ? Model.forClass( instance.getClass() ) : component ).getValidator();
- }
+ }*/
public static Expressions instance()
{
1.11 +81 -23 jboss-seam/src/main/org/jboss/seam/core/Validators.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: Validators.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Validators.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- Validators.java 20 Jun 2007 17:45:55 -0000 1.10
+++ Validators.java 24 Jun 2007 22:24:50 -0000 1.11
@@ -2,19 +2,30 @@
import static org.jboss.seam.annotations.Install.BUILT_IN;
+import java.beans.FeatureDescriptor;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.el.ValueExpression;
+
import org.hibernate.validator.ClassValidator;
import org.hibernate.validator.InvalidValue;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
+import org.jboss.seam.Seam;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.el.EL;
/**
* Caches instances of Hibernate Validator ClassValidator
@@ -53,6 +64,7 @@
}
//TODO: should use weak references here...
+ //TODO: use Model.forClass(...) instead!!
private Map<Key, ClassValidator> classValidators = Collections.synchronizedMap( new HashMap<Key, ClassValidator>() );
/**
@@ -64,6 +76,7 @@
public <T> ClassValidator<T> getValidator(Class<T> modelClass, String name)
{
Key key = new Key( modelClass, ResourceBundle.instance().getLocale() );
+ //TODO: use Model.forClass(...) instead!!
ClassValidator result = classValidators.get(key);
if (result==null)
{
@@ -108,38 +121,83 @@
}
/**
- * Validate that a value can be assigned to the property
- * identified by a value expression.
- * @param propertyExpression a value expression
- * @param value the value that is to be assigned
+ * Validate that the given value can be assigned to the property given by the value
+ * expression.
*
- * @return the validation failures, as InvalidValues
+ * @param valueExpression a value expression, referring to a property
+ * @param elContext the ELContext in which to evaluate the expression
+ * @param value a value to be assigned to the property
+ * @return a set of potential InvalidValues, from Hibernate Validator
*/
- public InvalidValue[] validate(String propertyExpression, Object value)
+ public InvalidValue[] validate(ValueExpression valueExpression, ELContext elContext, Object value)
+ {
+ ValidatingResolver validatingResolver = new ValidatingResolver( elContext.getELResolver() );
+ ELContext decoratedContext = EL.createELContext(elContext, validatingResolver);
+ valueExpression.setValue(decoratedContext, value);
+ return validatingResolver.getInvalidValues();
+ }
+
+ class ValidatingResolver extends ELResolver
{
- int dot = propertyExpression.lastIndexOf('.');
- int bracket = propertyExpression.lastIndexOf('[');
- if (dot<=0 && bracket<=0)
+ private ELResolver delegate;
+ private InvalidValue[] invalidValues;
+
+ public ValidatingResolver(ELResolver delegate)
{
- return new InvalidValue[0];
+ this.delegate = delegate;
}
- String componentName;
- String propertyName;
- if (dot>bracket)
+
+ public InvalidValue[] getInvalidValues()
{
- componentName = propertyExpression.substring(2, dot);
- propertyName = propertyExpression.substring( dot+1, propertyExpression.length()-1 );
+ return invalidValues;
}
- else
+
+ @Override
+ public Class<?> getCommonPropertyType(ELContext context, Object value)
+ {
+ return delegate.getCommonPropertyType(context, value);
+ }
+
+ @Override
+ public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object value)
+ {
+ return delegate.getFeatureDescriptors(context, value);
+ }
+
+ @Override
+ public Class<?> getType(ELContext context, Object x, Object y)
+ throws NullPointerException, PropertyNotFoundException, ELException
+ {
+ return delegate.getType(context, x, y);
+ }
+
+ @Override
+ public Object getValue(ELContext context, Object base, Object property)
+ throws NullPointerException, PropertyNotFoundException, ELException
+ {
+ return delegate.getValue(context, base, property);
+ }
+
+ @Override
+ public boolean isReadOnly(ELContext context, Object base, Object property)
+ throws NullPointerException, PropertyNotFoundException, ELException
+ {
+ return delegate.isReadOnly(context, base, property);
+ }
+
+ @Override
+ public void setValue(ELContext context, Object base, Object property, Object value)
+ throws NullPointerException, PropertyNotFoundException, PropertyNotWritableException, ELException
+ {
+ if (base!=null && property!=null )
{
- componentName = propertyExpression.substring(2, bracket);
- propertyName = propertyExpression.substring( bracket+1, propertyExpression.length()-2 );
+ context.setPropertyResolved(true);
+ invalidValues = getValidator( base.getClass(), Seam.getComponentName( base.getClass() ) )
+ .getPotentialInvalidValues( property.toString(), value );
+ }
+
}
- String modelExpression = propertyExpression.substring(0, dot) + '}';
- Object model = Expressions.instance().createValueExpression(modelExpression).getValue();
- ClassValidator validator = getValidator( model.getClass(), componentName );
- return validator.getPotentialInvalidValues(propertyName, value);
}
public static Validators instance()
More information about the jboss-cvs-commits
mailing list