….Or, “When is a blank value not a blank value!”

This week I hit a problem with XPages validation. I had a custom Java validator that was doing some complex validation across multiple components. The validator was affixed to a Dojo List Text Box. It had a requiredValidator as well, to ensure the value wasn’t blank. I was then doing some additional checking on the value. But my code suddenly started throwing an error on one document. Here is part of the stack trace:

java.lang.ClassCastException: java.util.Vector incompatible with java.lang.String
at validators.PassportValidator.validate(PassportValidator.java:17)
at com.ibm.xsp.validator.ValidatorImpl.validate(ValidatorImpl.java:50)
at javax.faces.component.UIInput.validateValue(UIInput.java:828)
at com.ibm.xsp.component.UIInputEx.validateItemValue(UIInputEx.java:562)
at com.ibm.xsp.component.UIInputEx.validateValue(UIInputEx.java:553)
at javax.faces.component.UIInput.validate(UIInput.java:688)
at javax.faces.component.UIInput.executeValidate(UIInput.java:893)
at javax.faces.component.UIInput.processValidators(UIInput.java:453)

The component was for a document that has a lot of fields. In Notes Client I would have used one long form or a tabbed table. For the web, it’s not a good idea to have a long form that users have to fill in and eventually submit, crossing their fingers that it doesn’t time out or something. For XPages, tabbed tables and validation are a world of pain. And as with many things related to XPages UI design, that’s not specific to XPages, it’s a generic problem for tabbed tables and the web.

My preferred approach for some time has been a “wizard” style user experience. The XPage uses Next / Previous to navigate between wizard pages. Each wizard page is a separate div loaded or not, with navigation reloading the page (I had a problem – I can’t remember the specifics – with using a Dynamic Content Control for this approach). The validation then runs on the current tab when you move forward or click on the “tab” link for a different page.

However, going to the previous page ran with disableValidators="true". This meant the underlying field was getting set, and the requiredValidator was not getting triggered and the validator was passing an empty Vector to my custom validator. My code though casting the value parameter in the validator to a String.

Ok, I thought, I can use value.toString(). It’s an empty string, so I can check that. Those who have tried that kind of thing will know where this is going. If it’s a Vector, value.toString() doesn’t give “”, it gives “[]”. Thankfully, my requiredValidator was already catching an empty value, so I just need to check that value.toString() is “[]”.

(Incidentally, there may well be a Util function in ODA that does that kind of check, I haven’t looked.)

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.