Philippe,

The problem you are seeing is not related to properties being initialized out 
of order. The @If component only evaluates its condition during render and 
saves the result in a hidden form field. When the form rewinds, it uses the 
value saved during render. In your case, the myProp != null condition is only 
evaluated during render (and is probably true at that time). During rewind, the 
@If condition is still true no matter what the value of myProp is.

To fix this, you need to add a volative=true parameter to the @If component, to 
force it to evaluate its condition at all times. But then you might get 
StaleLinkException problems...

Another way is to derive your own GenericLink component, that doesn't render 
during rewind:
    protected void renderComponent(IMarkupWriter writer,
                                   IRequestCycle cycle)
    {
+       if (cycle.isRewinding())
+               return;
        getRenderer().renderLink(writer, cycle, this);
    }

Hope this helps,

Raphael Jean
EntropySoft

> -----Original Message-----
> From: news [mailto:[EMAIL PROTECTED] On Behalf Of Philippe Joly
> Sent: vendredi 10 février 2006 16:02
> To: [email protected]
> Subject: Tapestry 4 rewind system : what the hell ??
> 
> Hi,
> 
> Using Tapestry 4 and Tomcat 5, I have seen that "sometimes" tapestry
> behaviour
> can be very strange.
> 
> I can show you an example of a code embedded in a If which is executed
> even if
> the If condition is false !
> (In fact, a component is evaluated before its parent components)
> 
> Example :
> 
> <span jwcid="@If" condition="ognl:myProp != null">
>   it is in theory not possible to have myProp null here...
>   (assuming myProp is not modified by another thread in the same time)
> </span>
> 
> 
> This always works fine :
> 
> <span jwcid="@If" condition="ognl:myProp != null">
>   <span jwcid="@Insert"
>         value="ognl:'http://www.google.com?'+ myProp.something" />
> </span>
> 
> 
> But this can fail with error source is null for getProperty(null,
> "something") :
> 
> <span jwcid="@If" condition="ognl:myProp != null">
>   <a jwcid="@GenericLink"
>       href="ognl:'http://www.google.com?'+ myProp.something" />
> </span>
> 
> That means that sometimes (and it could depend on components you are
> using) the
> order of the sequence of the properties initialisation is not always the
> same.
> Un enclosed component may be evaluated BEFORE its parent component.
> That  seems crazy to me.
> 
> Indeed, in a For, you expect the current element of the loop to be set
> before executing the code inside the loop.
> 
> I have created some quick and dirty example files (no database needed)
> to reproduce that problem.
> 
> By default, the page works.
> But if you uncomment the GenericLink in Strange.html (line 70).
> Then you get an error when you change the value of the first select.
> 
> 
> My real need is to generate a GenericLink using a propery of the current
> element
> of a For.
> In my application, it always works fine. But when I use the Back button,
> and if the previous page was generated by a form.refresh,
> then I get this stupid exception when I try to submit the page again.
> 
> Any idea / comment ?
> 
> Thank you
> Philippe
> 
> ---------------- Strange.html ----------------------------------------
> <?xml version="1.0" encoding="iso-8859-1"?>
> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
>     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
> <html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">
>       <head>
>               <title>Tapestry rewind system, you little !!</title>
>               <script type="text/javascript">
>                       <!--
>                       function displayWaitMessage()
>                       {
>                               var filterDiv =
> document.getElementById("filterDiv");
>                               var waitDiv   =
> document.getElementById("waitDiv");
> 
>                       filterDiv.style.display = "none";
>                               waitDiv.style.display   = "block";
>                       }
>                       // -->
>               </script>
>       </head>
>       <body jwcid="@Body">
>               <form jwcid="userForm">
>                       Filters : <br/>
>                       <select id ="selAgency"
>                               jwcid="agencySelect"
>                                       onchange="displayWaitMessage();
> this.form.events.refresh()"
>                       />
>                       <div id="filterDiv">
>                               <select id ="selSubAgency"
>                                       jwcid="subAgencySelect"
>                               />
>                               <br/>
>                               <input  type ="submit"
>                                       class    ="button"
>                                       title    ="Search"
>                                       value    ="Search"
>                                       jwcid    ="searchButton" />
>                       </div>
>                       <div id="waitDiv" style="display:none">
>                               Please wait...
>                       </div>
>                       <br/>
>                       <br/>
>                       <table title="List of users" cellpadding="10"
>                              style="border-style:solid; border-size:1px">
>                               <caption>Users</caption>
>                               <thead>
>                                       <tr>
>                                               <th>User Id</th>
>                                               <th>User Name</th>
>                                               <th>Agency</th>
>                                               <th>Sub-Agency</th>
>                                               <th>An url</th>
>                                       </tr>
>                               </thead>
>                               <tbody>
>                                       <tr jwcid="@For"
>                                           source="ognl:users"
>                                           value="ognl:user"
>                                           index="ognl:index"
>                                           element="tr"
>                                           keyExpression="id">
>                                               <span jwcid="@If" 
> condition="ognl:user
> != null">
>                                                       <td>
>                                                               <span 
> jwcid="@Insert"
> value="ognl:user.id" />
>                                                       </td>
>                                                       <td>
>                                                               <span 
> jwcid="@Insert"
> value="ognl:user.name" />
>                                                       </td>
>                                                       <td>
>                                                               <span 
> jwcid="@Insert"
> value="ognl:user.agency.name" />
>                                                       </td>
>                                                       <td>
>                                                               <span 
> jwcid="@Insert"
> value="ognl:user.subAgency.name" />
>                                                       </td>
>                                                       <td>
> <!--  HERE              <a jwcid="@GenericLink"
>                             href="ognl:'http://www.google.com?'+ user.id"
> />
> -->
>                                                               <a 
> jwcid="@Insert"
> 
> value="ognl:'http://www.google.com?'+ user.id" />
>                                                       </td>
>                                               </span>
>                                               <span jwcid="@Else">
>                                                       <td colspan="5">Current 
> user is
> null !!</td>
>                                               </span>
>                                       </tr>
>                               </tbody>
>                       </table>
>               </form>
>       </body>
> </html>
> 
> ---------------- Strange.page ----------------------------------------
> 
> <?xml version="1.0"?>
> <!DOCTYPE page-specification PUBLIC
> "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
> "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd";>
> <page-specification class="Strange">
> 
>       <property name="index" />
>       <property name="user" />
> 
>       <component id="userForm" type="Form">
>               <binding name="refresh" value="listener:onRefreshForm"/>
>       </component>
> 
>       <component id="agencySelect" type="PropertySelection">
>           <binding name="model" value="agencySelect"/>
>           <binding name="value" value="currentSelectedAgency"/>
>       </component>
> 
>       <component id="subAgencySelect" type="PropertySelection">
>           <binding name="model" value="subAgencySelect"/>
>           <binding name="value" value="currentSelectedSubAgency"/>
>       </component>
> 
>     <component id ="searchButton" type="Submit">
>               <binding name="listener" value="listener:onSearch"/>
>       </component>
> 
> 
> </page-specification>
> 
> ---------------- Strange.java ----------------------------------------
> import java.util.ArrayList;
> import java.util.List;
> 
> import org.apache.tapestry.IExternalPage;
> import org.apache.tapestry.IPage;
> import org.apache.tapestry.IRequestCycle;
> import org.apache.tapestry.engine.IEngineService;
> import org.apache.tapestry.form.IPropertySelectionModel;
> import org.apache.tapestry.html.BasePage;
> 
> public abstract class Strange extends BasePage implements IExternalPage {
>       public abstract List getUsers();
>       public abstract void setUsers(List users);
> 
>       public IPage onSearch() {
>               System.out.println("onSearch");
>               List users = StrangeUser.getUsers(getCurrentSelectedAgency(),
> 
> getCurrentSelectedSubAgency());
>               setUsers(users);
>               return null;
>       }
> 
>       public void onRefreshForm() {
>               System.out.println("onRefreshForm");
>       }
> 
>       public void activateExternalPage(Object[] arg0, IRequestCycle arg1)
> {
>               System.out.println("activateExternalPage");
>       }
> 
>       public abstract Agency getCurrentSelectedAgency();
>       public abstract SubAgency getCurrentSelectedSubAgency();
> 
>       public IPropertySelectionModel getAgencySelect() {
>               final List agencies = new ArrayList();
>               agencies.addAll(Agency.getAgencies());
> 
>               Agency ALLSpecialItem = new Agency("*", "ALL");
>               agencies.add(0, ALLSpecialItem);
> 
>               IPropertySelectionModel model = new IPropertySelectionModel()
> {
>                       public String getLabel(int arg0) {
>                               Agency agency = (Agency) agencies.get(arg0);
>                               return agency.getName();
>                       }
> 
>                       public Object getOption(int arg0){
>                               return agencies.get(arg0);
>                       }
> 
>                       public int getOptionCount(){
>                               return agencies.size();
>                       }
> 
>                       public String getValue(int arg0){
>                               Agency agency = (Agency) agencies.get(arg0);
>                               return agency.getId();
>                       }
> 
>                       public Object translateValue(String arg0)       {
>                               Agency result = null;
>                               for(int i=0; i<agencies.size() && result==null;
> i++) {
>                                       Agency agency = (Agency) 
> agencies.get(i);
>                                       if(agency.getId().equals(arg0)) result =
> agency;
>                               }
>                               return result;
>                       }
>               };
>               return  model;
> 
>       }
> 
>       public IPropertySelectionModel getSubAgencySelect() {
>               final List subAgencies = new ArrayList();
> 
>               Agency agency = getCurrentSelectedAgency();
>               if(agency != null && !agency.getId().equals("*")) {
>                       subAgencies.addAll(SubAgency.getSubAgencies(agency));
>               }
> 
>               SubAgency ALLSpecialItem = new SubAgency("*", "ALL", null);
>               subAgencies.add(0, ALLSpecialItem);
> 
>               IPropertySelectionModel model = new IPropertySelectionModel()
> {
>                       public String getLabel(int arg0) {
>                               SubAgency sa = (SubAgency) 
> subAgencies.get(arg0);
>                               return sa.getName();
>                       }
> 
>                       public Object getOption(int arg0) {
>                               return subAgencies.get(arg0);
>                       }
> 
>                       public int getOptionCount() {
>                               return subAgencies.size();
>                       }
> 
>                       public String getValue(int arg0) {
>                               SubAgency sa = (SubAgency) 
> subAgencies.get(arg0);
>                               return sa.getId();
>                       }
> 
>                       public Object translateValue(String arg0) {
>                               SubAgency result = null;
>                               for(int i=0; i<subAgencies.size() && 
> result==null;
> i++) {
>                                       SubAgency sa = (SubAgency)
> subAgencies.get(i);
>                                       if(sa.getId().equals(arg0)) result = sa;
>                               }
>                               return result;
>                       }
>               };
>               return  model;
>       }
> }
> 
> ---------------- Agency.java ----------------------------------------
> 
> import java.io.Serializable;
> import java.util.ArrayList;
> import java.util.List;
> 
> public class Agency implements Serializable {
> 
>       private static final long serialVersionUID      =
> 8980683753741373155L;
> 
>       private static List agencies = new ArrayList();
> 
>       static {
>               agencies.add(new Agency("0", "Agency 0"));
>               agencies.add(new Agency("1", "Agency 1"));
>               agencies.add(new Agency("2", "Agency 2"));
>               agencies.add(new Agency("3", "Agency 3"));
>       }
> 
>       public static List getAgencies() {
>               return agencies;
>       }
> 
>       private String id;
>       private String name;
> 
>       public Agency() {
>               super();
>       }
> 
>       public Agency(String id, String name) {
>               super();
>               this.id = id;
>               this.name = name;
>       }
> 
> 
>       public String getId() { return id; }
>       public void setId(String id) { this.id = id; }
> 
>       public String getName() { return name; }
>       public void setName(String name) { this.name = name; }
> 
> }
> 
> ---------------- SubAgency.java ---------------------------------------
> 
> import java.io.Serializable;
> import java.util.ArrayList;
> import java.util.List;
> 
> public class SubAgency extends Agency implements Serializable
> {
>       private static final long       serialVersionUID        = -
> 6067658180311656578L;
> 
>       private Agency parentAgency;
> 
>       private static SubAgency[]      subAgencies     = {
>  new SubAgency("0.0", "Sub Agency 0.0", (Agency)
> Agency.getAgencies().get(0)),
>  new SubAgency("0.1", "Sub Agency 0.1", (Agency)
> Agency.getAgencies().get(0)),
>  new SubAgency("1.0", "Sub Agency 1.0", (Agency)
> Agency.getAgencies().get(1)),
>  new SubAgency("1.1", "Sub Agency 1.1", (Agency)
> Agency.getAgencies().get(1)),
>  new SubAgency("1.2", "Sub Agency 1.2", (Agency)
> Agency.getAgencies().get(1)),
>  new SubAgency("2.0", "Sub Agency 2.0", (Agency)
> Agency.getAgencies().get(2)),
>  new SubAgency("2.1", "Sub Agency 2.1", (Agency)
> Agency.getAgencies().get(2)),
>  new SubAgency("3.0", "Sub Agency 3.0", (Agency)
> Agency.getAgencies().get(3))
>                       };
> 
>       public SubAgency() {
>               super();
>       }
> 
>       public SubAgency(String id, String name, Agency parentAgency) {
>               super(id, name);
>               this.parentAgency = parentAgency;
>       }
> 
>       public static SubAgency[] getSubAgencies() { return subAgencies; }
> 
>       public static List getSubAgencies(Agency agency) {
>               List result = new ArrayList();
> 
>               for (int i = 0; agency != null && i<subAgencies.length; i++) {
>                       SubAgency subAgency = subAgencies[i];
>                       if (agency.getId().equals("*") ||
>                           subAgency.getParentAgency().equals(agency) )
>                          result.add(subAgency);
>               }
>               return result;
>       }
> 
>       public Agency getParentAgency() { return parentAgency; }
>       public void setParentAgency(Agency parentAgency) {
>               this.parentAgency = parentAgency;
>       }
> }
> 
> ---------------- StrangeUser.java ----------------------------------------
> 
> import java.util.ArrayList;
> import java.util.List;
> 
> public class StrangeUser {
>       private static final StrangeUser[] users = {
>                       new StrangeUser("idA", "User A",
> SubAgency.getSubAgencies()[2]),
>                       new StrangeUser("idB", "User B",
> SubAgency.getSubAgencies()[1]),
>                       new StrangeUser("idC", "User C",
> SubAgency.getSubAgencies()[0]),
>                       new StrangeUser("idD", "User D",
> SubAgency.getSubAgencies()[3]),
>                       new StrangeUser("idE", "User E",
> SubAgency.getSubAgencies()[3]),
>                       new StrangeUser("idF", "User F",
> SubAgency.getSubAgencies()[5])
>       };
> 
>       public static List getUsers(Agency agency, SubAgency subAgency) {
>               if(agency==null) throw new IllegalArgumentException("agency
> null");
>               if(subAgency==null) throw new
> IllegalArgumentException("subAgency null");
> 
>               List result = new ArrayList();
>               for(int i=0; i<users.length; i++) {
>                       StrangeUser user = users[i];
>                       boolean goodAgency = agency.getId().equals("*") ||
>                                            agency.equals(user.getAgency());
>                       boolean goodSubAgency = subAgency.getId().equals("*") ||
> 
> subAgency.equals(user.getSubAgency());
> 
>                       if(goodAgency && goodSubAgency) {
>                               result.add(user);
>                       }
>               }
>               return result;
>       }
> 
>       private String id;
>       private String name;
>       private Agency agency;
>       private SubAgency subAgency;
> 
>       public StrangeUser() {
>               super();
>       }
>       public StrangeUser(String id, String name, SubAgency subAgency) {
>               super();
>               this.id = id;
>               this.name = name;
>               this.agency = subAgency.getParentAgency();
>               this.subAgency = subAgency;
>       }
> 
>       public Agency getAgency() { return agency; }
>       public void setAgency(Agency agency) { this.agency = agency; }
> 
>       public String getId() { return id; }
>       public void setId(String id) { this.id = id; }
> 
>       public String getName() { return name;  }
>       public void setName(String name)        {this.name = name; }
> 
>       public SubAgency getSubAgency() { return subAgency; }
>       public void setSubAgency(SubAgency subAgency) { this.subAgency =
> subAgency; }
> }
> 
> 
> 
> ---------------------------------------------------------------------
> 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