Tapestry's Simplicity Blues

classic Classic list List threaded Threaded
29 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Tapestry's Simplicity Blues

Howard Lewis Ship
> Here's a description I found with a quick google.
> http://developer.apple.com/documentation/LegacyTechnologies/WebObjects/WebObjects_5.1/DirectToWeb/WalkThrough/Generating_Components.html
>
> "WebAssistant" is what they call the wizard-ish GUI builder now.  A
> WebAssistant on top of Tapestry would be awesome.
>
>

Everything old is new again.  Ruby on Rails meet Direct2Web.  But
also, meet Trails, which is a Rails-like approach based on Tapestry,
Spring and Hibernate.

--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tapestry's Simplicity Blues

Howard Lewis Ship
In reply to this post by Karthik Abram
Wish I had had the foresight five years ago to build in explicit
support for a visual builder.

4.0 is adding flexibility to store state in many places, currently in
the session (as in 3.0) but also as query parameters / hidden form
fields.  Further nuances will likely be possible in the future as well
... I'd like to see support for WebObjects style state storage, where
multiple versions of the property are stored on the server, and the
client includes query parameter to select which version was in effect
when the page rendered.

On 5/12/05, Karthik Abram <[hidden email]> wrote:

>
> I've build fairly substantial applications with .NET - and I will have to
> disagree with some of the points below. True, .NET doesn't have a Hibernate
> like persistence layer, but the reality is that while java produced a
> zillion persistence options for the "Enterprise" app, ADO.NET's simple
> in-memory DataTable approach will suffice for 99% of the apps out there.
> That said, .NET 2.0 will change quite a few things ...
>
> The distinction between .NET and Tapestry is this: (a) State persistence in
> the client using the view-state, (b) GUI design tool, components that have a
> distince "design time" and "run time" mode of operation (components have an
> interface that allow it to interact with VS .NET for design time
> manipulation); (c) Thriving commercial component market with some really
> slick components.
>
> Of course the availability of tons of books/literature/websites also makes
> the learning curve a lot easier. That said, Tapestry will run on Linux, .NET
> requires a licensed OS.s
>
> -----Original Message-----
> From: Patrick Casey [mailto:[hidden email]]
> Sent: Thursday, May 12, 2005 3:02 AM
> To: 'Tapestry users'
> Subject: RE: Tapestry's Simplicity Blues
>
> <snip>
> > Thing is that I never worked with JSF or APS.NET to judge Tapestry with
> > other component web frameworks. From what I've read around, I sincerely
> > doubt that JSF is simplier, but I would really like some expeienced
> > ASP.NET
> > developer to say his opinion.
>
> I wouldn't necessarily call myself a .NET expert, but I did prototype a
> system in in a few months ago (I decided not to go down that road so I'm
> back in java). The short version of my experience.
>
> .NET does make the simple stuff simple. If you want to build a quick and
> dirty CRUD app with only a few forms, .NET is way faster than anything I've
> yet found in the java world. Between the WYSIWIG form editor, the component
> library, and the magic "don't worry about it, it just works" persistence
> strategy they have, it's really easy to do easy stuff.
>
> But, and here's where .NET and I parted ways, it doesn't have a lot of
> features to make the *hard* stuff simple. Want an abstract object
> persistence layer like Hibernate? So sorry, roll your own, or use a thin
> resultset wrapper like ADO. Want to use lots of generic forms and runtime
> data binding? Sorry, it's a design time framework. Sure you *can* bind at
> runtime, but if you do you can't use any of the cool features that made the
> easy stuff easy.
>
> All in all, I felt like it was something of a trap for serious development
> work. It makes banging together a sketchy prototype really easy, but then
> you end up not being able to use any of those easy features on the real
> project.
>
> If somebody would marry the easy-stuff-is-easy part of .NET with the
> hard-stuff-is-possible part of hibernate/java/tapestry, I'd switch to it in
> a heartbeat. To date though, nobody has pulled it off. If I were a gambling
> man, I'd bet on the Eclipse group making a decent go at it in the next
> couple of years.
>
> I'm not all that confident though that the current stable of open source
> projects out there (choose your poison) are going to get there though. In my
> experience they're usually written by developers who got fed up with crap
> like .NET and decided to tackle the interesting "hard stuff" problems
> instead of the tedious "easy stuff" issues. So we have at least a half dozen
> web application frameworks out there, but nobody has yet written a decent
> WYSYWIG gui for any of them (if I'm wrong here I'm 100% certain I'll get 20
> emails about it :).
>
> In any event, the short version is Tapestry/Hibernate/Java is way more
> *powerful* than .NET for the kind of work I do. It's not, however, easier.
>
> --- Pat
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>


