2012-09-11 104 views
0
@FacesValidator("uniqueValidator") 
public class UniqueValidator implements Validator 
{ 
    @Override 
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException 
    { 
     if(context == null) 
     { 
      throw new NullPointerException(); 
     } 
     if(component == null) 
     { 
      throw new NullPointerException(); 
     } 

     ValueExpression valueExpression = component.getValueExpression("value"); 
     if(valueExpression == null) 
     { 
      return; 
     } 

     ValueReference valueReference = valueExpression.getValueReference(context.getELContext()); 
     if(valueReference == null) 
     { 
      return; 
     } 

     Object base = valueReference.getBase(); 
     Object property = valueReference.getProperty(); 

     Tracer.out(base, property); 

     ..... 
    } 
} 

and ValueReference is always null。ValueExpression:如何獲取基礎對象?

有什麼不對?

回答

3

謝謝BeanValidator :)

public class ValueExpressionAnalyzer 
{ 
    public static ValueReference getReference(ELContext elContext, ValueExpression expression) 
    { 
     InterceptingResolver resolver = new InterceptingResolver(elContext.getELResolver()); 

     try 
     { 
      expression.setValue(new InterceptingContext(elContext, resolver), null); 
     } 
     catch(ELException ele) 
     { 
      return null; 
     } 

     ValueReference reference = resolver.getValueReference(); 
     if(reference != null) 
     { 
      Object base = reference.getBase(); 
      if(base instanceof CompositeComponentExpressionHolder) 
      { 
       ValueExpression ve = ((CompositeComponentExpressionHolder) base).getExpression((String) reference.getProperty()); 
       if(ve != null) 
       { 
        reference = getReference(elContext, ve); 
       } 
      } 
     } 
     return reference; 
    } 

    private static class InterceptingContext extends ELContext 
    { 
     private final ELContext context; 
     private final ELResolver resolver; 

     public InterceptingContext(ELContext context, ELResolver resolver) 
     { 
      this.context = context; 
      this.resolver = resolver; 
     } 

     // punch in our new ELResolver 
     @Override 
     public ELResolver getELResolver() 
     { 
      return resolver; 
     } 

     // The rest of the methods simply delegate to the existing context 

     @Override 
     public Object getContext(Class key) 
     { 
      return context.getContext(key); 
     } 

     @Override 
     public Locale getLocale() 
     { 
      return context.getLocale(); 
     } 

     @Override 
     public boolean isPropertyResolved() 
     { 
      return context.isPropertyResolved(); 
     } 

     @Override 
     public void putContext(Class key, Object contextObject) 
     { 
      context.putContext(key, contextObject); 
     } 

     @Override 
     public void setLocale(Locale locale) 
     { 
      context.setLocale(locale); 
     } 

     @Override 
     public void setPropertyResolved(boolean resolved) 
     { 
      context.setPropertyResolved(resolved); 
     } 

     @Override 
     public FunctionMapper getFunctionMapper() 
     { 
      return context.getFunctionMapper(); 
     } 

     @Override 
     public VariableMapper getVariableMapper() 
     { 
      return context.getVariableMapper(); 
     } 
    } 

    private static class InterceptingResolver extends ELResolver 
    { 
     private final ELResolver delegate; 
     private ValueReference valueReference; 

     public InterceptingResolver(ELResolver delegate) 
     { 
      this.delegate = delegate; 
     } 

     public ValueReference getValueReference() 
     { 
      return valueReference; 
     } 

     // Capture the base and property rather than write the value 
     @Override 
     public void setValue(ELContext context, Object base, Object property, Object value) 
     { 
      if(base != null && property != null) 
      { 
       context.setPropertyResolved(true); 
       valueReference = new ValueReference(base, property.toString()); 
      } 
     } 

     // The rest of the methods simply delegate to the existing context 

     @Override 
     public Object getValue(ELContext context, Object base, Object property) 
     { 
      return delegate.getValue(context, base, property); 
     } 

     @Override 
     public Class<?> getType(ELContext context, Object base, Object property) 
     { 
      return delegate.getType(context, base, property); 
     } 

     @Override 
     public boolean isReadOnly(ELContext context, Object base, Object property) 
     { 
      return delegate.isReadOnly(context, base, property); 
     } 

     @Override 
     public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) 
     { 
      return delegate.getFeatureDescriptors(context, base); 
     } 

     @Override 
     public Class<?> getCommonPropertyType(ELContext context, Object base) 
     { 
      return delegate.getCommonPropertyType(context, base); 
     } 

    } 
} 
+0

真好!但不能設置屬性值:(?! – dforce