title: JSF2 disabled attribute for validator evaluated only for first cycle?
body: <p>I found that disabled attribute for any validator I use in JSF2 is evaluated only in the first cycle if my managed bean is ViewScoped.</p>
  
  <p>But I would like to make use of <em>disabled</em> attribute for my validators based on data I get from 4th update phase. So I would expect it reevaluated in all cycles performed on the same view.</p>
  
  <p>Example xhtml page:</p>
  
  <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"&gt;
  
  &lt;h:head&gt;&lt;/h:head&gt;
  &lt;h:body&gt;
      &lt;h:form&gt;
          &lt;h:panelGrid id="pnlGrid"&gt;          
              &lt;h:inputText id="someValueId" value="#{testPageBean.someValue}"&gt;                
                  &lt;f:validateLength minimum="2" maximum="4" 
                     disabled="#{testPageBean.disableValidateLength}"/&gt;
              &lt;/h:inputText&gt;
              &lt;h:messages for="someValueId"/&gt;
  
              &lt;h:commandButton action="#{testPageBean.doSomething}" 
                 value="Do something" /&gt;
          &lt;/h:panelGrid&gt;
      &lt;/h:form&gt;
  &lt;/h:body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>and its <strong>view scoped</strong> managed bean</p>
  
  <pre><code>package cz.kamosh;
  
  import java.io.Serializable;
  
  import javax.faces.bean.ManagedBean;
  import javax.faces.bean.ViewScoped;
  
  @ManagedBean
  @ViewScoped
  public class TestPageBean implements Serializable {
  
      boolean disableValidateLength = false;
  
      private String someValue;
  
      public TestPageBean() {
          System.out.println("Constructor TestPageBean");
      }
  
      public String getSomeValue() {
          return someValue;
      }
  
      public void setSomeValue(String someValue) {
          this.someValue = someValue;
      }
  
      /**
       *  Some action without any navigation as a result
       */
      public void doSomething() {
          disableValidateLength = !disableValidateLength;
          System.out.printf(
                  "DoSomething, someValue: %1$s, disableValidateLength: %2$b\n",
                  someValue, disableValidateLength);
      }
  
      public boolean isDisableValidateLength() {
          System.out.printf("IsValidateLength, disableValidateLength: %1$b\n", 
                  disableValidateLength);
          return disableValidateLength;
      }
  }
  </code></pre>
  
  <p>I know that I should blame implementation <em>com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl</em>: </p>
  
  <pre><code>private void applyNested(FaceletContext ctx,
                               UIComponent parent) {
  
          // only process if it's been created
          if (!ComponentHandler.isNew(parent)) {
              return;
          }
      ...
  }
  </code></pre>
  
  <p>These three rows cause validator not being reevaluated its <em>disabled</em> attribute when I perform action:-(</p>
  
  <p>Could some please give me a hint, what was the motivation for JSF2 guys to implement  this way or even better how to solve my problem?</p>
  
  <p><strong><em>EDIT:</em></strong></p>
  
  <p>Version of JSF2: <em>2.0.3-SNAPSHOT</em></p>
  
  <p>web.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
      id="WebApp_ID" version="2.5"&gt;
      &lt;display-name&gt;JSF2Testing&lt;/display-name&gt;
      &lt;servlet&gt;
          &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
          &lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
          &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
      &lt;/servlet&gt;
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
          &lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
  
      &lt;context-param&gt;
          &lt;param-name&gt;javax.faces.PARTIAL_STATE_SAVING&lt;/param-name&gt;
          &lt;param-value&gt;false&lt;/param-value&gt;
      &lt;/context-param&gt;
  
  &lt;/web-app&gt;
  </code></pre>
  
  <p><HR></p>
  
  <p><strong><em>EDIT2</em></strong> Attempt to follow <a href="https://stackoverflow.com/questions/7445417/why-does-fvalidatedoublerange-only-work-for-sessionscoped">BalusC' suggestion</a></p>
  
  <p>Changes on page:</p>
  
  <pre><code>&lt;h:inputText id="someValueId" value="#{testPageBean.someValue}"&gt;                
      &lt;f:validator validatorId="myLengthValidator"/&gt;
      &lt;f:attribute name="disableMyLengthValidator" value="#{testPageBean.disableValidateLength}"/&gt;
      &lt;f:attribute name="minimum" value="2" /&gt;
      &lt;f:attribute name="maximum" value="4" /&gt;
  &lt;/h:inputText&gt;
  </code></pre>
  
  <p>Own validator used instead of standard <strong></strong>:</p>
  
  <pre><code>import java.io.Serializable;
  
  import javax.faces.component.UIComponent;
  import javax.faces.context.FacesContext;
  import javax.faces.validator.FacesValidator;
  import javax.faces.validator.LengthValidator;
  import javax.faces.validator.ValidatorException;
  
  @FacesValidator("myLengthValidator")
  public class MyLengthValidator extends LengthValidator implements Serializable {
  
      public MyLengthValidator() {
          System.out.println("MyLengthValidator constructor");
      }
  
      @Override
      public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {     
          if((Boolean)component.getAttributes().get("disableMyLengthValidator")) {
              return;
          }       
          setMinimum(Integer.valueOf((String)component.getAttributes().get("minimum")));
          setMaximum(Integer.valueOf((String)component.getAttributes().get("maximum")));
          super.validate(context, component, value);
      }
  }
  </code></pre>
  
  <p>My notes about this solution:</p>
  
  <ul>
  <li>requires own implementation even if for standard validators</li>
  <li>is dependent on attributes on component (inputText) level</li>
  <li>validator is triggered even if it should not be</li>
  <li>I am pretty sure it will not behave as we expect when client side validation is provided for validator</li>
  <li>I consider is as very ugly and not following JSF2 :-(</li>
  </ul>