You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Andreas Pardeike <an...@pardeike.net> on 2005/01/06 20:24:46 UTC

I'm lost - contrib:TableView fails on subsequent pages

Hello mighty list,

I have now searched and tested my guts in and out and I cannot track the
following problem down. What I have and did so far:

My goal is to have a generic table component that I only feed a cayenne
select query and the basic table parameters and it should do the rest.

I got the table working (including overwriting some contrib html to  
style
it my way) and so I placed it into my own component that I then put on a
page. It works fine and displays the table as it should (including  
populating
it with the query result as I want) but only for the initial page. As  
soon
as I click on a page number or sort a column, it throws a

## Either the tableModel parameter or both source and columns parameters
## must be specified by component Home/t1.table

Here are all relevant parts of what I did. If someone could give me a  
tip on
what might be wrong. When the table was not in its own component it just
worked fine including all its functions.

Home.html ------------------------------------------------------------

<html jwcid="@Border">
	<table jwcid="t1@FSGenericTable"
		source="ognl:source1"
		columns="artikelNummer, titel, forfattare, bandTyp, pris, lagerNummer"
		pageSize="10"
		pagesDisplayed="15"
		initialSortColumn="titel"/>
</html>


Home.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">

<page-specification class="Fsys.Pages.Home">

	<property-specification name="source1"
		type="java.lang.Object"
		initial-value="new Fsys.Models.FSGenericTableModel(getPage(),  
'query1')"
		persistent="yes"/>
	
</page-specification>


Home.java ------------------------------------------------------------

package Fsys.Pages;

import java.util.HashMap;
import java.util.Map;

import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.html.BasePage;
import org.objectstyle.cayenne.exp.Expression;
import org.objectstyle.cayenne.query.SelectQuery;

import Fsys.Cayenne.Artjoina;

public class Home extends BasePage
{
	public SelectQuery getQuery1()
	{
		Expression qual =  
Expression.fromString(Artjoina.ARTIKEL_GRUPP_PROPERTY +
				" = $grupp  and " + Artjoina.TITEL_PROPERTY + " like $titel");
		
		SelectQuery proto = new SelectQuery(Artjoina.class, qual);
		Map params = new HashMap();
		params.put("grupp", "BW");
		params.put("titel", "Om%");
		return proto.queryWithParameters(params);
	}
}


FSGenericTable.html -------------------------------------------------

<table jwcid="table" cellspacing="0" cellpadding="2" border="0"  
class="table">
	<tr>
		<td jwcid="@contrib:TableColumns" class="tableheader"/>
	</tr>
	<tr jwcid="@contrib:TableRows" class="ognl:beans.evenOdd.next">
		<td jwcid="@contrib:TableValues"/>
	</tr>
	<tr class="navigation">
		<td jwcid="@Any" colspan="ognl:columnCount" align="center">
			<span jwcid="pages"/>
		</td>
	</tr>
</table>


FSGenericTable.jwc ---------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE component-specification PUBLIC
   "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
   "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">

<component-specification class="Fsys.Components.FSGenericTable"
	allow-body="no"
	allow-informal-parameters="yes">
	
	<parameter name="source"
		type="java.lang.Object" required="yes" direction="in"/>
	
	<parameter name="columns"
		type="java.lang.String" required="yes" direction="in"/>
	
	<parameter name="initialSortColumn"
		type="java.lang.String" required="no" default-value="null"/>
	
	<parameter name="pageSize"
		type="int" required="no" default-value="20"/>
	
	<parameter name="pagesDisplayed"
		type="int" required="no" default-value="15"/>
	
	<component id="table" type="contrib:TableView">
		<inherited-binding name="source" parameter-name="source"/>
		<binding name="columns" expression="columns"/>
		<binding name="columnCount" expression="columnCount"/>
		<inherited-binding name="pageSize" parameter-name="pageSize"/>
		<inherited-binding name="initialSortColumn"  
parameter-name="initialSortColumn"/>
	</component>
	
	<component id="pages" type="contrib:TablePages">
		<inherited-binding name="pagesDisplayed"  
parameter-name="pagesDisplayed"/>
	</component>
	
	<bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/>
	
</component-specification>


FSGenericTable.java --------------------------------------------------

package Fsys.Components;

