Author: ekoneil
Date: Wed Aug  4 16:38:26 2004
New Revision: 35701

Added:
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/util/TableRenderer.java
   (contents, props changed)
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Caption.java
   (contents, props changed)
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Footer.java
   (contents, props changed)
   
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/caption/
   
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/caption/index.jsp
   (contents, props changed)
   
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/footer/
   
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/footer/index.jsp
   (contents, props changed)
   
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/header/
   
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/header/index.jsp
   (contents, props changed)
   
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridCaptionTest.xml
   
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridFooterTest.xml
   (contents, props changed)
   
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridHeaderTest.xml
   (contents, props changed)
Modified:
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnModel.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/DataGridModel.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/services/PagerService.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AbstractColumn.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AnchorColumn.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Columns.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/DataGrid.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/ImageColumn.java
   
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/LiteralColumn.java
   incubator/beehive/trunk/netui/test/webapps/drt/build.xml
   
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
Log:
Data grid feature work.

- rework the relationship between the tags and the JavaBean model objects.  The 
latter are now dropped into the PageContext and data bindable from the JSP 
pages.  This allows page authors to make decisions about the UI to render using 
things like the <c:if> tag based on the render state of a column, for example.
- continued code cleanup 
  - removing the model based rendering code in the DataGridModel
  - start cleaning up the inter-relationships between the columns / abstract 
column tags
- add a <netui-data:footer> tag to render a data grid footer row
- add a <netui-data:caption> tag to render a table caption for the data grid
- exploit the presence of render state knowledge in the ColumnModel objects to 
render custom headers on the grid columns
- three new tests for each of the above

BB: self
BVT: NetUI pass
CR: Daryl



Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnModel.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnModel.java
     (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/ColumnModel.java
     Wed Aug  4 16:38:26 2004
@@ -41,6 +41,13 @@
 {
     private static final Logger _logger = 
Logger.getInstance(ColumnModel.class);
 
+    public static final int DATA_RENDER_STATE = 0;
+    public static final int HEADER_RENDER_STATE = 1;
+    public static final int NO_RENDER_STATE = 2;
+
+    public static final int ATTR_GENERAL = 0;
+    public static final int ATTR_GENERAL_EXPRESSION = 1;
+    
     // todo: externalize these -- they need to be overridable from a JSP
     private static final String EMPTY_CELL = "&nbsp;";
     private static final String UNSORTED_IMAGE = 
"/resources/datagrid/arrow_off.png";
@@ -50,12 +57,7 @@
     private static final String UNFILTERED_IMAGE = 
"/resources/datagrid/noFilter.gif";
     private static final String FILTER_JSP = "/resources/datagrid/filter.jsp";
 
-    public static final int ATTR_GENERAL = 0;
-    public static final int ATTR_GENERAL_EXPRESSION = 1;
-   
     private DataGridModel _dataGridModel;
-    private StylePolicy _stylePolicy;
-
     private ArrayList _formatters = null;
 
     private String _filterAction;
@@ -67,15 +69,18 @@
 
     private String _value;
     private String _headerText;
-    private String _footerText;
 
     private Boolean _filterable = null;
     private Boolean _sortable = null;
 
-    private Object _renderData = null;
+    private int _renderState = NO_RENDER_STATE;
+
+    // todo: need to assert that the correct state shows up here
+    public void setRenderState(int renderState) {_renderState = renderState;}
+    public int getRenderState() {return _renderState;}
 
-    private boolean _canGroup = false;
-    private boolean _shouldGroup = false;
+    public boolean isRenderingHeader() {return _renderState == 
HEADER_RENDER_STATE;}
+    public boolean isRenderingData() {return _renderState == 
DATA_RENDER_STATE;}
 
     public void setDataGridModel(DataGridModel tableModel) {_dataGridModel = 
tableModel;}
     public DataGridModel getDataGridModel() {return _dataGridModel;}
@@ -92,9 +97,6 @@
     public String getHeaderText() {return _headerText;}
     public void setHeaderText(String headerText) {_headerText = headerText;}
 
-    public String getFooterText() {return _footerText;}
-    public void setFooterText(String footerText) {_footerText = footerText;}
-
     public Boolean isFilterable() {return _filterable;}
     public void setFilterable(Boolean filterable) {_filterable = filterable;}
 
@@ -107,9 +109,6 @@
     public void setFilterUri(String filterUri) {_filterUri = filterUri;}
     public String getFilterUri() {return _filterUri;}
 
-    public void setCssPolicy(StylePolicy stylePolicy) {_stylePolicy = 
stylePolicy;}
-    public StylePolicy getCssPolicy() {return _dataGridModel.getCssPolicy();}
-
     public SortService getSortService() {return 
_dataGridModel.getSortService();}
     public FilterService getFilterService() {return 
_dataGridModel.getFilterService();}
 
@@ -129,15 +128,6 @@
     {
     }
 
-    public void openHeaderCell(StringBuffer buf)
-    {
-        buf.append("<th");
-        if(getSortService().isPrimarySort(getSortExpression()))
-            getCssPolicy().writeStyleClass(buf, new int[] 
{StylePolicy.HEADER_CELL_CLASS, StylePolicy.HEADER_CELL_SORTED_CLASS});
-        else getCssPolicy().writeStyleClass(buf, 
StylePolicy.HEADER_CELL_CLASS);
-        buf.append(">");
-    }
-
     public void renderHeader(StringBuffer buffer)
     {
         assert _dataGridModel != null;
@@ -174,55 +164,37 @@
         }
     }
 
-    public void closeHeaderCell(StringBuffer buf)
-    {
-        buf.append("</th>\n");
-    }
-
-    public void openDataCell(StringBuffer buf)
-    {
-        buf.append("<td");
-        getCssPolicy().writeStyleClass(buf, StylePolicy.DATA_CELL_CLASS);
-        buf.append(">");
-    }
-
     public void renderDataCell(StringBuffer buffer)
     {
         String formatted = formatText(_value);
         buffer.append(formatted);
     }
 
-    public void closeDataCell(StringBuffer buf)
-    {
-        buf.append("</td>");
-    }
-    
-    public void openFooterCell(StringBuffer buf)
+    public void openHeaderCell(StringBuffer buf)
     {
-        buf.append("<td");
-        getCssPolicy().writeStyleClass(buf, StylePolicy.FOOTER_CELL_CLASS);
-        buf.append(">");
+        int[] styles = null;
+        if(getSortService().isPrimarySort(getSortExpression()))
+            styles = new int[] {StylePolicy.HEADER_CELL_CLASS, 
StylePolicy.HEADER_CELL_SORTED_CLASS};
+        else styles = new int[] {StylePolicy.HEADER_CELL_CLASS};
+
+        _dataGridModel.getTableRenderer().openHeaderCell(buf, styles);
     }
 
-    public void renderFooterCell(StringBuffer buffer)
+    public void closeHeaderCell(StringBuffer buf)
     {
-        assert _dataGridModel != null;
-
-        if(_footerText != null)
-            buffer.append(_footerText);
-        else renderEmptyCell(buffer);
+        _dataGridModel.getTableRenderer().closeHeaderCell(buf);
     }
 
-    public void closeFooterCell(StringBuffer buf)
+    public void openDataCell(StringBuffer buf)
     {
-        buf.append("</td>");
+        _dataGridModel.getTableRenderer().openTableCell(buf);
     }
 
-    public void renderGroupedData(StringBuffer buffer)
+    public void closeDataCell(StringBuffer buf)
     {
-        buffer.append(EMPTY_CELL);
+        _dataGridModel.getTableRenderer().closeTableCell(buf);
     }
-
+    
     protected void renderEmptyCell(StringBuffer buffer)
     {
         buffer.append(EMPTY_CELL);
@@ -240,10 +212,9 @@
 
     protected String formatText(Object text)
     {
-        if(_logger.isDebugEnabled()) _logger.debug("format text: \"" + text + 
"\"");
-
         if (text == null)
             return null;
+
         if (_formatters == null)
             return text.toString();
 
@@ -256,8 +227,6 @@
                 if(_logger.isDebugEnabled()) _logger.debug("run formatter of 
type \"" + currentFormatter.getClass().getName() + "\"");
 
                 text = currentFormatter.format(text);
-
-                if(_logger.isDebugEnabled()) _logger.debug("formatted text: 
\"" + text + "\"");
             }
             catch (JspException e) 
             {
@@ -265,8 +234,6 @@
                 if(_logger.isErrorEnabled()) _logger.error("A formatter of 
type \"" + currentFormatter.getClass().getName() + "\" threw an exception " + 
e, e);
             }
         }
-
-        if(_logger.isDebugEnabled()) _logger.debug("final formatted text: \"" 
+ text + "\"");
 
         return text.toString();
     }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/DataGridModel.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/DataGridModel.java
   (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/model/DataGridModel.java
   Wed Aug  4 16:38:26 2004
@@ -18,18 +18,14 @@
  */
 package org.apache.beehive.netui.databinding.datagrid.model;
 
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
+import java.util.*;
 import javax.servlet.jsp.PageContext;
 
 import org.apache.beehive.netui.databinding.datagrid.services.FilterService;
 import org.apache.beehive.netui.databinding.datagrid.services.PagerService;
 import org.apache.beehive.netui.databinding.datagrid.services.SortService;
 import org.apache.beehive.netui.databinding.datagrid.util.PagedDataSet;
+import org.apache.beehive.netui.databinding.datagrid.util.TableRenderer;
 import org.apache.beehive.netui.script.common.IDataAccessProvider;
 import org.apache.beehive.netui.tags.databinding.datagrid.DataGrid;
 import org.apache.beehive.netui.util.logging.Logger;
@@ -38,31 +34,29 @@
  *
  */
 public class DataGridModel
-    implements IDataAccessProvider
 {
     private static final Logger _logger = 
Logger.getInstance(DataGridModel.class);
-    private static final int NO_GROUPING = -1;
 
     private String _name = null;
-    private int _startRenderWindow = 0;
-    private int _endRenderWindow = 0;
 
-    private List _columns = null;
-    
-    private PagerModel _pagerModel = null;
+    private ArrayList _columns = null;
+    private Iterator _columnIterator = null;
+
     private StylePolicy _cssPolicy = null;
     private SortService _sortService = null;
     private FilterService _filterService = null;
+    private PagerModel _pagerModel = null;
     private PagerService _pagerService = null;
 
-    private DataGrid _grid;
+    // todo: would be great to not have a PageContext dependency here.  This 
should just be a smart JavaBean.
     private PageContext _pageContext;
 
     private PagedDataSet _dataSet = null;
+    private TableRenderer _tableRenderer = null;
 
-    public DataGridModel(DataGrid grid)
+    public DataGridModel()
     {
-        _grid = grid;
+        super();
     }
 
     public void initialize()
@@ -71,22 +65,28 @@
 
         PagerService ps = getPagerService();
         int lastPage = 
(int)Math.ceil((float)_dataSet.getSize()/(float)ps.getPageSize());
-        _startRenderWindow = (ps.getCurrentPage()-1)*10;
-        _endRenderWindow = (ps.getCurrentPage() != lastPage ? 
_startRenderWindow+ps.getPageSize() : _dataSet.getSize());
+        int startRenderWindow = (ps.getCurrentPage()-1)*10;
+        int endRenderWindow = (ps.getCurrentPage() != lastPage ? 
startRenderWindow+ps.getPageSize() : _dataSet.getSize());
 
         if(_logger.isDebugEnabled())
-            _logger.debug("start: " + _startRenderWindow + " end: " + 
_endRenderWindow +
+            _logger.debug("start: " + startRenderWindow + " end: " + 
endRenderWindow +
                           " lastPage: " + lastPage + " pageSize: " + 
ps.getPageSize() +
                           " dataSetSize: " + _dataSet.getSize());
 
-        assert _startRenderWindow <= _endRenderWindow;
+        assert startRenderWindow <= endRenderWindow;
 
         if(_logger.isDebugEnabled())
         {
-            _logger.debug("start render window: " + _startRenderWindow);
-            _logger.debug("end render window: " + _endRenderWindow);
+            _logger.debug("start render window: " + startRenderWindow);
+            _logger.debug("end render window: " + endRenderWindow);
             _logger.debug("last page: " + lastPage);
         }
+
+        _tableRenderer = new TableRenderer(_cssPolicy);
+    }
+    
+    public void uninitialize()
+    {
     }
 
     public void addColumn(ColumnModel column)
@@ -98,42 +98,6 @@
         _columns.add(column);
     }
 
-    public void render(Writer writer)
-    {
-        assert _pageContext != null;
-        assert _grid != null;
-
-        if(_logger.isDebugEnabled()) 
-            _logger.debug("render a data grid.  column count: " + (_columns != 
null ? "" + _columns.size() : "null"));
-
-        if(_columns == null) return;
-
-        initialize();
-
-        StringBuffer buf = new StringBuffer();
-
-        renderPager(buf);
-        openTable(buf);
-
-        // header <tr>
-        renderHeader(buf, _columns, _cssPolicy, _sortService);
-
-        // data <tr>
-        while(_dataSet.hasNext())
-        {
-            _dataSet.next();
-            renderBody(buf, _dataSet.getCurrentIndex(), _columns, _cssPolicy, 
_sortService);
-        }
-
-        // footer <tr>
-        if(shouldRenderFooter())
-            renderFooter(buf, _columns, _cssPolicy);
-
-        closeTable(buf);
-
-        write(writer, buf);
-    }
-
     public void renderPager(StringBuffer buf)
     {
         if(_pagerModel == null)
@@ -142,122 +106,54 @@
         _pagerModel.render(buf);
     }
 
-    public boolean shouldRenderFooter()
-    {
-        assert _columns != null;
-
-        for(int i = 0; i < _columns.size(); i++)
-        {
-            if(((ColumnModel)_columns.get(i)).getFooterText() != null) return 
true;
-        }
-
-        return false;
-    }
-
-    private final void renderHeader(StringBuffer buf, List columns, 
StylePolicy cssPolicy, SortService sortService)
+    public void openTable(StringBuffer buf)
     {
-        if(_logger.isDebugEnabled()) _logger.debug("render header");
-
-        openHeaderRow(buf);
-        for(int i = 0; i < columns.size(); i++)
-        {
-            ColumnModel cm = (ColumnModel)columns.get(i);
-
-            cm.openHeaderCell(buf);
-            cm.renderHeader(buf);
-            cm.closeHeaderCell(buf);
-        }
-        closeHeaderRow(buf);
+        _tableRenderer.openTable(buf);
     }
 
-    private void renderBody(StringBuffer buf, int index, List columns, 
StylePolicy cssPolicy, SortService sortService)
+    public void closeTable(StringBuffer buf)
     {
-        if(_logger.isDebugEnabled()) _logger.debug("render body");
-
-        for(int i = 0; i < columns.size(); i++)
-            ((ColumnModel)columns.get(i)).onBeginRow();
-
-        openDataRow(buf);
-
-        for(int i = 0; i < columns.size(); i++)
-        {
-            ColumnModel column = (ColumnModel)columns.get(i);
-            column.openDataCell(buf);
-            column.renderDataCell(buf);
-            column.closeDataCell(buf);
-        }
-
-        // loop over all columns to end the row
-        for(int i = 0; i < columns.size(); i++)
-            ((ColumnModel)columns.get(i)).onEndRow();
-
-        closeDataRow(buf);
+        _tableRenderer.closeTable(buf);
     }
 
-    public void openTable(StringBuffer buf)
+    public void openCaption(StringBuffer buf)
     {
-        buf.append("\n<table");
-        _cssPolicy.writeStyleClass(buf, StylePolicy.TABLE_CLASS);
-        buf.append(">");
+        _tableRenderer.openCaption(buf);
     }
 
-    public void closeTable(StringBuffer buf)
+    public void closeCaption(StringBuffer buf)
     {
-        buf.append("\n</table>\n");
+        _tableRenderer.closeCaption(buf);
     }
 
     public final void openHeaderRow(StringBuffer buf)
     {
-        buf.append("\n<thead>");
-        buf.append("\n<tr");
-        _cssPolicy.writeStyleClass(buf, StylePolicy.HEADER_ROW_CLASS);
-        buf.append(">");
+        _tableRenderer.openHeaderRow(buf);
     }
 
     public void closeHeaderRow(StringBuffer buf)
     {
-        buf.append("</tr>\n");
-        buf.append("</thead>\n");
+        _tableRenderer.closeHeaderRow(buf);
     }
 
     public void openDataRow(StringBuffer buf)
     {
-        // render the row against the current data item
-        buf.append("\n<tr");
-        if(getCurrentIndex() % 2 == 0)
-            _cssPolicy.writeStyleClass(buf, StylePolicy.ROW_CLASS);
-        else _cssPolicy.writeStyleClass(buf, StylePolicy.ALT_ROW_CLASS);
-        buf.append(">");
+        _tableRenderer.openTableRow(buf, getCurrentIndex());
     }
 
     public void closeDataRow(StringBuffer buf)
     {
-        buf.append("</tr>");
+        _tableRenderer.closeTableRow(buf);
     }
 
-    public static void openFooterRow(StringBuffer buf)
+    public void openFooterRow(StringBuffer buf)
     {
-        buf.append("\n<tr>");
+        _tableRenderer.openFooterRow(buf);
     }
 
-    public static void closeFooterRow(StringBuffer buf)
+    public void closeFooterRow(StringBuffer buf)
     {
-        buf.append("\n</tr>");
-    }
-
-    private static void renderFooter(StringBuffer buf, List columns, 
StylePolicy cssPolicy)
-    {
-        if(_logger.isDebugEnabled()) _logger.debug("render footer");
-
-        openFooterRow(buf);
-        for(int i = 0; i < columns.size(); i++)
-        {
-            ColumnModel column = (ColumnModel)columns.get(i);
-            column.openFooterCell(buf);
-            column.renderFooterCell(buf);
-            column.closeFooterCell(buf);
-        }
-        closeFooterRow(buf);
+        _tableRenderer.closeFooterRow(buf);
     }
 
     public void setDataSet(PagedDataSet dataSet) {_dataSet = dataSet;}
@@ -318,6 +214,8 @@
 
     public int getDataSetSize() {return _dataSet.getSize();}
 
+    public TableRenderer getTableRenderer() {return _tableRenderer;}
+
     /* ===========================================================
      *
      * IDataAccessProvider implementation
@@ -334,20 +232,10 @@
         return _dataSet.getCurrentItem();
     }
 
-    public Object getCurrentMetadata()
-    {
-        throw new UnsupportedOperationException("Metadata is not available on 
the current data item.");
-    }
-
     public String getDataSource()
     {
         return _dataSet.getDataSourceRef();
     }
-    
-    public IDataAccessProvider getProviderParent()
-    {
-        return _grid.getProviderParent();
-    }
 
     public Object nextDataItem()
     {
@@ -361,16 +249,18 @@
         return hasNext;
     }
 
-    private static final void write(Writer writer, StringBuffer buf)
+    public ColumnModel getNextColumnModel()
     {
-        try
-        {
-            writer.write(buf.toString());
-        }
-        catch(IOException io)
-        {
-            if(_logger.isErrorEnabled())
-                _logger.error("Exception writing JSP output: " + io, io);
-        }
+        if(_columnIterator == null)
+            resetColumnIterator();
+
+        if(_columnIterator.hasNext())
+            return (ColumnModel)_columnIterator.next();
+        else throw new NoSuchElementException("There are no more ColumnModel 
objects available in this iterator");
+    }
+
+    public void resetColumnIterator()
+    {
+        _columnIterator = _columns.iterator();
     }
 }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/services/PagerService.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/services/PagerService.java
 (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/services/PagerService.java
 Wed Aug  4 16:38:26 2004
@@ -43,7 +43,6 @@
     private ServletRequest _request = null;
     private Integer _currentPage = null;
     private Integer _pageSize = null;
-    private Integer _dataSetSize = null;
 
     public PagerService(ServletRequest request, String namespace)
     {

Added: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/util/TableRenderer.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/databinding/datagrid/util/TableRenderer.java
    Wed Aug  4 16:38:26 2004
@@ -0,0 +1,118 @@
+/*
+ * B E A   S Y S T E M S
+ * Copyright 2002-2004  BEA Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.databinding.datagrid.util;
+
+import org.apache.beehive.netui.databinding.datagrid.model.StylePolicy;
+
+public class TableRenderer
+{
+    private StylePolicy _stylePolicy = null;
+
+    public TableRenderer(StylePolicy stylePolicy)
+    {
+        _stylePolicy = stylePolicy;
+    }
+
+    public void openTable(StringBuffer buf)
+    {
+        buf.append("\n<table");
+        _stylePolicy.writeStyleClass(buf, StylePolicy.TABLE_CLASS);
+        buf.append(">");
+    }
+
+    public void closeTable(StringBuffer buf)
+    {
+        buf.append("\n</table>\n");
+    }
+
+    public void openCaption(StringBuffer buf)
+    {
+        buf.append("<caption>");
+    }
+
+    public void closeCaption(StringBuffer buf)
+    {
+        buf.append("</caption>\n");
+    }
+
+    public final void openHeaderRow(StringBuffer buf)
+    {
+        buf.append("\n<thead>");
+        buf.append("\n<tr");
+        _stylePolicy.writeStyleClass(buf, StylePolicy.HEADER_ROW_CLASS);
+        buf.append(">");
+    }
+
+    public void closeHeaderRow(StringBuffer buf)
+    {
+        buf.append("</tr>\n");
+        buf.append("</thead>\n");
+    }
+
+    public void openTableRow(StringBuffer buf, int rowIndex)
+    {
+        // render the row against the current data item
+        buf.append("\n<tr");
+        if(rowIndex % 2 == 0)
+            _stylePolicy.writeStyleClass(buf, StylePolicy.ROW_CLASS);
+        else _stylePolicy.writeStyleClass(buf, StylePolicy.ALT_ROW_CLASS);
+        buf.append(">");
+    }
+
+    public void closeTableRow(StringBuffer buf)
+    {
+        buf.append("</tr>");
+    }
+
+    public void openFooterRow(StringBuffer buf)
+    {
+        buf.append("\n<tr");
+        _stylePolicy.writeStyleClass(buf, StylePolicy.FOOTER_ROW_CLASS);       
 
+        buf.append(">");
+    }
+
+    public void closeFooterRow(StringBuffer buf)
+    {
+        buf.append("\n</tr>");
+    }
+
+    public void openHeaderCell(StringBuffer buf, int[] styleClasses)
+    {
+        buf.append("<th");
+        _stylePolicy.writeStyleClass(buf, styleClasses);
+        buf.append(">");
+    }
+
+    public void closeHeaderCell(StringBuffer buf)
+    {
+        buf.append("</th>\n");
+    }
+
+    public void openTableCell(StringBuffer buf)
+    {
+        buf.append("<td");
+        _stylePolicy.writeStyleClass(buf, StylePolicy.DATA_CELL_CLASS);
+        buf.append(">");
+    }
+
+    public void closeTableCell(StringBuffer buf)
+    {
+        buf.append("</td>");
+    }
+}

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AbstractColumn.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AbstractColumn.java
   (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AbstractColumn.java
   Wed Aug  4 16:38:26 2004
@@ -46,7 +46,6 @@
     private String _sortExpression = null;
     private String _filterExpression = null;
     private String _headerText = null;
-    private String _footerText = null;
 
     /**
      * @netui:attribute required="false" rtexprvalue="true"
@@ -70,19 +69,11 @@
 
     /**
      * @netui:attribute required="false" rtexprvalue="true"
-     * @netui.tldx:attribute
      */
     public void setHeaderText(String headerText) {_headerText = headerText;}
 
     /**
-     * @netui:attribute required="false" rtexprvalue="true"
-     * @netui.tldx:attribute
-     */
-    public void setFooterText(String footerText) {_footerText = footerText;}
-
-    /**
      * @netui:attribute required="true" rtexprvalue="true"
-     * @netui.tldx:attribute
      */
     public void setValue(String value) {_value = value;}
 
@@ -90,65 +81,86 @@
     {
         getColumnModel().addFormatter(formatter);
     }
+
     /**
      * Indicate that a formatter has reported an error so the formatter should 
output it's
      * body text.
      */
-    public void formatterHasError() {
-        // @todo: need to implement this.
+    public void formatterHasError()
+    {
+        // todo: need to implement this.
+    }
+
+    public ColumnModel getColumnModel()
+    {
+        return (ColumnModel)pageContext.getAttribute("column");
     }
 
     public int doStartTag()
     {
-        int gridRenderState = getDataGrid().getRenderState();
-        int columnsRenderState = getColumnsTag().getRenderState();
+        int gridRenderState = getDataGridTag().getRenderState();
 
         assert getParent() instanceof Columns;
         assert getColumnModel() != null;
-        
+
         if(_logger.isDebugEnabled())
-            _logger.debug("start tag.  grid render state: " + gridRenderState 
+ " columns render state: " + columnsRenderState);
-        
+            _logger.debug("start tag.  grid render state: " + gridRenderState);
+
+        int retVal = SKIP_BODY;
         // when starting to render, the ColumnModel associated with this tag 
needs to be created
         if(gridRenderState == DataGrid.START_RENDER_STATE)
         {
-            ColumnModel cm = getColumnModel();
+            ColumnModel cm = createColumnModel();
+            setColumnModel(cm);
             getColumnsTag().addColumn(cm);
         }
         // otherwise, the ColumnModel associated with this tag
         // needs to be fetched from the <columns> tag for the current
         // iteration
-        else 
+        else
         {
-            ColumnModel cm = getDataGrid().getNextColumnModel();
+            int columnsRenderState = getColumnsTag().getRenderState();
+
+            assert columnsRenderState == ColumnModel.DATA_RENDER_STATE ||
+                   columnsRenderState == ColumnModel.HEADER_RENDER_STATE;
+
+            getColumnsTag().loadNextColumn();
+            ColumnModel cm = getColumnModel();
+
+            assert cm != null : "The ColumnModel received by the grid column 
was null";
+
             setColumnModel(cm);
-            
+
             cm.setValue(_value);
             cm.setHeaderText(_headerText);
-            cm.setFooterText(_footerText);
+
             if(_filterable != null)
                 cm.setFilterable(_filterable);
             cm.setFilterExpression(_filterExpression);
+
             if(_sortable != null)
                 cm.setSortable(_sortable);
             cm.setSortExpression(_sortExpression);
 
             // allow subclasses to apply attributes to their ColumnModel 
objects
             applyAttributes();
+
+            cm.setRenderState(columnsRenderState);
+
+            retVal = EVAL_BODY_BUFFERED;
         }
 
-        if(columnsRenderState == Columns.DATA_RENDER_STATE)
-            return EVAL_BODY_BUFFERED;
-        else return SKIP_BODY;
+        return retVal;
     }
 
     public int doEndTag()
     {
-        if(_logger.isDebugEnabled()) _logger.debug("end tag");
+        if(_logger.isDebugEnabled())
+            _logger.debug("column end tag");
 
-        int retVal = EVAL_PAGE;
-        int gridRenderState = getDataGrid().getRenderState();
+        int gridRenderState = getDataGridTag().getRenderState();
 
+        int retVal = EVAL_PAGE;
         if (gridRenderState == DataGrid.START_RENDER_STATE)
         {
             retVal = EVAL_PAGE;
@@ -157,10 +169,9 @@
         {
             StringBuffer buf = new StringBuffer();
             int renderState = getColumnsTag().getRenderState();
-            ColumnModel cm = getColumnModel();
 
             // todo: need to assert that the identityHashCode of 'cm' is 
well-known
-            DataGridModel dgm = getDataGrid().getDataGridModel();
+            ColumnModel cm = getColumnModel();
 
             if (_logger.isDebugEnabled())
             {
@@ -169,35 +180,39 @@
                 _logger.debug("\tidentity hash code: " + 
System.identityHashCode(cm));
             }
 
+            DataGridModel dgm = 
(DataGridModel)pageContext.getAttribute("gridModel");
+
             assert dgm != null;
             assert cm != null;
 
-            if (renderState == Columns.HEADER_RENDER_STATE)
+            if (renderState == ColumnModel.HEADER_RENDER_STATE)
             {
                 if (_logger.isDebugEnabled()) _logger.debug("render a column's 
header cell");
+
                 cm.openHeaderCell(buf);
-                cm.renderHeader(buf);
+                if(_headerText != null)
+                    cm.renderHeader(buf);
+                else if( bodyContent != null)
+                    buf.append(bodyContent.getString());
                 cm.closeHeaderCell(buf);
             }
-            else if (renderState == Columns.DATA_RENDER_STATE)
+            else if (renderState == ColumnModel.DATA_RENDER_STATE)
             {
                 if (_logger.isDebugEnabled()) _logger.debug("render a column's 
data cell");
+
                 cm.openDataCell(buf);
                 cm.renderDataCell(buf);
                 cm.closeDataCell(buf);
             }
-            else if (renderState == Columns.FOOTER_RENDER_STATE)
-            {
-                if (_logger.isDebugEnabled()) _logger.debug("render a column's 
footer cell");
-                cm.openFooterCell(buf);
-                cm.renderFooterCell(buf);
-                cm.closeFooterCell(buf);
-            }
 
             if (buf != null && buf.length() > 0)
-                getDataGrid().appendContent(buf.toString());
+                getDataGridTag().appendContent(buf.toString());
+
+            cm.setRenderState(ColumnModel.NO_RENDER_STATE);
         }
 
+        getColumnsTag().unloadColumn();
+
         localRelease();
 
         return retVal;
@@ -215,46 +230,44 @@
         _sortable = null;
         _sortExpression = null;
         _headerText = null;
-        _footerText = null;
+
+        if(bodyContent != null)
+            bodyContent.clearBody();
     }
 
-    protected abstract ColumnModel getColumnModel();
+    protected abstract ColumnModel createColumnModel();
 
     protected abstract void setColumnModel(ColumnModel model);
 
     protected void applyAttributes()
     {
+        // implemented by sub-classes
     }
 
+    // todo: error reporting
     protected Columns getColumnsTag()
     {
-        // todo: error reporting
         assert getParent() instanceof Columns;
-        
+
         if(_parent != null)
             return _parent;
-        
+
         _parent = (Columns)getParent();
 
         return _parent;
     }
 
-    protected DataGrid getDataGrid()
+    // todo: error reporting
+    protected DataGrid getDataGridTag()
     {
         if(_dataGrid != null)
             return _dataGrid;
 
         Tag dataGrid = findAncestorWithClass(this, DataGrid.class);
-        
+
         assert dataGrid != null;
         _dataGrid = (DataGrid)dataGrid;
 
-        // todo: error reporting
         return _dataGrid;
-    }
-
-    protected int getRenderState()
-    {
-        return getDataGrid().getRenderState();
     }
 }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AnchorColumn.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AnchorColumn.java
     (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/AnchorColumn.java
     Wed Aug  4 16:38:26 2004
@@ -101,14 +101,14 @@
 
     protected void setColumnModel(ColumnModel column)
     {
+        assert column != null : "Can't set a null ColumnModel";
         assert column instanceof AnchorColumnModel;
+
         _column = (AnchorColumnModel)column;
     }
 
-    protected ColumnModel getColumnModel()
+    protected ColumnModel createColumnModel()
     {
-        if(_column == null)
-            return (_column = new AnchorColumnModel());
-        else return _column;
+        return new AnchorColumnModel();
     }
 }

Added: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Caption.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Caption.java
  Wed Aug  4 16:38:26 2004
@@ -0,0 +1,87 @@
+/*
+ * B E A   S Y S T E M S
+ * Copyright 2002-2004  BEA Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.tags.databinding.datagrid;
+
+import org.apache.beehive.netui.tags.AbstractBaseTag;
+import org.apache.beehive.netui.util.logging.Logger;
+
+import javax.servlet.jsp.tagext.Tag;
+
+/**
+ *
+ * @netui:tag name="caption" description="Renders a caption into a NetUI data 
grid"
+ * @netui.tldx:tag whitespace="indent"
+ *                 netuiexpressioninfo=""
+ *                 renderer=""
+ */
+public class Caption
+    extends AbstractBaseTag
+{
+    private static final Logger _logger = 
Logger.getInstance(AnchorColumn.class);
+
+    private DataGrid _dataGrid = null;
+
+    public String getTagName()
+    {
+        return "Caption";
+    }
+
+    public int doStartTag()
+    {
+        if(getDataGrid().getRenderState() == DataGrid.CAPTION_RENDER_STATE)
+            return EVAL_BODY_BUFFERED;
+        else return SKIP_BODY;
+    }
+
+    public int doEndTag()
+    {
+        if(bodyContent != null)
+        {
+            String caption = bodyContent.getString();
+            getDataGrid().addCaption(caption);
+        }
+
+        localRelease();
+
+        return EVAL_PAGE;
+    }
+
+    public void localRelease()
+    {
+        super.localRelease();
+
+        _dataGrid = null;
+        if(bodyContent != null)
+            bodyContent.clearBody();
+    }
+
+    protected DataGrid getDataGrid()
+    {
+        if(_dataGrid != null)
+            return _dataGrid;
+
+        Tag dataGrid = findAncestorWithClass(this, DataGrid.class);
+
+        assert dataGrid != null;
+        _dataGrid = (DataGrid)dataGrid;
+
+        // todo: error reporting
+        return _dataGrid;
+    }
+}

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Columns.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Columns.java
  (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Columns.java
  Wed Aug  4 16:38:26 2004
@@ -23,6 +23,8 @@
 import org.apache.beehive.netui.tags.AbstractBaseTag;
 import org.apache.beehive.netui.util.logging.Logger;
 
+import javax.servlet.jsp.JspException;
+
 /**
  *
  * @netui:tag name="columns" description="Container tag for columsn that will 
render in the grid"
@@ -34,11 +36,6 @@
 {
     private static final Logger _logger = Logger.getInstance(DataGrid.class);
 
-    public static final int NO_RENDER_STATE = -1;
-    public static final int HEADER_RENDER_STATE = 2;
-    public static final int DATA_RENDER_STATE = 3;
-    public static final int FOOTER_RENDER_STATE = 4;
-
     private DataGrid _grid = null;
 
     private Boolean _sortable = null;
@@ -46,12 +43,7 @@
     private String _sortAction = null;
     private String _filterAction = null;
     private DataGridModel _gridModel = null;
-    private int _renderState = NO_RENDER_STATE;
-
-    public Columns()
-    {
-        super();
-    }
+    private int _renderState = ColumnModel.NO_RENDER_STATE;
 
     public String getTagName() {return "Columns";}
     
@@ -87,57 +79,68 @@
     {
         assert getParent() instanceof DataGrid;
         _grid = (DataGrid)findAncestorWithClass(this, DataGrid.class);
+
         assert _grid != null;
-        _gridModel = _grid.getDataGridModel();
+        // todo: error reporting / instanceof assert
+        _gridModel = (DataGridModel)pageContext.getAttribute("dataGrid");
 
         int gridRenderState = _grid.getRenderState();
+
+        int retVal = EVAL_BODY_BUFFERED;
         if (gridRenderState == DataGrid.START_RENDER_STATE)
         {
-            // no-op
+            // in START_RENDER_STATE, the dataGrid needs to drop into its 
child tags
+            // in order to build-up a model of the grid that is going to be 
rendered
         }
-        else if (gridRenderState == DataGrid.GRID_RENDER_STATE)
+        else if(gridRenderState == DataGrid.GRID_RENDER_STATE)
         {
             StringBuffer content = new StringBuffer();
-            _renderState = HEADER_RENDER_STATE;
+            _renderState = ColumnModel.HEADER_RENDER_STATE;
             _gridModel.openHeaderRow(content);
             _grid.appendContent(content.toString());
         }
+        else if(gridRenderState == DataGrid.CAPTION_RENDER_STATE ||
+                gridRenderState == DataGrid.FOOTER_RENDER_STATE)
+        {
+            retVal = SKIP_BODY;
+        }
 
-        return EVAL_BODY_BUFFERED;
+        return retVal;
     }
 
     public int doAfterBody()
+        throws JspException
     {
-        int retVal = EVAL_BODY_BUFFERED;
-
         int gridRenderState = _grid.getRenderState();
+
+        // this should never happen
+        assert gridRenderState != DataGrid.CAPTION_RENDER_STATE ||
+               gridRenderState != DataGrid.FOOTER_RENDER_STATE
+               : "Rendering Columns with an invalid grid rendering state: " + 
gridRenderState;
+
+        int retVal = EVAL_BODY_BUFFERED;
         if (gridRenderState == DataGrid.START_RENDER_STATE)
         {
             retVal = SKIP_BODY;
         }
         else if (gridRenderState == DataGrid.GRID_RENDER_STATE)
         {
-            _grid.resetColumnModelIndex();
+            _gridModel.resetColumnIterator();
+
             StringBuffer content = new StringBuffer();
-            if (_renderState == HEADER_RENDER_STATE)
+            if (_renderState == ColumnModel.HEADER_RENDER_STATE)
             {
                 _gridModel.closeHeaderRow(content);
-                _gridModel.openDataRow(content);
 
-                //_gridModel.moveCursorToStart();
                 // prime the pump with the next item of data to render
                 if (_gridModel.hasNextDataItem())
                 {
+                    _gridModel.openDataRow(content);
                     _gridModel.nextDataItem();
-                    _renderState = DATA_RENDER_STATE;
-                }
-                else
-                {
-                    // todo: need to handle the "no-data" case here
-                    _renderState = FOOTER_RENDER_STATE;
+                    _renderState = ColumnModel.DATA_RENDER_STATE;
                 }
             }
-            else if (_renderState == DATA_RENDER_STATE)
+            else if (_renderState == ColumnModel.DATA_RENDER_STATE)
             {
                 _gridModel.closeDataRow(content);
                 if (_gridModel.hasNextDataItem())
@@ -147,48 +150,36 @@
                 }
                 else
                 {
-                    if (_gridModel.shouldRenderFooter())
-                    {
-                        _renderState = FOOTER_RENDER_STATE;
-                        DataGridModel.openFooterRow(content);
-                    }
-                    else
-                    {
-                        _renderState = NO_RENDER_STATE;
-                        retVal = SKIP_BODY;
-                    }
+                    _renderState = ColumnModel.NO_RENDER_STATE;
+                    retVal = SKIP_BODY;
                 }
             }
-            else if (_renderState == FOOTER_RENDER_STATE)
-            {
-                DataGridModel.closeFooterRow(content);
-                _renderState = -1;
-                retVal = SKIP_BODY;
-            }
 
             _grid.appendContent(content.toString());
         }
 
-        if(_logger.isDebugEnabled()) _logger.debug("render columns body with 
state: " + _renderState);
+        if(_logger.isDebugEnabled())
+            _logger.debug("render columns body with state: " + _renderState);
+
         return retVal;
     }
 
     public int doEndTag()
     {
         localRelease();
-
         return EVAL_PAGE;
     }
-    
+
     public void localRelease()
     {
         super.localRelease();
+
         _sortable = null;
         _filterable = null;
         _sortAction = null;
         _filterAction = null;
         _grid = null;
-        _renderState = NO_RENDER_STATE;
+        _renderState = ColumnModel.NO_RENDER_STATE;
         _gridModel = null;
     }
 
@@ -200,7 +191,9 @@
     public void addColumn(ColumnModel cm)
     {
         if(_logger.isDebugEnabled())
-            _logger.debug("adding column of type " + (cm != null ? 
cm.getClass().getName() : null) + " with identity " + 
System.identityHashCode(cm));
+            _logger.debug("adding column of type " +
+                    (cm != null ? cm.getClass().getName() : null) + " with 
identity " +
+                    System.identityHashCode(cm));
 
         if(_sortAction != null)
             cm.setSortUri(_sortAction);
@@ -210,10 +203,25 @@
 
         if(cm.isSortable() == null && _sortable != null)
             cm.setSortable(_sortable);
-        
+
         if(cm.isFilterable() == null && _filterable != null)
             cm.setFilterable(_filterable);
 
-        _grid.addColumn(cm);
+        if(_logger.isDebugEnabled())
+            _logger.debug("add a column: " + cm + " total columns: " +
+                          (_gridModel.getColumns() != null ? 
_gridModel.getColumns().size() : 0));
+
+        _gridModel.addColumn(cm);
+    }
+
+    public void loadNextColumn()
+    {
+        ColumnModel cm = _gridModel.getNextColumnModel();
+        pageContext.setAttribute("column", cm);
+    }
+
+    public void unloadColumn()
+    {
+        pageContext.removeAttribute("column");
     }
 }

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/DataGrid.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/DataGrid.java
 (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/DataGrid.java
 Wed Aug  4 16:38:26 2004
@@ -26,6 +26,7 @@
 
 import org.apache.beehive.netui.databinding.datagrid.model.ColumnModel;
 import org.apache.beehive.netui.databinding.datagrid.model.DataGridModel;
+import org.apache.beehive.netui.databinding.datagrid.model.StylePolicy;
 import 
org.apache.beehive.netui.databinding.datagrid.model.impl.DefaultStylePolicy;
 import 
org.apache.beehive.netui.databinding.datagrid.model.impl.EmptyStylePolicy;
 import 
org.apache.beehive.netui.databinding.datagrid.model.impl.LegacyStylePolicy;
@@ -49,33 +50,28 @@
     implements IDataAccessProvider
 {
     private static final Logger _logger = Logger.getInstance(DataGrid.class);
-    
-    public static final int DATAGRID_MODEL_RENDERING = 0;
-    public static final int JSP_TAG_RENDERING = 1;
+    private static final StylePolicy DEFAULT_STYLE_POLICY = new 
DefaultStylePolicy();
+    private static final StylePolicy EMPTY_STYLE_POLICY = new 
EmptyStylePolicy();
 
     public static final int START_RENDER_STATE = 10;
-    public static final int GRID_RENDER_STATE = 20;
-    public static final int END_RENDER_STATE = 30;
+    public static final int CAPTION_RENDER_STATE = 20;
+    public static final int GRID_RENDER_STATE = 30;
+    public static final int FOOTER_RENDER_STATE = 40;
+    public static final int END_RENDER_STATE = 50;
 
-    public static final String DEFAULT_STYLE_POLICY = "default";
+    public static final String DEFAULT_STYLE_POLICY_VALUE = "default";
 
     private DataGridModel _gridModel = null;
     private String _name = null;
-    private String _cssClassPolicy = DEFAULT_STYLE_POLICY;
+    private String _cssClassPolicy = DEFAULT_STYLE_POLICY_VALUE;
     private String _dataSource = null;
+    private String _captionText = null;
+    private String _footerText = null;
 
     private int _renderState = START_RENDER_STATE;
 
-    // todo: switch to StringBuilder or Writer / StringWriter
+    // todo: consider a switch to StringBuilder or Writer w/ a StringWriter?
     private StringBuffer _content = null;
-    private int _columnModelIndex = 0;
-
-    public DataGrid()
-    {
-        super();
-
-        _gridModel = new DataGridModel(this);
-    }
 
     public String getTagName()
     {
@@ -88,17 +84,24 @@
     public void setName(String name) {_name = name;}
 
     /**
-     * @netui:attribute required="false"
+     * @netui:attribute required="true"
+     * @netui.tldx:attribute language="netuiexpression"
+     */
+    public void setDataSource(String dataSource) {_dataSource = dataSource;}
+
+    /**
+     * @netui:attribute required="false" rtexprvalue="true"
      */
     public void setCssClassPolicy(String cssClassPolicy) {_cssClassPolicy = 
cssClassPolicy;}
 
     public int doStartTag()
         throws JspException
     {
+        _gridModel = new DataGridModel();
         _gridModel.setPageContext(pageContext);
         _gridModel.setName(_name);
 
-        // String dataSource
+        // create the dataSource expression
         String dataSource = getDataSource();
         dataSource = "{" + dataSource + "}";
 
@@ -110,11 +113,10 @@
 
         _gridModel.setDataSet(dataSet);
 
-        if(_cssClassPolicy.equals("default"))
-            // todo: perf -- allocate and reuse for all grids
-            _gridModel.setCssPolicy(new DefaultStylePolicy());
+        if(_cssClassPolicy == DEFAULT_STYLE_POLICY_VALUE || 
_cssClassPolicy.equals("default"))
+            _gridModel.setCssPolicy(DEFAULT_STYLE_POLICY);
         else if(_cssClassPolicy.equals("none"))
-            _gridModel.setCssPolicy(new EmptyStylePolicy());
+            _gridModel.setCssPolicy(EMPTY_STYLE_POLICY);
 
         // todo: implement state machine rendering here...
         _renderState = START_RENDER_STATE;
@@ -123,10 +125,13 @@
         // todo: optimize -- this doesn't need to happen when the data set is 
empty
         DataAccessProviderStack.addDataAccessProvider(this, pageContext);
 
+        pageContext.setAttribute("dataGrid", _gridModel);
+
         return EVAL_BODY_BUFFERED;
     }
 
     public int doAfterBody()
+        throws JspException
     {
         int retVal = EVAL_BODY_BUFFERED;
         if (_renderState == START_RENDER_STATE)
@@ -142,21 +147,45 @@
                 }
             }
             _gridModel.initialize();
+
+            // todo: render the pager based on where (top / bottom) it is 
configured to render
             _gridModel.renderPager(_content);
             _gridModel.openTable(_content);
 
+            _renderState = CAPTION_RENDER_STATE;
+        }
+        else if(_renderState == CAPTION_RENDER_STATE)
+        {
+            // append the <table>'s <caption> if one was specified
+            if(_captionText != null)
+            {
+                _gridModel.openCaption(_content);
+                _content.append(_captionText);
+                _gridModel.closeCaption(_content);
+            }
+
             _renderState = GRID_RENDER_STATE;
         }
-        else if (_renderState == GRID_RENDER_STATE)
+        else if(_renderState == GRID_RENDER_STATE)
+        {
+            _renderState = FOOTER_RENDER_STATE;
+        }
+        else if(_renderState == FOOTER_RENDER_STATE)
         {
+            if(_footerText != null)
+            {
+                _gridModel.openFooterRow(_content);
+                _content.append(_footerText);
+                _gridModel.closeFooterRow(_content);
+            }
+
             _gridModel.closeTable(_content);
-            // todo: need something like this to un-init the data set / set 
the index to -1 / etc
-            //_gridModel.destroy();
+            _gridModel.uninitialize();
 
             _renderState = END_RENDER_STATE;
             retVal = SKIP_BODY;
         }
-        else throw new RuntimeException("The DataGrid's render state '" + 
_renderState + "' is invalid");
+        else throw new JspException("The DataGrid's render state '" + 
_renderState + "' is invalid");
 
         return retVal;
     }
@@ -174,12 +203,15 @@
     {
         super.localRelease();
 
-        _gridModel = new DataGridModel(this);
-        _cssClassPolicy = DEFAULT_STYLE_POLICY;
+        pageContext.removeAttribute("dataGrid");
+
+        _gridModel = null;
+        _cssClassPolicy = DEFAULT_STYLE_POLICY_VALUE;
         _renderState = START_RENDER_STATE;
-        _columnModelIndex = 0;
         _content = null;
         _name = null;
+        _captionText = null;
+        _footerText = null;
     }
 
     /* ===========================================================
@@ -188,31 +220,6 @@
      *
      * ===========================================================
      */
-    public void addColumn(ColumnModel cm)
-    {
-        if(_logger.isDebugEnabled()) _logger.debug("add a column: " + cm + " 
total columns: " + 
-                                                   (_gridModel.getColumns() != 
null ? _gridModel.getColumns().size() : 0));
-
-        _gridModel.addColumn(cm);
-    }
-
-    public ColumnModel getNextColumnModel()
-    {
-        ColumnModel cm = _gridModel.getColumn(_columnModelIndex);
-        _columnModelIndex++;
-        return cm;
-    }
-
-    public void resetColumnModelIndex()
-    {
-        _columnModelIndex = 0;
-    }
-    
-    public DataGridModel getDataGridModel()
-    {
-        return _gridModel;
-    }
-
     public int getRenderState()
     {
         return _renderState;
@@ -226,6 +233,16 @@
         _content.append(content);
     }
 
+    public void addCaption(String captionText)
+    {
+        _captionText = captionText;
+    }
+
+    public void addFooter(String footerText)
+    {
+        _footerText = footerText;
+    }
+
     /* ===========================================================
      *
      * IDataAccessProvider implementation
@@ -246,16 +263,7 @@
 
     public Object getCurrentMetadata()
     {
-        return _gridModel.getCurrentMetadata();
-    }
-
-    /**
-     * @netui:attribute required="true"
-     * @netui.tldx:attribute language="netuiexpression"
-     */
-    public void setDataSource(String dataSource)
-    {
-        _dataSource = dataSource;
+        throw new UnsupportedOperationException();
     }
 
     public String getDataSource()

Added: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Footer.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/Footer.java
   Wed Aug  4 16:38:26 2004
@@ -0,0 +1,82 @@
+/*
+ * B E A   S Y S T E M S
+ * Copyright 2002-2004  BEA Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.tags.databinding.datagrid;
+
+import javax.servlet.jsp.tagext.Tag;
+
+import org.apache.beehive.netui.tags.AbstractBaseTag;
+
+/**
+ * @netui:tag name="footer" description="Renders a footer into a NetUI data 
grid"
+ * @netui.tldx:tag whitespace="indent"
+ *                 netuiexpressioninfo="" renderer=""*
+ */
+public class Footer
+    extends AbstractBaseTag
+{
+    private DataGrid _dataGrid = null;
+
+    public String getTagName()
+    {
+        return "Footer";
+    }
+
+    public int doStartTag()
+    {
+        if(getDataGrid().getRenderState() == DataGrid.FOOTER_RENDER_STATE)
+            return EVAL_BODY_BUFFERED;
+        else return SKIP_BODY;
+    }
+
+    public int doEndTag()
+    {
+        if(bodyContent != null)
+        {
+            String footer = bodyContent.getString();
+            getDataGrid().addFooter(footer);
+        }
+
+        localRelease();
+        
+        return EVAL_PAGE;
+    }
+
+    public void localRelease()
+    {
+        super.localRelease();
+
+        _dataGrid = null;
+        if(bodyContent != null)
+            bodyContent.clearBody();
+    }
+
+    protected DataGrid getDataGrid()
+    {
+        if(_dataGrid != null)
+            return _dataGrid;
+
+        Tag dataGrid = findAncestorWithClass(this, DataGrid.class);
+
+        assert dataGrid != null;
+        _dataGrid = (DataGrid)dataGrid;
+
+        // todo: error reporting
+        return _dataGrid;
+    }
+}

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/ImageColumn.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/ImageColumn.java
      (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/ImageColumn.java
      Wed Aug  4 16:38:26 2004
@@ -124,15 +124,14 @@
 
     protected void setColumnModel(ColumnModel column)
     {
+        assert column != null : "Can't set a null ColumnModel";
         assert column instanceof ImageColumnModel;
         _column = (ImageColumnModel)column;
     }
 
-    protected ColumnModel getColumnModel()
+    protected ColumnModel createColumnModel()
     {
-        if(_column == null)
-            return (_column = new ImageColumnModel());
-        else return _column;
+        return new ImageColumnModel();
     }
 }
 

Modified: 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/LiteralColumn.java
==============================================================================
--- 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/LiteralColumn.java
    (original)
+++ 
incubator/beehive/trunk/netui/src/tags-databinding/org/apache/beehive/netui/tags/databinding/datagrid/LiteralColumn.java
    Wed Aug  4 16:38:26 2004
@@ -48,14 +48,13 @@
 
     protected void setColumnModel(ColumnModel column)
     {
+        assert column != null : "Can't set a null ColumnModel";
         assert column instanceof ColumnModel;
         _column = column;
     }
 
-    protected ColumnModel getColumnModel()
+    protected ColumnModel createColumnModel()
     {
-        if(_column == null)
-            return (_column = new ColumnModel());
-        else return _column;
+        return new ColumnModel();
     }
 }

Modified: incubator/beehive/trunk/netui/test/webapps/drt/build.xml
==============================================================================
--- incubator/beehive/trunk/netui/test/webapps/drt/build.xml    (original)
+++ incubator/beehive/trunk/netui/test/webapps/drt/build.xml    Wed Aug  4 
16:38:26 2004
@@ -174,6 +174,12 @@
         </ant>
     </target>
 
+    <target name="start.with.shmem.asserts" description="Start server with 
asserts enabled for org.apache.beehive.netui">
+        <ant antfile="${runTomcat.ant}" target="start.with.shmem" 
inheritAll="false">
+            <property name="java.options" 
value="-ea:org.apache.beehive.netui..."/>
+        </ant>
+    </target>
+
     <target name="stop" description="Stop server">
         <ant antfile="${runTomcat.ant}" target="stop" inheritAll="false"/>
     </target>

Added: 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/caption/index.jsp
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/caption/index.jsp
       Wed Aug  4 16:38:26 2004
@@ -0,0 +1,30 @@
+<%@ page language="java" contentType="text/html;charset=UTF-8"%>
+<%@ taglib uri="beehive-netui-tags-html.tld" prefix="netui"%>
+<%@ taglib uri="beehive-netui-tags-databinding.tld" prefix="netui-data"%>
+<%@ taglib uri="beehive-netui-tags-template.tld" prefix="netui-template"%>
+<%@ page 
import="org.apache.beehive.netui.script.common.DataAccessProviderBean"%>
+<netui-template:template templatePage="../site/template.jsp">
+    <netui-template:setAttribute name="title" value="Basic Data Grid"/>
+    <netui-template:section name="body">
+    <p>
+<%@ include file="../util/portfolioXmlBean.jsp" %>
+<br/>
+<netui-data:dataGrid dataSource="pageScope.stocks" name="portfolio">
+    <netui-data:caption>
+        This is the table's caption.    
+    </netui-data:caption>
+    <netui-data:columns defaultSortable="true" defaultFilterable="false" 
sortAction="index.jsp" filterAction="index.jsp">
+        <netui-data:literalColumn headerText="Symbol" 
value="${container.item.symbol}" sortExpression="symbol"/>
+        <netui-data:literalColumn sortable="false" headerText="Price" 
value="${container.item.price}"/>
+        <netui-data:anchorColumn headerText="Web" href="${container.item.web}" 
value="${container.item.name}">
+            <netui:parameter name="rowid" value="${container.index}"/>
+            <netui:parameter name="symbol" value="${container.item.symbol}"/>
+        </netui-data:anchorColumn>
+    </netui-data:columns>
+</netui-data:dataGrid>
+<br/>
+<netui:anchor href="index.jsp">Reset</netui:anchor>
+<br/>
+    </p>
+    </netui-template:section>
+</netui-template:template>

Added: 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/footer/index.jsp
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/footer/index.jsp
        Wed Aug  4 16:38:26 2004
@@ -0,0 +1,30 @@
+<%@ page language="java" contentType="text/html;charset=UTF-8"%>
+<%@ taglib uri="beehive-netui-tags-html.tld" prefix="netui"%>
+<%@ taglib uri="beehive-netui-tags-databinding.tld" prefix="netui-data"%>
+<%@ taglib uri="beehive-netui-tags-template.tld" prefix="netui-template"%>
+<%@ page 
import="org.apache.beehive.netui.script.common.DataAccessProviderBean"%>
+<netui-template:template templatePage="../site/template.jsp">
+    <netui-template:setAttribute name="title" value="Basic Data Grid"/>
+    <netui-template:section name="body">
+    <p>
+<%@ include file="../util/portfolioXmlBean.jsp" %>
+<br/>
+<netui-data:dataGrid dataSource="pageScope.stocks" name="portfolio">
+    <netui-data:columns defaultSortable="true" defaultFilterable="false" 
sortAction="index.jsp" filterAction="index.jsp">
+        <netui-data:literalColumn headerText="Symbol" 
value="${container.item.symbol}" sortExpression="symbol"/>
+        <netui-data:literalColumn sortable="false" headerText="Price" 
value="${container.item.price}"/>
+        <netui-data:anchorColumn headerText="Web" href="${container.item.web}" 
value="${container.item.name}">
+            <netui:parameter name="rowid" value="${container.index}"/>
+            <netui:parameter name="symbol" value="${container.item.symbol}"/>
+        </netui-data:anchorColumn>
+    </netui-data:columns>
+    <netui-data:footer>
+        <td colspan="4"><center>This is the grid's footer</center></td>
+    </netui-data:footer>
+</netui-data:dataGrid>
+<br/>
+<netui:anchor href="index.jsp">Reset</netui:anchor>
+<br/>
+    </p>
+    </netui-template:section>
+</netui-template:template>

Added: 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/header/index.jsp
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/databinding/datagrid/header/index.jsp
        Wed Aug  4 16:38:26 2004
@@ -0,0 +1,46 @@
+<%@ page language="java" contentType="text/html;charset=UTF-8"%>
+<%@ taglib uri="beehive-netui-tags-html.tld" prefix="netui"%>
+<%@ taglib uri="beehive-netui-tags-databinding.tld" prefix="netui-data"%>
+<%@ taglib uri="beehive-netui-tags-template.tld" prefix="netui-template"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core"; prefix="c" %>
+
+<netui-template:template templatePage="../site/template.jsp">
+    <netui-template:setAttribute name="title" value="Basic Data Grid"/>
+    <netui-template:section name="body">
+    <p>
+<%@ include file="../util/portfolioXmlBean.jsp" %>
+<br/>
+<netui-data:dataGrid dataSource="pageScope.stocks" name="portfolio">
+    <netui-data:columns defaultSortable="true" defaultFilterable="false" 
sortAction="index.jsp" filterAction="index.jsp">
+        <netui-data:literalColumn value="${container.item.symbol}" 
sortExpression="symbol">
+            <c:if test="${column.renderingHeader}">
+                <netui:anchor href="index.jsp">Symbol Anchor</netui:anchor>
+            </c:if>
+        </netui-data:literalColumn>
+        <netui-data:literalColumn headerText="Price" sortable="false" 
value="${container.item.price}">
+            <c:if test="${column.renderingHeader}">
+                Should not render this.
+            </c:if>
+<%--
+            <c:if test="${column.renderingData}">
+                <netui:formatNumber pattern="$####.00" type="currency" 
country="us" language="en"/>
+            </c:if>
+--%>
+        </netui-data:literalColumn>
+        <netui-data:anchorColumn href="${container.item.web}" 
value="${container.item.name}">
+            <c:if test="${column.renderingHeader}">
+                Web URL
+            </c:if>
+            <c:if test="${column.renderingData}">
+                <netui:parameter name="rowid" value="${container.index}"/>
+                <netui:parameter name="symbol" 
value="${container.item.symbol}"/>
+            </c:if>
+        </netui-data:anchorColumn>
+    </netui-data:columns>
+</netui-data:dataGrid>
+<br/>
+<netui:anchor href="index.jsp">Reset</netui:anchor>
+<br/>
+    </p>
+    </netui-template:section>
+</netui-template:template>

Modified: 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
==============================================================================
--- 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
   (original)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
   Wed Aug  4 16:38:26 2004
@@ -1886,6 +1886,45 @@
          </features>
       </test>
       <test>
+         <name>DataGridCaptionTest</name>
+         <description>DataGridCaptionTest</description>
+         <webapp>coreWeb</webapp>
+         <categories>
+            <category>bvt</category>
+            <category>databinding</category>
+         </categories>
+         <features>
+            <feature>Databinding</feature>
+            <feature>Data Grid</feature>
+         </features>
+      </test>
+      <test>
+         <name>DataGridFooterTest</name>
+         <description>DataGridFooterTest</description>
+         <webapp>coreWeb</webapp>
+         <categories>
+            <category>bvt</category>
+            <category>databinding</category>
+         </categories>
+         <features>
+            <feature>Databinding</feature>
+            <feature>Data Grid</feature>
+         </features>
+      </test>
+      <test>
+         <name>DataGridHeaderTest</name>
+         <description>DataGridHeaderTest</description>
+         <webapp>coreWeb</webapp>
+         <categories>
+            <category>bvt</category>
+            <category>databinding</category>
+         </categories>
+         <features>
+            <feature>Databinding</feature>
+            <feature>Data Grid</feature>
+         </features>
+      </test>
+      <test>
          <name>DateConverter</name>
          <description>Date Converter on post.</description>
          <webapp>coreWeb</webapp>

Added: 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridCaptionTest.xml
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridCaptionTest.xml
   Wed Aug  4 16:38:26 2004
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ses:recorderSession 
xmlns:ses="http://beehive.apache.org/netui/tools/testrecorder/2004/session";>
+   <ses:sessionName>DataGridCaptionTest</ses:sessionName>
+   <ses:tester>ekoneil</ses:tester>
+   <ses:startDate>04 Aug 2004, 09:43:21.759 AM MDT</ses:startDate>
+   <ses:description>Simple test of the caption tag in the data 
grid.</ses:description>
+   <ses:tests>
+      <ses:test>
+         <ses:testNumber>1</ses:testNumber>
+         <ses:request>
+            <ses:protocol>HTTP</ses:protocol>
+            <ses:protocolVersion>1.1</ses:protocolVersion>
+            <ses:host>localhost</ses:host>
+            <ses:port>8080</ses:port>
+            <ses:uri>/coreWeb/databinding/datagrid/caption/index.jsp</ses:uri>
+            <ses:method>GET</ses:method>
+            <ses:parameters/>
+            <ses:cookies>
+               <ses:cookie>
+                  <ses:name>JSESSIONID</ses:name>
+                  <ses:value>4CFAEE21E4A8FF521459C22B2DB33C3C</ses:value>
+               </ses:cookie>
+            </ses:cookies>
+            <ses:headers>
+               <ses:header>
+                  <ses:name>accept</ses:name>
+                  
<ses:value>text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-charset</ses:name>
+                  <ses:value>ISO-8859-1,utf-8;q=0.7,*;q=0.7</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-encoding</ses:name>
+                  <ses:value>gzip,deflate</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-language</ses:name>
+                  <ses:value>en-us,en;q=0.5</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>connection</ses:name>
+                  <ses:value>keep-alive</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>cookie</ses:name>
+                  
<ses:value>JSESSIONID=4CFAEE21E4A8FF521459C22B2DB33C3C</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>host</ses:name>
+                  <ses:value>localhost:8080</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>keep-alive</ses:name>
+                  <ses:value>300</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>user-agent</ses:name>
+                  <ses:value>Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; 
rv:1.7) Gecko/20040614 Firefox/0.9</ses:value>
+               </ses:header>
+            </ses:headers>
+         </ses:request>
+         <ses:response>
+            <ses:statusCode>200</ses:statusCode>
+            <ses:reason/>
+            <ses:responseBody><![CDATA[<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 
4.01 Transitional//EN"
+       "http://www.w3.org/TR/html4/loose.dtd";>
+<html lang="en">
+<head>
+    <title>NetUI Data Grid Samples</title>
+    <link rel="stylesheet" 
href="/coreWeb/databinding/datagrid/site/css/default.css" type="text/css"/>
+  </head>
+  <base 
href="http://localhost:8080/coreWeb/databinding/datagrid/caption/index.jsp";>
+  <body>
+    <p>
+    <b>Basic Data Grid</b>
+    <table width="100%">
+    <tr><td></td></tr>
+    <tr><td>
+        
+    <p>
+
+
+
+<br/>
+Page 1 of 1&nbsp;&nbsp;
+<table class="datagrid"><caption>
+        This is the table's caption.    
+    </caption>
+
+<thead>
+<tr class="datagrid-header"><th class="datagrid-header-cell">Symbol</th>
+<th class="datagrid-header-cell">Price</th>
+<th class="datagrid-header-cell">Web</th>
+</tr>
+</thead>
+
+<tr class="datagrid-even"><td class="datagrid-data-cell">BEAS</td><td 
class="datagrid-data-cell">14.35</td><td class="datagrid-data-cell"><a 
href="http://www.bea.com?rowid=1&symbol=BEAS";><span>BEA 
Systems</span></a></td></tr>
+<tr class="datagrid-odd"><td class="datagrid-data-cell">CSCO</td><td 
class="datagrid-data-cell">19.42</td><td class="datagrid-data-cell"><a 
href="http://www.cisco.com?rowid=2&symbol=CSCO";><span>Cisco 
Systems</span></a></td></tr>
+<tr class="datagrid-even"><td class="datagrid-data-cell">GE</td><td 
class="datagrid-data-cell">59.42</td><td class="datagrid-data-cell"><a 
href="http://www.ge.com?rowid=3&symbol=GE";><span>General 
Electric</span></a></td></tr>
+<tr class="datagrid-odd"><td class="datagrid-data-cell">RHAT</td><td 
class="datagrid-data-cell">18.2</td><td class="datagrid-data-cell"><a 
href="http://www.redhat.com?rowid=4&symbol=RHAT";><span>RedHat 
Systems</span></a></td></tr>
+<tr class="datagrid-even"><td class="datagrid-data-cell">YHOO</td><td 
class="datagrid-data-cell">48.16</td><td class="datagrid-data-cell"><a 
href="http://www.yahoo.com?rowid=5&symbol=YHOO";><span>Yahoo 
Inc</span></a></td></tr>
+</table>
+
+<br/>
+<a href="/coreWeb/databinding/datagrid/caption/index.jsp">Reset</a>
+<br/>
+    </p>
+    
+    </td></tr>
+    </p>
+    <table>
+    <tr><td><a 
href="/netuiDRT/databinding/datagrid/basic/index.jsp">Home</a></td></tr>
+    </table>
+    </p>
+  </body>
+</html>]]></ses:responseBody>
+         </ses:response>
+      </ses:test>
+   </ses:tests>
+   <ses:endDate>04 Aug 2004, 09:43:25.014 AM MDT</ses:endDate>
+   <ses:testCount>1</ses:testCount>
+</ses:recorderSession>

Added: 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridFooterTest.xml
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridFooterTest.xml
    Wed Aug  4 16:38:26 2004
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ses:recorderSession 
xmlns:ses="http://beehive.apache.org/netui/tools/testrecorder/2004/session";>
+   <ses:sessionName>DataGridFooterTest</ses:sessionName>
+   <ses:tester>ekoneil</ses:tester>
+   <ses:startDate>04 Aug 2004, 03:55:53.109 PM MDT</ses:startDate>
+   <ses:description>Simple test of rendering a footer row in a data 
grid.</ses:description>
+   <ses:tests>
+      <ses:test>
+         <ses:testNumber>1</ses:testNumber>
+         <ses:request>
+            <ses:protocol>HTTP</ses:protocol>
+            <ses:protocolVersion>1.1</ses:protocolVersion>
+            <ses:host>localhost</ses:host>
+            <ses:port>8080</ses:port>
+            <ses:uri>/coreWeb/databinding/datagrid/footer/index.jsp</ses:uri>
+            <ses:method>GET</ses:method>
+            <ses:parameters/>
+            <ses:cookies>
+               <ses:cookie>
+                  <ses:name>JSESSIONID</ses:name>
+                  <ses:value>408DF8F5DC69FAA9EEE7A4B6579246E8</ses:value>
+               </ses:cookie>
+            </ses:cookies>
+            <ses:headers>
+               <ses:header>
+                  <ses:name>accept</ses:name>
+                  
<ses:value>text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-charset</ses:name>
+                  <ses:value>ISO-8859-1,utf-8;q=0.7,*;q=0.7</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-encoding</ses:name>
+                  <ses:value>gzip,deflate</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-language</ses:name>
+                  <ses:value>en-us,en;q=0.5</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>connection</ses:name>
+                  <ses:value>keep-alive</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>cookie</ses:name>
+                  
<ses:value>JSESSIONID=408DF8F5DC69FAA9EEE7A4B6579246E8</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>host</ses:name>
+                  <ses:value>localhost:8080</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>keep-alive</ses:name>
+                  <ses:value>300</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>user-agent</ses:name>
+                  <ses:value>Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; 
rv:1.7) Gecko/20040614 Firefox/0.9</ses:value>
+               </ses:header>
+            </ses:headers>
+         </ses:request>
+         <ses:response>
+            <ses:statusCode>200</ses:statusCode>
+            <ses:reason/>
+            <ses:responseBody><![CDATA[<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 
4.01 Transitional//EN"
+       "http://www.w3.org/TR/html4/loose.dtd";>
+<html lang="en">
+<head>
+    <title>NetUI Data Grid Samples</title>
+    <link rel="stylesheet" 
href="/coreWeb/databinding/datagrid/site/css/default.css" type="text/css"/>
+  </head>
+  <base 
href="http://localhost:8080/coreWeb/databinding/datagrid/footer/index.jsp";>
+  <body>
+    <p>
+    <b>Basic Data Grid</b>
+    <table width="100%">
+    <tr><td></td></tr>
+    <tr><td>
+        
+    <p>
+
+
+
+<br/>
+Page 1 of 1&nbsp;&nbsp;
+<table class="datagrid">
+<thead>
+<tr class="datagrid-header"><th class="datagrid-header-cell">Symbol</th>
+<th class="datagrid-header-cell">Price</th>
+<th class="datagrid-header-cell">Web</th>
+</tr>
+</thead>
+
+<tr class="datagrid-even"><td class="datagrid-data-cell">BEAS</td><td 
class="datagrid-data-cell">14.35</td><td class="datagrid-data-cell"><a 
href="http://www.bea.com?rowid=1&symbol=BEAS";><span>BEA 
Systems</span></a></td></tr>
+<tr class="datagrid-odd"><td class="datagrid-data-cell">CSCO</td><td 
class="datagrid-data-cell">19.42</td><td class="datagrid-data-cell"><a 
href="http://www.cisco.com?rowid=2&symbol=CSCO";><span>Cisco 
Systems</span></a></td></tr>
+<tr class="datagrid-even"><td class="datagrid-data-cell">GE</td><td 
class="datagrid-data-cell">59.42</td><td class="datagrid-data-cell"><a 
href="http://www.ge.com?rowid=3&symbol=GE";><span>General 
Electric</span></a></td></tr>
+<tr class="datagrid-odd"><td class="datagrid-data-cell">RHAT</td><td 
class="datagrid-data-cell">18.2</td><td class="datagrid-data-cell"><a 
href="http://www.redhat.com?rowid=4&symbol=RHAT";><span>RedHat 
Systems</span></a></td></tr>
+<tr class="datagrid-even"><td class="datagrid-data-cell">YHOO</td><td 
class="datagrid-data-cell">48.16</td><td class="datagrid-data-cell"><a 
href="http://www.yahoo.com?rowid=5&symbol=YHOO";><span>Yahoo 
Inc</span></a></td></tr>
+<tr class="datagrid-footer">
+        <td colspan="4"><center>This is the grid's footer</center></td>
+    
+</tr>
+</table>
+
+<br/>
+<a href="/coreWeb/databinding/datagrid/footer/index.jsp">Reset</a>
+<br/>
+    </p>
+    
+    </td></tr>
+    </p>
+    <table>
+    <tr><td><a 
href="/netuiDRT/databinding/datagrid/basic/index.jsp">Home</a></td></tr>
+    </table>
+    </p>
+  </body>
+</html>]]></ses:responseBody>
+         </ses:response>
+      </ses:test>
+   </ses:tests>
+   <ses:endDate>04 Aug 2004, 03:55:58.397 PM MDT</ses:endDate>
+   <ses:testCount>1</ses:testCount>
+</ses:recorderSession>

