This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
We're using (stuck on) JSF 1.2 and RichFaces 3.3.1. In a number of places, we use the rich:calendar control, like this:
That is, we are formatting a date like "23 Mar 2011", but also allowing the users to manually enter their own dates if they can keep to the correct format. Now if a user does enter a correctly formatted date, then hits the icon to popup the calendar, it will display the month of the entered date. If the user enters garbage and hits the popup button, the calendar will display the current month, and also a validation error if we show it. That's all good.
However, there are a couple of "in-between" cases. One is if the month is spelled out, eg., "11 November 1918". In that case, the calendar popup will still show the current month, and no validation error. The big problem is if the month is input correctly, but with an an unexpected case, eg., 23 mar 2011, 23 MAR 2011, 23 mAr 2011. In these cases, the popup calendar displays Undefined for the month, and NaN for the year. The error comes from org.richfaces.component.UICalendar, but when I traced into that, it looked like it was being passed bad data to work with, so the problem is earlier.
I'll file a bug report, but I'd like to trace into it further first. I'm not sure where to look though. What class would be responsible for parsing this string?
Well, actually I could, but that's just because I'm mean-spirited.
I suspect that you need look no farther than the java.text DateFormatter/parser class to find the problem. The NaN part is maybe a little weird, but Java is fond of parsers that silently give up once they're stopped being able to parse input.
An IDE is no substitute for an Intelligent Developer.
I would have thought so too, but after some more research I've found the problem is in calendar.js from RichFaces. There's a parseDate() function that creates a regular expression, based on the date pattern, to split the string into year, month, and day pieces, but it's done with the case insensitive flag:
Now, it will fail on a totally bogus month, like Xyz", and the whole parseDate() will return null, but "MAR" will produce a match and so it goes on. When the parsed out month isn't already a number, it calls getMonthByLabel() to make the conversion:
So that's case-sensitive, and gets a null for the month, without causing the parse to fail. Basically everything goes off the rails from there.
It looks like it's fixed by RichFaces 3.3.3.Final, though I can't find any JIRA report on it.
So I could upgrade to 3.3.3, but we're in acceptance testing now, and I'm afraid to do it. My other choice is to hack in a replacement for the getMonthByLabel() script somewhere. I might just do that instead.