What's new? | Help | Directory | Sign in
Google
gwt-advanced-table
GWT Advanced Table - GWT table widget supporting paging, sorting and filtering
  
  
  
  
    
Search
for
Updated Aug 20, 2007 by svetlin.nakov
TableModelService  

TableModelService

TableModelService is a service interface that provides data for displaying in a GWT AdvancedTable widget. The implementing class should provide paging, filtering and sorting as this interface specifies.

Source Code

public interface TableModelService extends RemoteService {
	public TableColumn[] getColumns();
	public int getRowsCount(DataFilter[] filters);
	public String[][] getRows(int startRow, int rowsCount,
		DataFilter[] filters, String sortColumn, boolean sortOrder);
}

Lifecycle

1) getColumns() is called by the client to populate the table columns

2) getRowsCount() is called by the client to estimate the number of available records on the server.

3) getRows() is called by the client to display a particular page (a subset of the available data)

The client call getRowsCount() and getRows() with the same filter. The implementing class can use database or other back-end as data source.


Comment by svetlin.nakov, Sep 05, 2007

This is a sample source code that you can use to bind the table to Hibernate:

// This is the Hibernate session (we assume it is open)
private Session session;


public int getRowsCount(String[] filterColumns, String[] filterValues) {
	// Create criteria for all entities, i.e. SELECT * FROM ...
	Criteria itemsCriteria = this.session.createCriteria(Item.class);

	// Apply data filters (if any), i.e. WHERE ...
	if (filterColumns != null) {
		// Check if filters are valid
		if (filterColumns.length != filterValues.length) {
			throw new IllegalArgumentException("Invalid filter!");
		}

		for (int i=0; i < filterColumns.length; i++) {
			String column = filterColumns[i];
			String value = filterValues[i];
			Criterion criterion = Expression.eq(column, value);
			itemsCriteria.add(criterion);
		}
	}
	
	// Apply row count projection, i.e. SELECT COUNT(*) ...
	itemsCriteria.setProjection(Projections.rowCount()); 

	// Return the rows count returned by the database query
	int recordsCount = (Integer) itemsCriteria.uniqueResult();
	return recordsCount;
}


@SuppressWarnings("unchecked")
public List<Item> getRows(int startRow, int rowsCount,
		String[] filterColumns, String[] filterValues, 
		String sortColumn, boolean sortOrder) {
	
	// Create criteria for all entities, i.e. SELECT * FROM ...
	Criteria itemsCriteria = this.session.createCriteria(Item.class);

	// Apply data filters (if any), i.e. WHERE ...
	if (filterColumns != null) {
		// Check if filters are valid
		if (filterColumns.length != filterValues.length) {
			throw new IllegalArgumentException("Invalid filter!");
		}

		for (int i=0; i < filterColumns.length; i++) {
			String column = filterColumns[i];
			String value = filterValues[i];
			Criterion criterion = Expression.eq(column, value);
			itemsCriteria.add(criterion);
		}
	}
	
	// Apply sorting criteria
	if (sortColumn != null) {
		Order order;
		if (sortOrder) {
			order = Order.asc(sortColumn);
		} 
		else {
			order = Order.desc(sortColumn);
		}
		itemsCriteria.addOrder(order);
	}
	
	// Apply data paging
	itemsCriteria.setFirstResult(startRow);
	itemsCriteria.setMaxResults(rowsCount);
	
	// Execute query and return results
	List<Item> items = itemsCriteria.list();
	return items;
}
Comment by svetlin.nakov, Sep 05, 2007

You may need this code also:

public class ItemsTableModelServiceImpl extends HibernateServiceImpl 
		implements TableModelService {

	private static final long serialVersionUID = 1L;

	TableColumn[] columns = { 
			new TableColumn("Title", "Title"), 
			new TableColumn("Description", "Description"),
			new TableColumn("IngestionDate", "Ingestion Date"), 
			new TableColumn("State", "State") };

	public TableColumn[] getColumns() {
		return columns;
	}

	public int getRowsCount(DataFilter[] filters) {
		ItemViewDAO itemViewDAO = new ItemViewDAO();
		String[] filterColumns = ReflectionUtils.extractFilterColumns(filters);
		String[] filterValues = ReflectionUtils.extractFilterValues(filters);
		int rowsCount = itemViewDAO.getRowsCount(filterColumns, filterValues);
		return rowsCount;
	}

	public String[][] getRows(int startRow, int rowsCount, 
			DataFilter[] filters, String sortColumn, boolean sortOrder) {
		ItemViewDAO itemViewDAO = new ItemViewDAO();
		String[] filterColumns = ReflectionUtils.extractFilterColumns(filters);
		String[] filterValues = ReflectionUtils.extractFilterValues(filters);
		List<ItemView> items = itemViewDAO.getRows(startRow, rowsCount, filterColumns, filterValues, sortColumn, sortOrder);
		String[][] tableRows = ReflectionUtils.convertToStringArray(items, this.columns);
		return tableRows;
	}

}
Comment by svetlin.nakov, Sep 05, 2007

This Hibernate session management interceptor class could also be useful:

public class HibernateServiceImpl extends RemoteServiceServlet {

	private static final long serialVersionUID = 1L;

	@Override
	public void service(ServletRequest request, ServletResponse response)
			throws ServletException, IOException {
		try {
			HibernateSessionManager.openSession();
			super.service(request, response);
			HibernateSessionManager.commitTransaction();
		}
		catch (Exception ex) {
			HibernateSessionManager.rollbackTransaction();
			if (ex instanceof RuntimeException) {
				throw (RuntimeException) ex;
			}
			else {
				throw new ServletException(ex);
			}
		}
		finally {
			HibernateSessionManager.closeSession();
		}
	}

}
Comment by ptomblin, Oct 08, 2007

I think it would be better if, instead of passing the filters into both getRowsCount and getRows, there was a single "setFilters" call, and then both getRowsCount and getRows would use those filters. In my implementation, I'd like to make a server-side copy of the filtered data just once, and then return the rows from that copy, instead of having to re-filter the data on every call.

Comment by ro...@softaria.com, Dec 06, 2007

I do not agree with ptomblin. Doing so you will have to create own instance of service for each of your user. Or otherwise, filters of concurrent users will be mixed in one server-side instance.


Sign in to add a comment