facelets
  1. facelets
  2. FACELETS-313

ValidateHandler / ConvertHandler need to process inner tags

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: ALL
    • Fix Version/s: 1.1.15
    • Component/s: jsf
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

    • Issuezilla Id:
      313

      Description

      In Shale Commons Validator, there is a validator that is used like this:

      <val:commonsValidator ...>
      <val:validatorVar name="minlength" value="4" />
      </val:commonsValidator>

      The <val:validatorVar> provides an argument for the validator, similar to an
      attribute or facet.

      This doesn't work when I made the approprioate TagHandler's for commonsValidator
      and validatorVar.

      com.sun.facelets.tag.jsf.Validator handler's apply() method looks like this:

      public final void apply(FaceletContext ctx, UIComponent parent)
      throws IOException, FacesException, FaceletException, ELException {

      if (parent == null || !(parent instanceof EditableValueHolder))

      { throw new TagException(this.tag, "Parent not an instance of EditableValueHolder: " + parent); }

      // only process if it's been created
      if (parent.getParent() == null) {
      // cast to a ValueHolder
      EditableValueHolder evh = (EditableValueHolder) parent;
      ValueExpression ve = null;
      Validator v = null;
      if (this.binding != null)

      { ve = this.binding.getValueExpression(ctx, Validator.class); v = (Validator) ve.getValue(ctx); }

      if (v == null) {
      v = this.createValidator(ctx);
      if (ve != null)

      { ve.setValue(ctx, v); }

      }
      if (v == null)

      { throw new TagException(this.tag, "No Validator was created"); }

      this.setAttributes(ctx, v);
      evh.addValidator(v);

      }

      }

      Since the nextHandler is never applied it appears all child tags of the
      validator will be ignored. In my case the TagHandler for val:validatorVar didn't
      seem to be invoked. Unfortunately, apply() is a final method so this behavior
      cannot be overridden in a subclass that handles the commonsValidator tag. The
      solution, which I have found to work, is to add

      nextHandler.apply(ctx, parent);

      right after

      evh.addValidator(v);

      The tag handler for val:validateVar can then get the parent UIComponent's
      validators, get at the last one, then modify the validator's configuration.
      This works after the above change.

      For completeness, I should mention that ConvertHandler probably has the same
      problem. I am not too sure where to apply the next handler, here is my guess:

      this.setAttributes(ctx, c);
      vh.setConverter(c);

      // Added here!!
      nextHandler.apply(ctx, parent);

      Object lv = vh.getLocalValue();
      FacesContext faces = ctx.getFacesContext();
      if (lv instanceof String)

      { vh.setValue(c.getAsObject(faces, parent, (String) lv)); }

      Right now Shale Commons Validator doesn't use any child tags for converters, but
      it's possible that some other tag library might, so the ConvertHandler should
      probably be fixed for completeness.

        Activity

        There are no comments yet on this issue.

          People

          • Assignee:
            Unassigned
            Reporter:
            jctsay
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: