Wednesday, September 07, 2005

Tapestry rant

Okay, time to spout off about Tapestry. Situation is this: let's say you have a page with a bunch of components. And this page happens to contain *secure* elements. Requirements state that the component can be viewable/read-only, updateable, or not present. Security model dictates, some time before render, what the state of each component should be. So, next issue is rendering the components. Should be as easy as updating the "disabled" attribute for the read-only, and eliminating/removing/not-rendering the components that are unauthorized.

What are the reasons for Tapestry completely hosing the easibility of this process?! This would be cake in XMLC or Wicket!

1. Components must be defined prior to render. Which means, you need to have the "disabled" parameter set to false on *every* single component you want to protect, at build-time. It is a pain to add a "binding" on at run-time and highly discouraged (http://article.gmane.org/gmane.comp.java.tapestry.user/25209).

2. Tapestry is incapable of removing components at render time. You don't have access to the DOM, you can't set a flag, nothing. I should clarify, this is the case for a) all default Tapestry components b) you can sort of work around this by wrapping the component in a Conditional component.

3. Tapestry default components do not allow render flags. In conjunction with issue #2, you can't just set a flag informing Tapestry to NOT render the component.

So, why does this really tick me off? Because I have many pages on which I now need to implement security (aforementioned implementation). I cannot, out-of-the-box, do what I need. I must go through each component and add the "disabled" attribute (only 130+ of them). I must choose to wrap the components in Conditionals if I don't want them rendered. IMO, this is a ton of work and really defeats the purpose of dynamic page generation.

My acceptable is solution is to go through and create wrapper components for each of the Tapestry components we're using. I'll add a default "disabled" attribute that I can hose with at run-time (so the user doesn't have to add it specifically) and a flag that determines whether the component should render. This is going to take more time than I likely have. Wish I knew about this issues months ago, I *may* have reconsidered my choice of web application framework.

One alternative, Java Server Faces, does exactly what I want in its UIComponentBase:
http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/javax/faces/component/UIComponentBase.html#UIComponentBase()

In conclusion, the more I work with Tapestry the more I feel like my hand is being held and while it provides some nifty aspects (reusable components, form validation), I can accomplish essentially the same thing in some other frameworks. The more I look into JSF, the more I'm realizing its value....

No comments: