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]