Quote from "Tapestry in Action" book by Howard L. Ship, p.308:

"Declared properties, both persistent and transient, may also have an
initial value. <... omitted... > The initial value is an OGNL expression.
The expression is evaluated just once, after the page's (or component's)
finishLoad() method is invoked. The value for the expression is used to set
the property, but it is also saved and used later to update the property
when the page is detached from the request, before being stored into the
page pool for later reuse."

Now, my (real) page properties are: the service object that knows how to
retrieve certain data (a product list), and the actual retrieved data. Both
the service object, and the data it returns, are considered "read-mostly" -
that is, they don't change often and can be considered static. Thus I put
them into properties, and assign an initial value that I know shouldn't (and
won't) change. And, of course, I don't change these properties during the
page render.

My goal is to have the properties having the same values every time page is
loaded from the pool - so the properties are set 1) on initial page creation
and 2) every time they are going into the pool - exactly what is described
(prescribed?) in the book. How's that for an "incorrect usage" of this
feature? To me, I'm trying to use it for exactly what it was designed for.
The problem here is that it's implemented in a doubtful way. 

Now, thanks for the PageRenderListener suggestion, I'll definitely try that,
but to me, this "feature" warrants a bug report. I'd like the developers to
comment on that, though.

My proposed way of fixing it would be - in
PageLoader.establishDefaultPropertyValues() make it looping over the same
list over and over, and keep count of updated properties on each pass, as
well as the total # of properties updated. Something like that (my additions
marked with ">") :

>int totalUpdated = 0;
>int updated = 0;
>int lastUpdated = -1; // anything that's not 0
int count = _propertyInitializers.size();
>while (totalUpdated < count) {
        for (int i = 0; i < count; i++) {
                PageDetachListener initializer = (PageDetachListener)
_propertyInitializers.get(i);
>               try {
                        initializer.pageDetached(null);
>                       updated++;
>               } catch (Exception e) {
>                       if (lastUpdated == 0) {
>                               throw e;
>                       }
>               }
        }
>       totalUpdated += updated;
>       lastUpdated = updated;
>       updated = 0;
>}

Loop can be exited either when a) all properties are updated or b) when we
haven't updated anything in last pass, and an exception is thrown - meaning
we have an unresolvable reference on our hands.

-- Alex

-----Original Message-----
From: Jamie Orchard-Hays [mailto:[EMAIL PROTECTED] 
Sent: Thursday, August 11, 2005 11:45 AM
To: Tapestry users
Subject: Re: Tapestry 3.0.3 - property initialization sequence


You're not using this feature correctly. It's for the state of the  
property when it's returned to the page pool, not for when you use it  
on the page.

Implement PageRenderListener in your Java file, then implement  
pageBeginRender() and initialize your variables there. You'll be able  
to get the proper sequence happening.

Jamie


On Aug 11, 2005, at 10:49 AM, Savitsky, Alex wrote:

> So far it has always been alphabetic, but point taken. Still, if
> the order
> of initialization is pretty much undefined - is there a reliable  
> way to
> specify page properties that depend one on another?
>
> -- Alex
>
> -----Original Message-----
> From: Patrick Casey [mailto:[EMAIL PROTECTED]
> Sent: Thursday, August 11, 2005 10:45 AM
> To: 'Tapestry users'
> Subject: RE: Tapestry 3.0.3 - property initialization sequence
>
>
>
>     I've got $0.25 that says it's probably some variable on a hashmap 
> internally, so I wouldn't count on it always being alphabetic,
> although you
> could pretty much assume it won't happen in the same order they're  
> on the
> page :).
>
>     --- Pat
>
>
>> -----Original Message-----
>> From: Savitsky, Alex [mailto:[EMAIL PROTECTED]
>> Sent: Thursday, August 11, 2005 7:33 AM
>> To: '[email protected]'
>> Subject: Tapestry 3.0.3 - property initialization sequence
>>
>> Hi,
>>
>> Found a funny quirk in the way page properties are initialized, that 
>> can possibly lead to exceptions:
>>
>> Test.page:
>> <?xml version="1.0" encoding="UTF-8"?>
>> <!DOCTYPE page-specification
>>       PUBLIC "-//Apache Software Foundation//Tapestry Specification 
>> 3.0//EN"
>>       "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd
>> <http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd> "> 
>> <page-specification class="org.apache.tapestry.html.BasePage">
>>     <property-specification name="p2" 
>> type="java.lang.Integer">1</property-specification>
>>     <property-specification name="p1"
>> type="java.lang.Integer">p2.intValue() + 1</property-specification> 
>> </page-specification>
>>
>> Load the page, get an NPE. Reason? I went in with a debugger to
>> check,
>> and it looks like the properties are initialized in alphabetic order
>> (so that "p1" is initialized BEFORE "p2"). Swap the variable names  
>> (so
>> that "p2" depend on "p1", instead of the other way around), and the
>> page loads fine.
>>
>> Am I missing something, or it is really being done that way? In this 
>> case, is it really the best way to handle that? Wouldn't a some sort 
>> of endless loop be better, so that initialization of "dependent" 
>> properties could be deferred until their "parent" properties are 
>> initialized?
>>
>> I haven't tried Tapestry 4 yet, does anyone know, was that... m-m-
>> m...
>> "feature" fixed there?
>>
>> Regards,
>>
>> Alex Savitsky
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to