As I edited the code to remove RichFaces from our Application, a simple problem arose and led to two days worth of work. This is not unusual, and we are actually quite happy about the changes we have made, since they ought to make the application run far better in the future.
The problem was as follows: without RichFaces, creating a new prayer request from the prayer list page required a simple command button pointing to a simple xhtml page, “prayerRequestEditor”, where you could edit a new prayer request, save, and return. However, we intend to have at least one other page in the application link to PrayerRequestEditor. How were we to ensure that, on completing the edit, the user would be returned to the page they recently left? The immediate solution was to copy the entire prayerRequestEditor and define different navigation rules for the two identical files. Surely, we thought, there must be a way to avoid having to maintain two identical files on the server.
Our first solution, which we spent the majority of two days pursuing, was to implement Apache-Shale dialog manager.
A dialog manager such as this one uses a small number of easy-to-understand states to define a “dialog” or “flow” for a webapplication. Navigation from page to page, actions between and inside views, and action reversal should all be gracefully carried out in a properly written and executed dialog. Shale’s logic was very much to my liking.
Not only did Shale promise to rid us of wasteful code copying by modeling multiple subdialogs pointing to the same dialog body, it also offered a way to implement dialog-scoped data. Data stored in web session tends to slow things down, so it is best to keep controller-bean’s properties in request-scope, causing them to be erased from session after each mouse click. Unfortunately, this also forces us to reload them with each mouse-click if they are needed, and that puts an even greater strain on the database. The happy medium is the dialog scope, which, if it existed, would magically mark objects for cleanup when the dialog, and their usefulness, ended, but keep them in session for the duration of the dialog. Shale offered this functionality through a dataClass object in which we could store variables like a currentList and currentPrayerRequest as dialog-scoped.
Unfortunately, it took us more than two full day’s work to get the framework running, and even then, it did not do what it promised.
Our first problems arose when, upon entering the prayerRequestEditor subdialog of the listManager parent, the supposedly dialog-scoped current-variables were empty. Null pointer exceptions flew; we grumbled quietly and fired up debugger.
Several hours later Mr. Chandler had waded through a morass of code and abstract dialogs, dialogContexts, and dialogContextHelpers and was convinced that there was a bug in Shale’s source. The subdialog did not know it had a parent dataClass.
Several more hours later Mr. Chandler had waded through a quicksand of Shale’s source, trying several changes, non of which were successful. With our new deep knowledge of Shale’s workings, however, he decide to hard-code the parent id onto an instance of the prayerRequestEdit dialog.
It was 10:20 pm when we finished jerry-rigging the prayerRequestEdit sub-dialog and, bleary-eyed, celebrated our success. In fact, we celebrated two successes, as, for the first time outside of junit, we created and committed a new prayer request.
We were too tired to grumble over the fact that we had spent two days trying to avoid duplicating code for navigation purposes, and had failed. Because we entered prayerRequestEdit outside of dialog-config, we could not find a way to cause the listManager dialog to treat it like a subdialog. We had to hardcode the end-event viewId, meaning that we would need to create a duplicate dialog with a separate viewId if we wanted to access prayerRequestEdit from two different pages!
Our experience with Shale has, to say the least, been disappointing. Today’s Note for Dense Summer Interns: if a code framework causes you to work many times longer on a problem than you would have, and still doesn’t solve the problem, consider getting a new framework. As you will see in the next Jobber’s Log, that’s what we did.
Common Acronym Confusion of the Day: JSF, as programmers use the term, stands for Java Server Faces, not Joint Strike Fighter.
Filed under: Headsmack, Jobber's Log | Tagged: JSF, Shale
