Hello again,

----- Original Message ----- From: "Thiago H. de Paula Figueiredo" <thiag...@gmail.com>
To: "Tapestry users" <users@tapestry.apache.org>
Sent: Tuesday, November 02, 2010 4:09 PM
Subject: Re: Let's make @ActivationRequestParameter first-class citizen


Something I personally find odd is to have two different object ids being
used in the same page to edit or view the same object. Of course, I don't
know your requirements, but that's something I wouldn't do, as the same
thing would have two or more URLs.

My example was definetly stupid, I made up the parameter names out of my head, it's not something I have in real. Pages definetly should not be overloaded with overly different functionality.

Maybe the simpliest example would be EditEmployeePage which can be used both for *creating* and *editing* an Employee.
When you edit an Employee, you have "employeeId" page context.
When you create an Employee, you have "companyId" page context 'cause you have to know which company this employee will belong to, once created. Both cases have just one argument in context, so using plain onActivate(Long argument) would not work. Of course, simple workaround for this would be additional context argument that would provide differentiation, but I think the example is good. In more complex cases this would be really troublesome (such as I mentioned previously).

Bottom line of my thinking is that differentiation of page render parameters is much more flexibile via naming than via ordering/count mechanism, and that's why I love @ActivationRequestParameter way.

For example, sometimes this cross-cutting logic needs to access
@PageActivationContext fields directly, but I cannot use this annotation
in filter implementations (maybe by parsing URLs, but that's cumbersome
and not compile-safe).

You don't need to parse yourself: use the ComponentEventLinkEncoder
service and its decodeComponentEventRequest() and
decodePageRenderRequest() methods. For conversions, use the TypeCoercer
services. That's exactly what Tapestry internally does.

Fields annotated with @SessionState are also not available (maybe
available through some global Tapestry service by some (?!) name, but
not directly referencing class field)...etc...

Use the ApplicationStateManager service for that. Again, that's exactly
what Tapestry internally does. @SessionState fields are replaced by method
invocations, so there's no difference in directly accessing fields. They
don't even exist in runtime since T5.2. Don't forget that @SessionState is
stored by object type, not page or field name. @Persist are.

I appreaciate the effort Thiago, but I'm not convinced. :)

I picked Tapestry among other web frameworks primarely because it (mostly) allows me to use natural, compile-safe way to reference instances/fields. For eg:

@InjectPage
private EmployeePage employeePage;
...and then somewhere in my web...
if (employeePage.getEmployeeId() == ...)

This referencing employeeId field in page class is so natural java programming. I don't need to think about URL params here, their indices etc. The same when I generate links (for redirect let's say):
return employeePage.configuredWithId(31231);

This fields can be @Persist, or @Sessionstate, or whatever, everything is always natural and comile-safe. I just reference them. As I see it, ComponentRequestFilters just don't provide this level of commodity. I also consider them as a "advanced" usage of Tapestry, because I guess average Joe just don't want to know about internal ApplicationStateManager or ComponentEventLinkEncoder or such. He should know it if he's doing something unconventional, but I really think I'm trying to develop just usual web functionality here, nothing fancy.

I know inheritance can be really bad if overused (Howard's main problem with Tapestry versions prior to v5 was inheritance), but as I said, in simple cases when I spot 2-3 of my pages have some common preprocessing logic, I really think superclass is the way to go. Otherwise I would end up with multitude of cumbersome filters.

I guess at the end, we can agree to disagree. :)

Sometimes, to my collegues, when we compare Tapestry with usual request-driven web frameworks, it seems as if comparing Hibernate with JDBC. JDBC is dead simple, everyone understands it, there is no place to wonder how one should do something. But that's common characteristic of all libraries that don't try to do much for you, and you're left with much tedious tasks yourself. When one like Howard tries to give much higher level of abstraction and power, it's no easy task to develop such tool, you have to try out few things that none before you did. Majority of them turn out great, and some of them I wish stayed as usual. Then again, I can see how opinions on certain features can vary amoung users. For eg, I completely dislike class reloading for all the packaging (and other) burden it gives me where I can see others appreciate it. People seem not to care so much of compile-safety whereas it is for me *by far* Tapestry's biggest selling point. First thing that I did was to develop my own version of SafePagelink that can take page *instance* argument so I can provide it via my page:

public Object getConfiguredEmployeePageForLink() {
   return employeePage.configuredWithId(31231);
}
And this is not something you would rarely use so it's not important - these are render links we're talking here, so it's the thing you use couple of times on each web page.

I guess we all differ.

-Vjeran


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to