--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tapestry's Simplicity Blues

Jamie Orchard-Hays
In reply to this post by Konstantin Ignatyev
If you can get a crud app running in a few minutes with any of those,
I'll be impressed. Two things that are powerful in WO are the GUI tool
(drag and drop your components onto a page, wire a couple of properties)
and the freezer. We really don't have that GUI tool in our Java world.

Konstantin Iignatyev wrote:

> Bryan Lewis wrote:
>
>> A great example of this was the old WebObjects Direct-To-Web
>> framework.  You
>> could throw together a quick CRUD app in no time... point the tool at
>> your
>> model and hit a button.  It took me less than a minute to get a
>> running app
>> the first time I tried it (four years ago).  You could revise the pages
>> inside the wizard-ish GUI builder tool, but when you were ready to
>> make more
>> serious modifications you could tell it to generate the source code.  (I
>> think they called it "freezing" the app.)  It would give you a fully
>> functional app built on the normal frameworks and you could do
>> whatever you
>> want (except go back into the wizard-ish GUI builder tool).
>>
>>  
>>
>
> Sounds pretty much similar to Trails, or MDA, or Middlegen.
>
> Just an observation
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Tapestry's Simplicity Blues

Patrick Casey
In reply to this post by Howard Lewis Ship


> -----Original Message-----
> From: Howard Lewis Ship [mailto:[hidden email]]
> Sent: Thursday, May 12, 2005 9:11 AM
> To: Tapestry users
> Subject: Re: Tapestry's Simplicity Blues
>
> Wish I had had the foresight five years ago to build in explicit
> support for a visual builder.
>
> 4.0 is adding flexibility to store state in many places, currently in
> the session (as in 3.0) but also as query parameters / hidden form
> fields.  Further nuances will likely be possible in the future as well
> ... I'd like to see support for WebObjects style state storage, where
> multiple versions of the property are stored on the server, and the
> client includes query parameter to select which version was in effect
> when the page rendered.
<snip>

I actually rolled a (primitive) version of the functionality you're
describing last week. Each of my pages now has "base" properties and
"persistent" properties. All persistent properties aren't stored in the page
object, but rather in an attached persistent object e.g.