import java.util.regex.Pattern;
import org.apache.tapestry.BaseComponent;

public abstract class FSGenericTable extends BaseComponent
{
	static Pattern p = Pattern.compile(",");
	
	private String[] _columns;
	private String _columnStr;
	
	public String getColumns()
	{
		return _columnStr;
	}
	
	public void setColumns(String columns)
	{
		_columns = p.split(columns);
		_columnStr = "";
		for(int i = 0; i < _columns.length; i++)
		{
			_columns[i] = _columns[i].trim();
			String name = getPage().getMessage(_columns[i]);
			if(name == null)
				name = _columns[i];
			
			_columnStr += _columns[i] + ":" +
				getPage().getMessage(_columns[i]) + ":" + _columns[i] + ",";
		}
		_columnStr = _columnStr.substring(0, _columnStr.length() - 1);
	}
	
	public int getColumnCount()
	{
		return _columns.length;
	}
}


FSGenericTableModel.java --------------------------------------------

package Fsys.Models;

import java.util.*;

import org.apache.tapestry.IPage;
import org.apache.tapestry.contrib.table.model.IBasicTableModel;
import org.apache.tapestry.contrib.table.model.ITableColumn;
import org.objectstyle.cayenne.query.Ordering;
import org.objectstyle.cayenne.query.SelectQuery;

import Fsys.Cayenne.Artjoina;
import Fsys.Common.Visit;

public class FSGenericTableModel implements IBasicTableModel
{
	private IPage page;
	private String propName;
	private List result = null;
	private int resultSize = -1;
	private String lastSort = "";
	private boolean lastSortOrder;
	
	public FSGenericTableModel(Object o, String param)
	{
		page = (IPage)o;
		propName = param;
	}
	
	private void PerformQuery(int rowsPerPage, String sortBy, boolean  
sortOrder)
	{
		boolean needsRefresh = (rowsPerPage == 0);
		if((sortBy == null || lastSort == null) && sortBy != lastSort)
			needsRefresh = true;
		if(sortBy != null && lastSort != null && !lastSort.equals(sortBy))
			needsRefresh = true;
		if(sortOrder != lastSortOrder)
			needsRefresh = true;
		
		if(needsRefresh)
		{
			SelectQuery query = (SelectQuery)page.getProperty(propName);
			if(query != null)
			{
				query.setPageSize(rowsPerPage);
				if(sortBy != null)
					query.addOrdering(new Ordering(sortBy, sortOrder ?
										Ordering.DESC : Ordering.ASC));
				
				result = ((Visit)page.getVisit()).getDataContext().
												performQuery(query);
				if(rowsPerPage > 0)
				{
					lastSort = sortBy;
					lastSortOrder = sortOrder;
				}
			}
			else
				result = null;
		}
	}
	
	public int getRowCount()
	{
		if(resultSize == -1)
		{
			PerformQuery(1, null, false);
			if(result != null)
				resultSize = result.size();
			else
				resultSize = 0;
		}
		return resultSize;
	}
	
	public Iterator getCurrentPageRows(int firstRow, int rowsPerPage,
						ITableColumn sortColumn, boolean sortOrder)
	{
		String sortBy = null;
		if(sortColumn != null)
			sortBy = sortColumn.getColumnName();
		
		PerformQuery(rowsPerPage, sortBy, sortOrder);
		
		List pageResult = new ArrayList();
		if(result != null)
		{
			int max = firstRow + rowsPerPage;
			if(max > result.size())
				max = result.size();
			for(int i = firstRow; i < max; i++)
				pageResult.add((Artjoina)result.get(i));
		}
		return pageResult.iterator();
	}
}


------------------------------------------------------------------------ 
-------

Error when clicking on any link or page number on the table. URL shown  
when
the error occurs (initial URL was http://localhost:8080/fsys/app):

http://localhost:8080/fsys/app?service=direct/1/Home/ 
t1.pages.linkPage&sp=AHome%2Ft1.table&sp=2


An exception has occurred.

You may continue by restarting the session.

org.apache.tapestry.ApplicationRuntimeException
Either the tableModel parameter or both source and columns parameters  
must be specified by component Home/t1.table
Stack Trace:

     *  
org.apache.tapestry.contrib.table.components.TableView.getTableModel(Tab 
leView.java:199)
     *  
org.apache.tapestry.contrib.table.components.TablePages.setCurrentPage(T 
ablePages.java:192)
     *  
org.apache.tapestry.contrib.table.components.TablePages.changePage(Table 
Pages.java:184)
     * sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     *  
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav 
a:39)
     *  
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor 
Impl.java:25)
     * java.lang.reflect.Method.invoke(Method.java:324)
     *  