Added: 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridHeaderTest.xml
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DataGridHeaderTest.xml
    Wed Aug  4 16:38:26 2004
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ses:recorderSession 
xmlns:ses="http://beehive.apache.org/netui/tools/testrecorder/2004/session";>
+   <ses:sessionName>DataGridHeaderTest</ses:sessionName>
+   <ses:tester>ekoneil</ses:tester>
+   <ses:startDate>04 Aug 2004, 09:42:35.713 AM MDT</ses:startDate>
+   <ses:description>Simple test of customized headers in the data 
grid.</ses:description>
+   <ses:tests>
+      <ses:test>
+         <ses:testNumber>1</ses:testNumber>
+         <ses:request>
+            <ses:protocol>HTTP</ses:protocol>
+            <ses:protocolVersion>1.1</ses:protocolVersion>
+            <ses:host>localhost</ses:host>
+            <ses:port>8080</ses:port>
+            <ses:uri>/coreWeb/databinding/datagrid/header/index.jsp</ses:uri>
+            <ses:method>GET</ses:method>
+            <ses:parameters/>
+            <ses:cookies>
+               <ses:cookie>
+                  <ses:name>JSESSIONID</ses:name>
+                  <ses:value>4CFAEE21E4A8FF521459C22B2DB33C3C</ses:value>
+               </ses:cookie>
+            </ses:cookies>
+            <ses:headers>
+               <ses:header>
+                  <ses:name>accept</ses:name>
+                  
<ses:value>text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-charset</ses:name>
+                  <ses:value>ISO-8859-1,utf-8;q=0.7,*;q=0.7</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-encoding</ses:name>
+                  <ses:value>gzip,deflate</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-language</ses:name>
+                  <ses:value>en-us,en;q=0.5</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>connection</ses:name>
+                  <ses:value>keep-alive</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>cookie</ses:name>
+                  
<ses:value>JSESSIONID=4CFAEE21E4A8FF521459C22B2DB33C3C</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>host</ses:name>
+                  <ses:value>localhost:8080</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>keep-alive</ses:name>
+                  <ses:value>300</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>user-agent</ses:name>
+                  <ses:value>Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; 
rv:1.7) Gecko/20040614 Firefox/0.9</ses:value>
+               </ses:header>
+            </ses:headers>
+         </ses:request>
+         <ses:response>
+            <ses:statusCode>200</ses:statusCode>
+            <ses:reason/>
+            <ses:responseBody><![CDATA[<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 
4.01 Transitional//EN"
+       "http://www.w3.org/TR/html4/loose.dtd";>
+<html lang="en">
+<head>
+    <title>NetUI Data Grid Samples</title>
+    <link rel="stylesheet" 
href="/coreWeb/databinding/datagrid/site/css/default.css" type="text/css"/>
+  </head>
+  <base 
href="http://localhost:8080/coreWeb/databinding/datagrid/header/index.jsp";>
+  <body>
+    <p>
+    <b>Basic Data Grid</b>
+    <table width="100%">
+    <tr><td></td></tr>
+    <tr><td>
+        
+    <p>
+
+
+
+<br/>
+Page 1 of 1&nbsp;&nbsp;
+<table class="datagrid">
+<thead>
+<tr class="datagrid-header"><th class="datagrid-header-cell">
+            
+                <a 
href="/coreWeb/databinding/datagrid/header/index.jsp">Symbol Anchor</a>
+            
+        </th>
+<th class="datagrid-header-cell">Price</th>
+<th class="datagrid-header-cell">
+            
+                Web URL
+            
+            
+        </th>
+</tr>
+</thead>
+
+<tr class="datagrid-even"><td class="datagrid-data-cell">BEAS</td><td 
class="datagrid-data-cell">14.35</td><td class="datagrid-data-cell"><a 
href="http://www.bea.com?rowid=1&symbol=BEAS";><span>BEA 
Systems</span></a></td></tr>
+<tr class="datagrid-odd"><td class="datagrid-data-cell">CSCO</td><td 
class="datagrid-data-cell">19.42</td><td class="datagrid-data-cell"><a 
href="http://www.cisco.com?rowid=2&symbol=CSCO";><span>Cisco 
Systems</span></a></td></tr>
+<tr class="datagrid-even"><td class="datagrid-data-cell">GE</td><td 
class="datagrid-data-cell">59.42</td><td class="datagrid-data-cell"><a 
href="http://www.ge.com?rowid=3&symbol=GE";><span>General 
Electric</span></a></td></tr>
+<tr class="datagrid-odd"><td class="datagrid-data-cell">RHAT</td><td 
class="datagrid-data-cell">18.2</td><td class="datagrid-data-cell"><a 
href="http://www.redhat.com?rowid=4&symbol=RHAT";><span>RedHat 
Systems</span></a></td></tr>
+<tr class="datagrid-even"><td class="datagrid-data-cell">YHOO</td><td 
class="datagrid-data-cell">48.16</td><td class="datagrid-data-cell"><a 
href="http://www.yahoo.com?rowid=5&symbol=YHOO";><span>Yahoo 
Inc</span></a></td></tr>
+</table>
+
+<br/>
+<a href="/coreWeb/databinding/datagrid/header/index.jsp">Reset</a>
+<br/>
+    </p>
+    
+    </td></tr>
+    </p>
+    <table>
+    <tr><td><a 
href="/netuiDRT/databinding/datagrid/basic/index.jsp">Home</a></td></tr>
+    </table>
+    </p>
+  </body>
+</html>]]></ses:responseBody>
+         </ses:response>
+      </ses:test>
+   </ses:tests>
+   <ses:endDate>04 Aug 2004, 09:42:40.981 AM MDT</ses:endDate>
+   <ses:testCount>1</ses:testCount>
+</ses:recorderSession>

Reply via email to