Public class foo extends BasePage {

Private FormProperties fPersistentProperties;
Private String fSomeNonPersistentString

Public String getSomePersistentProperty() {
        Return fPersistentProperties.getSomePersistentProperty();
}

Then the when the page starts rendering I generate a unique key for this
particular page rendering and stuff it into the page as it renders. After
page render I then drop the persistent properties into a linked hashmap in
the visit object, using the previously generated key.

Then, whenever any link or button on the aforementioned form is clicked on
the client, I bootstrap the page back into the appropriate state by yanking
the persistent properties out of the visit object by way of the key.

It seems to be working fine for me, although it's a wee bit expensive on the
memory front, burning about 200 bytes per page render, so I had to put a cap
on the number of pages I remember per user and only keep around the last 100
pages per user. If the user clicks a link that references a page that's been
flushed, I just throw a stale link.

The specific code's pretty closely linked to my particular implementation,
but the approach might work in a more general case approach.

--- Pat



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: IRequestCycle cookie madness

Michael Echerer
In reply to this post by Barry Books
Barry Books wrote:
>  I'm pretty sure that's the case. Perhaps the best way to think of it is setCookie puts a cookie into the response header and getCookie gets one from the request header.
>
Can confirm this. We use a Tapestry service to produce images. If the
session is new, because the home page creates a session and this page
contains an image using the Tapestry service, the service cannot see the
session as the page and image are requested by the browser
simultanously. Hence the sessionid for the cookie is sent back too late
to be used for the concurrent image service request.
As we try the cache images if session data is unchanged, I had to
implement workarounds for users with cookies vs. url rewriting
(basically checking whether a session is new and cookies are used, "old"
sessions are no problem)

>
> On Wednesday, May 11, 2005, at 02:27PM, Eric Schneider <[hidden email]> wrote:
>
>
>>Barry,
>>
>>
>>>>The problem is setting the cookie just puts the cookie into the  
>>>>response header. Until the browser makes another request the  
>>>>cookie is not really set.
>>
>>Is this really the case?  If you set a cookie in a http request, it's  
>>not available in the http response?   Because I can confirm that the  
>>cookie was set in the browser when the response comes back (addition  
>>request doesn't seem to be required).
>>
>>I'll try the RedirectException, see if that does the trick.
>>
>>Thanks for the suggestion.
>>
>>e.
>>
>>
>>On May 11, 2005, at 3:01 PM, Barry Books wrote:
>>
>>
>>>>From the way you describe your code you are trying to retrieve the  
>>>>cookie in the same request cycle you set it. The problem is  
>>>>setting the cookie just puts the cookie into the response header.  
>>>>Until the browser makes another request the cookie is not really  
>>>>set. You could either hide this feature by also storing the  
>>>>information in the visit object or throw a page redirect exception  
>>>>which would cause the browser to retrieve a new page with the  
>>>>cookie set.
>>>>
>>>
>>>Barry
>>>
>>>On Wednesday, May 11, 2005, at 01:46PM, Eric Schneider  
>>><[hidden email]> wrote:
>>>
>>>
>>>
>>>>Hi,
>>>>
>>>>I'm having trouble getting my head around some behavior that I'm
>>>>seeing.   Here's the scenario:
>>>>
>>>>I have two components that appear on every page of my application,
>>>>component A & B.
>>>>
>>>>When I start a new Visit to the application, the Home page renders
>>>>and users can invoke an action on component A that sets a cookie and
>>>>returns the next page.   Based on the value of this cookie some
>>>>behavior on component B should change when the next page is
>>>>rendered.   Simple enough.
>>>>
>>>>The problem I'm having, for whatever reason, component B is not able
>>>>to retrieve the cookie value on the first render after the cookie is
>>>>originally set.   All subsequent actions (any action, not just the
>>>>one related to Component A), component B is able to retrieve the
>>>>cookie successfully.
>>>>
>>>>Here's where I get lost trying to figure out how the RequestCycle
>>>>works.  Both components (A & B) implement PageRenderListener and
>>>>define a pageBeginRender(PageEvent event) method (this is where I
>>>>attempt get a handle of the cookie).  I've added some debugging
>>>>output to these methods and the results are a bit puzzling.
>>>>
>>>>After first action is invoked, the order goes something like this:
>>>>
>>>>- Component A: pageBeginRender() is fired
>>>>- Component B: pageBeginRender() is fired
>>>>- Cookie is written
>>>>- Component A: pageBeginRender() is fired (2nd time)
>>>>- Component B: pageBeginRender() is fired (2nd time)
>>>>- Attempt to retrieve cookie returns null
>>>>- Component A: pageBeginRender() is fired (3rd time)
>>>>- Component B: pageBeginRender() is fired (3rd time)
>>>>- Additional attempt to retrieve cookie returns null
>>>>- Next page renders.
>>>>
>>>>The any additional request, the cycle's path seems much simpler:
>>>>
>>>>- Component A: pageBeginRender() is fired
>>>>- Component B: pageBeginRender() is fired
>>>>- Cookie successfully returns
>>>>
>>>>Anyone have any advice on what's going on here?
>>>>
>>>>Thanks,
>>>>Eric
>>>>
>>>>
>>>>
>>>>
>>>>---------------------------------------------------------------------
>>>>To unsubscribe, e-mail: [hidden email]
>>>>For additional commands, e-mail: tapestry-user-
>>>>[hidden email]
>>>>
>>>>
>>>>
>>>>
>>>
>>>---------------------------------------------------------------------
>>>To unsubscribe, e-mail: [hidden email]
>>>For additional commands, e-mail: [hidden email]
>>>
>>
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tapestry's Simplicity Blues

Ben Eng
In reply to this post by Erik Hatcher
On Wed, May 11, 2005 at 07:59:23PM -0400, Erik Hatcher wrote:

>
> On May 11, 2005, at 5:02 PM, Ben Eng wrote:
>
> >On Wed, May 11, 2005 at 11:36:39AM -0400, Erik Hatcher wrote:
> >
> >You don't like how I implemented events before and after listener
> >invocation?
> >
> >  http://issues.apache.org/jira/browse/TAPESTRY-294
>
> To be honest, I had forgotten about your patch.
>
> In your terms my post-listener  
> event is fired only if the original listener succeed without thrown  
> an exception or if throws Page/RedirectException.  I don't think an  
> "after" listener event could be coded in your contribution to do  
> that.  Please correct me if I'm wrong.

The "after" listener event is fired in a finally, so it should be
ok. Perhaps it would be worthwhile catching any exception and passing
it in the event.

Ben

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tapestry's Simplicity Blues

Erik Hatcher

On May 12, 2005, at 9:43 PM, Ben Eng wrote:

>> In your terms my post-listener
>> event is fired only if the original listener succeed without thrown
>> an exception or if throws Page/RedirectException.  I don't think an
>> "after" listener event could be coded in your contribution to do
>> that.  Please correct me if I'm wrong.
>>
>
> The "after" listener event is fired in a finally, so it should be
> ok. Perhaps it would be worthwhile catching any exception and passing
> it in the event.

But that isn't ok in my use-case.  I do not want the after listener  
fired in the event of an error.  However, there are two exceptions  
which are not errors - PageRedirectException and RedirectException.    
See what I mean?

Alternatively, as you mention if the after event could be given the  
exception to base its behavior on, that would also work in my case.

Again, it's ultimately up to Howard on whether your approach is the  
right fit for 4.0 or not.  It would seem that a HiveMind interceptor  
scheme would be a more integrated fit for 4.0.

     Erik


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tapestry's Simplicity Blues

Pablo Ruggia
In reply to this post by Patrick Casey
On 5/12/05, Patrick Casey <[hidden email]> wrote:

>
>
> > -----Original Message-----
> > From: Howard Lewis Ship [mailto:[hidden email]]
> > Sent: Thursday, May 12, 2005 9:11 AM
> > To: Tapestry users
> > Subject: Re: Tapestry's Simplicity Blues
> >
> > Wish I had had the foresight five years ago to build in explicit
> > support for a visual builder.
> >
> > 4.0 is adding flexibility to store state in many places, currently in
> > the session (as in 3.0) but also as query parameters / hidden form
> > fields.  Further nuances will likely be possible in the future as well
> > ... I'd like to see support for WebObjects style state storage, where
> > multiple versions of the property are stored on the server, and the
> > client includes query parameter to select which version was in effect
> > when the page rendered.
> <snip>
>
> I actually rolled a (primitive) version of the functionality you're
> describing last week. Each of my pages now has "base" properties and
> "persistent" properties. All persistent properties aren't stored in the page
> object, but rather in an attached persistent object e.g.
>
> Public class foo extends BasePage {
>
> Private FormProperties fPersistentProperties;
> Private String fSomeNonPersistentString
>
> Public String getSomePersistentProperty() {
>         Return fPersistentProperties.getSomePersistentProperty();
> }
>
> Then the when the page starts rendering I generate a unique key for this
> particular page rendering and stuff it into the page as it renders. After
> page render I then drop the persistent properties into a linked hashmap in
> the visit object, using the previously generated key.
>
> Then, whenever any link or button on the aforementioned form is clicked on
> the client, I bootstrap the page back into the appropriate state by yanking
> the persistent properties out of the visit object by way of the key.
>
> It seems to be working fine for me, although it's a wee bit expensive on the
> memory front, burning about 200 bytes per page render, so I had to put a cap
> on the number of pages I remember per user and only keep around the last 100
> pages per user. If the user clicks a link that references a page that's been
> flushed, I just throw a stale link.
>
> The specific code's pretty closely linked to my particular implementation,
> but the approach might work in a more general case approach.
>
> --- Pat
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

I'm doing something similar, I like this aproach. But i'm really
afraid of how much memory it will eat up, and I can't estimate what a
reasonable limit of pages to save is.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tapestry's Simplicity Blues

Bryan Lewis
The old WebObjects backtracking feature (a similar concept) kept only the
last 30 pages by default.  If the user got too busy with the back button
he'd get an error page "You backtracked too far."


----- Original Message -----
From: "Pablo Ruggia" <[hidden email]>
To: "Tapestry users" <[hidden email]>
Sent: Tuesday, May 17, 2005 1:01 AM
Subject: Re: Tapestry's Simplicity Blues


On 5/12/05, Patrick Casey <[hidden email]> wrote:

>
>
> > -----Original Message-----
> > From: Howard Lewis Ship [mailto:[hidden email]]
> > Sent: Thursday, May 12, 2005 9:11 AM
> > To: Tapestry users
> > Subject: Re: Tapestry's Simplicity Blues
> >
> > Wish I had had the foresight five years ago to build in explicit
> > support for a visual builder.
> >
> > 4.0 is adding flexibility to store state in many places, currently in
> > the session (as in 3.0) but also as query parameters / hidden form
> > fields.  Further nuances will likely be possible in the future as well
> > ... I'd like to see support for WebObjects style state storage, where
> > multiple versions of the property are stored on the server, and the
> > client includes query parameter to select which version was in effect
> > when the page rendered.
> <snip>
>
> I actually rolled a (primitive) version of the functionality you're
> describing last week. Each of my pages now has "base" properties and
> "persistent" properties. All persistent properties aren't stored in the
page

> object, but rather in an attached persistent object e.g.
>
> Public class foo extends BasePage {
>
> Private FormProperties fPersistentProperties;
> Private String fSomeNonPersistentString
>
> Public String getSomePersistentProperty() {
>         Return fPersistentProperties.getSomePersistentProperty();
> }
>
> Then the when the page starts rendering I generate a unique key for this
> particular page rendering and stuff it into the page as it renders. After
> page render I then drop the persistent properties into a linked hashmap in
> the visit object, using the previously generated key.
>
> Then, whenever any link or button on the aforementioned form is clicked on
> the client, I bootstrap the page back into the appropriate state by
yanking
> the persistent properties out of the visit object by way of the key.
>
> It seems to be working fine for me, although it's a wee bit expensive on
the
> memory front, burning about 200 bytes per page render, so I had to put a
cap
> on the number of pages I remember per user and only keep around the last
100
> pages per user. If the user clicks a link that references a page that's
been

> flushed, I just throw a stale link.
>
> The specific code's pretty closely linked to my particular implementation,
> but the approach might work in a more general case approach.
>
> --- Pat
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

I'm doing something similar, I like this aproach. But i'm really
afraid of how much memory it will eat up, and I can't estimate what a
reasonable limit of pages to save is.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

12