org.apache.tapestry.listener.ListenerMap.invokeTargetMethod(ListenerMap. 
java:257)
     *  
org.apache.tapestry.listener.ListenerMap.access$100(ListenerMap.java: 
46)
     *  
org.apache.tapestry.listener.ListenerMap$SyntheticListener.invoke(Listen 
erMap.java:97)
     *  
org.apache.tapestry.listener.ListenerMap$SyntheticListener.actionTrigger 
ed(ListenerMap.java:102)
     * org.apache.tapestry.link.DirectLink.trigger(DirectLink.java:119)
     *  
org.apache.tapestry.engine.DirectService.service(DirectService.java: 
169)
     *  
org.apache.tapestry.engine.AbstractEngine.service(AbstractEngine.java: 
872)
     *  
org.apache.tapestry.ApplicationServlet.doService(ApplicationServlet.java 
:197)
     *  
org.apache.tapestry.ApplicationServlet.doGet(ApplicationServlet.java: 
158)
     * javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
     * javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
     *  
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica 
tionFilterChain.java:247)
     *  
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt 
erChain.java:193)
     *  
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValv 
e.java:256)
     *  
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.i 
nvokeNext(StandardPipeline.java:643)
     *  
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java: 
480)
     *  
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
     *  
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValv 
e.java:191)
     *  
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.i 
nvokeNext(StandardPipeline.java:643)
     *  
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java: 
480)
     *  
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
     *  
org.apache.catalina.core.StandardContext.invoke(StandardContext.java: 
2422)
     *  
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java 
:180)
     *  
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.i 
nvokeNext(StandardPipeline.java:643)
     *  
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherVa 
lve.java:171)
     *  
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.i 
nvokeNext(StandardPipeline.java:641)
     *  
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java 
:163)
     *  
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.i 
nvokeNext(StandardPipeline.java:641)
     *  
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java: 
480)
     *  
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
     *  
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve. 
java:174)
     *  
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.i 
nvokeNext(StandardPipeline.java:643)
     *  
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java: 
480)
     *  
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
     *  
org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:199)
     *  
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java: 
828)
     *  
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processC 
onnection(Http11Protocol.java:700)
     *  
org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java: 
584)
     *  
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool 
..java:683)
     * java.lang.Thread.run(Thread.java:552)

Regards,
Andreas Pardeike


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: I'm lost - contrib:TableView fails on subsequent pages (SOLVED, but why?)

Posted by Andreas Pardeike <an...@pardeike.net>.
On 6 jan 2005, at 20.24, Andreas Pardeike wrote:

> I have now searched and tested my guts in and out and I cannot track 
> the
> following problem down. What I have and did so far:
>
> My goal is to have a generic table component that I only feed a cayenne
> select query and the basic table parameters and it should do the rest.
>
> I got the table working (including overwriting some contrib html to 
> style
> it my way) and so I placed it into my own component that I then put on 
> a
> page. It works fine and displays the table as it should (including 
> populating
> it with the query result as I want) but only for the initial page. As 
> soon
> as I click on a page number or sort a column, it throws a
>
> ## Either the tableModel parameter or both source and columns 
> parameters
> ## must be specified by component Home/t1.table

I've solved my own problem but I am still unclear WHY this actually 
solves
the problem and why I have to fix this in first place.

The fix was to change the method

	public String getColumns()
	{
		return _columnStr;
	}

to

	public String getColumns()
	{
		if(_columnStr == null)
			return "";
		return _columnStr;
	}

inside FSGenericTable.java. Seems like this returns null somewhere 
in-between
the page preparation and TableView does not like this. Returning an 
empty
column definition string fixes it because (at it seems) the final 
request for
the columns parameter seems to return the correct string and that makes 
the
table show up correctly.

Why is that so?

Regards,
Andreas Pardeike


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org